Merge "Fixes - config-registry registered to OSGi, used modules's factory bundle...
authorEd Warnicke <eaw@cisco.com>
Wed, 27 Nov 2013 22:14:08 +0000 (22:14 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 27 Nov 2013 22:14:08 +0000 (22:14 +0000)
198 files changed:
opendaylight/arphandler/pom.xml
opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/ArpHandler.java
opendaylight/commons/opendaylight/pom.xml
opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleFactory.java
opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleTest.java
opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleWithInitialConfigurationTest.java
opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackWithXmlConfigModuleTest.java
opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java
opendaylight/configuration/integrationtest/pom.xml
opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerConfig.java
opendaylight/distribution/opendaylight/pom.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini
opendaylight/distribution/opendaylight/src/main/resources/configuration/controller.config [new file with mode: 0644]
opendaylight/forwarding/staticrouting/pom.xml
opendaylight/forwarding/staticrouting/src/main/java/org/opendaylight/controller/forwarding/staticrouting/internal/StaticRoutingImplementation.java
opendaylight/forwardingrulesmanager/api/pom.xml
opendaylight/forwardingrulesmanager/implementation/pom.xml
opendaylight/forwardingrulesmanager/integrationtest/pom.xml
opendaylight/hosttracker/api/pom.xml
opendaylight/hosttracker/api/src/main/java/org/opendaylight/controller/hosttracker/HostIdFactory.java [new file with mode: 0644]
opendaylight/hosttracker/api/src/main/java/org/opendaylight/controller/hosttracker/IHostId.java [new file with mode: 0644]
opendaylight/hosttracker/api/src/main/java/org/opendaylight/controller/hosttracker/IPHostId.java [new file with mode: 0644]
opendaylight/hosttracker/api/src/main/java/org/opendaylight/controller/hosttracker/IPMacHostId.java [new file with mode: 0644]
opendaylight/hosttracker/api/src/main/java/org/opendaylight/controller/hosttracker/IfIptoHost.java
opendaylight/hosttracker/implementation/pom.xml
opendaylight/hosttracker/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/HostTracker.java
opendaylight/hosttracker/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/HostTrackerCallable.java
opendaylight/hosttracker/implementation/src/test/java/org/opendaylight/controller/hosttracker/internal/HostTrackerTest.java
opendaylight/hosttracker/integrationtest/pom.xml
opendaylight/hosttracker/integrationtest/src/test/java/org/opendaylight/controller/hosttracker/internal/HostTrackerIT.java
opendaylight/md-sal/forwardingrules-manager/pom.xml
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FRMUtil.java
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FlowConsumerImpl.java
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/GroupConsumerImpl.java
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/MeterConsumerImpl.java
opendaylight/md-sal/model/model-flow-base/src/main/yang/flow-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/queue-types.yang [new file with mode: 0644]
opendaylight/md-sal/model/model-flow-base/src/main/yang/table-types.yang
opendaylight/md-sal/model/model-flow-management/src/main/yang/queue-config.yang [new file with mode: 0644]
opendaylight/md-sal/model/model-flow-service/src/main/yang/group-service.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/port-service.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/queue-service.yang [new file with mode: 0644]
opendaylight/md-sal/model/pom.xml
opendaylight/md-sal/pom.xml
opendaylight/md-sal/sal-binding-broker/pom.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplSingletonModule.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplSingletonModuleFactory.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RpcBrokerImplModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RpcBrokerImplModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRoutingTableImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RuntimeCodeGenerator.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/BindingClassListener.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/CodecMapping.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/GeneratorListener.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/InstanceIdentifierCodecImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/RuntimeGeneratedMappingServiceImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataTransactionImpl.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentDataServiceConnector.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMappingService.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CommitHandlersTransactions.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/ConnectorActivator.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DataModificationTracker.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DeserializationException.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingContext.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/AbstractDataServiceTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug01Test.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug02Test.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug03Test.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/RpcRegistrationNullPointer.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-config/src/main/yang/opendaylight-md-sal-binding.yang
opendaylight/md-sal/sal-binding-it/pom.xml
opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java
opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/AbstractTest.java
opendaylight/md-sal/sal-binding-it/src/test/resources/controller.config [new file with mode: 0644]
opendaylight/md-sal/sal-binding-it/src/test/resources/logback.xml
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/RegistrationListener.java [new file with mode: 0644]
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataChangeEvent.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataCommitHandlerRegistration.java [new file with mode: 0644]
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataProvisionService.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/AbstractDataModification.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/DataChangeEventImpl.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/InitialDataChangeEventImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/AbstractLockableDelegator.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-api/pom.xml
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataStore.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-api/src/main/yang/opendaylight-md-sal-common.yang [new file with mode: 0644]
opendaylight/md-sal/sal-dom-api/src/main/yang/opendaylight-md-sal-dom.yang [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/pom.xml
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomBrokerImplModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomBrokerImplModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/HashMapDataStoreModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/HashMapDataStoreModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerActivator.java [deleted file]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.xtend [new file with mode: 0644]
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/DataBrokerImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataTransactionImpl.java
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/SchemaServiceImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataStoreStatsWrapper.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataUtils.xtend [deleted file]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/HashMapDataStore.xtend
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataMerger.xtend [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/DataProviderServiceProxy.java
opendaylight/md-sal/sal-dom-broker/src/main/yang/opendaylight-dom-broker-impl.yang [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/pom.xml
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceManager.xtend [deleted file]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfProvider.java [deleted file]
opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft01.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonToCompositeNodeProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToJsonProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToXmlProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlReader.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToCompositeNodeProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/MediaTypes.java [deleted file]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ResponseException.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/StructuredData.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/FromJsonToCompositeNodeTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/FromXmlToCompositeNodeTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonBasicDataTypesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonWithAugmentTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-composite-node/data-container-yang/data-container.yang
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-composite-node/data-container.xml
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-container.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaf.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaflist.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-list.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/xml/data.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/yang.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-data-types/simple-data-types.yang
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-data-types/xml/data.xml
opendaylight/md-sal/samples/pom.xml
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsManagerActivator.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java
opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java
opendaylight/md-sal/topology-manager/pom.xml [new file with mode: 0644]
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend [new file with mode: 0644]
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/Rpcs.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/rpc.xml
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/rpcInner.xml
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/rpcInnerInner.xml
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/rpcInnerInner_complex_output.xml
opendaylight/northbound/containermanager/src/main/java/org/opendaylight/controller/containermanager/northbound/ContainerConfigs.java
opendaylight/northbound/containermanager/src/main/java/org/opendaylight/controller/containermanager/northbound/ContainerManagerNorthbound.java
opendaylight/northbound/hosttracker/pom.xml
opendaylight/northbound/integrationtest/pom.xml
opendaylight/northbound/staticrouting/pom.xml
opendaylight/samples/loadbalancer/pom.xml
opendaylight/samples/loadbalancer/src/main/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerService.java
opendaylight/samples/northbound/loadbalancer/pom.xml
opendaylight/statisticsmanager/integrationtest/pom.xml
opendaylight/topologymanager/integrationtest/pom.xml
opendaylight/web/devices/pom.xml

index 8f1f4d5d2e7a85da93715a1ebba4cb66e3137a78..e3576e6ed86cc9284243be20f57358bbe7ce331b 100644 (file)
@@ -14,7 +14,7 @@
     <tag>HEAD</tag>
   </scm>
   <artifactId>arphandler</artifactId>
-  <version>0.4.1-SNAPSHOT</version>
+  <version>0.5.1-SNAPSHOT</version>
   <packaging>bundle</packaging>
 
   <build>
@@ -27,6 +27,7 @@
         <configuration>
           <instructions>
             <Import-Package>
+              org.opendaylight.controller.sal.packet.address,
               org.opendaylight.controller.connectionmanager,
               org.opendaylight.controller.sal.connection,
               org.opendaylight.controller.sal.core,
@@ -72,7 +73,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index abe104a40638f1a58e47fdcc5f91eda6b1f87359..8c91c71533a19282c9f1c48e8697dd3f81d181ee 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
@@ -37,6 +36,8 @@ import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
 import org.opendaylight.controller.clustering.services.IClusterServices;
 import org.opendaylight.controller.connectionmanager.IConnectionManager;
+import org.opendaylight.controller.hosttracker.HostIdFactory;
+import org.opendaylight.controller.hosttracker.IHostId;
 import org.opendaylight.controller.hosttracker.IfHostListener;
 import org.opendaylight.controller.hosttracker.IfIptoHost;
 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
@@ -80,27 +81,29 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
     private BlockingQueue<ARPCacheEvent> ARPCacheEvents = new LinkedBlockingQueue<ARPCacheEvent>();
     private Thread cacheEventHandler;
     private boolean stopping = false;
+
     /*
      * A cluster allocated cache. Used for synchronizing ARP request/reply
-     * events across all cluster controllers. To raise an event, we put() a specific
-     * event object (as key) and all nodes handle it in the entryUpdated callback.
+     * events across all cluster controllers. To raise an event, we put() a
+     * specific event object (as key) and all nodes handle it in the
+     * entryUpdated callback.
      *
      * In case of ARPReply, we put true value to send replies to any requestors
      * by calling generateAndSendReply
      */
     private ConcurrentMap<ARPEvent, Boolean> arpRequestReplyEvent;
 
-    void setConnectionManager(IConnectionManager cm){
+    void setConnectionManager(IConnectionManager cm) {
         this.connectionManager = cm;
     }
 
-    void unsetConnectionManager(IConnectionManager cm){
-        if (this.connectionManager == cm){
+    void unsetConnectionManager(IConnectionManager cm) {
+        if (this.connectionManager == cm) {
             connectionManager = null;
         }
     }
 
-    void setClusterContainerService(IClusterContainerServices s){
+    void setClusterContainerService(IClusterContainerServices s) {
         this.clusterContainerService = s;
     }
 
@@ -164,11 +167,10 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
         }
     }
 
-    protected void sendARPReply(NodeConnector p, byte[] sMAC, InetAddress sIP,
-            byte[] tMAC, InetAddress tIP) {
+    protected void sendARPReply(NodeConnector p, byte[] sMAC, InetAddress sIP, byte[] tMAC, InetAddress tIP) {
         byte[] senderIP = sIP.getAddress();
         byte[] targetIP = tIP.getAddress();
-        ARP arp = createARP(ARP.REPLY,sMAC,senderIP,tMAC,targetIP);
+        ARP arp = createARP(ARP.REPLY, sMAC, senderIP, tMAC, targetIP);
 
         Ethernet ethernet = createEthernet(sMAC, tMAC, arp);
 
@@ -214,8 +216,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
 
         // Make sure that the host is a legitimate member of this subnet
         if (!subnet.hasNodeConnector(p)) {
-            log.debug("{} showing up on {} does not belong to {}",
-                    new Object[] { sourceIP, p, subnet });
+            log.debug("{} showing up on {} does not belong to {}", new Object[] { sourceIP, p, subnet });
             return;
         }
 
@@ -237,9 +238,9 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
         }
 
         /*
-         * OpCode != request -> ARP Reply. If there are hosts (in
-         * arpRequestors) waiting for the ARP reply for this sourceIP, it's
-         * time to generate the reply and send it to these hosts.
+         * OpCode != request -> ARP Reply. If there are hosts (in arpRequestors)
+         * waiting for the ARP reply for this sourceIP, it's time to generate
+         * the reply and send it to these hosts.
          *
          * If sourceIP==targetIP, it is a Gratuitous ARP. If there are hosts (in
          * arpRequestors) waiting for the ARP reply for this sourceIP, it's time
@@ -247,27 +248,29 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
          */
 
         if (pkt.getOpCode() != ARP.REQUEST || sourceIP.equals(targetIP)) {
-            // Raise a reply event so that any waiting requestors will be sent a reply
-            // the true value indicates we should generate replies to requestors across the cluster
+            // Raise a reply event so that any waiting requestors will be sent a
+            // reply
+            // the true value indicates we should generate replies to requestors
+            // across the cluster
             log.trace("Received ARP reply packet from {}, reply to all requestors.", sourceIP);
             arpRequestReplyEvent.put(new ARPReply(sourceIP, sourceMAC), true);
             return;
         }
 
         /*
-         * ARP Request Handling:
-         * If targetIP is the IP of the subnet, reply with ARP REPLY
-         * If targetIP is a known host, PROXY ARP (by sending ARP REPLY) on behalf of known target hosts.
-         * For unknown target hosts, generate and send an ARP request to ALL switches/ports using
-         * the IP address defined in the subnet as source address
+         * ARP Request Handling: If targetIP is the IP of the subnet, reply with
+         * ARP REPLY If targetIP is a known host, PROXY ARP (by sending ARP
+         * REPLY) on behalf of known target hosts. For unknown target hosts,
+         * generate and send an ARP request to ALL switches/ports using the IP
+         * address defined in the subnet as source address
          */
         /*
          * If target IP is gateway IP, Send ARP reply
          */
         if ((targetIP.equals(subnet.getNetworkAddress()))
                 && (NetUtils.isBroadcastMACAddr(targetMAC) || Arrays.equals(targetMAC, getControllerMAC()))) {
-            if (connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL){
-                if (log.isTraceEnabled()){
+            if (connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL) {
+                if (log.isTraceEnabled()) {
                     log.trace("Received local ARP req. for default gateway. Replying with controller MAC: {}",
                             HexEncode.bytesToHexString(getControllerMAC()));
                 }
@@ -280,8 +283,9 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
             return;
         }
 
-
-        HostNodeConnector host = hostTracker.hostQuery(targetIP);
+        // Hosttracker hosts db key implementation
+        IHostId id = HostIdFactory.create(targetIP, null);
+        HostNodeConnector host = hostTracker.hostQuery(id);
         // unknown host, initiate ARP request
         if (host == null) {
             // add the requestor to the list so that we can replay the reply
@@ -293,48 +297,40 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
                     arpRequestors.put(targetIP, requestorSet);
                 }
                 requestorSet.add(requestor);
-                countDownTimers.put(targetIP, (short) 2); // reset timeout to 2sec
+                countDownTimers.put(targetIP, (short) 2); // reset timeout to
+                                                          // 2sec
             }
-            //Raise a bcast request event, all controllers need to send one
+            // Raise a bcast request event, all controllers need to send one
             log.trace("Sending a bcast ARP request for {}", targetIP);
             arpRequestReplyEvent.put(new ARPRequest(targetIP, subnet), false);
         } else {
             /*
-             * Target host known (across the cluster), send ARP REPLY make sure that targetMAC
-             * matches the host's MAC if it is not broadcastMAC
+             * Target host known (across the cluster), send ARP REPLY make sure
+             * that targetMAC matches the host's MAC if it is not broadcastMAC
              */
             if (NetUtils.isBroadcastMACAddr(targetMAC) || Arrays.equals(host.getDataLayerAddressBytes(), targetMAC)) {
                 log.trace("Received ARP req. for known host {}, sending reply...", targetIP);
                 if (connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL) {
-                    sendARPReply(p,
-                            host.getDataLayerAddressBytes(),
-                            host.getNetworkAddress(),
-                            pkt.getSenderHardwareAddress(),
-                            sourceIP);
+                    sendARPReply(p, host.getDataLayerAddressBytes(), host.getNetworkAddress(),
+                            pkt.getSenderHardwareAddress(), sourceIP);
                 } else {
-                    arpRequestReplyEvent.put(new ARPReply(
-                            p,
-                            host.getNetworkAddress(),
-                            host.getDataLayerAddressBytes(),
-                            sourceIP,
-                            pkt.getSenderHardwareAddress()), false);
+                    arpRequestReplyEvent.put(new ARPReply(p, host.getNetworkAddress(), host.getDataLayerAddressBytes(),
+                            sourceIP, pkt.getSenderHardwareAddress()), false);
                 }
             } else {
                 /*
-                 * Target MAC has been changed. For now, discard it.
-                 * TODO: We may need to send unicast ARP REQUEST on behalf of
-                 * the target back to the sender to trigger the sender to update
-                 * its table
+                 * Target MAC has been changed. For now, discard it. TODO: We
+                 * may need to send unicast ARP REQUEST on behalf of the target
+                 * back to the sender to trigger the sender to update its table
                  */
             }
         }
     }
 
     /**
-     *  Send a broadcast ARP Request to the switch/ ports  using
-     *  the networkAddress of the subnet as sender IP
-     *  the controller's MAC as sender MAC
-     *  the targetIP as the target Network Address
+     * Send a broadcast ARP Request to the switch/ ports using the
+     * networkAddress of the subnet as sender IP the controller's MAC as sender
+     * MAC the targetIP as the target Network Address
      */
     protected void sendBcastARPRequest(InetAddress targetIP, Subnet subnet) {
         log.trace("sendBcatARPRequest targetIP:{} subnet:{}", targetIP, subnet);
@@ -349,10 +345,11 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
         }
         byte[] targetHardwareAddress = new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
 
-        //TODO: should use IBroadcastHandler instead
+        // TODO: should use IBroadcastHandler instead
         for (NodeConnector p : nodeConnectors) {
-            //filter out any non-local or internal ports
-            if (!(connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL) || topologyManager.isInternal(p)) {
+            // filter out any non-local or internal ports
+            if (!(connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL)
+                    || topologyManager.isInternal(p)) {
                 continue;
             }
             log.trace("Sending toward nodeConnector:{}", p);
@@ -374,8 +371,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
 
     /**
      * Send a unicast ARP Request to the known host on a specific switch/port as
-     * defined in the host.
-     * The sender IP is the networkAddress of the subnet
+     * defined in the host. The sender IP is the networkAddress of the subnet
      * The sender MAC is the controller's MAC
      */
     protected void sendUcastARPRequest(HostNodeConnector host, Subnet subnet) {
@@ -425,15 +421,14 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
 
         Subnet subnet = null;
         if (switchManager != null) {
-            subnet = switchManager.getSubnetByNetworkAddress(host
-                    .getNetworkAddress());
+            subnet = switchManager.getSubnetByNetworkAddress(host.getNetworkAddress());
         }
         if (subnet == null) {
             log.debug("can't find subnet matching {}", host.getNetworkAddress());
             return;
         }
 
-        if (connectionManager.getLocalityStatus(host.getnodeconnectorNode()) == ConnectionLocality.LOCAL){
+        if (connectionManager.getLocalityStatus(host.getnodeconnectorNode()) == ConnectionLocality.LOCAL) {
             log.trace("Send a ucast ARP req. to: {}", host);
             sendUcastARPRequest(host, subnet);
         } else {
@@ -443,9 +438,9 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
     }
 
     /**
-     * An IP packet is punted to the controller, this means that the
-     * destination host is not known to the controller.
-     * Need to discover it by sending a Broadcast ARP Request
+     * An IP packet is punted to the controller, this means that the destination
+     * host is not known to the controller. Need to discover it by sending a
+     * Broadcast ARP Request
      *
      * @param pkt
      * @param p
@@ -454,7 +449,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
 
         InetAddress dIP = NetUtils.getInetAddress(pkt.getDestinationAddress());
         if (dIP == null) {
-           return;
+            return;
         }
 
         // try to find a matching subnet
@@ -468,20 +463,21 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
         }
 
         // see if we know about the host
-        HostNodeConnector host = hostTracker.hostFind(dIP);
+        // Hosttracker hosts db key implementation
+        IHostId id = HostIdFactory.create(dIP, null);
+        HostNodeConnector host = hostTracker.hostFind(id);
 
         if (host == null) {
             // if we don't, know about the host, try to find it
-            log.trace("Punted IP pkt to {}, sending bcast ARP event...",
-                      dIP);
+            log.trace("Punted IP pkt to {}, sending bcast ARP event...", dIP);
             /*
              * unknown destination host, initiate bcast ARP request
              */
             arpRequestReplyEvent.put(new ARPRequest(dIP, subnet), false);
 
-        } else if (routing == null ||
-                   routing.getRoute(p.getNode(), host.getnodeconnectorNode()) != null) {
-            /* if IRouting is available, make sure that this packet can get it's
+        } else if (routing == null || routing.getRoute(p.getNode(), host.getnodeconnectorNode()) != null) {
+            /*
+             * if IRouting is available, make sure that this packet can get it's
              * destination normally before teleporting it there. If it's not
              * available, then assume it's reachable.
              *
@@ -490,9 +486,11 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
 
             log.trace("forwarding punted IP pkt to {} received at {}", dIP, p);
 
-            /* if we know where the host is and there's a path from where this
+            /*
+             * if we know where the host is and there's a path from where this
              * packet was punted to where the host is, then deliver it to the
-             * host for now */
+             * host for now
+             */
             NodeConnector nc = host.getnodeConnector();
 
             // re-encode the Ethernet packet (the parent of the IPv4 packet)
@@ -500,8 +498,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
             rp.setOutgoingNodeConnector(nc);
             this.dataPacketService.transmitDataPacket(rp);
         } else {
-            log.trace("ignoring punted IP pkt to {} because there is no route from {}",
-                      dIP, p);
+            log.trace("ignoring punted IP pkt to {} because there is no route from {}", dIP, p);
         }
     }
 
@@ -524,19 +521,20 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
 
         allocateCaches();
         retrieveCaches();
+
     }
 
     @SuppressWarnings({ "unchecked" })
     private void retrieveCaches() {
-        ConcurrentMap<?,?> map;
+        ConcurrentMap<?, ?> map;
 
-        if (this.clusterContainerService == null){
+        if (this.clusterContainerService == null) {
             log.error("Cluster service unavailable, can't retieve ARPHandler caches!");
             return;
         }
 
         map = clusterContainerService.getCache(ARP_EVENT_CACHE_NAME);
-        if (map != null){
+        if (map != null) {
             this.arpRequestReplyEvent = (ConcurrentMap<ARPEvent, Boolean>) map;
         } else {
             log.error("Cache allocation failed for {}", ARP_EVENT_CACHE_NAME);
@@ -544,30 +542,31 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
     }
 
     private void allocateCaches() {
-        if (clusterContainerService == null){
+        if (clusterContainerService == null) {
             nonClusterObjectCreate();
             log.error("Clustering service unavailable. Allocated non-cluster caches for ARPHandler.");
             return;
         }
 
-        try{
+        try {
             clusterContainerService.createCache(ARP_EVENT_CACHE_NAME,
                     EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
-        } catch (CacheConfigException e){
+        } catch (CacheConfigException e) {
             log.error("ARPHandler cache configuration invalid!");
-        } catch (CacheExistException e){
+        } catch (CacheExistException e) {
             log.debug("ARPHandler cache exists, skipped allocation.");
         }
 
     }
 
-    private void nonClusterObjectCreate(){
+    private void nonClusterObjectCreate() {
         arpRequestReplyEvent = new ConcurrentHashMap<ARPEvent, Boolean>();
     }
+
     /**
-     * Function called by the dependency manager when at least one
-     * dependency become unsatisfied or when the component is shutting
-     * down because for example bundle is being stopped.
+     * Function called by the dependency manager when at least one dependency
+     * become unsatisfied or when the component is shutting down because for
+     * example bundle is being stopped.
      *
      */
     void destroy() {
@@ -575,9 +574,8 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
     }
 
     /**
-     * Function called by dependency manager after "init ()" is called
-     * and after the services provided by the class are registered in
-     * the service registry
+     * Function called by dependency manager after "init ()" is called and after
+     * the services provided by the class are registered in the service registry
      *
      */
     void start() {
@@ -587,12 +585,12 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
     }
 
     /**
-     * Function called by the dependency manager before the services
-     * exported by the component are unregistered, this will be
-     * followed by a "destroy ()" calls
+     * Function called by the dependency manager before the services exported by
+     * the component are unregistered, this will be followed by a "destroy ()"
+     * calls
      *
      */
-    void stop(){
+    void stop() {
     }
 
     void stopping() {
@@ -626,25 +624,25 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
                 handlePuntedIPPacket((IPv4) nextPak, inPkt.getIncomingNodeConnector());
             } else if (nextPak instanceof ARP) {
                 log.trace("Handle ARP packet: {}", formattedPak);
-                handleARPPacket((Ethernet) formattedPak, (ARP) nextPak, inPkt
-                        .getIncomingNodeConnector());
+                handleARPPacket((Ethernet) formattedPak, (ARP) nextPak, inPkt.getIncomingNodeConnector());
             }
         }
         return PacketResult.IGNORED;
     }
 
-    private ARP createARP(short opCode, byte[] senderMacAddress, byte[] senderIP, byte[] targetMacAddress, byte[] targetIP) {
-            ARP arp = new ARP();
-            arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
-            arp.setProtocolType(EtherTypes.IPv4.shortValue());
-            arp.setHardwareAddressLength((byte) 6);
-            arp.setProtocolAddressLength((byte) 4);
-            arp.setOpCode(opCode);
-            arp.setSenderHardwareAddress(senderMacAddress) ;
-            arp.setSenderProtocolAddress(senderIP);
-            arp.setTargetHardwareAddress(targetMacAddress);
-            arp.setTargetProtocolAddress(targetIP);
-            return arp;
+    private ARP createARP(short opCode, byte[] senderMacAddress, byte[] senderIP, byte[] targetMacAddress,
+            byte[] targetIP) {
+        ARP arp = new ARP();
+        arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
+        arp.setProtocolType(EtherTypes.IPv4.shortValue());
+        arp.setHardwareAddressLength((byte) 6);
+        arp.setProtocolAddressLength((byte) 4);
+        arp.setOpCode(opCode);
+        arp.setSenderHardwareAddress(senderMacAddress);
+        arp.setSenderProtocolAddress(senderIP);
+        arp.setTargetHardwareAddress(targetMacAddress);
+        arp.setTargetProtocolAddress(targetIP);
+        return arp;
     }
 
     private Ethernet createEthernet(byte[] sourceMAC, byte[] targetMAC, ARP arp) {
@@ -682,10 +680,10 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
 
                 // Clean up ARP event cache
                 try {
-                    if (clusterContainerService.amICoordinator() && ! arpRequestReplyEvent.isEmpty()){
+                    if (clusterContainerService.amICoordinator() && !arpRequestReplyEvent.isEmpty()) {
                         arpRequestReplyEvent.clear();
                     }
-                } catch (Exception e){
+                } catch (Exception e) {
                     log.warn("ARPHandler: A cluster member failed to clear event cache.");
                 }
             }
@@ -701,7 +699,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
     private void generateAndSendReply(InetAddress sourceIP, byte[] sourceMAC) {
         if (log.isTraceEnabled()) {
             log.trace("generateAndSendReply called with params sourceIP:{} sourceMAC:{}", sourceIP,
-                      HexEncode.bytesToHexString(sourceMAC));
+                    HexEncode.bytesToHexString(sourceMAC));
         }
         Set<HostNodeConnector> hosts = arpRequestors.remove(sourceIP);
         if ((hosts == null) || hosts.isEmpty()) {
@@ -711,38 +709,27 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
         countDownTimers.remove(sourceIP);
         for (HostNodeConnector host : hosts) {
             if (log.isTraceEnabled()) {
-                log.trace("Sending ARP Reply with src {}/{}, target {}/{}",
-                          new Object[] {
-                              HexEncode.bytesToHexString(sourceMAC),
-                              sourceIP,
-                              HexEncode.bytesToHexString(host.getDataLayerAddressBytes()),
-                              host.getNetworkAddress() });
+                log.trace(
+                        "Sending ARP Reply with src {}/{}, target {}/{}",
+                        new Object[] { HexEncode.bytesToHexString(sourceMAC), sourceIP,
+                                HexEncode.bytesToHexString(host.getDataLayerAddressBytes()), host.getNetworkAddress() });
             }
-            if (connectionManager.getLocalityStatus(host.getnodeconnectorNode()) == ConnectionLocality.LOCAL){
-                sendARPReply(host.getnodeConnector(),
-                        sourceMAC,
-                        sourceIP,
-                        host.getDataLayerAddressBytes(),
+            if (connectionManager.getLocalityStatus(host.getnodeconnectorNode()) == ConnectionLocality.LOCAL) {
+                sendARPReply(host.getnodeConnector(), sourceMAC, sourceIP, host.getDataLayerAddressBytes(),
                         host.getNetworkAddress());
             } else {
                 /*
-                 * In the remote event a requestor moved to another
-                 * controller it may turn out it now we need to send
-                 * the ARP reply from a different controller, this
-                 * cover the case
+                 * In the remote event a requestor moved to another controller
+                 * it may turn out it now we need to send the ARP reply from a
+                 * different controller, this cover the case
                  */
                 arpRequestReplyEvent.put(
-                        new ARPReply(
-                            host.getnodeConnector(),
-                            sourceIP,
-                            sourceMAC,
-                            host.getNetworkAddress(),
-                            host.getDataLayerAddressBytes()), false);
+                        new ARPReply(host.getnodeConnector(), sourceIP, sourceMAC, host.getNetworkAddress(), host
+                                .getDataLayerAddressBytes()), false);
             }
         }
     }
 
-
     @Override
     public void entryUpdated(ARPEvent key, Boolean new_value, String cacheName, boolean originLocal) {
         log.trace("Got and entryUpdated for cacheName {} key {} isNew {}", cacheName, key, new_value);
@@ -753,12 +740,13 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
     public void entryCreated(ARPEvent key, String cacheName, boolean originLocal) {
         // nothing to do
     }
+
     @Override
     public void entryDeleted(ARPEvent key, String cacheName, boolean originLocal) {
         // nothing to do
     }
 
-    private void enqueueARPCacheEvent (ARPEvent event, boolean new_value) {
+    private void enqueueARPCacheEvent(ARPEvent event, boolean new_value) {
         try {
             ARPCacheEvent cacheEvent = new ARPCacheEvent(event, new_value);
             if (!ARPCacheEvents.contains(cacheEvent)) {
@@ -771,7 +759,8 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
     }
 
     /*
-     * this thread monitors the connectionEvent queue for new incoming events from
+     * this thread monitors the connectionEvent queue for new incoming events
+     * from
      */
     private class ARPCacheEventHandler implements Runnable {
         @Override
@@ -787,24 +776,22 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
                             log.trace("Trigger and ARP Broadcast Request upon receipt of {}", req);
                             sendBcastARPRequest(req.getTargetIP(), req.getSubnet());
 
-                        //If unicast and local, send reply
+                            // If unicast and local, send reply
                         } else if (connectionManager.getLocalityStatus(req.getHost().getnodeconnectorNode()) == ConnectionLocality.LOCAL) {
                             log.trace("ARPCacheEventHandler - sendUcatARPRequest upon receipt of {}", req);
                             sendUcastARPRequest(req.getHost(), req.getSubnet());
                         }
                     } else if (event instanceof ARPReply) {
                         ARPReply rep = (ARPReply) event;
-                        // New reply received by controller, notify all awaiting requestors across the cluster
+                        // New reply received by controller, notify all awaiting
+                        // requestors across the cluster
                         if (ev.isNewReply()) {
                             log.trace("Trigger a generateAndSendReply in response to {}", rep);
                             generateAndSendReply(rep.getTargetIP(), rep.getTargetMac());
-                        // Otherwise, a specific reply. If local, send out.
+                            // Otherwise, a specific reply. If local, send out.
                         } else if (connectionManager.getLocalityStatus(rep.getPort().getNode()) == ConnectionLocality.LOCAL) {
                             log.trace("ARPCacheEventHandler - sendUcatARPReply locally in response to {}", rep);
-                            sendARPReply(rep.getPort(),
-                                    rep.getSourceMac(),
-                                    rep.getSourceIP(),
-                                    rep.getTargetMac(),
+                            sendARPReply(rep.getPort(), rep.getSourceMac(), rep.getSourceIP(), rep.getTargetMac(),
                                     rep.getTargetIP());
                         }
                     }
index 8feb1600b5f9c84e444f3a060d84ae418e1015f9..794986a7bb7b62fd0a755da2470f53297b3f521b 100644 (file)
     <yangtools.binding.version>0.6.0-SNAPSHOT</yangtools.binding.version>
     <!--versions for bits of the controller -->
     <controller.version>0.4.1-SNAPSHOT</controller.version>
+    <hosttracker.version>0.5.1-SNAPSHOT</hosttracker.version>
+    <arphandler.version>0.5.1-SNAPSHOT</arphandler.version>
+    <forwarding.staticrouting>0.5.1-SNAPSHOT</forwarding.staticrouting>
+    <samples.loadbalancer>0.5.1-SNAPSHOT</samples.loadbalancer>
     <config.version>0.2.3-SNAPSHOT</config.version>
     <netconf.version>0.2.3-SNAPSHOT</netconf.version>
     <mdsal.version>1.0-SNAPSHOT</mdsal.version>
index a157e1ed5d4ff087b7d44963217e1886bfab9678..5e8612f7b94eae1fda8119ec7b25cafb98eafa0c 100644 (file)
@@ -8,6 +8,22 @@
  */
 package org.opendaylight.controller.config.yang.logback.config;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DependencyResolverFactory;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.osgi.framework.BundleContext;
+import org.slf4j.LoggerFactory;
+
 import ch.qos.logback.classic.Logger;
 import ch.qos.logback.classic.LoggerContext;
 import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
@@ -17,21 +33,10 @@ import ch.qos.logback.core.Appender;
 import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
 import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
 import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
+
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
-import org.apache.commons.lang3.StringUtils;
-import org.opendaylight.controller.config.api.DependencyResolver;
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.osgi.framework.BundleContext;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
+import com.google.common.collect.Sets;
 
 /**
 *
@@ -39,15 +44,15 @@ import java.util.Map.Entry;
 public class LogbackModuleFactory extends
         org.opendaylight.controller.config.yang.logback.config.AbstractLogbackModuleFactory {
 
-    private static final String INSTANCE_NAME = "singleton";
+    public static final String INSTANCE_NAME = "singleton";
     private Map<String, LoggerTO> loggersDTOs;
     private Map<String, RollingFileAppenderTO> rollingDTOs;
     private Map<String, ConsoleAppenderTO> consoleDTOs;
     private Map<String, FileAppenderTO> fileDTOs;
 
     @Override
-    public LogbackModule instantiateModule(String instanceName,
-            DependencyResolver dependencyResolver, BundleContext bundleContext) {
+    public LogbackModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+            BundleContext bundleContext) {
         Preconditions.checkArgument(instanceName.equals(INSTANCE_NAME),
                 "There should be just one instance of logback, named " + INSTANCE_NAME);
         prepareDTOs();
@@ -61,9 +66,8 @@ public class LogbackModuleFactory extends
     }
 
     @Override
-    public LogbackModule instantiateModule(String instanceName,
-            DependencyResolver dependencyResolver, LogbackModule oldModule,
-            AutoCloseable oldInstance, BundleContext bundleContext) {
+    public LogbackModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+            LogbackModule oldModule, AutoCloseable oldInstance, BundleContext bundleContext) {
         Preconditions.checkArgument(instanceName.equals(INSTANCE_NAME),
                 "There should be just one instance of logback, named " + INSTANCE_NAME);
         prepareDTOs();
@@ -220,4 +224,14 @@ public class LogbackModuleFactory extends
         return Lists.newArrayList(loggersToReturn.values());
     }
 
+    @Override
+    public Set<LogbackModule> getDefaultModules(DependencyResolverFactory dependencyResolverFactory,
+            BundleContext bundleContext) {
+        DependencyResolver resolver = dependencyResolverFactory.createDependencyResolver(new ModuleIdentifier(
+                getImplementationName(), INSTANCE_NAME));
+        LogbackModule defaultLogback = instantiateModule(INSTANCE_NAME, resolver, bundleContext);
+        Set<LogbackModule> defaultModules = Sets.newHashSet(defaultLogback);
+        return defaultModules;
+    }
+
 }
index 846b9cd352b48ebd34fa13ea99ab0301adf97501..296ce79f6e9cefeb5723107a59cef9b4cc0f3194 100644 (file)
@@ -7,29 +7,24 @@
  */
 package org.opendaylight.controller.config.yang.logback.config;
 
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-import static org.junit.matchers.JUnitMatchers.containsString;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
-import org.opendaylight.controller.config.api.ConflictingVersionException;
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.api.jmx.CommitStatus;
 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 
+import javax.management.ObjectName;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.junit.matchers.JUnitMatchers.containsString;
+
 public class LogbackModuleTest extends AbstractConfigTest {
 
     private static final String INSTANCE_NAME = "singleton";
@@ -37,14 +32,14 @@ public class LogbackModuleTest extends AbstractConfigTest {
     private LogbackModuleFactory factory;
 
     @Before
-    public void setUp() throws IOException, ClassNotFoundException, InterruptedException {
+    public void setUp() throws Exception {
 
         factory = new LogbackModuleFactory();
         super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
     }
 
     @Test
-    public void testCreateBean() throws InstanceAlreadyExistsException {
+    public void testCreateBean() throws Exception {
 
         CommitStatus status = createBeans(true, "target/rollingApp",
                 "%-4relative [%thread] %-5level %logger{35} - %msg%n", "30MB", 1, 5, "target/%i.log", "rolling",
@@ -55,7 +50,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testReusingInstance() throws InstanceAlreadyExistsException {
+    public void testReusingInstance() throws Exception {
         createBeans(true, "target/rollingApp", "%-4relative [%thread] %-5level %logger{35} - %msg%n", "30MB", 1, 5,
                 "target/%i.log", "rolling", "consoleName", "ALL", "logger1", "DEBUG", "FixedWindowRollingPolicy", 0,
                 "FileAppender").commit();
@@ -70,8 +65,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testRecreateInstance() throws InstanceAlreadyExistsException, ValidationException,
-            ConflictingVersionException, InstanceNotFoundException {
+    public void testRecreateInstance() throws Exception {
         createBeans(true, "target/rollingApp", "%-4relative [%thread] %-5level %logger{35} - %msg%n", "30MB", 1, 5,
                 "target/%i.log", "rolling", "consoleName", "ALL", "logger1", "DEBUG", "FixedWindowRollingPolicy", 0,
                 "FileAppender").commit();
@@ -88,7 +82,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testDestroyInstance() throws InstanceNotFoundException, InstanceAlreadyExistsException {
+    public void testDestroyInstance() throws Exception {
         createBeans(true, "target/rollingApp", "%-4relative [%thread] %-5level %logger{35} - %msg%n", "30MB", 1, 5,
                 "target/%i.log", "rolling", "consoleName", "ALL", "logger1", "DEBUG", "FixedWindowRollingPolicy", 0,
                 "FileAppender").commit();
@@ -104,7 +98,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
 
     @Ignore
     @Test
-    public void testValidation1() throws InstanceAlreadyExistsException {
+    public void testValidation1() throws Exception {
         try {
             createBeans(true, "target/rollingApp", "%-4relative [%thread] %-5level %logger{35} - %msg%n", "30MB", 1, 5,
                     "target/%i.log", "rolling", "consoleName", "ALL", "logger1", "DEBUG", "FixedWindowRollingPolicy",
@@ -116,7 +110,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testValidation2() throws InstanceAlreadyExistsException {
+    public void testValidation2() throws Exception {
         try {
             createBeans(true, "target/rollingApp", null, "30MB", 1, 5, "target/%i.log", "rolling", "consoleName",
                     "ALL", "logger1", "DEBUG", "FixedWindowRollingPolicy", 0, "FileAppender").commit();
@@ -127,7 +121,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testValidation4() throws InstanceAlreadyExistsException {
+    public void testValidation4() throws Exception {
         try {
             createBeans(true, "target/rollingApp", "%-4relative [%thread] %-5level %logger{35} - %msg%n", null, 1, 5,
                     "target/%i.log", "rolling", "consoleName", "ALL", "logger1", "DEBUG", "FixedWindowRollingPolicy",
@@ -139,7 +133,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testValidation6() throws InstanceAlreadyExistsException {
+    public void testValidation6() throws Exception {
         try {
             createBeans(true, "", "%-4relative [%thread] %-5level %logger{35} - %msg%n", "30MB", 1, 5, "target/%i.log",
                     "rolling", "consoleName", "ALL", "logger1", "DEBUG", "FixedWindowRollingPolicy", 0, "FileAppender")
@@ -151,7 +145,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testValidation7() throws InstanceAlreadyExistsException {
+    public void testValidation7() throws Exception {
         try {
             createBeans(
 
@@ -164,7 +158,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testValidation8() throws InstanceAlreadyExistsException {
+    public void testValidation8() throws Exception {
         try {
             createBeans(true, "target/rollingApp", "%-4relative [%thread] %-5level %logger{35} - %msg%n", "30MB", 1, 5,
                     "target/%i.log", "rolling", "consoleName", "ALL", null, "DEBUG", "FixedWindowRollingPolicy", 0,
@@ -176,7 +170,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testValidation9() throws InstanceAlreadyExistsException {
+    public void testValidation9() throws Exception {
         try {
             createBeans(true, "target/rollingApp", "%-4relative [%thread] %-5level %logger{35} - %msg%n", "30MB", 1, 5,
                     "target/%i.log", "rolling", "consoleName", "ALL", "", "DEBUG", "FixedWindowRollingPolicy", 0,
@@ -188,7 +182,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testValidation10() throws InstanceAlreadyExistsException {
+    public void testValidation10() throws Exception {
         try {
             createBeans(true, "target/rollingApp", "%-4relative [%thread] %-5level %logger{35} - %msg%n", "30MB", null,
                     5, "target/%i.log", "rolling", "consoleName", "ALL", "logger1", "DEBUG",
@@ -200,7 +194,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testValidation11() throws InstanceAlreadyExistsException {
+    public void testValidation11() throws Exception {
         try {
             createBeans(true, "target/rollingApp", "%-4relative [%thread] %-5level %logger{35} - %msg%n", "30MB", 1,
                     null, "target/%i.log", "rolling", "consoleName", "ALL", "logger1", "DEBUG",
@@ -212,7 +206,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testValidation12() throws InstanceAlreadyExistsException {
+    public void testValidation12() throws Exception {
         try {
             createBeans(true, "target/rollingApp", "%-4relative [%thread] %-5level %logger{35} - %msg%n", "30MB", 1,
                     null, "target/%i.log", "rolling", "consoleName", "ALL", "logger1", "DEBUG", null, 1, "FileAppender")
@@ -224,7 +218,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testValidation13() throws InstanceAlreadyExistsException {
+    public void testValidation13() throws Exception {
         try {
             createBeans(true, "target/rollingApp", "%-4relative [%thread] %-5level %logger{35} - %msg%n", "30MB", 1,
                     null, "target/%i.log", "rolling", "consoleName", "ALL", "logger1", "DEBUG", "", 1, "FileAppender")
@@ -236,7 +230,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testValidation14() throws InstanceAlreadyExistsException {
+    public void testValidation14() throws Exception {
         try {
             createBeans(true, "target/rollingApp", "%-4relative [%thread] %-5level %logger{35} - %msg%n", "30MB", 1,
                     null, "target/%i.log", "rolling", "consoleName", "ALL", "logger1", "DEBUG", "RollingPolicy", 1,
@@ -248,7 +242,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testTimeBasedRollingPolicy() throws InstanceAlreadyExistsException {
+    public void testTimeBasedRollingPolicy() throws Exception {
         createBeans(true, "target/rollingApp", "%-4relative [%thread] %-5level %logger{35} - %msg%n", "30MB", null,
                 null, "target/%d.log", "rolling", "consoleName", "ALL", "logger1", "DEBUG", "TimeBasedRollingPolicy",
                 1, "FileAppender").commit();
@@ -257,10 +251,10 @@ public class LogbackModuleTest extends AbstractConfigTest {
     private ConfigTransactionJMXClient createBeans(Boolean isAppend, String rollingFileName, String encoderPattern,
             String maxFileSize, Integer minIndex, Integer maxIndex, String fileNamePattern, String rollingName,
             String consoleName, String thresholdFilter, String loggerName, String level, String rollingPolicyType,
-            int maxHistory, String fileAppName) throws InstanceAlreadyExistsException {
+            int maxHistory, String fileAppName) throws Exception {
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        ObjectName nameCreated = transaction.createModule(factory.getImplementationName(), INSTANCE_NAME);
-        LogbackModuleMXBean bean = transaction.newMXBeanProxy(nameCreated, LogbackModuleMXBean.class);
+        ObjectName nameRetrieved = transaction.lookupConfigBean(factory.getImplementationName(), INSTANCE_NAME);
+        LogbackModuleMXBean bean = transaction.newMXBeanProxy(nameRetrieved, LogbackModuleMXBean.class);
 
         List<RollingFileAppenderTO> rollingAppenders = new ArrayList<>();
         RollingFileAppenderTO rollingAppender = new RollingFileAppenderTO();
index 79e46ae6d212d56b4613643d48315ca535844375..eeb8289e86196665cd971ce932112779fee04bb7 100644 (file)
@@ -17,7 +17,9 @@ 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 org.apache.commons.io.FileUtils;
@@ -142,7 +144,8 @@ public class LogbackModuleWithInitialConfigurationTest extends AbstractConfigTes
 
     }
 
-    public ObjectName createBeans() throws JoranException, InstanceAlreadyExistsException, IOException {
+    public ObjectName createBeans() throws JoranException, InstanceAlreadyExistsException, IOException,
+            MalformedObjectNameException, InstanceNotFoundException {
 
         LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
 
@@ -200,8 +203,8 @@ public class LogbackModuleWithInitialConfigurationTest extends AbstractConfigTes
         loggersDTOs.add(log);
 
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        ObjectName nameCreated = transaction.createModule(factory.getImplementationName(), "singleton");
-        LogbackModuleMXBean bean = transaction.newMXBeanProxy(nameCreated, LogbackModuleMXBean.class);
+        ObjectName nameRetrieved = transaction.lookupConfigBean(factory.getImplementationName(), LogbackModuleFactory.INSTANCE_NAME);
+        LogbackModuleMXBean bean = transaction.newMXBeanProxy(nameRetrieved, LogbackModuleMXBean.class);
 
         bean.setLoggerTO(loggersDTOs);
         bean.setRollingFileAppenderTO(rollingAppenders);
@@ -210,6 +213,6 @@ public class LogbackModuleWithInitialConfigurationTest extends AbstractConfigTes
 
         transaction.commit();
 
-        return nameCreated;
+        return nameRetrieved;
     }
 }
index 004c18c5e08c0b2224e3f50b69654961a68e3258..8718f8a9ce3121c260d41555f8ff509849c09b97 100644 (file)
@@ -17,6 +17,7 @@ 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 org.apache.commons.io.FileUtils;
@@ -27,12 +28,12 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hardcod
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Lists;
-
 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;
+
 public class LogbackWithXmlConfigModuleTest extends AbstractConfigTest {
 
     private LogbackModuleFactory factory;
@@ -56,14 +57,16 @@ public class LogbackWithXmlConfigModuleTest extends AbstractConfigTest {
 
     /**
      * Tests configuration of Logger factory.
+     *
+     * @throws MalformedObjectNameException
      */
     @Test
-    public void test() throws InstanceAlreadyExistsException, InstanceNotFoundException {
+    public void test() throws InstanceAlreadyExistsException, InstanceNotFoundException, MalformedObjectNameException {
 
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        ObjectName nameCreated = transaction.createModule(factory.getImplementationName(), "singleton");
+        ObjectName nameRetrieved = transaction.lookupConfigBean(factory.getImplementationName(), LogbackModuleFactory.INSTANCE_NAME);
 
-        LogbackModuleMXBean bean = transaction.newMXBeanProxy(nameCreated, LogbackModuleMXBean.class);
+        LogbackModuleMXBean bean = transaction.newMXBeanProxy(nameRetrieved, LogbackModuleMXBean.class);
 
         assertEquals(1, bean.getConsoleAppenderTO().size());
 
@@ -73,9 +76,9 @@ public class LogbackWithXmlConfigModuleTest extends AbstractConfigTest {
 
         transaction = configRegistryClient.createTransaction();
 
-        nameCreated = transaction.lookupConfigBean(factory.getImplementationName(), "singleton");
+        nameRetrieved = transaction.lookupConfigBean(factory.getImplementationName(), "singleton");
 
-        bean = JMX.newMXBeanProxy(platformMBeanServer, nameCreated, LogbackModuleMXBean.class);
+        bean = JMX.newMXBeanProxy(platformMBeanServer, nameRetrieved, LogbackModuleMXBean.class);
 
         assertEquals(1, bean.getConsoleAppenderTO().size());
         assertEquals(1, bean.getRollingFileAppenderTO().size());
@@ -89,11 +92,6 @@ public class LogbackWithXmlConfigModuleTest extends AbstractConfigTest {
     @Test
     public void testAllLoggers() throws InstanceAlreadyExistsException, InstanceNotFoundException {
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        transaction.createModule(factory.getImplementationName(), "singleton");
-
-        transaction.commit();
-
-        transaction = configRegistryClient.createTransaction();
 
         LogbackModuleMXBean bean = JMX.newMXBeanProxy(ManagementFactory.getPlatformMBeanServer(),
                 transaction.lookupConfigBean("logback", "singleton"), LogbackModuleMXBean.class);
@@ -103,13 +101,16 @@ public class LogbackWithXmlConfigModuleTest extends AbstractConfigTest {
 
     /**
      * Add new logger using FileAppender
+     *
+     * @throws MalformedObjectNameException
      */
     @Test
-    public void testAddNewLogger() throws InstanceAlreadyExistsException, InstanceNotFoundException {
+    public void testAddNewLogger() throws InstanceAlreadyExistsException, InstanceNotFoundException,
+            MalformedObjectNameException {
 
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        ObjectName nameCreated = transaction.createModule(factory.getImplementationName(), "singleton");
-        LogbackModuleMXBean bean = transaction.newMXBeanProxy(nameCreated, LogbackModuleMXBean.class);
+        ObjectName nameRetrieved = transaction.lookupConfigBean(factory.getImplementationName(), LogbackModuleFactory.INSTANCE_NAME);
+        LogbackModuleMXBean bean = transaction.newMXBeanProxy(nameRetrieved, LogbackModuleMXBean.class);
 
         assertEquals(5, bean.getLoggerTO().size());
 
@@ -124,8 +125,8 @@ public class LogbackWithXmlConfigModuleTest extends AbstractConfigTest {
         transaction.commit();
 
         transaction = configRegistryClient.createTransaction();
-        nameCreated = transaction.lookupConfigBean(factory.getImplementationName(), "singleton");
-        bean = JMX.newMXBeanProxy(platformMBeanServer, nameCreated, LogbackModuleMXBean.class);
+        nameRetrieved = transaction.lookupConfigBean(factory.getImplementationName(), "singleton");
+        bean = JMX.newMXBeanProxy(platformMBeanServer, nameRetrieved, LogbackModuleMXBean.class);
 
         assertEquals(6, bean.getLoggerTO().size());
     }
index fcdc10f109bca6289b3cc181821970430ffa6066..9356dd3752331f2f34fcc33b5df87151081a04b7 100644 (file)
@@ -125,7 +125,7 @@ public class ExtenderYangTracker extends BundleTracker<Object> implements YangSt
         // inconsistent state
         inconsistentBundlesToYangURLs.putAll(bundle, addedURLs);
 
-        logger.debug("Yang store is falling back on last consistent state containing {}, inconsistent yang files {}, reason {}",
+        logger.debug("Yang store is falling back on last consistent state containing {}, inconsistent yang files {}",
                 consistentBundlesToYangURLs, inconsistentBundlesToYangURLs, failureReason);
         logger.warn("Yang store is falling back on last consistent state containing {} files, inconsistent yang files size is {}, reason {}",
                 consistentBundlesToYangURLs.size(), inconsistentBundlesToYangURLs.size(), failureReason.toString());
index 788c8e8a09ae52d08a420b5e79b8138f2eb566aa..894f94bc46b67d11e2858715d8602dec1a54755e 100644 (file)
@@ -84,7 +84,7 @@
       <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index b82d2dae3cbf769a5e64239f178d6aaa3e7703f0..99568dfcce886fb89de47fba5cc775b00a24530a 100644 (file)
@@ -35,7 +35,7 @@ import org.opendaylight.controller.sal.utils.StatusCode;
  * files through java serialization API when saving to/reading from Container
  * Manager startup configuration file.
  */
-@XmlRootElement(name = "container-config")
+@XmlRootElement(name = "containerConfig")
 @XmlAccessorType(XmlAccessType.NONE)
 public class ContainerConfig implements Serializable {
     private static final long serialVersionUID = 2L;
index 74a133f9139261d9741183337034b4c9c791b4f5..5b08af79f835e39b0d729424d31cf522ea78c256 100644 (file)
           <artifactId>sal-common-util</artifactId>
           <version>${mdsal.version}</version>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>sal-netconf-connector</artifactId>
+          <version>${mdsal.version}</version>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-core-api</artifactId>
           <artifactId>forwardingrules-manager</artifactId>
           <version>${mdsal.version}</version>
         </dependency>
-
+        <dependency>
+          <groupId>org.opendaylight.controller.md</groupId>
+          <artifactId>statistics-manager</artifactId>
+          <version>${mdsal.version}</version>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>concepts</artifactId>
           <artifactId>yang-jmx-generator</artifactId>
           <version>${config.version}</version>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>netty-event-executor-config</artifactId>
+          <version>${config.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>netty-threadgroup-config</artifactId>
+          <version>${config.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>threadpool-config-api</artifactId>
+          <version>${config.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>threadpool-config-impl</artifactId>
+          <version>${config.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>yang-store-api</artifactId>
+          <version>${config.version}</version>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>yang-store-api</artifactId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwarding.staticrouting</artifactId>
-      <version>${controller.version}</version>
+      <version>${forwarding.staticrouting}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>arphandler</artifactId>
-      <version>${controller.version}</version>
+      <version>${arphandler.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>${controller.version}</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker.implementation</artifactId>
-      <version>${controller.version}</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>samples.loadbalancer</artifactId>
-      <version>${controller.version}</version>
+      <version>${samples.loadbalancer}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index dacdd2546ef235fda3453c10d522294b297348a0..bfc3962040de008313256355ae917948d0caf5e4 100644 (file)
@@ -22,7 +22,9 @@ netconf.tcp.port=8383
 #netconf.tls.keystore=
 #netconf.tls.keystore.password=
 
-netconf.config.persister.storageAdapterClass=org.opendaylight.controller.netconf.persist.impl.NoOpStorageAdapter
+netconf.config.persister.storageAdapterClass=org.opendaylight.controller.config.persist.storage.file.FileStorageAdapter
+fileStorage=configuration/controller.config
+numberOfBackups=1
 yangstore.blacklist=.*controller.model.*
 
 # Set Default start level for framework
@@ -115,3 +117,6 @@ org.jolokia.listenForHttpService=false
 
 # Logging configuration for Tomcat-JUL logging
 java.util.logging.config.file=configuration/tomcat-logging.properties
+
+#Hosttracker hostsdb key scheme setting
+hosttracker.keyscheme=IP
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/controller.config b/opendaylight/distribution/opendaylight/src/main/resources/configuration/controller.config
new file mode 100644 (file)
index 0000000..947c15b
--- /dev/null
@@ -0,0 +1,127 @@
+//START OF CONFIG-LAST
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+<modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+       <module>
+               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</type>
+               <name>yang-schema-service</name>
+       </module>
+       <module>
+               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:hash-map-data-store</type>
+               <name>hash-map-data-store</name>
+       </module>
+       <module>
+               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
+               <name>dom-broker</name>
+               <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
+                       <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
+                       <name>ref_hash-map-data-store</name>
+               </data-store>
+       </module>
+       <module>
+               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
+               <name>binding-broker-impl</name>
+               <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                       <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+                       <name>ref_binding-notification-broker</name>
+               </notification-service>
+               <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                       <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+                       <name>ref_binding-data-broker</name>
+               </data-broker>
+       </module>
+       <module>
+               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
+               <name>runtime-mapping-singleton</name>
+       </module>
+       <module>
+               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
+               <name>binding-notification-broker</name>
+       </module>
+       <module>
+               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-broker</type>
+               <name>binding-data-broker</name>
+               <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                       <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+                       <name>ref_dom-broker</name>
+               </dom-broker>
+               <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
+               <name>ref_runtime-mapping-singleton</name>
+               </mapping-service>
+       </module>
+</modules>
+<services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+       <service>
+       <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+               <instance>
+               <name>ref_yang-schema-service</name>
+               <provider>/config/modules/module[name='schema-service-singleton']/instance[name='yang-schema-service']</provider>
+               </instance>
+       </service>
+       <service>
+               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+               <instance>
+                       <name>ref_binding-notification-broker</name>
+                       <provider>/config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker']</provider>
+               </instance>
+       </service>
+       <service>
+               <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
+               <instance>
+                       <name>ref_hash-map-data-store</name>
+                       <provider>/config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store']</provider>
+               </instance>
+       </service>
+       <service>
+               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
+               <instance>
+                       <name>ref_binding-broker-impl</name>
+                       <provider>/config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl']</provider>
+               </instance>
+       </service>
+       <service>
+               <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
+               <instance>
+                       <name>ref_runtime-mapping-singleton</name>
+                       <provider>/config/modules/module[name='runtime-generated-mapping']/instance[name='runtime-mapping-singleton']</provider>
+               </instance>
+       </service>
+       <service>
+       <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+               <instance>
+                       <name>ref_dom-broker</name>
+                       <provider>/config/modules/module[name='dom-broker-impl']/instance[name='dom-broker']</provider>
+               </instance>
+       </service>
+       <service>
+               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+               <instance>
+               <name>ref_binding-data-broker</name>
+               <provider>/config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker']</provider>
+       </instance>
+       </service>
+</services>
+</data>
+
+//END OF SNAPSHOT
+urn:opendaylight:l2:types?module=opendaylight-l2-types&revision=2013-08-27
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:threadpool?module=threadpool&revision=2013-04-09
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05
+urn:ietf:params:netconf:capability:candidate:1.0
+urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04
+urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&revision=2013-11-12
+urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&revision=2013-06-17
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28
+urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2010-09-24
+urn:ietf:params:netconf:capability:rollback-on-error:1.0
+urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&revision=2010-09-24
+urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?module=threadpool-impl&revision=2013-04-05
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:logback:config?module=config-logging&revision=2013-07-16
+urn:opendaylight:yang:extension:yang-ext?module=yang-ext&revision=2013-07-09
+urn:opendaylight:params:xml:ns:yang:iana?module=iana&revision=2013-08-16
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:ieee754?module=ieee754&revision=2013-08-19
+//END OF CONFIG
index bee0da249630ba7e3191b72ad6b101841fdde334..f160cddaade8ee635db3341d30abc85b97a837b9 100644 (file)
@@ -1,90 +1,92 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.opendaylight.controller</groupId>
-    <artifactId>commons.opendaylight</artifactId>
-    <version>1.4.1-SNAPSHOT</version>
-    <relativePath>../../commons/opendaylight</relativePath>
-  </parent>
-  <scm>
-    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
-    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
-    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
-    <tag>HEAD</tag>
-  </scm>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>commons.opendaylight</artifactId>
+  <version>1.4.1-SNAPSHOT</version>
+  <relativePath>../../commons/opendaylight</relativePath>
+ </parent>
+ <scm>
+  <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+  <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+  <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
+  <tag>HEAD</tag>
+ </scm>
 
 <artifactId>forwarding.staticrouting</artifactId>
 <version>0.4.1-SNAPSHOT</version>
 <packaging>bundle</packaging>
+ <artifactId>forwarding.staticrouting</artifactId>
<version>0.5.1-SNAPSHOT</version>
+ <packaging>bundle</packaging>
 
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <version>${bundle.plugin.version}</version>
-        <extensions>true</extensions>
-        <configuration>
-          <instructions>
-            <Import-Package>
-              org.opendaylight.controller.sal.utils,
-              org.opendaylight.controller.sal.core,
-              org.opendaylight.controller.configuration,
-              org.opendaylight.controller.forwardingrulesmanager,
-              org.opendaylight.controller.hosttracker,
-              org.opendaylight.controller.hosttracker.hostAware,
-              org.opendaylight.controller.clustering.services,
-              org.opendaylight.controller.sal.packet,
-              org.opendaylight.controller.sal.routing,
-              org.opendaylight.controller.topologymanager,
-              org.eclipse.osgi.framework.console,
-              org.osgi.framework,
-              org.slf4j,
-              org.apache.felix.dm,
-              org.apache.commons.lang3.builder
-            </Import-Package>
-            <Export-Package>
-              org.opendaylight.controller.forwarding.staticrouting
-            </Export-Package>
-            <Bundle-Activator>
-              org.opendaylight.controller.forwarding.staticrouting.internal.Activator
-            </Bundle-Activator>
-          </instructions>
-          <manifestLocation>${project.basedir}/META-INF</manifestLocation>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-  <dependencies>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>topologymanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>hosttracker</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>configuration</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
-    </dependency>
-  </dependencies>
+ <build>
+  <plugins>
+   <plugin>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>maven-bundle-plugin</artifactId>
+    <version>${bundle.plugin.version}</version>
+    <extensions>true</extensions>
+    <configuration>
+     <instructions>
+      <Import-Package>
+       org.opendaylight.controller.sal.packet.address,
+       org.opendaylight.controller.sal.utils,
+       org.opendaylight.controller.sal.core,
+       org.opendaylight.controller.configuration,
+       org.opendaylight.controller.forwardingrulesmanager,
+       org.opendaylight.controller.hosttracker,
+       org.opendaylight.controller.hosttracker.hostAware,
+       org.opendaylight.controller.clustering.services,
+       org.opendaylight.controller.sal.packet,
+       org.opendaylight.controller.sal.routing,
+       org.opendaylight.controller.topologymanager,
+       org.eclipse.osgi.framework.console,
+       org.osgi.framework,
+       org.slf4j,
+       org.apache.felix.dm,
+       org.apache.commons.lang3.builder
+      </Import-Package>
+      <Export-Package>
+       org.opendaylight.controller.forwarding.staticrouting
+      </Export-Package>
+      <Bundle-Activator>
+       org.opendaylight.controller.forwarding.staticrouting.internal.Activator
+      </Bundle-Activator>
+     </instructions>
+     <manifestLocation>${project.basedir}/META-INF</manifestLocation>
+    </configuration>
+   </plugin>
+  </plugins>
+ </build>
+ <dependencies>
+  <dependency>
+   <groupId>org.opendaylight.controller</groupId>
+   <artifactId>topologymanager</artifactId>
+   <version>0.4.1-SNAPSHOT</version>
+  </dependency>
+  <dependency>
+   <groupId>org.opendaylight.controller</groupId>
+   <artifactId>forwardingrulesmanager</artifactId>
+   <version>0.4.1-SNAPSHOT</version>
+  </dependency>
+  <dependency>
+   <groupId>org.opendaylight.controller</groupId>
+   <artifactId>hosttracker</artifactId>
+   <version>${hosttracker.version}</version>
+  </dependency>
+  <dependency>
+   <groupId>org.opendaylight.controller</groupId>
+   <artifactId>configuration</artifactId>
+   <version>0.4.1-SNAPSHOT</version>
+  </dependency>
+  <dependency>
+   <groupId>junit</groupId>
+   <artifactId>junit</artifactId>
+  </dependency>
+  <dependency>
+   <groupId>org.opendaylight.controller</groupId>
+   <artifactId>sal</artifactId>
+   <version>0.5.1-SNAPSHOT</version>
+  </dependency>
+ </dependencies>
 </project>
index 315543514e4156e17af453237f001271b6cb4e33..2ce2465d976e28a82a7a3bc8e66ddc9df144300c 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
@@ -42,6 +41,8 @@ import org.opendaylight.controller.forwarding.staticrouting.IForwardingStaticRou
 import org.opendaylight.controller.forwarding.staticrouting.IStaticRoutingAware;
 import org.opendaylight.controller.forwarding.staticrouting.StaticRoute;
 import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig;
+import org.opendaylight.controller.hosttracker.HostIdFactory;
+import org.opendaylight.controller.hosttracker.IHostId;
 import org.opendaylight.controller.hosttracker.IfIptoHost;
 import org.opendaylight.controller.hosttracker.IfNewHostNotify;
 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
@@ -57,10 +58,9 @@ import org.slf4j.LoggerFactory;
 /**
  * Static Routing feature provides the bridge between SDN and Non-SDN networks.
  */
-public class StaticRoutingImplementation implements IfNewHostNotify,
-        IForwardingStaticRouting, IObjectReader, IConfigurationContainerAware {
-    private static Logger log = LoggerFactory
-            .getLogger(StaticRoutingImplementation.class);
+public class StaticRoutingImplementation implements IfNewHostNotify, IForwardingStaticRouting, IObjectReader,
+        IConfigurationContainerAware {
+    private static Logger log = LoggerFactory.getLogger(StaticRoutingImplementation.class);
     private static String ROOT = GlobalConstants.STARTUPHOME.toString();
     ConcurrentMap<String, StaticRoute> staticRoutes;
     ConcurrentMap<String, StaticRouteConfig> staticRouteConfigs;
@@ -101,8 +101,7 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
     }
 
     @Override
-    public Object readObject(ObjectInputStream ois)
-            throws FileNotFoundException, IOException, ClassNotFoundException {
+    public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
         // Perform the class deserialization locally, from inside the package
         // where the class is defined
         return ois.readObject();
@@ -111,8 +110,8 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
     @SuppressWarnings("unchecked")
     private void loadConfiguration() {
         ObjectReader objReader = new ObjectReader();
-        ConcurrentMap<String, StaticRouteConfig> confList = (ConcurrentMap<String, StaticRouteConfig>) objReader
-                .read(this, staticRoutesFileName);
+        ConcurrentMap<String, StaticRouteConfig> confList = (ConcurrentMap<String, StaticRouteConfig>) objReader.read(
+                this, staticRoutesFileName);
 
         if (confList == null) {
             return;
@@ -123,7 +122,6 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
         }
     }
 
-
     private Status saveConfig() {
         return saveConfigInternal();
     }
@@ -132,9 +130,8 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
         Status status;
         ObjectWriter objWriter = new ObjectWriter();
 
-        status = objWriter.write(
-                new ConcurrentHashMap<String, StaticRouteConfig>(
-                        staticRouteConfigs), staticRoutesFileName);
+        status = objWriter.write(new ConcurrentHashMap<String, StaticRouteConfig>(staticRouteConfigs),
+                staticRoutesFileName);
 
         if (status.isSuccess()) {
             return status;
@@ -144,23 +141,19 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
     }
 
     @SuppressWarnings("deprecation")
-        private void allocateCaches() {
+    private void allocateCaches() {
         if (this.clusterContainerService == null) {
-            log
-                    .info("un-initialized clusterContainerService, can't create cache");
+            log.info("un-initialized clusterContainerService, can't create cache");
             return;
         }
 
         try {
-            clusterContainerService.createCache(
-                    "forwarding.staticrouting.routes", EnumSet
-                            .of(IClusterServices.cacheMode.TRANSACTIONAL));
-            clusterContainerService.createCache(
-                    "forwarding.staticrouting.configs", EnumSet
-                            .of(IClusterServices.cacheMode.TRANSACTIONAL));
+            clusterContainerService.createCache("forwarding.staticrouting.routes",
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+            clusterContainerService.createCache("forwarding.staticrouting.configs",
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
         } catch (CacheExistException cee) {
-            log
-                    .error("\nCache already exists - destroy and recreate if needed");
+            log.error("\nCache already exists - destroy and recreate if needed");
         } catch (CacheConfigException cce) {
             log.error("\nCache configuration invalid - check cache mode");
         }
@@ -169,8 +162,7 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
     @SuppressWarnings({ "unchecked", "deprecation" })
     private void retrieveCaches() {
         if (this.clusterContainerService == null) {
-            log
-                    .info("un-initialized clusterContainerService, can't retrieve cache");
+            log.info("un-initialized clusterContainerService, can't retrieve cache");
             return;
         }
 
@@ -195,7 +187,7 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
                     try {
                         ra.staticRouteUpdate(s, update);
                     } catch (Exception e) {
-                        log.error("",e);
+                        log.error("", e);
                     }
                 }
             }
@@ -216,15 +208,16 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
 
         @Override
         public Object call() throws Exception {
-            if (!added
-                    || (staticRoute.getType() == StaticRoute.NextHopType.SWITCHPORT)) {
+            if (!added || (staticRoute.getType() == StaticRoute.NextHopType.SWITCHPORT)) {
                 notifyStaticRouteUpdate(staticRoute, added);
             } else {
                 InetAddress nh = staticRoute.getNextHopAddress();
-                HostNodeConnector host = hostTracker.hostQuery(nh);
+                // HostTracker hosts db key scheme implementation
+                IHostId id = HostIdFactory.create(nh, null);
+                HostNodeConnector host = hostTracker.hostQuery(id);
                 if (host == null) {
                     log.debug("Next hop {}  is not present, try to discover it", nh.getHostAddress());
-                    Future<HostNodeConnector> future = hostTracker.discoverHost(nh);
+                    Future<HostNodeConnector> future = hostTracker.discoverHost(id);
                     if (future != null) {
                         try {
                             host = future.get();
@@ -337,8 +330,7 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
     public StaticRoute getBestMatchStaticRoute(InetAddress ipAddress) {
         ByteBuffer bblongestPrefix = null;
         try {
-            bblongestPrefix = ByteBuffer.wrap(InetAddress.getByName("0.0.0.0")
-                    .getAddress());
+            bblongestPrefix = ByteBuffer.wrap(InetAddress.getByName("0.0.0.0").getAddress());
         } catch (Exception e) {
             return null;
         }
@@ -368,9 +360,8 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
             return status;
         }
         if (staticRouteConfigs.get(config.getName()) != null) {
-                return new Status(StatusCode.CONFLICT,
-                                "A valid Static Route configuration with this name " +
-                                                "already exists. Please use a different name");
+            return new Status(StatusCode.CONFLICT, "A valid Static Route configuration with this name "
+                    + "already exists. Please use a different name");
         }
 
         // Update database
@@ -378,10 +369,8 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
 
         for (Map.Entry<String, StaticRoute> entry : staticRoutes.entrySet()) {
             if (entry.getValue().compareTo(sRoute) == 0) {
-                return new Status(StatusCode.CONFLICT,
-                        "This conflicts with an existing Static Route " +
-                                "Configuration. Please check the configuration " +
-                                        "and try again");
+                return new Status(StatusCode.CONFLICT, "This conflicts with an existing Static Route "
+                        + "Configuration. Please check the configuration " + "and try again");
             }
         }
         staticRoutes.put(config.getName(), sRoute);
@@ -402,8 +391,7 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
             checkAndUpdateListeners(name, sRoute, false);
             return new Status(StatusCode.SUCCESS, null);
         }
-        return new Status(StatusCode.NOTFOUND,
-                        "Static Route with name " + name + " is not found");
+        return new Status(StatusCode.NOTFOUND, "Static Route with name " + name + " is not found");
     }
 
     void setClusterContainerService(IClusterContainerServices s) {
@@ -433,11 +421,9 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
             containerName = "";
         }
 
-        staticRoutesFileName = ROOT + "staticRouting_" + containerName
-                + ".conf";
+        staticRoutesFileName = ROOT + "staticRouting_" + containerName + ".conf";
 
-        log.debug("forwarding.staticrouting starting on container {}",
-                  containerName);
+        log.debug("forwarding.staticrouting starting on container {}", containerName);
         allocateCaches();
         retrieveCaches();
         this.executor = Executors.newFixedThreadPool(1);
@@ -446,8 +432,8 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
         }
 
         /*
-         *  Slow probe to identify any gateway that might have silently appeared
-         *  after the Static Routing Configuration.
+         * Slow probe to identify any gateway that might have silently appeared
+         * after the Static Routing Configuration.
          */
         gatewayProbeTimer = new Timer();
         gatewayProbeTimer.schedule(new TimerTask() {
@@ -455,24 +441,23 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
             public void run() {
                 for (Map.Entry<String, StaticRoute> s : staticRoutes.entrySet()) {
                     StaticRoute route = s.getValue();
-                    if ((route.getType() == StaticRoute.NextHopType.IPADDRESS)
-                            && route.getHost() == null) {
+                    if ((route.getType() == StaticRoute.NextHopType.IPADDRESS) && route.getHost() == null) {
                         checkAndUpdateListeners(s.getKey(), route, true);
                     }
                 }
             }
         }, 60 * 1000, 60 * 1000);
+
     }
 
     /**
-     * Function called by the dependency manager when at least one
-     * dependency become unsatisfied or when the component is shutting
-     * down because for example bundle is being stopped.
+     * Function called by the dependency manager when at least one dependency
+     * become unsatisfied or when the component is shutting down because for
+     * example bundle is being stopped.
      *
      */
     void destroy() {
-        log.debug("Destroy all the Static Routing Rules given we are "
-                + "shutting down");
+        log.debug("Destroy all the Static Routing Rules given we are " + "shutting down");
 
         gatewayProbeTimer.cancel();
 
@@ -481,18 +466,17 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
     }
 
     /**
-     * Function called by dependency manager after "init ()" is called
-     * and after the services provided by the class are registered in
-     * the service registry
+     * Function called by dependency manager after "init ()" is called and after
+     * the services provided by the class are registered in the service registry
      *
      */
     void start() {
     }
 
     /**
-     * Function called by the dependency manager before the services
-     * exported by the component are unregistered, this will be
-     * followed by a "destroy ()" calls
+     * Function called by the dependency manager before the services exported by
+     * the component are unregistered, this will be followed by a "destroy ()"
+     * calls
      *
      */
     void stop() {
index 2de9287670b446715144b9ffc37366267e461279..f25756cc115eb9ed61c40361b9b3d4d18ce6e7d1 100644 (file)
@@ -68,7 +68,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 613c2f164feae0b7452b03f37d4f66799485078d..23c36a37528b671829584177ac0f9ed4e5498f94 100644 (file)
@@ -74,7 +74,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 15b31d5ea675370a1588006d94a5f5695d8e3353..7904bd3a8f78f522a9a5dc93bd5b621ea3ab1488 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker.implementation</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 5846aa3d1a81810dbd41abb26e5c50266feb561f..ea66c34fa3f69dcb63800a0a5898a02720627103 100644 (file)
@@ -1,81 +1,82 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <parent>
-    <groupId>org.opendaylight.controller</groupId>
-    <artifactId>commons.opendaylight</artifactId>
-    <version>1.4.1-SNAPSHOT</version>
-    <relativePath>../../commons/opendaylight</relativePath>
 </parent>
 <scm>
-    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
-    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
-    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
-    <tag>HEAD</tag>
 </scm>
 <artifactId>hosttracker</artifactId>
 <version>0.4.1-SNAPSHOT</version>
 <packaging>bundle</packaging>
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>commons.opendaylight</artifactId>
+  <version>1.4.1-SNAPSHOT</version>
+  <relativePath>../../commons/opendaylight</relativePath>
+ </parent>
+ <scm>
+  <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+  <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+  <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
+  <tag>HEAD</tag>
+ </scm>
+ <artifactId>hosttracker</artifactId>
<version>0.5.1-SNAPSHOT</version>
+ <packaging>bundle</packaging>
 
 <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <version>${bundle.plugin.version}</version>
-        <extensions>true</extensions>
-        <configuration>
-          <instructions>
-            <Export-Package>
-              org.opendaylight.controller.hosttracker,
-              org.opendaylight.controller.hosttracker.hostAware
-            </Export-Package>
-            <Import-Package>
-              org.opendaylight.controller.sal.core,
-              org.opendaylight.controller.sal.utils,
-              org.opendaylight.controller.topologymanager,
-              org.opendaylight.controller.sal.packet.address,
-              org.opendaylight.controller.switchmanager,
-              org.opendaylight.controller.clustering.services,
-              javax.xml.bind.annotation,
-              javax.xml.bind,
-              org.apache.felix.dm,
-              org.apache.commons.lang3.builder,
-              org.osgi.service.component,
-              org.slf4j,
-              org.eclipse.osgi.framework.console,
-              org.osgi.framework
-            </Import-Package>
-          </instructions>
-          <manifestLocation>${project.basedir}/META-INF</manifestLocation>
-        </configuration>
-      </plugin>
-    </plugins>
 </build>
 <dependencies>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>topologymanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>switchmanager</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-    </dependency>
 </dependencies>
+ <build>
+  <plugins>
+   <plugin>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>maven-bundle-plugin</artifactId>
+    <version>${bundle.plugin.version}</version>
+    <extensions>true</extensions>
+    <configuration>
+     <instructions>
+      <Export-Package>
+       org.opendaylight.controller.hosttracker,
+       org.opendaylight.controller.hosttracker.hostAware
+      </Export-Package>
+      <Import-Package>
+       org.opendaylight.controller.sal.core,
+       org.opendaylight.controller.sal.utils,
+       org.opendaylight.controller.topologymanager,
+       org.opendaylight.controller.sal.packet.address,
+       org.opendaylight.controller.switchmanager,
+       org.opendaylight.controller.clustering.services,
+       javax.xml.bind.annotation,
+       javax.xml.bind,
+       org.apache.felix.dm,
+       org.apache.commons.lang3.builder,
+       org.osgi.service.component,
+       org.slf4j,
+       org.eclipse.osgi.framework.console,
+       org.osgi.framework
+      </Import-Package>
+     </instructions>
+     <manifestLocation>${project.basedir}/META-INF</manifestLocation>
+    </configuration>
+   </plugin>
+  </plugins>
+ </build>
+ <dependencies>
+  <dependency>
+   <groupId>org.opendaylight.controller</groupId>
+   <artifactId>topologymanager</artifactId>
+   <version>0.4.1-SNAPSHOT</version>
+  </dependency>
+  <dependency>
+   <groupId>org.opendaylight.controller</groupId>
+   <artifactId>switchmanager</artifactId>
+  </dependency>
+  <dependency>
+   <groupId>org.opendaylight.controller</groupId>
+   <artifactId>clustering.services</artifactId>
+   <version>0.4.1-SNAPSHOT</version>
+  </dependency>
+  <dependency>
+   <groupId>org.opendaylight.controller</groupId>
+   <artifactId>sal</artifactId>
+   <version>0.5.1-SNAPSHOT</version>
+  </dependency>
+  <dependency>
+   <groupId>junit</groupId>
+   <artifactId>junit</artifactId>
+  </dependency>
+ </dependencies>
 </project>
+
diff --git a/opendaylight/hosttracker/api/src/main/java/org/opendaylight/controller/hosttracker/HostIdFactory.java b/opendaylight/hosttracker/api/src/main/java/org/opendaylight/controller/hosttracker/HostIdFactory.java
new file mode 100644 (file)
index 0000000..4585306
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.hosttracker;
+
+import java.net.InetAddress;
+
+import org.opendaylight.controller.sal.packet.address.DataLinkAddress;
+
+/*
+ * Class used to generate a key based on the scheme choosen for hostsdb storage in hosttracker.
+ * @author Deepak Udapudi
+ */
+public class HostIdFactory {
+    public static final String DEFAULT_IP_KEY_SCHEME = "IP";
+    public static final String IP_MAC_KEY_SCHEME = "IP+MAC";
+    private static String scheme = null;
+    static {
+        scheme = System.getProperty("hosttracker.keyscheme");
+    }
+
+    public static String getScheme() {
+        return scheme;
+    }
+
+    public static IHostId create(InetAddress ip, DataLinkAddress mac) {
+        IHostId ipHostId = new IPHostId(ip);
+        if (scheme != null) {
+            switch (scheme) {
+
+            case DEFAULT_IP_KEY_SCHEME:
+                return ipHostId;
+            case IP_MAC_KEY_SCHEME:
+                IHostId ipMacHostId = new IPMacHostId(ip, mac);
+                return ipMacHostId;
+            default:
+                return ipHostId;
+
+            }
+        }
+        return ipHostId;
+    }
+
+}
diff --git a/opendaylight/hosttracker/api/src/main/java/org/opendaylight/controller/hosttracker/IHostId.java b/opendaylight/hosttracker/api/src/main/java/org/opendaylight/controller/hosttracker/IHostId.java
new file mode 100644 (file)
index 0000000..03f409e
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.hosttracker;
+
+import java.io.Serializable;
+
+/*
+ * Marker interface used by the key classes for their implementation
+ * @author Deepak Udapudi
+ */
+
+public interface IHostId extends Serializable {
+
+}
diff --git a/opendaylight/hosttracker/api/src/main/java/org/opendaylight/controller/hosttracker/IPHostId.java b/opendaylight/hosttracker/api/src/main/java/org/opendaylight/controller/hosttracker/IPHostId.java
new file mode 100644 (file)
index 0000000..9e2123c
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.hosttracker;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+
+/*
+ * IP only key class implementation using the marker interface IHostId
+ * @author Deepak Udapudi
+ */
+
+public class IPHostId implements IHostId, Serializable {
+    private static final long serialVersionUID = 1L;
+    private InetAddress ipAddress;
+
+    public InetAddress getIpAddress() {
+        return ipAddress;
+    }
+
+    public void setIpAddress(InetAddress ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    public IPHostId(InetAddress ipAddress) {
+        super();
+        this.ipAddress = ipAddress;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((ipAddress == null) ? 0 : ipAddress.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        IPHostId other = (IPHostId) obj;
+        if (ipAddress == null) {
+            if (other.ipAddress != null)
+                return false;
+        } else if (!ipAddress.equals(other.ipAddress))
+            return false;
+        return true;
+    }
+
+    public static IHostId fromIP(InetAddress addr) {
+        return new IPHostId(addr);
+    }
+
+}
diff --git a/opendaylight/hosttracker/api/src/main/java/org/opendaylight/controller/hosttracker/IPMacHostId.java b/opendaylight/hosttracker/api/src/main/java/org/opendaylight/controller/hosttracker/IPMacHostId.java
new file mode 100644 (file)
index 0000000..4ab84eb
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.hosttracker;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+
+/*
+ * IP + Mac key class implementation using the marker interface IHostId
+ * @author Deepak Udapudi
+ */
+
+import org.opendaylight.controller.sal.packet.address.DataLinkAddress;
+
+public class IPMacHostId implements IHostId, Serializable {
+
+    private static final long serialVersionUID = 1L;
+    private InetAddress ipAddress;
+    private DataLinkAddress macAddr;
+
+    public IPMacHostId(InetAddress ipAddress, DataLinkAddress macAddr) {
+        super();
+        this.ipAddress = ipAddress;
+        this.macAddr = macAddr;
+    }
+
+    public InetAddress getIpAddress() {
+        return ipAddress;
+    }
+
+    public void setIpAddress(InetAddress ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    public DataLinkAddress getMacAddr() {
+        return macAddr;
+    }
+
+    public void setMacAddr(DataLinkAddress macAddr) {
+        this.macAddr = macAddr;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((ipAddress == null) ? 0 : ipAddress.hashCode());
+        result = prime * result + ((macAddr == null) ? 0 : macAddr.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        IPMacHostId other = (IPMacHostId) obj;
+        if (ipAddress == null) {
+            if (other.ipAddress != null)
+                return false;
+        } else if (!ipAddress.equals(other.ipAddress))
+            return false;
+        if (macAddr == null) {
+            if (other.macAddr != null)
+                return false;
+        } else if (!macAddr.equals(other.macAddr))
+            return false;
+        return true;
+    }
+
+    public static IHostId fromIPAndMac(InetAddress ip, DataLinkAddress mac) {
+        return new IPMacHostId(ip, mac);
+    }
+
+}
index 2451e196f2eaf962a32d8cc53db9b0983b206bcc..e70a6e18650c9c39d09553e94c8f53a584addc22 100644 (file)
@@ -32,47 +32,100 @@ public interface IfIptoHost {
      * statically through Northbound APIs. If a binding is unknown, then an ARP
      * request is initiated immediately to discover the host.
      *
-     * @param networkAddress
-     *            IP Address of the Host encapsulated in class InetAddress
+     * @param id
+     *            IP address and Mac Address combination encapsulated in IHostId
+     *            interface
      * @return {@link org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector}
      *         Class that contains the Host info such as its MAC address, Switch
      *         ID, port, VLAN. If Host is not found, returns NULL
      */
-    public HostNodeConnector hostFind(InetAddress networkAddress);
+    public HostNodeConnector hostFind(IHostId id);
+
+    /**
+     * Applications call this interface methods to determine IP address to MAC
+     * binding and its connectivity to an OpenFlow switch in term of Node, Port,
+     * and VLAN. These bindings are learned dynamically as well as can be added
+     * statically through Northbound APIs. If a binding is unknown, then an ARP
+     * request is initiated immediately to discover the host.
+     *
+     * @param addr
+     *            IP address of the host
+     * @return {@link org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector}
+     *         Class that contains the Host info such as its MAC address, Switch
+     *         ID, port, VLAN. If Host is not found, returns NULL
+     */
+    public HostNodeConnector hostFind(InetAddress addr);
 
     /**
      * Checks the local Host Database to see if a Host has been learned for a
-     * given IP address.
+     * given IP address and Mac combination using the HostId.
      *
-     * @param networkAddress
-     *            IP Address of the Host encapsulated in class InetAddress
+     * @param id
+     *            IP address and Mac Address combination encapsulated in IHostId
+     *            interface
+     * @return {@link org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector}
+     *         Class that contains the Host info such as its MAC address, Switch
+     *         ID, port, VLAN. If Host is not found, returns NULL
+     *
+     */
+    public HostNodeConnector hostQuery(IHostId id);
+
+    /**
+     * Checks the local Host Database to see if a Host has been learned for a
+     * given IP address and Mac combination using the HostId.
+     *
+     * @param addr
+     *            IP address of the Host
      * @return {@link org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector}
      *         Class that contains the Host info such as its MAC address, Switch
      *         ID, port, VLAN. If Host is not found, returns NULL
      *
      */
-    public HostNodeConnector hostQuery(InetAddress networkAddress);
+    public HostNodeConnector hostQuery(InetAddress addr);
 
     /**
-     * Initiates an immediate discovery of the Host for a given IP address. This
+     * Initiates an immediate discovery of the Host for a given Host id. This
      * provides for the calling applications to block on the host discovery.
      *
-     * @param networkAddress
-     *            IP address encapsulated in InetAddress class
+     * @param id
+     *            IP address and Mac Address combination encapsulated in IHostId
+     *            interface
+     * @return Future
+     *         {@link org.opendaylight.controller.hosttracker.HostTrackerCallable}
+     */
+    public Future<HostNodeConnector> discoverHost(IHostId id);
+
+    /**
+     * Initiates an immediate discovery of the Host for a given Host id. This
+     * provides for the calling applications to block on the host discovery.
+     *
+     * @param addr
+     *            IP address of the host
      * @return Future
      *         {@link org.opendaylight.controller.hosttracker.HostTrackerCallable}
      */
-    public Future<HostNodeConnector> discoverHost(InetAddress networkAddress);
+    public Future<HostNodeConnector> discoverHost(InetAddress addr);
 
     /**
      * Returns the Network Hierarchy for a given Host. This API is typically
      * used by applications like Hadoop for Rack Awareness functionality.
      *
-     * @param IP
-     *            address of the Host encapsulated in InetAddress class
+     * @param id
+     *            IP address and Mac Address combination encapsulated in IHostId
+     *            interface
      * @return List of String ArrayList containing the Hierarchies.
      */
-    public List<List<String>> getHostNetworkHierarchy(InetAddress hostAddress);
+    public List<List<String>> getHostNetworkHierarchy(IHostId id);
+
+    /**
+     * Returns the Network Hierarchy for a given Host. This API is typically
+     * used by applications like Hadoop for Rack Awareness functionality.
+     *
+     * @param addr
+     *            IP address of the host
+     * @return List of String ArrayList containing the Hierarchies.
+     */
+    public List<List<String>> getHostNetworkHierarchy(InetAddress addr);
 
     /**
      * Returns all the the Hosts either learned dynamically or added statically
@@ -124,8 +177,7 @@ public interface IfIptoHost {
      * @return The status object as described in {@code Status} indicating the
      *         result of this action.
      */
-    public Status addStaticHost(String networkAddress, String dataLayerAddress,
-            NodeConnector nc, String vlan);
+    public Status addStaticHost(String networkAddress, String dataLayerAddress, NodeConnector nc, String vlan);
 
     /**
      * Allows the deletion of statically learned Host
@@ -135,4 +187,14 @@ public interface IfIptoHost {
      *         result of this action.
      */
     public Status removeStaticHost(String networkAddress);
+
+    /**
+     * Allows the deletion of statically learned Host
+     *
+     * @param networkAddress
+     * @param macAddress
+     * @return The status object as described in {@code Status} indicating the
+     *         result of this action.
+     */
+    public Status removeStaticHostUsingIPAndMac(String networkAddress, String macAddress);
 }
index 6faf2e91782495efe48be290910f5958f80a8e92..258327cca7254472dcf8d8208b21a920a0f0ecc5 100644 (file)
@@ -8,7 +8,7 @@
     <relativePath>../../commons/opendaylight</relativePath>
   </parent>
   <artifactId>hosttracker.implementation</artifactId>
-  <version>0.4.1-SNAPSHOT</version>
+  <version>0.5.1-SNAPSHOT</version>
   <packaging>bundle</packaging>
   <scm>
     <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index df62c1985a62b5e7b11db450a39586d3ce0a8d58..e1a8ef806a0f9ad9225392db87c3b656c0a6dbb8 100644 (file)
@@ -37,6 +37,10 @@ import org.opendaylight.controller.clustering.services.CacheExistException;
 import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
 import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.hosttracker.HostIdFactory;
+import org.opendaylight.controller.hosttracker.IHostId;
+import org.opendaylight.controller.hosttracker.IPHostId;
+import org.opendaylight.controller.hosttracker.IPMacHostId;
 import org.opendaylight.controller.hosttracker.IfHostListener;
 import org.opendaylight.controller.hosttracker.IfIptoHost;
 import org.opendaylight.controller.hosttracker.IfNewHostNotify;
@@ -84,13 +88,25 @@ import org.slf4j.LoggerFactory;
  *       removed the database
  */
 
+/***
+ *
+ * HostTracker db key scheme implementation support. Support has been added for
+ * IP only or IP + MAC scheme as of now. User can use either of the schemes
+ * based on the configuration done in config.ini file. By default IP only key
+ * scheme is choosen. The attribute to be set in config.ini is
+ * hosttracker.keyscheme. It could have a value of 0 or 1 as of now. 0 is for IP
+ * only scheme. 1 is for IP + MAC scheme.
+ *
+ *
+ */
+
 public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAware, IInventoryListener,
-        ITopologyManagerAware, ICacheUpdateAware<InetAddress, HostNodeConnector>, CommandProvider {
+        ITopologyManagerAware, ICacheUpdateAware<IHostId, HostNodeConnector>, CommandProvider {
     static final String ACTIVE_HOST_CACHE = "hosttracker.ActiveHosts";
     static final String INACTIVE_HOST_CACHE = "hosttracker.InactiveHosts";
     private static final Logger logger = LoggerFactory.getLogger(HostTracker.class);
     protected final Set<IHostFinder> hostFinder = new CopyOnWriteArraySet<IHostFinder>();;
-    protected ConcurrentMap<InetAddress, HostNodeConnector> hostsDB;
+    protected ConcurrentMap<IHostId, HostNodeConnector> hostsDB;
     /*
      * Following is a list of hosts which have been requested by NB APIs to be
      * added, but either the switch or the port is not sup, so they will be
@@ -109,13 +125,15 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     protected boolean stopping;
     private static boolean hostRefresh = true;
     private static int hostRetryCount = 5;
+    private String keyScheme = null;
+
     private static class ARPPending {
-        protected InetAddress hostIP;
+        protected IHostId hostId;
         protected short sent_count;
         protected HostTrackerCallable hostTrackerCallable;
 
-        public InetAddress getHostIP() {
-            return hostIP;
+        public IHostId getHostId() {
+            return hostId;
         }
 
         public short getSent_count() {
@@ -126,8 +144,8 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
             return hostTrackerCallable;
         }
 
-        public void setHostIP(InetAddress networkAddr) {
-            this.hostIP = networkAddr;
+        public void setHostId(IHostId id) {
+            this.hostId = id;
         }
 
         public void setSent_count(short count) {
@@ -141,7 +159,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
 
     // This list contains the hosts for which ARP requests are being sent
     // periodically
-    ConcurrentMap<InetAddress, ARPPending> ARPPendingList;
+    ConcurrentMap<IHostId, ARPPending> ARPPendingList;
     /*
      * This list below contains the hosts which were initially in ARPPendingList
      * above, but ARP response didn't come from there hosts after multiple
@@ -158,7 +176,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
      *
      * We can't recover from condition 3 above
      */
-    ConcurrentMap<InetAddress, ARPPending> failedARPReqList;
+    ConcurrentMap<IHostId, ARPPending> failedARPReqList;
 
     public HostTracker() {
     }
@@ -175,6 +193,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         /* ARP Refresh Timer to go off every 5 seconds to implement ARP aging */
         arpRefreshTimer = new Timer();
         arpRefreshTimer.schedule(new ARPRefreshHandler(), 5000, 5000);
+        keyScheme = HostIdFactory.getScheme();
         logger.debug("startUp: Caches created, timers started");
     }
 
@@ -204,8 +223,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
             return;
         }
         logger.debug("Retrieving cache for HostTrackerAH");
-        hostsDB = (ConcurrentMap<InetAddress, HostNodeConnector>) this.clusterContainerService
-                .getCache(ACTIVE_HOST_CACHE);
+        hostsDB = (ConcurrentMap<IHostId, HostNodeConnector>) this.clusterContainerService.getCache(ACTIVE_HOST_CACHE);
         if (hostsDB == null) {
             logger.error("Cache couldn't be retrieved for HostTracker");
         }
@@ -220,10 +238,10 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     }
 
     public void nonClusterObjectCreate() {
-        hostsDB = new ConcurrentHashMap<InetAddress, HostNodeConnector>();
+        hostsDB = new ConcurrentHashMap<IHostId, HostNodeConnector>();
         inactiveStaticHosts = new ConcurrentHashMap<NodeConnector, HostNodeConnector>();
-        ARPPendingList = new ConcurrentHashMap<InetAddress, ARPPending>();
-        failedARPReqList = new ConcurrentHashMap<InetAddress, ARPPending>();
+        ARPPendingList = new ConcurrentHashMap<IHostId, ARPPending>();
+        failedARPReqList = new ConcurrentHashMap<IHostId, ARPPending>();
     }
 
     public void shutDown() {
@@ -262,66 +280,72 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     }
 
     private boolean hostExists(HostNodeConnector host) {
-        HostNodeConnector lhost = hostsDB.get(host.getNetworkAddress());
+        IHostId id = HostIdFactory.create(host.getNetworkAddress(), host.getDataLayerAddress());
+        HostNodeConnector lhost = hostsDB.get(id);
         return host.equals(lhost);
     }
 
-    private HostNodeConnector getHostFromOnActiveDB(InetAddress networkAddress) {
-        return hostsDB.get(networkAddress);
+    private HostNodeConnector getHostFromOnActiveDB(IHostId id) {
+        return hostsDB.get(id);
     }
 
-    private Entry<NodeConnector, HostNodeConnector> getHostFromInactiveDB(InetAddress networkAddress) {
+    private Entry<NodeConnector, HostNodeConnector> getHostFromInactiveDB(IHostId id) {
         for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts.entrySet()) {
-            if (entry.getValue().equalsByIP(networkAddress)) {
-                logger.debug("getHostFromInactiveDB(): Inactive Host found for IP:{} ", networkAddress.getHostAddress());
+            HostNodeConnector hnc = entry.getValue();
+            IHostId cmpId = HostIdFactory.create(hnc.getNetworkAddress(), hnc.getDataLayerAddress());
+            if (cmpId.equals(id)) {
+                logger.debug("getHostFromInactiveDB(): Inactive Host found for ID:{} ", decodeIPFromId(id));
                 return entry;
             }
         }
-        logger.debug("getHostFromInactiveDB() Inactive Host Not found for IP: {}", networkAddress.getHostAddress());
+        logger.debug("getHostFromInactiveDB() Inactive Host Not found for ID: {}", decodeIPFromId(id));
         return null;
     }
 
-    private void removeHostFromInactiveDB(InetAddress networkAddress) {
+    private void removeHostFromInactiveDB(IHostId id) {
         NodeConnector nodeConnector = null;
         for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts.entrySet()) {
-            if (entry.getValue().equalsByIP(networkAddress)) {
+            HostNodeConnector hnc = entry.getValue();
+            IHostId cmpId = HostIdFactory.create(hnc.getNetworkAddress(), hnc.getDataLayerAddress());
+            if (cmpId.equals(id)) {
                 nodeConnector = entry.getKey();
                 break;
             }
         }
         if (nodeConnector != null) {
             inactiveStaticHosts.remove(nodeConnector);
-            logger.debug("removeHostFromInactiveDB(): Host Removed for IP: {}", networkAddress.getHostAddress());
+            logger.debug("removeHostFromInactiveDB(): Host Removed for IP: {}", decodeIPFromId(id));
             return;
         }
-        logger.debug("removeHostFromInactiveDB(): Host Not found for IP: {}", networkAddress.getHostAddress());
+        logger.debug("removeHostFromInactiveDB(): Host Not found for IP: {}", decodeIPFromId(id));
     }
 
     protected boolean hostMoved(HostNodeConnector host) {
-        if (hostQuery(host.getNetworkAddress()) != null) {
+        IHostId id = HostIdFactory.create(host.getNetworkAddress(), host.getDataLayerAddress());
+        if (hostQuery(id) != null) {
             return true;
         }
         return false;
     }
 
     @Override
-    public HostNodeConnector hostQuery(InetAddress networkAddress) {
-        return hostsDB.get(networkAddress);
+    public HostNodeConnector hostQuery(IHostId id) {
+        return hostsDB.get(id);
     }
 
     @Override
-    public Future<HostNodeConnector> discoverHost(InetAddress networkAddress) {
+    public Future<HostNodeConnector> discoverHost(IHostId id) {
         if (executor == null) {
             logger.debug("discoverHost: Null executor");
             return null;
         }
-        Callable<HostNodeConnector> worker = new HostTrackerCallable(this, networkAddress);
+        Callable<HostNodeConnector> worker = new HostTrackerCallable(this, id);
         Future<HostNodeConnector> submit = executor.submit(worker);
         return submit;
     }
 
     @Override
-    public HostNodeConnector hostFind(InetAddress networkAddress) {
+    public HostNodeConnector hostFind(IHostId id) {
         /*
          * Sometimes at boot with containers configured in the startup we hit
          * this path (from TIF) when hostFinder has not been set yet Caller
@@ -333,21 +357,21 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
             return null;
         }
 
-        HostNodeConnector host = hostQuery(networkAddress);
+        HostNodeConnector host = hostQuery(id);
         if (host != null) {
-            logger.debug("hostFind(): Host found for IP: {}", networkAddress.getHostAddress());
+            logger.debug("hostFind(): Host found for IP: {}", id);
             return host;
         }
 
         /* Add this host to ARPPending List for any potential retries */
 
-        addToARPPendingList(networkAddress);
-        logger.debug("hostFind(): Host Not Found for IP: {}, Inititated Host Discovery ...",
-                networkAddress.getHostAddress());
+        addToARPPendingList(id);
+        logger.debug("hostFind(): Host Not Found for IP: {}, Inititated Host Discovery ...", id);
 
         /* host is not found, initiate a discovery */
         for (IHostFinder hf : hostFinder) {
-            hf.find(networkAddress);
+            InetAddress addr = decodeIPFromId(id);
+            hf.find(addr);
         }
         return null;
     }
@@ -361,7 +385,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     @Override
     public Set<HostNodeConnector> getActiveStaticHosts() {
         Set<HostNodeConnector> list = new HashSet<HostNodeConnector>();
-        for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
+        for (Entry<IHostId, HostNodeConnector> entry : hostsDB.entrySet()) {
             HostNodeConnector host = entry.getValue();
             if (host.isStaticHost()) {
                 list.add(host);
@@ -376,31 +400,32 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         return list;
     }
 
-    private void addToARPPendingList(InetAddress networkAddr) {
+    private void addToARPPendingList(IHostId id) {
         ARPPending arphost = new ARPPending();
 
-        arphost.setHostIP(networkAddr);
+        arphost.setHostId(id);
         arphost.setSent_count((short) 1);
-        ARPPendingList.put(networkAddr, arphost);
-        logger.debug("Host Added to ARPPending List, IP: {}", networkAddr);
+        ARPPendingList.put(id, arphost);
+        logger.debug("Host Added to ARPPending List, IP: {}", decodeIPFromId(id));
+
     }
 
-    public void setCallableOnPendingARP(InetAddress networkAddr, HostTrackerCallable callable) {
+    public void setCallableOnPendingARP(IHostId id, HostTrackerCallable callable) {
         ARPPending arphost;
-        for (Entry<InetAddress, ARPPending> entry : ARPPendingList.entrySet()) {
+        for (Entry<IHostId, ARPPending> entry : ARPPendingList.entrySet()) {
             arphost = entry.getValue();
-            if (arphost.getHostIP().equals(networkAddr)) {
+            if (arphost.getHostId().equals(id)) {
                 arphost.setHostTrackerCallable(callable);
             }
         }
     }
 
-    private void processPendingARPReqs(InetAddress networkAddr) {
+    private void processPendingARPReqs(IHostId id) {
         ARPPending arphost;
 
-        if ((arphost = ARPPendingList.remove(networkAddr)) != null) {
+        if ((arphost = ARPPendingList.remove(id)) != null) {
             // Remove the arphost from ARPPendingList as it has been learned now
-            logger.debug("Host Removed from ARPPending List, IP: {}", networkAddr);
+            logger.debug("Host Removed from ARPPending List, IP: {}", id);
             HostTrackerCallable htCallable = arphost.getHostTrackerCallable();
             if (htCallable != null) {
                 htCallable.wakeup();
@@ -412,26 +437,27 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
          * It could have been a host from the FailedARPReqList
          */
 
-        if (failedARPReqList.containsKey(networkAddr)) {
-            failedARPReqList.remove(networkAddr);
-            logger.debug("Host Removed from FailedARPReqList List, IP: {}", networkAddr);
+        if (failedARPReqList.containsKey(id)) {
+            failedARPReqList.remove(id);
+            logger.debug("Host Removed from FailedARPReqList List, IP: {}", decodeIPFromId(id));
         }
     }
 
     // Learn a new Host
     private void learnNewHost(HostNodeConnector host) {
+        IHostId id = HostIdFactory.create(host.getNetworkAddress(), host.getDataLayerAddress());
         host.initArpSendCountDown();
-        HostNodeConnector rHost = hostsDB.putIfAbsent(host.getNetworkAddress(), host);
+        HostNodeConnector rHost = hostsDB.putIfAbsent(id, host);
         if (rHost != null) {
             // Another host is already learned for this IP address, replace it
-            replaceHost(host.getNetworkAddress(), rHost, host);
+            replaceHost(id, rHost, host);
         } else {
             logger.debug("New Host Learned: MAC: {}  IP: {}", HexEncode.bytesToHexString(host
                     .getDataLayerAddressBytes()), host.getNetworkAddress().getHostAddress());
         }
     }
 
-    private void replaceHost(InetAddress networkAddr, HostNodeConnector removedHost, HostNodeConnector newHost) {
+    private void replaceHost(IHostId id, HostNodeConnector removedHost, HostNodeConnector newHost) {
         // Ignore ARP messages from internal nodes
         NodeConnector newHostNc = newHost.getnodeConnector();
         boolean newHostIsInternal = topologyManager.isInternal(newHostNc);
@@ -441,7 +467,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
 
         newHost.initArpSendCountDown();
 
-        if (hostsDB.replace(networkAddr, removedHost, newHost)) {
+        if (hostsDB.replace(id, removedHost, newHost)) {
             logger.debug("Host move occurred: Old Host IP:{}, New Host IP: {}", removedHost.getNetworkAddress()
                     .getHostAddress(), newHost.getNetworkAddress().getHostAddress());
             logger.debug("Old Host MAC: {}, New Host MAC: {}",
@@ -453,25 +479,25 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
             /*
              * Host replacement has failed, do the recovery
              */
-            hostsDB.put(networkAddr, newHost);
+            hostsDB.put(id, newHost);
             logger.error("Host replacement failed. Overwrite the host. Repalced Host: {}, New Host: {}", removedHost,
                     newHost);
         }
         notifyHostLearnedOrRemoved(removedHost, false);
         notifyHostLearnedOrRemoved(newHost, true);
         if (!newHost.isStaticHost()) {
-            processPendingARPReqs(networkAddr);
+            processPendingARPReqs(id);
         }
     }
 
     // Remove known Host
-    private void removeKnownHost(InetAddress key) {
+    private void removeKnownHost(IHostId key) {
         HostNodeConnector host = hostsDB.get(key);
         if (host != null) {
             logger.debug("Removing Host: IP:{}", host.getNetworkAddress().getHostAddress());
             hostsDB.remove(key);
         } else {
-            logger.error("removeKnownHost(): Host for IP address {} not found in hostsDB", key.getHostAddress());
+            logger.error("removeKnownHost(): Host for IP address {} not found in hostsDB", decodeIPFromId(key));
         }
     }
 
@@ -487,7 +513,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         public void run() {
             HostNodeConnector removedHost = null;
             InetAddress networkAddr = host.getNetworkAddress();
-
+            IHostId id = HostIdFactory.create(networkAddr, host.getDataLayerAddress());
             /* Check for Host Move case */
             if (hostMoved(host)) {
                 /*
@@ -496,9 +522,10 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                  * location parameters with new information, and notify the
                  * applications listening to host move.
                  */
-                removedHost = hostsDB.get(networkAddr);
+
+                removedHost = hostsDB.get(id);
                 if (removedHost != null) {
-                    replaceHost(networkAddr, removedHost, host);
+                    replaceHost(id, removedHost, host);
                     return;
                 } else {
                     logger.error("Host to be removed not found in hostsDB");
@@ -509,7 +536,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
             learnNewHost(host);
 
             /* check if there is an outstanding request for this host */
-            processPendingARPReqs(networkAddr);
+            processPendingARPReqs(id);
             notifyHostLearnedOrRemoved(host, true);
         }
     }
@@ -519,10 +546,13 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         logger.debug("Received for Host: IP {}, MAC {}, {}", host.getNetworkAddress().getHostAddress(),
                 HexEncode.bytesToHexString(host.getDataLayerAddressBytes()), host);
         if (hostExists(host)) {
-            HostNodeConnector existinghost = hostsDB.get(host.getNetworkAddress());
+            IHostId id = HostIdFactory.create(host.getNetworkAddress(), host.getDataLayerAddress());
+            HostNodeConnector existinghost = hostsDB.get(id);
             existinghost.initArpSendCountDown();
             // Update the host
-            hostsDB.put(host.getNetworkAddress(), existinghost);
+
+            hostsDB.put(id, existinghost);
+            logger.debug("hostListener returned without adding the host");
             return;
         }
         new NotifyHostThread(host).start();
@@ -720,8 +750,8 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
      *         Switch-Ids as String).
      */
     @Override
-    public List<List<String>> getHostNetworkHierarchy(InetAddress hostAddress) {
-        HostNodeConnector host = hostQuery(hostAddress);
+    public List<List<String>> getHostNetworkHierarchy(IHostId id) {
+        HostNodeConnector host = hostQuery(id);
         if (host == null) {
             return null;
         }
@@ -903,16 +933,16 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     public void subnetNotify(Subnet sub, boolean add) {
         logger.debug("Received subnet notification: {}  add={}", sub, add);
         if (add) {
-            for (Entry<InetAddress, ARPPending> entry : failedARPReqList.entrySet()) {
+            for (Entry<IHostId, ARPPending> entry : failedARPReqList.entrySet()) {
                 ARPPending arphost;
                 arphost = entry.getValue();
                 if (hostFinder == null) {
                     logger.warn("ARPHandler Services are not available on subnet addition");
                     continue;
                 }
-                logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
+                logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", decodeIPFromId(arphost.getHostId()));
                 for (IHostFinder hf : hostFinder) {
-                    hf.find(arphost.getHostIP());
+                    hf.find(decodeIPFromId(arphost.getHostId()));
                 }
             }
         }
@@ -928,14 +958,14 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
             /* This routine runs every 4 seconds */
             logger.trace("Number of Entries in ARP Pending/Failed Lists: ARPPendingList = {}, failedARPReqList = {}",
                     ARPPendingList.size(), failedARPReqList.size());
-            for (Entry<InetAddress, ARPPending> entry : ARPPendingList.entrySet()) {
+            for (Entry<IHostId, ARPPending> entry : ARPPendingList.entrySet()) {
                 arphost = entry.getValue();
 
-                if (hostsDB.containsKey(arphost.getHostIP())) {
+                if (hostsDB.containsKey(arphost.getHostId())) {
                     // this host is already learned, shouldn't be in
                     // ARPPendingList
                     // Remove it and continue
-                    logger.warn("Learned Host {} found in ARPPendingList", arphost.getHostIP());
+                    logger.warn("Learned Host {} found in ARPPendingList", decodeIPFromId(arphost.getHostId()));
                     ARPPendingList.remove(entry.getKey());
                     continue;
                 }
@@ -950,10 +980,10 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                         continue;
                     }
                     for (IHostFinder hf : hostFinder) {
-                        hf.find(arphost.getHostIP());
+                        hf.find(decodeIPFromId(arphost.getHostId()));
                     }
                     arphost.sent_count++;
-                    logger.debug("ARP Sent from ARPPending List, IP: {}", arphost.getHostIP().getHostAddress());
+                    logger.debug("ARP Sent from ARPPending List, IP: {}", decodeIPFromId(arphost.getHostId()));
                 } else if (arphost.getSent_count() >= hostRetryCount) {
                     /*
                      * ARP requests have been sent without receiving a reply,
@@ -961,12 +991,12 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                      */
                     ARPPendingList.remove(entry.getKey());
                     logger.debug("ARP reply not received after multiple attempts, removing from Pending List IP: {}",
-                            arphost.getHostIP().getHostAddress());
+                            decodeIPFromId(arphost.getHostId()));
                     /*
                      * Add this host to a different list which will be processed
                      * on link up events
                      */
-                    logger.debug("Adding the host to FailedARPReqList IP: {}", arphost.getHostIP().getHostAddress());
+                    logger.debug("Adding the host to FailedARPReqList IP: {}", decodeIPFromId(arphost.getHostId()));
                     failedARPReqList.put(entry.getKey(), arphost);
 
                 } else {
@@ -996,7 +1026,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                 logger.error("ARPRefreshHandler(): hostsDB is not allocated yet:");
                 return;
             }
-            for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
+            for (Entry<IHostId, HostNodeConnector> entry : hostsDB.entrySet()) {
                 HostNodeConnector host = entry.getValue();
                 if (host.isStaticHost()) {
                     /* this host was learned via API3, don't age it out */
@@ -1073,6 +1103,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         HostNodeConnector host = null;
         try {
             host = new HostNodeConnector(dataLayerAddress, networkAddr, nc, vlan);
+            IHostId id = HostIdFactory.create(networkAddr, new EthernetAddress(dataLayerAddress));
             if (hostExists(host)) {
                 // This host is already learned either via ARP or through a
                 // northbound request
@@ -1081,7 +1112,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                 return new Status(StatusCode.SUCCESS);
             }
 
-            if (hostsDB.get(networkAddr) != null) {
+            if (hostsDB.get(id) != null) {
                 // There is already a host with this IP address (but behind
                 // a different (switch, port, vlan) tuple. Return an error
                 return new Status(StatusCode.CONFLICT, "Host with this IP already exists.");
@@ -1101,7 +1132,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
              */
             if (switchManager.isNodeConnectorEnabled(nc)) {
                 learnNewHost(host);
-                processPendingARPReqs(networkAddr);
+                processPendingARPReqs(id);
                 notifyHostLearnedOrRemoved(host, true);
             } else {
                 inactiveStaticHosts.put(nc, host);
@@ -1152,8 +1183,10 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                 return new Status(StatusCode.BADREQUEST, "Host already exists");
             }
 
+            IHostId id = HostIdFactory.create(networkAddr, new EthernetAddress(dataLayerAddress));
+
             if ((tobeUpdatedHost = hostsDB.get(networkAddr)) != null) {
-                if (hostsDB.replace(networkAddr, tobeUpdatedHost, host)) {
+                if (hostsDB.replace(id, tobeUpdatedHost, host)) {
                     logger.debug("Host replaced from hostsDB. Old host: {} New Host: {}", tobeUpdatedHost, host);
                     notifyHostLearnedOrRemoved(tobeUpdatedHost, false);
                     notifyHostLearnedOrRemoved(host, true);
@@ -1199,9 +1232,10 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
      *         otherwise
      */
 
-    public Status removeStaticHostReq(InetAddress networkAddress) {
+    public Status removeStaticHostReq(InetAddress networkAddress, DataLinkAddress mac) {
         // Check if host is in active hosts database
-        HostNodeConnector host = getHostFromOnActiveDB(networkAddress);
+        IHostId id = HostIdFactory.create(networkAddress, mac);
+        HostNodeConnector host = getHostFromOnActiveDB(id);
         if (host != null) {
             // Validation check
             if (!host.isStaticHost()) {
@@ -1209,19 +1243,19 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
             }
             // Remove and notify
             notifyHostLearnedOrRemoved(host, false);
-            removeKnownHost(networkAddress);
+            removeKnownHost(id);
             return new Status(StatusCode.SUCCESS, null);
         }
 
         // Check if host is in inactive hosts database
-        Entry<NodeConnector, HostNodeConnector> entry = getHostFromInactiveDB(networkAddress);
+        Entry<NodeConnector, HostNodeConnector> entry = getHostFromInactiveDB(id);
         if (entry != null) {
             host = entry.getValue();
             // Validation check
             if (!host.isStaticHost()) {
                 return new Status(StatusCode.FORBIDDEN, "Host " + networkAddress.getHostName() + " is not static");
             }
-            this.removeHostFromInactiveDB(networkAddress);
+            this.removeHostFromInactiveDB(id);
             return new Status(StatusCode.SUCCESS, null);
         }
 
@@ -1243,7 +1277,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         switch (type) {
         case REMOVED:
             logger.debug("Received removed node {}", node);
-            for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
+            for (Entry<IHostId, HostNodeConnector> entry : hostsDB.entrySet()) {
                 HostNodeConnector host = entry.getValue();
                 if (host.getnodeconnectorNode().equals(node)) {
                     logger.debug("Node: {} is down, remove from Hosts_DB", node);
@@ -1313,23 +1347,65 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     @Override
     public Status removeStaticHost(String networkAddress) {
         try {
+            if ((keyScheme != null) && (!keyScheme.equals(HostIdFactory.DEFAULT_IP_KEY_SCHEME))) {
+                return new Status(StatusCode.NOTALLOWED, "Host DB Key scheme used is not IP only scheme.");
+            }
             InetAddress address = InetAddress.getByName(networkAddress);
-            return removeStaticHostReq(address);
+            return removeStaticHostReq(address, null);
         } catch (UnknownHostException e) {
             logger.debug("Invalid IP Address when trying to remove host", e);
             return new Status(StatusCode.BADREQUEST, "Invalid IP Address when trying to remove host");
         }
     }
 
+    @Override
+    public Status removeStaticHostUsingIPAndMac(String networkAddress, String macAddress) {
+        try {
+            if ((keyScheme != null) && (keyScheme.equals(HostIdFactory.DEFAULT_IP_KEY_SCHEME))) {
+                return new Status(StatusCode.NOTALLOWED, "Host DB Key scheme used is not IP only scheme.");
+            }
+            InetAddress address = InetAddress.getByName(networkAddress);
+            DataLinkAddress mac = new EthernetAddress(HexEncode.bytesFromHexString(macAddress));
+            return removeStaticHostReq(address, mac);
+        } catch (UnknownHostException e) {
+            logger.debug("Invalid IP Address when trying to remove host", e);
+            return new Status(StatusCode.BADREQUEST, "Invalid IP Address when trying to remove host");
+        } catch (ConstructionException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            return new Status(StatusCode.BADREQUEST, "Invalid Input parameters have been passed.");
+        }
+    }
+
+    private InetAddress decodeIPFromId(IHostId id) {
+        if ((keyScheme != null) && (keyScheme.equals(HostIdFactory.DEFAULT_IP_KEY_SCHEME))) {
+            IPHostId ipId = (IPHostId) id;
+            return (ipId.getIpAddress());
+        } else if ((keyScheme != null) && (keyScheme.equals(HostIdFactory.IP_MAC_KEY_SCHEME))) {
+            IPMacHostId ipMacId = (IPMacHostId) id;
+            return (ipMacId.getIpAddress());
+        }
+        return null;
+    }
+
+    private DataLinkAddress decodeMacFromId(IHostId id) {
+        if ((keyScheme != null) && (!keyScheme.equals(HostIdFactory.DEFAULT_IP_KEY_SCHEME))) {
+            IPMacHostId ipMacId = (IPMacHostId) id;
+            return (ipMacId.getMacAddr());
+        }
+
+        return null;
+    }
+
     private void handleNodeConnectorStatusUp(NodeConnector nodeConnector) {
         ARPPending arphost;
         HostNodeConnector host = null;
 
         logger.trace("handleNodeConnectorStatusUp {}", nodeConnector);
 
-        for (Entry<InetAddress, ARPPending> entry : failedARPReqList.entrySet()) {
+        for (Entry<IHostId, ARPPending> entry : failedARPReqList.entrySet()) {
             arphost = entry.getValue();
-            logger.trace("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
+            logger.trace("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostId());
             if (hostFinder == null) {
                 logger.warn("ARPHandler is not available at interface  up");
                 logger.warn("Since this event is missed, host(s) connected to interface {} may not be discovered",
@@ -1341,13 +1417,14 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
             // Use hostFinder's "probe" method
             try {
                 byte[] dataLayerAddress = NetUtils.getBroadcastMACAddr();
-                host = new HostNodeConnector(dataLayerAddress, arphost.getHostIP(), nodeConnector, (short) 0);
+                host = new HostNodeConnector(dataLayerAddress, decodeIPFromId(arphost.getHostId()), nodeConnector,
+                        (short) 0);
                 for (IHostFinder hf : hostFinder) {
                     hf.probe(host);
                 }
             } catch (ConstructionException e) {
                 logger.debug("HostNodeConnector couldn't be created for Host: {}, NodeConnector: {}",
-                        arphost.getHostIP(), nodeConnector);
+                        arphost.getHostId(), nodeConnector);
                 logger.error("", e);
             }
         }
@@ -1356,7 +1433,8 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         if (host != null) {
             inactiveStaticHosts.remove(nodeConnector);
             learnNewHost(host);
-            processPendingARPReqs(host.getNetworkAddress());
+            IHostId id = HostIdFactory.create(host.getNetworkAddress(), host.getDataLayerAddress());
+            processPendingARPReqs(id);
             notifyHostLearnedOrRemoved(host, true);
         }
     }
@@ -1364,7 +1442,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     private void handleNodeConnectorStatusDown(NodeConnector nodeConnector) {
         logger.trace("handleNodeConnectorStatusDown {}", nodeConnector);
 
-        for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
+        for (Entry<IHostId, HostNodeConnector> entry : hostsDB.entrySet()) {
             HostNodeConnector host = entry.getValue();
             if (host.getnodeConnector().equals(nodeConnector)) {
                 logger.debug(" NodeConnector: {} is down, remove from Hosts_DB", nodeConnector);
@@ -1420,6 +1498,8 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
             this.containerName = "";
         }
         startUp();
+
+        logger.debug("key Scheme in hosttracker is {}", keyScheme);
     }
 
     /**
@@ -1467,7 +1547,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     }
 
     @Override
-    public void entryCreated(InetAddress key, String cacheName, boolean originLocal) {
+    public void entryCreated(IHostId key, String cacheName, boolean originLocal) {
         if (originLocal) {
             return;
         }
@@ -1475,11 +1555,11 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     }
 
     @Override
-    public void entryUpdated(InetAddress key, HostNodeConnector new_value, String cacheName, boolean originLocal) {
+    public void entryUpdated(IHostId key, HostNodeConnector new_value, String cacheName, boolean originLocal) {
     }
 
     @Override
-    public void entryDeleted(InetAddress key, String cacheName, boolean originLocal) {
+    public void entryDeleted(IHostId key, String cacheName, boolean originLocal) {
     }
 
     private void registerWithOSGIConsole() {
@@ -1494,17 +1574,41 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
 
     public void _dumpPendingARPReqList(CommandInterpreter ci) {
         ARPPending arphost;
-        for (Entry<InetAddress, ARPPending> entry : ARPPendingList.entrySet()) {
+        for (Entry<IHostId, ARPPending> entry : ARPPendingList.entrySet()) {
             arphost = entry.getValue();
-            ci.println(arphost.getHostIP().toString());
+            ci.println(arphost.getHostId().toString());
         }
     }
 
     public void _dumpFailedARPReqList(CommandInterpreter ci) {
         ARPPending arphost;
-        for (Entry<InetAddress, ARPPending> entry : failedARPReqList.entrySet()) {
+        for (Entry<IHostId, ARPPending> entry : failedARPReqList.entrySet()) {
             arphost = entry.getValue();
-            ci.println(arphost.getHostIP().toString());
+            ci.println(arphost.getHostId().toString());
         }
     }
+
+    @Override
+    public HostNodeConnector hostFind(InetAddress addr) {
+        IHostId id = HostIdFactory.create(addr, null);
+        return (hostFind(id));
+    }
+
+    @Override
+    public HostNodeConnector hostQuery(InetAddress addr) {
+        IHostId id = HostIdFactory.create(addr, null);
+        return (hostQuery(id));
+    }
+
+    @Override
+    public Future<HostNodeConnector> discoverHost(InetAddress addr) {
+        IHostId id = HostIdFactory.create(addr, null);
+        return discoverHost(id);
+    }
+
+    @Override
+    public List<List<String>> getHostNetworkHierarchy(InetAddress addr) {
+        IHostId id = HostIdFactory.create(addr, null);
+        return getHostNetworkHierarchy(id);
+    }
 }
index 303308270d77d36eb803b42feca3096bbfeed0fb..a1d29dd27fe014696db69b0e08cadff297465d3b 100644 (file)
@@ -18,19 +18,24 @@ package org.opendaylight.controller.hosttracker.internal;
  * find a host in HostTracker's database and want to discover the host
  * in the same thread without being called by a callback function.
  */
-import java.net.InetAddress;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 
+import org.opendaylight.controller.hosttracker.IHostId;
 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
 
+/**
+ *
+ *
+ */
 public class HostTrackerCallable implements Callable<HostNodeConnector> {
 
-    InetAddress trackedHost;
+    //host id which could be ip or a combination of ip + mac based on the scheme chosen.
+    IHostId trackedHost;
     HostTracker hostTracker;
     protected CountDownLatch latch;
 
-    public HostTrackerCallable(HostTracker tracker, InetAddress inet) {
+    public HostTrackerCallable(HostTracker tracker, IHostId inet) {
         trackedHost = inet;
         hostTracker = tracker;
         latch = new CountDownLatch(1);
index dc15f96f6efadb2f727f1a469cbb59d9a921f1b9..d7c60e67a91dfa85213343e41e3f495bacf83e55 100644 (file)
@@ -10,10 +10,13 @@ package org.opendaylight.controller.hosttracker.internal;
 \r
 import java.net.InetAddress;\r
 import java.net.UnknownHostException;\r
+\r
 import junit.framework.TestCase;\r
 \r
 import org.junit.Assert;\r
 import org.junit.Test;\r
+import org.opendaylight.controller.hosttracker.IHostId;\r
+import org.opendaylight.controller.hosttracker.IPHostId;\r
 \r
 public class HostTrackerTest extends TestCase {\r
 \r
@@ -25,10 +28,11 @@ public class HostTrackerTest extends TestCase {
         Assert.assertFalse(hostTracker == null);\r
 \r
         InetAddress hostIP = InetAddress.getByName("192.168.0.8");\r
+        IHostId id  = IPHostId.fromIP(hostIP);\r
 \r
         HostTrackerCallable htCallable = new HostTrackerCallable(hostTracker,\r
-                hostIP);\r
-        Assert.assertTrue(htCallable.trackedHost.equals(hostIP));\r
+                id);\r
+        Assert.assertTrue(htCallable.trackedHost.equals(id));\r
         Assert.assertTrue(htCallable.hostTracker.equals(hostTracker));\r
 \r
         long count = htCallable.latch.getCount();\r
@@ -43,9 +47,11 @@ public class HostTrackerTest extends TestCase {
         Assert.assertFalse(hostTracker == null);\r
 \r
         InetAddress hostIP_1 = InetAddress.getByName("192.168.0.8");\r
+        IHostId id1 = IPHostId.fromIP(hostIP_1);\r
         InetAddress hostIP_2 = InetAddress.getByName("192.168.0.18");\r
-        hostTracker.discoverHost(hostIP_1);\r
-        hostTracker.discoverHost(hostIP_2);\r
+        IHostId id2 = IPHostId.fromIP(hostIP_2);\r
+        hostTracker.discoverHost(id1);\r
+        hostTracker.discoverHost(id2);\r
         hostTracker.nonClusterObjectCreate();\r
     }\r
 \r
index 7274ef8e55556d284ab46c12c4ecdf397addd92a..8f4163d68674d8a65cd0fb94689d42b6a6679189 100644 (file)
   </scm>
 
   <artifactId>hosttracker.integrationtest</artifactId>
-  <version>0.4.1-SNAPSHOT</version>
+  <version>0.5.1-SNAPSHOT</version>
 
   <dependencies>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker.implementation</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
@@ -53,7 +53,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>arphandler</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${arphandler.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index cea8af009f79c1fd65e6c0734e7fb5f096e1a991..a454eb97e1305b9a5dbec63a0d4c895edc11ccb3 100644 (file)
@@ -27,6 +27,8 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.opendaylight.controller.hosttracker.IHostId;
+import org.opendaylight.controller.hosttracker.IPHostId;
 import org.opendaylight.controller.hosttracker.IfIptoHost;
 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
 import org.opendaylight.controller.sal.core.Node;
@@ -45,6 +47,7 @@ import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+
 //import org.opendaylight.controller.hosttracker.*;
 
 @RunWith(PaxExam.class)
@@ -56,6 +59,7 @@ public class HostTrackerIT {
 
     private IfIptoHost hosttracker = null;
     private IInventoryListener invtoryListener = null;
+
     // Configure the OSGi container
     @Configuration
     public Option[] config() {
@@ -218,7 +222,6 @@ public class HostTrackerIT {
         st = this.hosttracker.addStaticHost("192.168.0.13", "11:22:33:44:55:77", nc1_2, "0");
         Assert.assertFalse(st.isSuccess());
 
-
         this.invtoryListener.notifyNodeConnector(nc1_1, UpdateType.ADDED, null);
 
         // check all host list
@@ -257,12 +260,15 @@ public class HostTrackerIT {
         Status st = this.hosttracker.addStaticHost("192.168.0.8", "11:22:33:44:55:66", nc1_1, null);
         st = this.hosttracker.addStaticHost("192.168.0.13", "11:22:33:44:55:77", nc1_2, "");
 
-        HostNodeConnector hnc_1 = this.hosttracker.hostFind(InetAddress.getByName("192.168.0.8"));
+        IHostId id1 = IPHostId.fromIP(InetAddress.getByName("192.168.0.8"));
+        HostNodeConnector hnc_1 = this.hosttracker.hostFind(id1);
         assertNull(hnc_1);
 
         this.invtoryListener.notifyNodeConnector(nc1_1, UpdateType.ADDED, null);
 
-        hnc_1 = this.hosttracker.hostFind(InetAddress.getByName("192.168.0.8"));
+        IHostId id2 = IPHostId.fromIP(InetAddress.getByName("192.168.0.8"));
+        hnc_1 = this.hosttracker.hostFind(id2);
+
         assertNotNull(hnc_1);
 
     }
index b5f540222a353ede646ddb18246c55e4c9854d82..597483ef6541456b4e417c255e71465e8fa0fe79 100644 (file)
       <artifactId>model-flow-management</artifactId>
       <version>1.0-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-common</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-binding-broker-impl</artifactId>
index 522b09681b5b77f523d65b010cbc8fb30ade09bd..ae6ce2f8004dd3a3244ff2567507b175fade9f53 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcAction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdAction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActions;
@@ -57,7 +58,7 @@ public class FRMUtil {
 
     }
 
-    public static boolean validateMatch(NodeFlow flow) {
+    public static boolean validateMatch(Flow flow) {
         Match match = flow.getMatch();
         if (match != null) {
             EthernetMatch ethernetmatch = match.getEthernetMatch();
@@ -198,9 +199,12 @@ public class FRMUtil {
         return true;
     }
 
-    public static boolean validateInstructions(NodeFlow flow) {
+    public static boolean validateInstructions(Flow flow) {
         List<Instruction> instructionsList = new ArrayList<>();
         Instructions instructions = flow.getInstructions();
+        if( instructions == null ) {
+            return false;
+        }
         instructionsList = instructions.getInstruction();
 
         for (Instruction instruction : instructionsList) {
index 2ffe0ecd87eee775b08f6e5b51c1e0febcb66baf..9d2a6a0b110f333be53b6640cb02c83653982e99 100644 (file)
@@ -1,8 +1,10 @@
 package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -20,12 +22,7 @@ import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.Data
 import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.IContainer;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
-import org.opendaylight.controller.switchmanager.ISwitchManager;
-import org.opendaylight.controller.switchmanager.Switch;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey;
@@ -54,6 +51,7 @@ import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -86,8 +84,7 @@ public class FlowConsumerImpl implements IForwardingRulesManager {
     private boolean inContainerMode; // being used by global instance only
 
     public FlowConsumerImpl() {
-        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Flows.class).child(Flow.class)
-                .toInstance();
+        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Flows.class).toInstance();
         flowService = FRMConsumerImpl.getProviderSession().getRpcService(SalFlowService.class);
 
         if (null == flowService) {
@@ -116,12 +113,11 @@ public class FlowConsumerImpl implements IForwardingRulesManager {
         }
         // addFlowTest();
         System.out.println("-------------------------------------------------------------------");
-        allocateCaches();
         commitHandler = new FlowDataCommitHandler();
         FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler);
         clusterContainerService = (IClusterContainerServices) ServiceHelper.getGlobalInstance(
                 IClusterContainerServices.class, this);
-        container = (IContainer) ServiceHelper.getGlobalInstance(IContainer.class, this);
+        allocateCaches();
         /*
          * If we are not the first cluster node to come up, do not initialize
          * the static flow entries ordinal
@@ -204,13 +200,20 @@ public class FlowConsumerImpl implements IForwardingRulesManager {
         System.out.println("Instruction list" + (dataObject).getInstructions().getInstruction().toString());
 
         // updating the staticflow cache
+        /*
+         *  Commented out... as in many other places... use of ClusteringServices is breaking things
+         *  insufficient time to debug
         Integer ordinal = staticFlowsOrdinal.get(0);
         staticFlowsOrdinal.put(0, ++ordinal);
         staticFlows.put(ordinal, dataObject);
+        */
 
         // We send flow to the sounthbound plugin
         flowService.addFlow(input.build());
+        /*
+         * Commented out as this will also break due to improper use of ClusteringServices
         updateLocalDatabase((NodeFlow) dataObject, true);
+        */
     }
 
     /**
@@ -237,13 +240,19 @@ public class FlowConsumerImpl implements IForwardingRulesManager {
         System.out.println("Instruction list" + (dataObject).getInstructions().getInstruction().toString());
 
         // updating the staticflow cache
+        /*
+         * Commented out due to problems caused by improper use of ClusteringServices
         Integer ordinal = staticFlowsOrdinal.get(0);
         staticFlowsOrdinal.put(0, ++ordinal);
         staticFlows.put(ordinal, dataObject);
+        */
 
         // We send flow to the sounthbound plugin
         flowService.removeFlow(input.build());
+        /*
+         * Commented out due to problems caused by improper use of ClusteringServices
         updateLocalDatabase((NodeFlow) dataObject, false);
+        */
     }
 
     /**
@@ -257,33 +266,60 @@ public class FlowConsumerImpl implements IForwardingRulesManager {
         UpdateFlowInputBuilder input = new UpdateFlowInputBuilder();
         UpdatedFlowBuilder updatedflowbuilder = new UpdatedFlowBuilder();
         updatedflowbuilder.fieldsFrom(dataObject);
+        input.setNode(dataObject.getNode());
         input.setUpdatedFlow(updatedflowbuilder.build());
 
         // updating the staticflow cache
+        /*
+         * Commented out due to problems caused by improper use of ClusteringServices.
         Integer ordinal = staticFlowsOrdinal.get(0);
         staticFlowsOrdinal.put(0, ++ordinal);
         staticFlows.put(ordinal, dataObject);
+        */
 
         // We send flow to the sounthbound plugin
         flowService.updateFlow(input.build());
+        /*
+         * Commented out due to problems caused by improper use of ClusteringServices.
         updateLocalDatabase((NodeFlow) dataObject, true);
+        */
     }
 
     @SuppressWarnings("unchecked")
     private void commitToPlugin(internalTransaction transaction) {
-        for (Entry<InstanceIdentifier<?>, Flow> entry : transaction.additions.entrySet()) {
-            System.out.println("Coming add cc in FlowDatacommitHandler");
-            addFlow(entry.getKey(), entry.getValue());
+        Set<Entry<InstanceIdentifier<?>, DataObject>> createdEntries = transaction.getModification().getCreatedConfigurationData().entrySet();
+
+        /*
+         * This little dance is because updatedEntries contains both created and modified entries
+         * The reason I created a new HashSet is because the collections we are returned are immutable.
+         */
+        Set<Entry<InstanceIdentifier<?>, DataObject>> updatedEntries = new HashSet<Entry<InstanceIdentifier<?>, DataObject>>();
+        updatedEntries.addAll(transaction.getModification().getUpdatedConfigurationData().entrySet());
+        updatedEntries.removeAll(createdEntries);
+
+        Set<InstanceIdentifier<?>> removeEntriesInstanceIdentifiers = transaction.getModification().getRemovedConfigurationData();
+        transaction.getModification().getOriginalConfigurationData();
+        for (Entry<InstanceIdentifier<?>, DataObject> entry : createdEntries) {
+            if(entry.getValue() instanceof Flow) {
+                System.out.println("Coming add cc in FlowDatacommitHandler");
+                addFlow(entry.getKey(), (Flow) entry.getValue());
+            }
         }
         for (@SuppressWarnings("unused")
-        Entry<InstanceIdentifier<?>, Flow> entry : transaction.updates.entrySet()) {
-            System.out.println("Coming update cc in FlowDatacommitHandler");
-            updateFlow(entry.getKey(), entry.getValue());
+        Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) {
+            if(entry.getValue() instanceof Flow) {
+                System.out.println("Coming update cc in FlowDatacommitHandler");
+                updateFlow(entry.getKey(), (Flow) entry.getValue());
+            }
         }
 
-        for (Entry<InstanceIdentifier<?>, Flow> entry : transaction.removals.entrySet()) {
-            System.out.println("Coming remove cc in FlowDatacommitHandler");
-            removeFlow(entry.getKey(), entry.getValue());
+        for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers ) {
+            DataObject removeValue = transaction.getModification().getOriginalConfigurationData().get(instanceId);
+            if(removeValue instanceof Flow) {
+                System.out.println("Coming remove cc in FlowDatacommitHandler");
+                removeFlow(instanceId, (Flow) removeValue);
+
+            }
         }
 
     }
@@ -329,39 +365,42 @@ public class FlowConsumerImpl implements IForwardingRulesManager {
             for (Entry<InstanceIdentifier<?>, DataObject> entry : puts) {
 
                 // validating the DataObject
-
-                Status status = validate(container, (NodeFlow) entry);
-                if (!status.isSuccess()) {
-                    logger.warn("Invalid Configuration for flow {}. The failure is {}", entry, status.getDescription());
-                    String error = "Invalid Configuration (" + status.getDescription() + ")";
-                    logger.error(error);
-                    return;
-                }
-                // Presence check
-                if (flowEntryExists((NodeFlow) entry)) {
-                    String error = "Entry with this name on specified table already exists";
-                    logger.warn("Entry with this name on specified table already exists: {}", entry);
-                    logger.error(error);
-                    return;
-                }
-                if (originalSwView.containsKey(entry)) {
-                    logger.warn("Operation Rejected: A flow with same match and priority exists on the target node");
-                    logger.trace("Aborting to install {}", entry);
-                    continue;
-                }
-                if (!FRMUtil.validateMatch((NodeFlow) entry)) {
-                    logger.error("Not a valid Match");
-                    return;
-                }
-                if (!FRMUtil.validateInstructions((NodeFlow) entry)) {
-                    logger.error("Not a valid Instruction");
-                    return;
-                }
-                if (entry.getValue() instanceof Flow) {
-                    Flow flow = (Flow) entry.getValue();
-                    preparePutEntry(entry.getKey(), flow);
+                DataObject value = entry.getValue();
+                if(value instanceof Flow ) {
+                    Flow flow = (Flow)value;
+                    boolean status = validate(flow);
+                    if (!status) {
+                        return;
+                    }
+                    // Presence check
+                    /*
+                     * This is breaking due to some improper use of caches...
+                     *
+                    if (flowEntryExists(flow)) {
+                        String error = "Entry with this name on specified table already exists";
+                        logger.warn("Entry with this name on specified table already exists: {}", entry);
+                        logger.error(error);
+                        return;
+                    }
+                    if (originalSwView.containsKey(entry)) {
+                        logger.warn("Operation Rejected: A flow with same match and priority exists on the target node");
+                        logger.trace("Aborting to install {}", entry);
+                        continue;
+                    }
+                    */
+                    if (!FRMUtil.validateMatch(flow)) {
+                        logger.error("Not a valid Match");
+                        return;
+                    }
+                    if (!FRMUtil.validateInstructions(flow)) {
+                        logger.error("Not a valid Instruction");
+                        return;
+                    }
+                    /*
+                     * Commented out due to Clustering Services issues
+                     * preparePutEntry(entry.getKey(), flow);
+                     */
                 }
-
             }
 
             // removals = modification.getRemovedConfigurationData();
@@ -398,7 +437,7 @@ public class FlowConsumerImpl implements IForwardingRulesManager {
             commitToPlugin(this);
             // We return true if internal transaction is successful.
             // return Rpcs.getRpcResult(true, null, Collections.emptySet());
-            return Rpcs.getRpcResult(true, null, null);
+            return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
         }
 
         /**
@@ -411,58 +450,48 @@ public class FlowConsumerImpl implements IForwardingRulesManager {
             // NOOP - we did not modified any internal state during
             // requestCommit phase
             // return Rpcs.getRpcResult(true, null, Collections.emptySet());
-            return Rpcs.getRpcResult(true, null, null);
+            return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
 
         }
 
-        public Status validate(IContainer container, NodeFlow dataObject) {
+        public boolean validate(Flow flow) {
+
+            String msg = ""; // Specific part of warn/error log
 
-            // container validation
-            Switch sw = null;
-            Node node = null;
-            String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container.getName();
-            ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
-                    containerName, this);
+            boolean result  = true;
             // flow Name validation
-            if (dataObject.getFlowName() == null || dataObject.getFlowName().trim().isEmpty()
-                    || !dataObject.getFlowName().matches(NAMEREGEX)) {
-                return new Status(StatusCode.BADREQUEST, "Invalid Flow name");
+            if (flow.getFlowName() == null || flow.getFlowName().trim().isEmpty()
+                    || !flow.getFlowName().matches(NAMEREGEX)) {
+                msg = "Invalid Flow name";
+                result = false;
             }
             // Node Validation
-            if (dataObject.getNode() == null) {
-                return new Status(StatusCode.BADREQUEST, "Node is null");
+            if (result == true && flow.getNode() == null) {
+                msg = "Node is null";
+                result = false;
             }
 
-            if (switchManager != null) {
-                for (Switch device : switchManager.getNetworkDevices()) {
-                    node = (Node) device.getNode();
-                    if (device.getNode().equals(dataObject.getNode())) {
-                        sw = device;
-                        break;
-                    }
-                }
-                if (sw == null) {
-                    return new Status(StatusCode.BADREQUEST, String.format("Node %s not found", node));
-                }
-            } else {
-                logger.debug("switchmanager is not set yet");
-            }
+            // TODO: Validate we are seeking to program a flow against a valid Node
 
-            if (dataObject.getPriority() != null) {
-                if (dataObject.getPriority() < 0 || dataObject.getPriority() > 65535) {
-                    return new Status(StatusCode.BADREQUEST, String.format("priority %s is not in the range 0 - 65535",
-                            dataObject.getPriority()));
+            if (result == true && flow.getPriority() != null) {
+                if (flow.getPriority() < 0 || flow.getPriority() > 65535) {
+                    msg = String.format("priority %s is not in the range 0 - 65535",
+                            flow.getPriority());
+                    result = false;
                 }
             }
-
-            return new Status(StatusCode.SUCCESS);
+            if (result == false) {
+                logger.warn("Invalid Configuration for flow {}. The failure is {}",flow,msg);
+                logger.error("Invalid Configuration ({})",msg);
+            }
+            return result;
         }
 
-        private boolean flowEntryExists(NodeFlow config) {
+        private boolean flowEntryExists(Flow flow) {
             // Flow name has to be unique on per table id basis
             for (ConcurrentMap.Entry<FlowKey, Flow> entry : originalSwView.entrySet()) {
-                if (entry.getValue().getFlowName().equals(config.getFlowName())
-                        && entry.getValue().getTableId().equals(config.getTableId())) {
+                if (entry.getValue().getFlowName().equals(flow.getFlowName())
+                        && entry.getValue().getTableId().equals(flow.getTableId())) {
                     return true;
                 }
             }
index 851e7d9b2685420b5093d8771770a64a3fe52250..714ac89ba13ccf66f3de6e211276d2aace61aba9 100644 (file)
@@ -2,6 +2,7 @@ package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -33,6 +34,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.Add
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupAdded;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupRemoved;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder;
+
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder;
@@ -40,10 +43,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.gro
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes.GroupType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.Meter;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -225,7 +230,7 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
                 return new Status(StatusCode.BADREQUEST, "Group Name is invalid");
             }
 
-            returnResult = doesGroupEntryExists(group.getKey(), groupName, containerName);
+           /* returnResult = doesGroupEntryExists(group.getKey(), groupName, containerName);
 
             if (FRMUtil.operation.ADD == operation && returnResult) {
                 logger.error("Record with same Group Name exists");
@@ -233,7 +238,7 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
             } else if (!returnResult) {
                 logger.error("Group record does not exist");
                 return new Status(StatusCode.BADREQUEST, "Group record does not exist");
-            }
+            }*/
 
             if (!(group.getGroupType().getIntValue() >= GroupType.GroupAll.getIntValue() && group.getGroupType()
                     .getIntValue() <= GroupType.GroupFf.getIntValue())) {
@@ -259,7 +264,7 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
 
     }
 
-    private boolean doesGroupEntryExists(GroupKey key, String groupName, String containerName) {
+   /* private boolean doesGroupEntryExists(GroupKey key, String groupName, String containerName) {
         if (!originalSwGroupView.containsKey(key)) {
             return false;
         }
@@ -271,8 +276,8 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
                 }
             }
         }
-        return false;
-    }
+        return true;
+    }*/
 
     /**
      * Update Group entries to the southbound plugin/inventory and our internal
@@ -292,11 +297,11 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
             return groupOperationStatus;
         }
 
-        if (originalSwGroupView.containsKey(groupKey)) {
+        /*if (originalSwGroupView.containsKey(groupKey)) {
             originalSwGroupView.remove(groupKey);
             originalSwGroupView.put(groupKey, groupUpdateDataObject);
         }
-
+*/
         if (groupUpdateDataObject.isInstall()) {
             UpdateGroupInputBuilder groupData = new UpdateGroupInputBuilder();
             updateGroupBuilder = new UpdatedGroupBuilder();
@@ -304,10 +309,10 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
             groupData.setUpdatedGroup(updateGroupBuilder.build());
             // TODO how to get original group and modified group.
 
-            if (installedSwGroupView.containsKey(groupKey)) {
+          /*  if (installedSwGroupView.containsKey(groupKey)) {
                 installedSwGroupView.remove(groupKey);
                 installedSwGroupView.put(groupKey, groupUpdateDataObject);
-            }
+            }*/
 
             groupService.updateGroup(groupData.build());
         }
@@ -330,7 +335,7 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
             return groupOperationStatus;
         }
 
-        originalSwGroupView.put(groupKey, groupAddDataObject);
+        //originalSwGroupView.put(groupKey, groupAddDataObject);
 
         if (groupAddDataObject.isInstall()) {
             AddGroupInputBuilder groupData = new AddGroupInputBuilder();
@@ -339,19 +344,49 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
             groupData.setGroupId(groupAddDataObject.getGroupId());
             groupData.setGroupType(groupAddDataObject.getGroupType());
             groupData.setNode(groupAddDataObject.getNode());
-            installedSwGroupView.put(groupKey, groupAddDataObject);
+        //   installedSwGroupView.put(groupKey, groupAddDataObject);
             groupService.addGroup(groupData.build());
         }
 
         return groupOperationStatus;
     }
 
-    private RpcResult<Void> commitToPlugin(internalTransaction transaction) {
+    /**
+     * Remove Group to the southbound plugin and our internal database
+     *
+     * @param path
+     * @param dataObject
+     */
+    private Status removeGroup(InstanceIdentifier<?> path, Group groupRemoveDataObject) {
+        GroupKey groupKey = groupRemoveDataObject.getKey();
+        Status groupOperationStatus = validateGroup(groupRemoveDataObject, FRMUtil.operation.ADD);
+
+        if (!groupOperationStatus.isSuccess()) {
+            logger.error("Group data object validation failed %s" + groupRemoveDataObject.getGroupName());
+            return groupOperationStatus;
+        }
+        //originalSwGroupView.put(groupKey, groupAddDataObject);
+
+        if (groupRemoveDataObject.isInstall()) {
+            RemoveGroupInputBuilder groupData = new RemoveGroupInputBuilder();
+            groupData.setBuckets(groupRemoveDataObject.getBuckets());
+            groupData.setContainerName(groupRemoveDataObject.getContainerName());
+            groupData.setGroupId(groupRemoveDataObject.getGroupId());
+            groupData.setGroupType(groupRemoveDataObject.getGroupType());
+            groupData.setNode(groupRemoveDataObject.getNode());
+        //   installedSwGroupView.put(groupKey, groupAddDataObject);
+            groupService.removeGroup(groupData.build());
+        }
+
+        return groupOperationStatus;
+    }
+    
+    private RpcResult<Void> commitToPlugin(InternalTransaction transaction) {
         for (Entry<InstanceIdentifier<?>, Group> entry : transaction.additions.entrySet()) {
 
             if (!addGroup(entry.getKey(), entry.getValue()).isSuccess()) {
                 transaction.additions.remove(entry.getKey());
-                return Rpcs.getRpcResult(false, null, null);
+                return Rpcs.getRpcResult(false, null, Collections.<RpcError>emptySet());
             }
         }
 
@@ -359,12 +394,18 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
 
             if (!updateGroup(entry.getKey(), entry.getValue()).isSuccess()) {
                 transaction.updates.remove(entry.getKey());
-                return Rpcs.getRpcResult(false, null, null);
+                return Rpcs.getRpcResult(false, null, Collections.<RpcError>emptySet());
             }
         }
 
-        for (InstanceIdentifier<?> removal : transaction.removals) {
-            // removeFlow(removal);
+        for (InstanceIdentifier<?> groupId : transaction.removals) {
+                       DataObject removeValue = transaction.getModification().getOriginalConfigurationData().get(groupId);     
+                
+                       if(removeValue instanceof Group) {
+                           if(!removeGroup(groupId, (Group)removeValue).isSuccess()) {
+                               return Rpcs.getRpcResult(false, null, Collections.<RpcError>emptySet()); 
+                           }             
+                       }
         }
 
         return Rpcs.getRpcResult(true, null, null);
@@ -372,19 +413,18 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
 
     private final class GroupDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
 
-        @SuppressWarnings("unchecked")
         @Override
         public DataCommitTransaction<InstanceIdentifier<?>, DataObject> requestCommit(
                 DataModification<InstanceIdentifier<?>, DataObject> modification) {
             // We should verify transaction
             System.out.println("Coming in GroupDatacommitHandler");
-            internalTransaction transaction = new internalTransaction(modification);
+            InternalTransaction transaction = new InternalTransaction(modification);
             transaction.prepareUpdate();
             return transaction;
         }
     }
 
-    private final class internalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
+    private final class InternalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
 
         private final DataModification<InstanceIdentifier<?>, DataObject> modification;
 
@@ -393,7 +433,7 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
             return modification;
         }
 
-        public internalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
+        public InternalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
             this.modification = modification;
         }
 
@@ -407,33 +447,31 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
          *
          */
         void prepareUpdate() {
-
-            Set<Entry<InstanceIdentifier<?>, DataObject>> puts = modification.getUpdatedConfigurationData().entrySet();
-            for (Entry<InstanceIdentifier<?>, DataObject> entry : puts) {
+               
+                Set<Entry<InstanceIdentifier<?>, DataObject>> groupAdded = modification.getCreatedConfigurationData().entrySet();
+             for (Entry<InstanceIdentifier<?>, DataObject> entry : groupAdded) {
+                 if (entry.getValue() instanceof Group) {
+                     Group group = (Group) entry.getValue();
+                     additions.put(entry.getKey(), group);                     
+                 }
+
+             }
+
+            Set<Entry<InstanceIdentifier<?>, DataObject>> groupUpdate = modification.getUpdatedConfigurationData().entrySet();
+            for (Entry<InstanceIdentifier<?>, DataObject> entry : groupUpdate) {
                 if (entry.getValue() instanceof Group) {
                     Group group = (Group) entry.getValue();
-                    preparePutEntry(entry.getKey(), group);
+                    ///will be fixed once getUpdatedConfigurationData returns only updated data not created data with it.
+                    if (additions.containsKey(entry.getKey())) {
+                       updates.put(entry.getKey(), group);
+                    }
                 }
 
             }
 
             removals = modification.getRemovedConfigurationData();
         }
-
-        private void preparePutEntry(InstanceIdentifier<?> key, Group group) {
-
-            Group original = originalSwGroupView.get(key);
-            if (original != null) {
-                // It is update for us
-
-                updates.put(key, group);
-            } else {
-                // It is addition for us
-
-                additions.put(key, group);
-            }
-        }
-
+        
         /**
          * We are OK to go with execution of plan
          *
@@ -457,7 +495,7 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
             // NOOP - we did not modified any internal state during
             // requestCommit phase
             // return Rpcs.getRpcResult(true, null, Collections.emptySet());
-            return Rpcs.getRpcResult(true, null, null);
+            return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
 
         }
 
index bd0ceb3fea8011aaa575dea0e71e4cbb8a1032c9..483b9a47196580a2b16c9e0c63b2e41be7a40e9f 100644 (file)
@@ -2,6 +2,7 @@ package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -33,6 +34,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.Add
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterAdded;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterRemoved;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder;
@@ -45,6 +47,7 @@ import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -57,13 +60,17 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
     private MeterDataCommitHandler commitHandler;
 
     private ConcurrentMap<MeterKey, Meter> originalSwMeterView;
+    @SuppressWarnings("unused")
     private ConcurrentMap<MeterKey, Meter> installedSwMeterView;
-
+    @SuppressWarnings("unused")
     private ConcurrentMap<Node, List<Meter>> nodeMeters;
+    @SuppressWarnings("unused")
     private ConcurrentMap<MeterKey, Meter> inactiveMeters;
+    @SuppressWarnings("unused")
+    private IContainer container;
 
     private IClusterContainerServices clusterMeterContainerService = null;
-    private IContainer container;
+    
 
     public MeterConsumerImpl() {
         InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Meters.class).child(Meter.class)
@@ -218,11 +225,11 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
                 meterBuilder.setMeterBandHeaders(meterAddDataObject.getMeterBandHeaders());
                 meterBuilder.setMeterId(meterAddDataObject.getMeterId());
                 meterBuilder.setNode(meterAddDataObject.getNode());
-                originalSwMeterView.put(meterKey, meterAddDataObject);
+               // originalSwMeterView.put(meterKey, meterAddDataObject);
                 meterService.addMeter(meterBuilder.build());
             }
 
-            originalSwMeterView.put(meterKey, meterAddDataObject);
+           // originalSwMeterView.put(meterKey, meterAddDataObject);
         } else {
             return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
         }
@@ -243,10 +250,10 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
 
         if (null != meterKey && validateMeter(meterUpdateDataObject, FRMUtil.operation.UPDATE).isSuccess()) {
 
-            if (originalSwMeterView.containsKey(meterKey)) {
+           /* if (originalSwMeterView.containsKey(meterKey)) {
                 originalSwMeterView.remove(meterKey);
                 originalSwMeterView.put(meterKey, meterUpdateDataObject);
-            }
+            }*/
 
             if (meterUpdateDataObject.isInstall()) {
                 UpdateMeterInputBuilder updateMeterInputBuilder = new UpdateMeterInputBuilder();
@@ -254,10 +261,10 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
                 updateMeterBuilder.fieldsFrom(meterUpdateDataObject);
                 updateMeterInputBuilder.setUpdatedMeter(updateMeterBuilder.build());
 
-                if (installedSwMeterView.containsKey(meterKey)) {
+              /*  if (installedSwMeterView.containsKey(meterKey)) {
                     installedSwMeterView.remove(meterKey);
                     installedSwMeterView.put(meterKey, meterUpdateDataObject);
-                }
+                }*/
 
                 meterService.updateMeter(updateMeterInputBuilder.build());
             }
@@ -276,18 +283,23 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
      *
      * @param dataObject
      */
-    private Status RemoveMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {
-        MeterKey meterKey = meterUpdateDataObject.getKey();
-
-        if (null != meterKey && validateMeter(meterUpdateDataObject, FRMUtil.operation.ADD).isSuccess()) {
-            if (meterUpdateDataObject.isInstall()) {
-                UpdateMeterInputBuilder updateMeterBuilder = new UpdateMeterInputBuilder();
-
-                installedSwMeterView.put(meterKey, meterUpdateDataObject);
-                meterService.updateMeter(updateMeterBuilder.build());
+    private Status removeMeter(InstanceIdentifier<?> path, Meter meterRemoveDataObject) {
+        MeterKey meterKey = meterRemoveDataObject.getKey();
+
+        if (null != meterKey && validateMeter(meterRemoveDataObject, FRMUtil.operation.DELETE).isSuccess()) {
+            if (meterRemoveDataObject.isInstall()) {
+                RemoveMeterInputBuilder meterBuilder = new RemoveMeterInputBuilder();
+                meterBuilder.setContainerName(meterRemoveDataObject.getContainerName());
+                meterBuilder.setNode(meterRemoveDataObject.getNode());
+                meterBuilder.setFlags(meterRemoveDataObject.getFlags());
+                meterBuilder.setMeterBandHeaders(meterRemoveDataObject.getMeterBandHeaders());
+                meterBuilder.setMeterId(meterRemoveDataObject.getMeterId());
+                meterBuilder.setNode(meterRemoveDataObject.getNode());
+               // originalSwMeterView.put(meterKey, meterAddDataObject);
+                meterService.removeMeter(meterBuilder.build());
             }
 
-            originalSwMeterView.put(meterKey, meterUpdateDataObject);
+           // originalSwMeterView.put(meterKey, meterAddDataObject);
         } else {
             return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
         }
@@ -299,7 +311,6 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
         String containerName;
         String meterName;
         Status returnStatus = null;
-        boolean returnResult;
 
         if (null != meter) {
             containerName = meter.getContainerName();
@@ -319,7 +330,7 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
                 return returnStatus;
             }
 
-            returnResult = doesMeterEntryExists(meter.getKey(), meterName, containerName);
+         /*   returnResult = doesMeterEntryExists(meter.getKey(), meterName, containerName);
 
             if (FRMUtil.operation.ADD == operation && returnResult) {
                 logger.error("Record with same Meter Name exists");
@@ -329,7 +340,7 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
                 logger.error("Group record does not exist");
                 returnStatus = new Status(StatusCode.BADREQUEST, "Meter record does not exist");
                 return returnStatus;
-            }
+            }*/
 
             for (int i = 0; i < meter.getMeterBandHeaders().getMeterBandHeader().size(); i++) {
                 if (!meter.getFlags().isMeterBurst()) {
@@ -367,7 +378,7 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
         return new Status(StatusCode.SUCCESS);
     }
 
-    private boolean doesMeterEntryExists(MeterKey key, String meterName, String containerName) {
+    /*private boolean doesMeterEntryExists(MeterKey key, String meterName, String containerName) {
         if (!originalSwMeterView.containsKey(key)) {
             return false;
         }
@@ -380,34 +391,9 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
             }
         }
         return false;
-    }
-
-    private RpcResult<Void> commitToPlugin(internalTransaction transaction) {
-        for (Entry<InstanceIdentifier<?>, Meter> entry : transaction.additions.entrySet()) {
-
-            if (!addMeter(entry.getKey(), entry.getValue()).isSuccess()) {
-                return Rpcs.getRpcResult(false, null, null);
-            }
-        }
-        for (@SuppressWarnings("unused")
-        Entry<InstanceIdentifier<?>, Meter> entry : transaction.updates.entrySet()) {
-
-            if (!updateMeter(entry.getKey(), entry.getValue()).isSuccess()) {
-                return Rpcs.getRpcResult(false, null, null);
-            }
-        }
-
-        for (InstanceIdentifier<?> removal : transaction.removals) {
-            /*
-             * if (!removeMeter(entry.getKey(),entry.getValue()).isSuccess()) {
-             * return Rpcs.getRpcResult(false, null, null); }
-             */
-        }
-
-        return Rpcs.getRpcResult(true, null, null);
-    }
+    }*/
 
-    private final class internalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
+    private final class InternalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
 
         private final DataModification<InstanceIdentifier<?>, DataObject> modification;
 
@@ -416,7 +402,7 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
             return modification;
         }
 
-        public internalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
+        public InternalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
             this.modification = modification;
         }
 
@@ -430,33 +416,30 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
          *
          */
         void prepareUpdate() {
-
-            Set<Entry<InstanceIdentifier<?>, DataObject>> puts = modification.getUpdatedConfigurationData().entrySet();
-            for (Entry<InstanceIdentifier<?>, DataObject> entry : puts) {
+            
+            Set<Entry<InstanceIdentifier<?>, DataObject>> addMeter = modification.getCreatedConfigurationData().entrySet();
+            for (Entry<InstanceIdentifier<?>, DataObject> entry : addMeter) {
                 if (entry.getValue() instanceof Meter) {
-                    Meter Meter = (Meter) entry.getValue();
-                    preparePutEntry(entry.getKey(), Meter);
+                    Meter meter = (Meter) entry.getValue();
+                    additions.put(entry.getKey(), meter);                    
                 }
 
             }
+            
+            Set<Entry<InstanceIdentifier<?>, DataObject>> updateMeter = modification.getUpdatedConfigurationData().entrySet();
+            for (Entry<InstanceIdentifier<?>, DataObject> entry : updateMeter) {
+                if (entry.getValue() instanceof Meter) {
+                    Meter meter = (Meter) entry.getValue();
+                  ///will be fixed once getUpdatedConfigurationData returns only updated data not created data with it.
+                    if (!additions.containsKey(entry.getKey())) {
+                       updates.put(entry.getKey(), meter);       
+                    }
+                }
+            }
 
             removals = modification.getRemovedConfigurationData();
         }
 
-        private void preparePutEntry(InstanceIdentifier<?> key, Meter meter) {
-
-            Meter original = originalSwMeterView.get(key);
-            if (original != null) {
-                // It is update for us
-
-                updates.put(key, meter);
-            } else {
-                // It is addition for us
-
-                additions.put(key, meter);
-            }
-        }
-
         /**
          * We are OK to go with execution of plan
          *
@@ -480,10 +463,37 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
             // NOOP - we did not modified any internal state during
             // requestCommit phase
             // return Rpcs.getRpcResult(true, null, Collections.emptySet());
-            return Rpcs.getRpcResult(true, null, null);
+            return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
+
+        }
+
+    }
+    
+    private RpcResult<Void> commitToPlugin(InternalTransaction transaction) {
+        for (Entry<InstanceIdentifier<?>, Meter> entry : transaction.additions.entrySet()) {
+
+            if (!addMeter(entry.getKey(), entry.getValue()).isSuccess()) {
+                return Rpcs.getRpcResult(false, null, Collections.<RpcError>emptySet());
+            }
+        }
+        for (Entry<InstanceIdentifier<?>, Meter> entry : transaction.updates.entrySet()) {
+
+            if (!updateMeter(entry.getKey(), entry.getValue()).isSuccess()) {
+                return Rpcs.getRpcResult(false, null, Collections.<RpcError>emptySet());
+            }
+        }
 
+        for (InstanceIdentifier<?> meterId : transaction.removals) {
+            DataObject removeValue = transaction.getModification().getOriginalConfigurationData().get(meterId);        
+                
+                if(removeValue instanceof Meter) {
+                    if(!removeMeter(meterId, (Meter)removeValue).isSuccess()) {
+                        return Rpcs.getRpcResult(false, null, Collections.<RpcError>emptySet());
+                        }
+                }    
         }
 
+        return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
     }
 
     private final class MeterDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
@@ -492,7 +502,7 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
                 DataModification<InstanceIdentifier<?>, DataObject> modification) {
             // We should verify transaction
             System.out.println("Coming in MeterDataCommitHandler");
-            internalTransaction transaction = new internalTransaction(modification);
+            InternalTransaction transaction = new InternalTransaction(modification);
             transaction.prepareUpdate();
             return transaction;
         }
index 67c6933cc7b3158d5435b2929cfae9bfaa99dad5..29ea8ddf1889bc8d3cfec6e37d070896fc0bd3ae 100644 (file)
@@ -4,7 +4,7 @@ module opendaylight-flow-types {
 
     import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
     import ietf-yang-types {prefix yang; revision-date "2010-09-24";}    
-    import opendaylight-match-types {prefix match; revision-date 2013-10-26";}
+    import opendaylight-match-types {prefix match; revision-date "2013-10-26";}
     import opendaylight-action-types {prefix action;}
 
     revision "2013-10-26" {
diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/queue-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/queue-types.yang
new file mode 100644 (file)
index 0000000..57a9237
--- /dev/null
@@ -0,0 +1,77 @@
+module opendaylight-queue-types {
+    namespace "urn:opendaylight:flow:types:queue";
+    prefix queue-types;
+
+    import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
+    import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
+    
+    revision "2013-09-25" {
+        description "Initial revision of Queue Inventory model";
+    }
+    
+    typedef queue-properties {
+        type enumeration {
+            enum min_rate;
+            enum max_rate;
+        }
+    }
+   
+    
+    grouping common-queue {
+
+        leaf property {
+            type uint16;
+            description "One of OFPQT_.";  
+        }
+           
+    }
+    
+     
+    grouping queue-prop-min-rate       {
+               
+               uses common-queue;
+               
+        leaf rate {
+            type uint16;
+            description "OFPQT_MIN, len: 16";  
+        }
+           
+    }
+    
+    
+      
+    grouping queue-prop-max-rate       {
+               
+               uses common-queue;
+               
+        leaf rate {
+            type uint16;
+            description "OFPQT_MAX, len: 16";  
+        }
+           
+    }
+     grouping queue-packet     {
+               
+               
+        leaf queue-id {
+            type uint32;
+            description "id for the specific queue.";  
+        }
+        
+        leaf port {
+            type uint32;
+            description "Port this queue is attached to.";  
+        }
+        uses common-queue;
+    }
+    
+   grouping queue-config-request 
+   {
+           leaf port {
+            type uint32;
+            description "Port to be queried.";  
+        }
+        
+        }
+ }
+}
\ No newline at end of file
index 2a16bfcf503e41369912ea646c0cc974737528a3..1b6a689750df8e3bd88e8ef632791b7a65384f3a 100644 (file)
@@ -4,7 +4,7 @@ module opendaylight-table-types {
 
     import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
     import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
-    import opendaylight-flow-types {prefix flow;revision-date 2013-10-26";}
+    import opendaylight-flow-types {prefix flow;revision-date "2013-10-26";}
     import opendaylight-action-types {prefix action;}
 
     revision "2013-10-26" {
diff --git a/opendaylight/md-sal/model/model-flow-management/src/main/yang/queue-config.yang b/opendaylight/md-sal/model/model-flow-management/src/main/yang/queue-config.yang
new file mode 100644 (file)
index 0000000..b362e3f
--- /dev/null
@@ -0,0 +1,34 @@
+module queue-management {
+    namespace "urn:opendaylight:queue:config";
+    prefix queue-cfg;
+
+    import yang-ext {prefix ext; revision-date "2013-07-09";}
+    import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}      
+     
+    import opendaylight-queue-types {prefix queue; revision-date "2013-09-25";}
+
+   
+    revision "2013-10-24" {
+        description "Initial revision of queue service";
+    }
+
+    grouping queue-entry {
+        leaf node {
+            type inv:node-connector-ref;
+           
+        }
+        uses queue:queue-config-request;
+    }   
+     
+    container queues {
+        list queue {
+            key "id node"; 
+                        
+            leaf id {
+                type uint32;
+            }                       
+            
+            uses queue-entry;
+        }
+    }    
+}
\ No newline at end of file
index bb010353280b8fa281c0901dde2e8d771f62ac13..b21423b7d4d94d6db1a850a3cbac99bf5547a2d3 100644 (file)
@@ -41,7 +41,7 @@ module sal-group {
 
     rpc remove-group {
         input {
-            uses group-update;
+            uses node-group;
             uses tr:transaction-aware;            
         }
         output {
index 9588652a1c6cdb8fb63901f8cb4ccf72228c7b9c..d49675ad39366bb3e8c9b3a5a191f2a677683ce7 100644 (file)
@@ -5,6 +5,7 @@ module sal-port {
     import yang-ext {prefix ext; revision-date "2013-07-09";}
     import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
     import opendaylight-port-types {prefix port-type;revision-date "2013-09-25";}
+    import flow-capable-transaction {prefix tr;}
 
     revision "2013-11-07" {
         description "Initial revision of port service";
@@ -31,6 +32,10 @@ module sal-port {
     rpc update-port {
         input {
             uses port-update;
+            uses tr:transaction-aware;
+        }
+        output {
+            uses tr:transaction-aware;
         }
     }
      
diff --git a/opendaylight/md-sal/model/model-flow-service/src/main/yang/queue-service.yang b/opendaylight/md-sal/model/model-flow-service/src/main/yang/queue-service.yang
new file mode 100644 (file)
index 0000000..bf79cbf
--- /dev/null
@@ -0,0 +1,29 @@
+module sal-queue {
+    namespace "urn:opendaylight:queue:service";
+    prefix queue;
+
+    import yang-ext {prefix ext; revision-date "2013-07-09";}
+    import opendaylight-inventory {prefix inv; revision-date "2013-08-19";}
+    import opendaylight-queue-types {prefix queue-type; revision-date "2013-09-25";}
+
+    revision "2013-11-07" {
+        description "Initial revision of queue service";
+    }        
+    
+    grouping node-queue {
+        uses "inv:node-context-ref";
+        
+        uses queue-type:queue-packet;
+    }
+
+     
+    rpc get-queue {
+        output {
+            uses queue-type:queue-packet;
+        }
+    }  
+    
+    notification queue-get-config-reply {
+        uses node-queue;
+    }
+}
\ No newline at end of file
index eccb691fa72b3b3f1390d71a97b757b78cfc0fd6..34ad23844f363da800bc33a12b9dfee7eae045cb 100644 (file)
                                         target/generated-sources/sal
                                     </outputBaseDir>
                                 </generator>
+                                <generator>
+                                    <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
+                                    <outputBaseDir>target/site/restconf</outputBaseDir>
+                                </generator>
                             </codeGenerators>
                             <inspectDependencies>true</inspectDependencies>
                         </configuration>
index bdbcce0950fa449dbc43a7be562fa22bbb7f3ade..94c31dd0411eb041fc11fd61adcab23dd369a105 100644 (file)
@@ -40,7 +40,8 @@
         <!-- Connectors -->
         <module>sal-connector-api</module>
         <module>sal-rest-connector</module>
-
+        <module>sal-netconf-connector</module>
+        
         <!-- Clustered Data Store -->
         <module>clustered-data-store/implementation</module>
 
index c356ff6b0e15258127524119d28f057d9a993755..a5e5c74f4c578a42026b3cda684a0ceae982cd61 100644 (file)
@@ -16,7 +16,6 @@
 
     <build>
         <plugins>
-        
             <plugin>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-maven-plugin</artifactId>
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModule.java
new file mode 100644 (file)
index 0000000..c3fe5f7
--- /dev/null
@@ -0,0 +1,53 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: binding-broker-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:33:01 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import org.opendaylight.controller.sal.binding.impl.BindingAwareBrokerImpl;
+import org.osgi.framework.BundleContext;
+
+/**
+*
+*/
+public final class BindingBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule
+{
+
+    private BundleContext bundleContext;
+
+    public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, BindingBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void validate(){
+        super.validate();
+        // Add custom validation for module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        BindingAwareBrokerImpl broker = new BindingAwareBrokerImpl(getBundleContext());
+        broker.setDataBroker(getDataBrokerDependency());
+        broker.setNotifyBroker(getNotificationServiceDependency());
+        broker.start();
+        return broker;
+    }
+
+    public BundleContext getBundleContext() {
+        return bundleContext;
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModuleFactory.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModuleFactory.java
new file mode 100644 (file)
index 0000000..5390251
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: binding-broker-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:33:01 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
+/**
+*
+*/
+public class BindingBrokerImplModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModuleFactory
+{
+
+    
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
+        BindingBrokerImplModule module = (BindingBrokerImplModule) super.createModule(instanceName, dependencyResolver, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
+    
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver,
+            DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
+        BindingBrokerImplModule module = (BindingBrokerImplModule) super.createModule(instanceName, dependencyResolver, old, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplSingletonModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplSingletonModule.java
deleted file mode 100644 (file)
index ab94db9..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yang.md.sal.binding.impl;
-
-import org.opendaylight.controller.sal.binding.impl.BindingAwareBrokerImpl;
-import org.osgi.framework.BundleContext;
-
-import com.google.common.base.Preconditions;
-
-/**
-*
-*/
-public final class BindingBrokerImplSingletonModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplSingletonModule
-{
-
-    private BundleContext bundleContext;
-
-    public BindingBrokerImplSingletonModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
-        super(identifier, dependencyResolver);
-    }
-
-    public BindingBrokerImplSingletonModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, BindingBrokerImplSingletonModule oldModule, java.lang.AutoCloseable oldInstance) {
-        super(identifier, dependencyResolver, oldModule, oldInstance);
-    }
-
-    @Override
-    public void validate() {
-        super.validate();
-        Preconditions.checkNotNull(getBundleContext());
-    }
-
-    
-    @Override
-    public boolean canReuseInstance(AbstractBindingBrokerImplSingletonModule oldModule) {
-        return true;
-    }
-    
-    
-    public java.lang.AutoCloseable createInstance() {
-        BindingAwareBrokerImpl broker = new BindingAwareBrokerImpl(getBundleContext());
-        broker.start();
-        return broker;
-    }
-
-    public BundleContext getBundleContext() {
-        return bundleContext;
-    }
-
-    public void setBundleContext(BundleContext bundleContext) {
-        this.bundleContext = bundleContext;
-    }
-}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplSingletonModuleFactory.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplSingletonModuleFactory.java
deleted file mode 100644 (file)
index b0a6310..0000000
+++ /dev/null
@@ -1,56 +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.yang.md.sal.binding.impl;
-
-import org.opendaylight.controller.config.api.DependencyResolver;
-import org.opendaylight.controller.config.api.DependencyResolverFactory;
-import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.spi.Module;
-import org.osgi.framework.BundleContext;
-
-import java.util.Collections;
-import java.util.Set;
-
-/**
-*
-*/
-public class BindingBrokerImplSingletonModuleFactory extends
-        org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplSingletonModuleFactory {
-
-    private static final String SINGLETON_NAME = "binding-broker-singleton";
-    public static ModuleIdentifier SINGLETON_IDENTIFIER = new ModuleIdentifier(NAME, SINGLETON_NAME);
-
-    @Override
-    public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
-        throw new UnsupportedOperationException("Only default instance supported.");
-    }
-
-    @Override
-    public Module createModule(String instanceName, DependencyResolver dependencyResolver,
-            DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
-        Module instance = super.createModule(instanceName, dependencyResolver, old, bundleContext);
-        ((BindingBrokerImplSingletonModule)instance).setBundleContext(bundleContext);
-        return instance;
-    }
-
-    @Override
-    public Set<BindingBrokerImplSingletonModule> getDefaultModules(DependencyResolverFactory dependencyResolverFactory,
-            BundleContext bundleContext) {
-
-        DependencyResolver dependencyResolver = dependencyResolverFactory
-                .createDependencyResolver(SINGLETON_IDENTIFIER);
-        BindingBrokerImplSingletonModule instance = new BindingBrokerImplSingletonModule(SINGLETON_IDENTIFIER,
-                dependencyResolver);
-        instance.setBundleContext(bundleContext);
-
-        return Collections.singleton(instance);
-    }
-
-}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java
new file mode 100644 (file)
index 0000000..8cbfbb6
--- /dev/null
@@ -0,0 +1,83 @@
+/**
+ * Generated file
+
+ * Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: binding-data-broker
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 20 17:33:01 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter;
+import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentDataServiceConnector;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+
+import com.google.common.util.concurrent.MoreExecutors;
+
+/**
+*
+*/
+public final class DataBrokerImplModule extends
+        org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractDataBrokerImplModule {
+
+    private BundleContext bundleContext;
+
+    public DataBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+            org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public DataBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+            org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+            DataBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void validate() {
+        super.validate();
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        DataBrokerImpl dataBindingBroker = new DataBrokerImpl();
+        
+        // FIXME: obtain via dependency management
+        ExecutorService executor = Executors.newCachedThreadPool();
+        ExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);
+        dataBindingBroker.setExecutor(listeningExecutor);
+
+        
+        
+        Broker domBroker = getDomBrokerDependency();
+        BindingIndependentMappingService mappingService = getMappingServiceDependency();
+        
+        if (domBroker != null && mappingService != null) {
+            BindingIndependentDataServiceConnector runtimeMapping = new BindingIndependentDataServiceConnector();
+            runtimeMapping.setMappingService(mappingService);
+            runtimeMapping.setBaDataService(dataBindingBroker);
+            domBroker.registerProvider(runtimeMapping, getBundleContext());
+        }
+
+        return dataBindingBroker;
+    }
+
+    public BundleContext getBundleContext() {
+        return bundleContext;
+    }
+
+    public void setBundleContext(BundleContext bundleContext2) {
+        this.bundleContext = bundleContext2;
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModuleFactory.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModuleFactory.java
new file mode 100644 (file)
index 0000000..4022dd4
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: binding-data-broker
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:33:01 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
+/**
+*
+*/
+public class DataBrokerImplModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractDataBrokerImplModuleFactory
+{
+
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
+        DataBrokerImplModule module = (DataBrokerImplModule) super.createModule(instanceName, dependencyResolver, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
+    
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver,
+            DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
+        DataBrokerImplModule module = (DataBrokerImplModule) super.createModule(instanceName, dependencyResolver, old, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModule.java
new file mode 100644 (file)
index 0000000..72231d1
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: binding-notification-broker
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:33:01 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl;
+
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+/**
+*
+*/
+public final class NotificationBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractNotificationBrokerImplModule
+{
+
+    public NotificationBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public NotificationBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, NotificationBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void validate(){
+        super.validate();
+        // Add custom validation for module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        ExecutorService executor = Executors.newFixedThreadPool(5);
+        ListeningExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);
+        NotificationBrokerImpl broker = new NotificationBrokerImpl(listeningExecutor);
+        return broker;
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModuleFactory.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModuleFactory.java
new file mode 100644 (file)
index 0000000..24ca0bb
--- /dev/null
@@ -0,0 +1,19 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: binding-notification-broker
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:33:01 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+/**
+*
+*/
+public class NotificationBrokerImplModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractNotificationBrokerImplModuleFactory
+{
+
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RpcBrokerImplModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RpcBrokerImplModule.java
new file mode 100644 (file)
index 0000000..7824da8
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: binding-rpc-broker
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:33:01 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+/**
+*
+*/
+public final class RpcBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractRpcBrokerImplModule
+{
+
+    public RpcBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public RpcBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, RpcBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void validate(){
+        super.validate();
+        // Add custom validation for module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        //TODO:implement
+        throw new java.lang.UnsupportedOperationException("Unimplemented stub method");
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RpcBrokerImplModuleFactory.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RpcBrokerImplModuleFactory.java
new file mode 100644 (file)
index 0000000..61c7364
--- /dev/null
@@ -0,0 +1,19 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: binding-rpc-broker
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:33:01 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+/**
+*
+*/
+public class RpcBrokerImplModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractRpcBrokerImplModuleFactory
+{
+
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java
new file mode 100644 (file)
index 0000000..6537b4c
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: runtime-generated-mapping
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 18:20:19 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import javassist.ClassPool;
+
+import org.opendaylight.controller.sal.binding.dom.serializer.impl.RuntimeGeneratedMappingServiceImpl;
+import org.osgi.framework.BundleContext;
+
+import com.google.common.base.Preconditions;
+
+/**
+*
+*/
+public final class RuntimeMappingModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractRuntimeMappingModule
+{
+
+    private BundleContext bundleContext;
+
+    public RuntimeMappingModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public RuntimeMappingModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, RuntimeMappingModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void validate(){
+        super.validate();
+        Preconditions.checkNotNull(bundleContext);
+        // Add custom validation for module attributes here.
+    }
+    
+    @Override
+    public boolean canReuseInstance(AbstractRuntimeMappingModule oldModule) {
+        return true;
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        RuntimeGeneratedMappingServiceImpl service = new RuntimeGeneratedMappingServiceImpl();
+        ClassPool pool = new ClassPool(); // Should be default singleton
+        service.setPool(pool);
+        service.start(getBundleContext());
+        return service;
+    }
+
+    private BundleContext getBundleContext() {
+        return bundleContext;
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModuleFactory.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModuleFactory.java
new file mode 100644 (file)
index 0000000..f104c73
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: runtime-generated-mapping
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 18:20:19 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DependencyResolverFactory;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
+/**
+*
+*/
+public class RuntimeMappingModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractRuntimeMappingModuleFactory
+{
+
+    
+    private static  RuntimeMappingModule SINGLETON = null;
+    private static ModuleIdentifier IDENTIFIER = new ModuleIdentifier(NAME, "runtime-mapping-singleton");
+
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
+        throw new UnsupportedOperationException("Only default instance supported");
+    }
+    
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver,
+            DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
+        RuntimeMappingModule module = (RuntimeMappingModule) super.createModule(instanceName, dependencyResolver, old, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
+    
+    @Override
+    public Set<RuntimeMappingModule> getDefaultModules(DependencyResolverFactory dependencyResolverFactory,
+            BundleContext bundleContext) {
+        if(SINGLETON == null) {
+            DependencyResolver dependencyResolver = dependencyResolverFactory.createDependencyResolver(IDENTIFIER);
+            SINGLETON = new RuntimeMappingModule(IDENTIFIER , dependencyResolver);
+            SINGLETON.setBundleContext(bundleContext);
+        }
+        
+        
+        return Collections.singleton(SINGLETON);
+    }
+
+}
index 02da17465665e06e572639343d93b0c42c8635d4..116a8177f977ca98f864e0d7c10eea5eaf561605 100644 (file)
@@ -30,7 +30,7 @@ class RpcRoutingTableImpl<C extends BaseIdentity,S extends RpcService> implement
     }
     
     
-    override getRoute(InstanceIdentifier nodeInstance) {
+    override getRoute(InstanceIdentifier<? extends Object> nodeInstance) {
         val ret = routes.get(nodeInstance);
         if(ret !== null) {
             return ret;
@@ -44,6 +44,6 @@ class RpcRoutingTableImpl<C extends BaseIdentity,S extends RpcService> implement
     
     @SuppressWarnings("rawtypes")
     override updateRoute(InstanceIdentifier<? extends Object> path, S service) {
-        routes.put(path as InstanceIdentifier,service);
+        routes.put(path as InstanceIdentifier<? extends DataObject>,service);
     }
 }
\ No newline at end of file
index 93c192c0af54222533da37727f4575520dea9259..801e4984c0401b04ce268b11fb2f5c9360f71f57 100644 (file)
@@ -11,7 +11,6 @@ import javassist.ClassPool
 import org.opendaylight.yangtools.yang.binding.RpcService
 
 import javassist.CtClass
-import static com.google.common.base.Preconditions.*
 import javassist.CtMethod
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
 import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext
@@ -65,9 +64,7 @@ class RuntimeCodeGenerator implements org.opendaylight.controller.sal.binding.co
     }
 
     override <T extends RpcService> getRouterFor(Class<T> iface) {
-        val contexts = new HashSet<Class<? extends BaseIdentity>>
-
-        val instance = <RpcRouterCodegenInstance<T>>withClassLoader(iface.classLoader) [ |
+        val instance = <RpcRouterCodegenInstance<T>>withClassLoaderAndLock(iface.classLoader,lock) [ |
             val supertype = iface.asCtClass
             val metadata = supertype.rpcMetadata;
             val targetCls = createClass(iface.routerName, supertype) [
@@ -210,7 +207,7 @@ class RuntimeCodeGenerator implements org.opendaylight.controller.sal.binding.co
         ]
         val finalClass = targetCls.toClass(iface.classLoader, iface.protectionDomain)
         return new RuntimeGeneratedInvokerPrototype(supportedNotification,
-            finalClass as Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener>);
+            finalClass as Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener<?>>);
     }
 
     
@@ -218,13 +215,16 @@ class RuntimeCodeGenerator implements org.opendaylight.controller.sal.binding.co
 
 
     protected def resolveInvokerClass(Class<? extends NotificationListener> class1) {
-        val invoker = invokerClasses.get(class1);
-        if (invoker !== null) {
-            return invoker;
-        }
-        val newInvoker = generateListenerInvoker(class1);
-        invokerClasses.put(class1, newInvoker);
-        return newInvoker
+        return <RuntimeGeneratedInvokerPrototype>withClassLoaderAndLock(class1.classLoader,lock) [|
+            val invoker = invokerClasses.get(class1);
+            if (invoker !== null) {
+                return invoker;
+            }
+            val newInvoker = generateListenerInvoker(class1);
+            invokerClasses.put(class1, newInvoker);
+            return newInvoker
+            
+        ]
     }
 }
 
@@ -235,7 +235,7 @@ package class RuntimeGeneratedInvoker implements NotificationInvoker {
     val NotificationListener delegate;
 
     @Property
-    var org.opendaylight.controller.sal.binding.api.NotificationListener invocationProxy;
+    var org.opendaylight.controller.sal.binding.api.NotificationListener<Notification> invocationProxy;
 
     @Property
     var RuntimeGeneratedInvokerPrototype prototype;
@@ -243,7 +243,7 @@ package class RuntimeGeneratedInvoker implements NotificationInvoker {
     new(NotificationListener delegate, RuntimeGeneratedInvokerPrototype prototype) {
         _delegate = delegate;
         _prototype = prototype;
-        _invocationProxy = prototype.protoClass.newInstance;
+        _invocationProxy = prototype.protoClass.newInstance as org.opendaylight.controller.sal.binding.api.NotificationListener<Notification>;
         RuntimeCodeHelper.setDelegate(_invocationProxy, delegate);
     }
 
@@ -262,7 +262,7 @@ package class RuntimeGeneratedInvokerPrototype {
     val Set<Class<? extends Notification>> supportedNotifications;
 
     @Property
-    val Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener> protoClass;
+    val Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener<?>> protoClass;
 }
 
 package class RpcServiceMetadata {
index 19e99617606ff9198379f48fec1be32a052e11b5..35f48745f9fc86a9919c751419fd6254744de2d5 100644 (file)
@@ -30,8 +30,8 @@ public class CodecMapping {
         }
     }
 
-    public static void setClassToCaseMap(Class<? extends BindingCodec> codec,
-            Map<Class,BindingCodec> classToCaseRawCodec) {
+    public static void setClassToCaseMap(Class<? extends BindingCodec<?,?>> codec,
+            Map<Class<?>,BindingCodec<?,?>> classToCaseRawCodec) {
         Field instanceIdField;
         try {
             instanceIdField = codec.getField(CLASS_TO_CASE_MAP);
@@ -47,8 +47,8 @@ public class CodecMapping {
         
     }
 
-    public static void setCompositeNodeToCaseMap(Class<? extends BindingCodec> codec,
-            Map<CompositeNode,BindingCodec> compositeToCase) {
+    public static void setCompositeNodeToCaseMap(Class<? extends BindingCodec<?,?>> codec,
+            Map<CompositeNode,BindingCodec<?,?>> compositeToCase) {
         Field instanceIdField;
         try {
             instanceIdField = codec.getField(COMPOSITE_TO_CASE);
@@ -63,7 +63,7 @@ public class CodecMapping {
     }
 
     public static void setAugmentationCodec(Class<? extends BindingCodec<Map<QName, Object>, Object>> dataCodec,
-            BindingCodec augmentableCodec) {
+            BindingCodec<?,?> augmentableCodec) {
             Field instanceIdField;
             try {
                 instanceIdField = dataCodec.getField(AUGMENTATION_CODEC);
index 3f74c9eaf4bd0387e1e31157fe3c7039570a845e..0a8ea84cf60638f7290bc01ba1bfb4512d35c02c 100644 (file)
@@ -9,6 +9,8 @@ public interface GeneratorListener {
 
     
     
+    void onClassProcessed(Class<?> cl);
+    
     void onCodecCreated(Class<?> codec);
     void onValueCodecCreated(Class<?> valueClass,Class<?> valueCodec);
     void onChoiceCodecCreated(Class<?> choiceClass,Class<? extends BindingCodec<Map<QName, Object>,Object>> choiceCodec);
index fd02fde4070f30737539416f5abf1719483c8698..270660980643cfa6e58a1bcc5fc7aeff856fc584 100644 (file)
@@ -95,6 +95,7 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
         return new NodeIdentifier(QName.create(previousQname,qname.localName));
     }
     
+    @SuppressWarnings("rawtypes")
     private def dispatch PathArgument serializePathArgument(IdentifiableItem argument, QName previousQname) {
         val Map<QName,Object> predicates = new HashMap();
         val type = argument.type;
@@ -111,7 +112,7 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
         return new NodeIdentifierWithPredicates(QName.create(previousQname,qname.localName),predicates);
     }
     
-    def resolveQname(Class class1) {
+    def resolveQname(Class<?> class1) {
         val qname = classToQName.get(class1);
         if(qname !== null) {
             return qname;
@@ -119,5 +120,6 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
         val qnameField = class1.getField("QNAME");
         val qnameValue = qnameField.get(null) as QName;
         classToQName.put(class1,qnameValue);
+        return qnameValue;
     }
 }
\ No newline at end of file
index e8e4c4375dba6548d7aa58fb81820c616d920f66..b81100836f7a422cdebca5de63010e512e5d7ac0 100644 (file)
@@ -36,6 +36,7 @@ import org.opendaylight.yangtools.yang.binding.Augmentable;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.binding.BindingCodec;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Identifier;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
@@ -120,6 +121,9 @@ public class LazyGeneratedCodecRegistry implements //
         ReferencedTypeImpl typeref = new ReferencedTypeImpl(type.getPackageName(), type.getName());
         @SuppressWarnings("rawtypes")
         WeakReference<Class> weakRef = typeToClass.get(typeref);
+        if(weakRef == null) {
+            LOG.error("Could not find loaded class for path: {} and type: {}",path,typeref.getFullyQualifiedName());
+        }
         return weakRef.get();
     }
 
@@ -147,9 +151,29 @@ public class LazyGeneratedCodecRegistry implements //
     @Override
     @SuppressWarnings("rawtypes")
     public void bindingClassEncountered(Class cls) {
+        
         ConcreteType typeRef = Types.typeForClass(cls);
+        if(typeToClass.containsKey(typeRef)) {
+            return;
+        }
+        LOG.info("Binding Class {} encountered.",cls);
         WeakReference<Class> weakRef = new WeakReference<>(cls);
         typeToClass.put(typeRef, weakRef);
+        if(DataObject.class.isAssignableFrom(cls)) {
+            @SuppressWarnings({"unchecked","unused"})
+            Object cdc = getCodecForDataObject((Class<? extends DataObject>) cls);
+        }
+    }
+    
+    @Override
+    public void onClassProcessed(Class<?> cls) {
+        ConcreteType typeRef = Types.typeForClass(cls);
+        if(typeToClass.containsKey(typeRef)) {
+            return;
+        }
+        LOG.info("Binding Class {} encountered.",cls);
+        WeakReference<Class> weakRef = new WeakReference<>((Class) cls);
+        typeToClass.put(typeRef, weakRef);
     }
 
     private DataSchemaNode getSchemaNode(List<QName> path) {
@@ -280,6 +304,12 @@ public class LazyGeneratedCodecRegistry implements //
             ReferencedTypeImpl typeref = new ReferencedTypeImpl(caseNode.getValue().getPackageName(), caseNode
                     .getValue().getName());
             ChoiceCaseNode node = (ChoiceCaseNode) SchemaContextUtil.findDataSchemaNode(module, caseNode.getKey());
+            if (node == null) {
+                LOG.error("YANGTools Bug: SchemaNode for {}, with path {} was not found in context.",
+                        typeref.getFullyQualifiedName(), caseNode.getKey());
+                continue;
+            }
+
             @SuppressWarnings("rawtypes")
             ChoiceCaseCodecImpl value = new ChoiceCaseCodecImpl(node);
             typeToCaseNodes.putIfAbsent(typeref, value);
@@ -300,7 +330,7 @@ public class LazyGeneratedCodecRegistry implements //
         BindingCodec<Map<QName, Object>, Object> delegate = newInstanceOf(choiceCodec);
         ChoiceCodecImpl<?> newCodec = new ChoiceCodecImpl(delegate);
         choiceCodecs.put(choiceClass, newCodec);
-        CodecMapping.setClassToCaseMap(choiceCodec, (Map<Class, BindingCodec>) classToCaseRawCodec);
+        CodecMapping.setClassToCaseMap(choiceCodec, (Map<Class<?>, BindingCodec<?, ?>>) classToCaseRawCodec);
         CodecMapping.setCompositeNodeToCaseMap(choiceCodec, newCodec.getCompositeToCase());
 
     }
@@ -540,7 +570,7 @@ public class LazyGeneratedCodecRegistry implements //
         public BindingCodec get(Object key) {
             if (key instanceof Class) {
                 Class cls = (Class) key;
-                bindingClassEncountered(cls);
+                //bindingClassEncountered(cls);
                 ChoiceCaseCodecImpl caseCodec = getCaseCodecFor(cls);
                 return caseCodec.getDelegate();
             }
@@ -557,11 +587,6 @@ public class LazyGeneratedCodecRegistry implements //
             this.choiceCases = choiceCases;
         }
 
-        @Override
-        public Set<java.util.Map.Entry<CompositeNode, BindingCodec>> entrySet() {
-            return null;
-        }
-
         @Override
         public BindingCodec get(Object key) {
             if (false == (key instanceof CompositeNode)) {
@@ -575,6 +600,8 @@ public class LazyGeneratedCodecRegistry implements //
             }
             return null;
         }
+        
+        
     }
 
     /**
@@ -585,7 +612,7 @@ public class LazyGeneratedCodecRegistry implements //
      *            Key type
      */
     @SuppressWarnings("rawtypes")
-    private static abstract class MapFacadeBase<T> implements Map<T, BindingCodec> {
+    private static abstract class MapFacadeBase<T> implements Map<T, BindingCodec<?, ?>> {
 
         @Override
         public boolean containsKey(Object key) {
@@ -613,7 +640,7 @@ public class LazyGeneratedCodecRegistry implements //
         }
 
         @Override
-        public Collection<BindingCodec> values() {
+        public Collection<BindingCodec<?, ?>> values() {
             return null;
         }
 
@@ -622,12 +649,12 @@ public class LazyGeneratedCodecRegistry implements //
         }
 
         @Override
-        public BindingCodec<Map<QName, Object>, Object> put(T key, BindingCodec value) {
+        public BindingCodec<Map<QName, Object>, Object> put(T key, BindingCodec<?,?> value) {
             throw notModifiable();
         }
 
         @Override
-        public void putAll(Map<? extends T, ? extends BindingCodec> m) {
+        public void putAll(Map<? extends T, ? extends BindingCodec<?, ?>> m) {
             throw notModifiable();
         }
 
@@ -647,7 +674,8 @@ public class LazyGeneratedCodecRegistry implements //
         }
 
         @Override
-        public Set<java.util.Map.Entry<T, BindingCodec>> entrySet() {
+        public Set<java.util.Map.Entry<T, BindingCodec<?, ?>>> entrySet() {
+            // TODO Auto-generated method stub
             return null;
         }
 
index 4614c60ca12e2f8ee14f9c73b6b93f4894d63c93..ec69fd3b68c8ee84c39edde4e58207adb771b5bd 100644 (file)
@@ -17,18 +17,9 @@ import java.util.Map.Entry
 import java.util.AbstractMap.SimpleEntry
 import org.opendaylight.yangtools.yang.model.api.SchemaPath
 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
-import java.util.ArrayList
-import org.opendaylight.yangtools.yang.common.QName
 import org.opendaylight.yangtools.yang.binding.DataContainer
-import static com.google.common.base.Preconditions.*;
-import java.util.List
-import org.opendaylight.yangtools.yang.data.api.Node
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
-import org.opendaylight.yangtools.concepts.Delegator
 import java.util.concurrent.ConcurrentMap
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
-import org.opendaylight.yangtools.yang.binding.BindingCodec
 import com.google.common.collect.HashMultimap
 import com.google.common.util.concurrent.SettableFuture
 import java.util.concurrent.Future
@@ -39,8 +30,13 @@ import org.slf4j.LoggerFactory
 import org.opendaylight.controller.sal.binding.dom.serializer.api.ValueWithQName
 import org.opendaylight.controller.sal.binding.dom.serializer.api.DataContainerCodec
 import org.opendaylight.yangtools.binding.generator.util.Types
+import org.osgi.framework.BundleContext
+import java.util.Hashtable
+import org.osgi.framework.ServiceRegistration
+import org.opendaylight.controller.sal.binding.impl.connect.dom.DeserializationException
+import java.util.concurrent.Callable
 
-class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener {
+class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener, AutoCloseable {
 
     @Property
     ClassPool pool;
@@ -66,6 +62,8 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
 
     val promisedSchemas = HashMultimap.<Type, SettableFuture<SchemaNode>>create;
 
+    ServiceRegistration<SchemaServiceListener> listenerRegistration
+
     override onGlobalContextUpdated(SchemaContext arg0) {
         recreateBindingContext(arg0);
         registry.onGlobalContextUpdated(arg0);
@@ -83,7 +81,6 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
             val context = entry.value;
             updateBindingFor(context.childNodes, schemaContext);
             updateBindingFor(context.cases, schemaContext);
-            
 
             val typedefs = context.typedefs;
             for (typedef : typedefs.values) {
@@ -93,7 +90,7 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
             for (augmentation : augmentations) {
                 binding.typeToDefinition.put(augmentation, augmentation);
             }
-            
+
             binding.typeToAugmentation.putAll(context.typeToAugmentation);
         }
     }
@@ -131,18 +128,36 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
     }
 
     override dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode node) {
-        if (node == null) {
-            return null;
+        return tryDeserialization[ |
+            if (node == null) {
+                return null;
+            }
+            val targetType = path.targetType
+            val transformer = registry.getCodecForDataObject(targetType);
+            val ret = transformer.deserialize(node)?.value as DataObject;
+            return ret;
+        ]
+    }
+
+    override fromDataDom(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry) {
+        return tryDeserialization[ |
+            registry.instanceIdentifierCodec.deserialize(entry);
+        ]
+    }
+
+    private static def <T> T tryDeserialization(Callable<T> deserializationBlock) throws DeserializationException {
+        try {
+            deserializationBlock.call()
+        } catch (Exception e) {
+            // FIXME: Make this block providing more information.
+            throw new DeserializationException(e);
         }
-        val targetType = path.targetType
-        val transformer = registry.getCodecForDataObject(targetType);
-        val ret = transformer.deserialize(node)?.value as DataObject;
-        return ret;
     }
 
     private def void updateBindingFor(Map<SchemaPath, GeneratedTypeBuilder> map, SchemaContext module) {
         for (entry : map.entrySet) {
             val schemaNode = SchemaContextUtil.findDataSchemaNode(module, entry.key);
+
             //LOG.info("{} : {}",entry.key,entry.value.fullyQualifiedName)
             if (schemaNode != null) {
                 typeToSchemaNode.put(entry.value, schemaNode);
@@ -152,7 +167,7 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
         }
     }
 
-    public def void start() {
+    public def void start(BundleContext ctx) {
         binding = new TransformerGenerator(pool);
         registry = new LazyGeneratedCodecRegistry()
         registry.generator = binding
@@ -162,7 +177,9 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
         binding.typeToDefinition = typeToDefinition
         binding.typeToSchemaNode = typeToSchemaNode
         binding.typeDefinitions = typeDefinitions
-
+        if (ctx !== null) {
+            listenerRegistration = ctx.registerService(SchemaServiceListener, this, new Hashtable<String, String>());
+        }
     }
 
     private def getTypeDefinition(Type type) {
@@ -215,4 +232,9 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
         }
         promisedSchemas.removeAll(builder);
     }
+
+    override close() throws Exception {
+        listenerRegistration?.unregister();
+    }
+
 }
index 8e059aa22ed4e8ec1946afc18154b5fe9a38ded6..01390d7c41612e819b3cffc9964538f66263bf38 100644 (file)
@@ -95,6 +95,7 @@ class TransformerGenerator {
         return withClassLoaderAndLock(inputType.classLoader, lock) [ |
             val ret = getGeneratedClass(inputType)
             if (ret !== null) {
+                listener.onClassProcessed(inputType);
                 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
             }
             val ref = Types.typeForClass(inputType)
@@ -102,6 +103,7 @@ class TransformerGenerator {
             val typeSpecBuilder = typeToDefinition.get(ref)
             val typeSpec = typeSpecBuilder.toInstance();
             val newret = generateTransformerFor(inputType, typeSpec, node);
+            listener.onClassProcessed(inputType);
             return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
         ]
     }
@@ -117,6 +119,7 @@ class TransformerGenerator {
             val typeSpecBuilder = typeToDefinition.get(ref)
             val typeSpec = typeSpecBuilder.toInstance();
             val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
+            listener.onClassProcessed(inputType);
             return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
         ]
     }
@@ -184,7 +187,7 @@ class TransformerGenerator {
         ]
     }
 
-    private def Class getGeneratedClass(Class<? extends Object> cls) {
+    private def Class<?> getGeneratedClass(Class<? extends Object> cls) {
 
         try {
             return loadClassWithTCCL(cls.codecClassName)
@@ -211,13 +214,15 @@ class TransformerGenerator {
         if (transformer !== null) {
             return transformer;
         }
-        val valueTransformer = generateValueTransformer(cls, type);
-        return valueTransformer;
+        return withClassLoaderAndLock(cls.classLoader,lock) [|
+            val valueTransformer = generateValueTransformer(cls, type);
+            return valueTransformer;
+        ]
     }
 
     private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
         try {
-            log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
+            //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
             val properties = typeSpec.allProperties;
             val ctCls = createClass(inputType.codecClassName) [
                 //staticField(Map,"AUGMENTATION_SERIALIZERS");
@@ -235,7 +240,7 @@ class TransformerGenerator {
                                 _resultName = QNAME;
                             }
                             java.util.List _childNodes = new java.util.ArrayList();
-                            Â«inputType.name» value = («inputType.name») $2;
+                            Â«inputType.resolvedName» value = («inputType.name») $2;
                             Â«FOR key : node.keyDefinition»
                                 Â«val propertyName = key.getterName»
                                 Â«val keyDef = node.getDataChildByName(key)»
@@ -261,7 +266,7 @@ class TransformerGenerator {
                                 Â«val property = properties.get(propertyName)»
                                 Â«deserializeProperty(keyDef, property, propertyName)»;
                             Â«ENDFOR»
-                            Â«inputType.name» _value = new Â«inputType.name»(«node.keyDefinition.keyConstructorList»);
+                            Â«inputType.resolvedName» _value = new Â«inputType.name»(«node.keyDefinition.keyConstructorList»);
                             return _value;
                         }
                     '''
@@ -291,10 +296,10 @@ class TransformerGenerator {
         }
     }
 
-    private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class inputType, GeneratedType type,
+    private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class<?> inputType, GeneratedType type,
         ChoiceCaseNode node) {
         try {
-            log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
+            //log.info("Generating DOM Codec for {} with {}, TCCL is: {}", inputType, inputType.classLoader,Thread.currentThread.contextClassLoader)
             val ctCls = createClass(type.codecClassName) [
                 //staticField(Map,"AUGMENTATION_SERIALIZERS");
                 implementsType(BINDING_CODEC)
@@ -308,7 +313,7 @@ class TransformerGenerator {
                             Â«QName.name» _resultName = Â«QName.name».create($1,QNAME.getLocalName());
                             java.util.List _childNodes = new java.util.ArrayList();
                             Â«type.resolvedName» value = («type.resolvedName») $2;
-                            Â«transformDataContainerBody(type.allProperties, node)»
+                            Â«transformDataContainerBody(type,type.allProperties, node)»
                             return ($r) _childNodes;
                         }
                     '''
@@ -349,9 +354,9 @@ class TransformerGenerator {
     }
 
     private def dispatch  Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
-        Class inputType, GeneratedType typeSpec, SchemaNode node) {
+        Class<?> inputType, GeneratedType typeSpec, SchemaNode node) {
         try {
-            log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
+            //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
             val ctCls = createClass(typeSpec.codecClassName) [
                 //staticField(Map,"AUGMENTATION_SERIALIZERS");
                 staticQNameField(inputType);
@@ -396,9 +401,9 @@ class TransformerGenerator {
     }
 
     private def Class<? extends BindingCodec<Map<QName, Object>, Object>> generateAugmentationTransformerFor(
-        Class inputType, GeneratedType type, AugmentationSchema node) {
+        Class<?> inputType, GeneratedType type, AugmentationSchema node) {
         try {
-            log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
+            //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
             val properties = type.allProperties
             val ctCls = createClass(type.codecClassName) [
                 //staticField(Map,"AUGMENTATION_SERIALIZERS");
@@ -446,7 +451,7 @@ class TransformerGenerator {
                             return null;
                             }
                             java.util.Map _compositeNode = (java.util.Map) $2;
-                            ////System.out.println(_localQName + " " + _compositeNode);
+                            //System.out.println(_localQName + " " + _compositeNode);
                             Â«type.builderName» _builder = new Â«type.builderName»();
                             Â«FOR child : node.childNodes»
                                 Â«val signature = properties.getFor(child)»
@@ -475,9 +480,9 @@ class TransformerGenerator {
     }
 
     private def dispatch  Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
-        Class inputType, GeneratedType typeSpec, ChoiceNode node) {
+        Class<?> inputType, GeneratedType typeSpec, ChoiceNode node) {
         try {
-            log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
+            //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
             val ctCls = createClass(typeSpec.codecClassName) [
                 //staticField(Map,"AUGMENTATION_SERIALIZERS");
                 //staticQNameField(inputType);
@@ -500,7 +505,9 @@ class TransformerGenerator {
                                 return null;
                             }
                             java.util.Map.Entry _input = new Â«SimpleEntry.name»($1,_baValue);
-                            return (java.util.List) _codec.serialize(_input);
+                            Object _ret =  _codec.serialize(_input);
+                            //System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
+                            return («List.name») _ret;
                         }
                     '''
                 ]
@@ -617,7 +624,7 @@ class TransformerGenerator {
                 return null;
             }
             java.util.Map _compositeNode = (java.util.Map) $2;
-            ////System.out.println(_localQName + " " + _compositeNode);
+            //System.out.println(_localQName + " " + _compositeNode);
             Â«type.builderName» _builder = new Â«type.builderName»();
             Â«deserializeDataNodeContainerBody(type, node)»
             Â«deserializeAugmentations»
@@ -660,7 +667,7 @@ class TransformerGenerator {
         String propertyName) '''
         java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
             localName»"));
-        ////System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
+        //System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
         java.util.List Â«propertyName» = new java.util.ArrayList();
         if(_dom_«propertyName» != null) {
             java.util.List _serialized = new java.util.ArrayList();
@@ -668,15 +675,15 @@ class TransformerGenerator {
             boolean _hasNext = _iterator.hasNext();
             while(_hasNext) {
                 Object _listItem = _iterator.next();
-                ////System.out.println("  item" + _listItem);
+                //System.out.println("  item" + _listItem);
                 Object _value = Â«type.actualTypeArguments.get(0).serializer.resolvedName».fromDomStatic(_localQName,_listItem);
-                ////System.out.println("  value" + _value);
+                //System.out.println("  value" + _value);
                 Â«propertyName».add(_value);
                 _hasNext = _iterator.hasNext();
             }
         }
         
-        ////System.out.println(" list" + Â«propertyName»);
+        //System.out.println(" list" + Â«propertyName»);
     '''
 
     private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
@@ -737,29 +744,38 @@ class TransformerGenerator {
 
             val returnType = typeSpec.valueReturnType;
             if (returnType == null) {
-
                 val ctCls = createDummyImplementation(inputType, typeSpec);
                 val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
                 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
             }
+            var hasBinding = false;
+            try {
+                val bindingCodecClass = loadClassWithTCCL(BINDING_CODEC.name);
+                hasBinding = bindingCodecClass !== null;
+            } catch (ClassNotFoundException e) {
+                hasBinding = false;
+            }
+            val hasYangBinding = hasBinding
             val ctCls = createClass(typeSpec.codecClassName) [
                 //staticField(Map,"AUGMENTATION_SERIALIZERS");
-                implementsType(BINDING_CODEC)
-                staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
-                implementsType(BindingDeserializer.asCtClass)
+                if(hasYangBinding) {
+                    implementsType(BINDING_CODEC)
+                    staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
+                    implementsType(BindingDeserializer.asCtClass)
+                }
                 method(Object, "toDomValue", Object) [
                     modifiers = PUBLIC + FINAL + STATIC
                     body = '''
                         {
-                            ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
+                            //System.out.println("«inputType.simpleName»#toDomValue: "+$1);
                             
                             if($1 == null) {
                                 return null;
                             }
                             Â«typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
-                            ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
+                            //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
                             Â«returnType.resolvedName» _value =  _encapsulatedValue.getValue();
-                            ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
+                            //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
                             Object _domValue = Â«serializeValue(returnType, "_value")»;
                             return _domValue;
                         }
@@ -776,7 +792,7 @@ class TransformerGenerator {
                     modifiers = PUBLIC + FINAL + STATIC
                     body = '''
                         {
-                            ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
+                            //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
                             
                             if($1 == null) {
                                 return null;
@@ -849,13 +865,14 @@ class TransformerGenerator {
         return null;
     }
 
-    private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
+    private def dispatch Class<?> generateValueTransformer(
         Class<?> inputType, Enumeration typeSpec) {
         try {
-            log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
+            //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
             val ctCls = createClass(typeSpec.codecClassName) [
                 //staticField(Map,"AUGMENTATION_SERIALIZERS");
-                implementsType(BINDING_CODEC)
+                //implementsType(BINDING_CODEC)
+                
                 method(Object, "toDomValue", Object) [
                     modifiers = PUBLIC + FINAL + STATIC
                     body = '''
@@ -891,7 +908,7 @@ class TransformerGenerator {
 
             val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
             log.info("DOM Codec for {} was generated {}", inputType, ret)
-            return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+            return ret;
         } catch (CodeGenerationException e) {
             throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
         } catch (Exception e) {
@@ -982,7 +999,7 @@ class TransformerGenerator {
             Â«QName.name» _resultName = Â«QName.name».create($1,QNAME.getLocalName());
             java.util.List _childNodes = new java.util.ArrayList();
             Â«type.resolvedName» value = («type.resolvedName») $2;
-            Â«transformDataContainerBody(type.allProperties, node)»
+            Â«transformDataContainerBody(type,type.allProperties, node)»
             Â«serializeAugmentations»
             return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
         }
@@ -993,7 +1010,7 @@ class TransformerGenerator {
             Â«QName.name» _resultName = Â«QName.name».create($1,QNAME.getLocalName());
             java.util.List _childNodes = new java.util.ArrayList();
             Â«type.resolvedName» value = («type.resolvedName») $2;
-            Â«transformDataContainerBody(type.allProperties, node)»
+            Â«transformDataContainerBody(type,type.allProperties, node)»
             Â«serializeAugmentations»
             return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
         }
@@ -1004,7 +1021,7 @@ class TransformerGenerator {
         Â«QName.name» _resultName = Â«QName.name».create($1,QNAME.getLocalName());
             java.util.List _childNodes = new java.util.ArrayList();
             Â«type.resolvedName» value = («type.resolvedName») $2;
-            Â«transformDataContainerBody(type.allProperties, node)»
+            Â«transformDataContainerBody(type,type.allProperties, node)»
             Â«serializeAugmentations»
             return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
         }
@@ -1019,11 +1036,11 @@ class TransformerGenerator {
         }
     '''
 
-    private def transformDataContainerBody(Map<String, Type> properties, DataNodeContainer node) {
+    private def transformDataContainerBody(Type type,Map<String, Type> properties, DataNodeContainer node) {
         val ret = '''
             Â«FOR child : node.childNodes.filter[!augmenting]»
                 Â«var signature = properties.getFor(child)»
-                //System.out.println("«signature.key»" + value.«signature.key»());
+                //System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
                 Â«serializeProperty(child, signature.value, signature.key)»
             Â«ENDFOR»
         '''
@@ -1152,11 +1169,11 @@ class TransformerGenerator {
         return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
     }
 
-    private def codecClassName(Class typeSpec) {
+    private def codecClassName(Class<?> typeSpec) {
         return '''«typeSpec.name»$Broker$Codec$DOM'''
     }
 
-    private def dispatch HashMap<String, Type> getAllProperties(GeneratedType type) {
+    private def HashMap<String, Type> getAllProperties(GeneratedType type) {
         val ret = new HashMap<String, Type>();
         type.collectAllProperties(ret);
         return ret;
@@ -1186,12 +1203,11 @@ class TransformerGenerator {
         return type.asCtClass.name;
     }
 
-    def String getResolvedName(Class type) {
+    def String getResolvedName(Class<?> type) {
         return type.asCtClass.name;
     }
 
     def CtClass asCtClass(Type type) {
-        val name = type.fullyQualifiedName
         val cls = loadClassWithTCCL(type.fullyQualifiedName)
         return cls.asCtClass;
     }
index 31d5d0126fc8115546d1d1b7709671e946b2e026..1762aac090a0eac4a29cdac122d986298d773ec1 100644 (file)
@@ -44,17 +44,18 @@ import static org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils
 import java.util.concurrent.Executors
 import java.util.Collections
 import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.controller.sal.binding.impl.connect.dom.ConnectorActivator
+import java.util.concurrent.locks.ReentrantLock
+import java.util.concurrent.Callable
+import java.util.WeakHashMap
+import javax.annotation.concurrent.GuardedBy
 
 class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
     private static val log = LoggerFactory.getLogger(BindingAwareBrokerImpl)
 
-
     private InstanceIdentifier<? extends DataObject> root = InstanceIdentifier.builder().toInstance();
 
-    private val clsPool = ClassPool.getDefault()
-    private var RuntimeCodeGenerator generator;
-    
+    private static val clsPool = ClassPool.getDefault()
+    public static var RuntimeCodeGenerator generator;
 
     /**
      * Map of all Managed Direct Proxies
@@ -68,28 +69,29 @@ class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
      * 
      * 
      */
-    private val Map<Class<? extends RpcService>, RpcRouter<? extends RpcService>> rpcRouters = new ConcurrentHashMap();
+    private val Map<Class<? extends RpcService>, RpcRouter<? extends RpcService>> rpcRouters = new WeakHashMap();
 
     @Property
-    private var NotificationBrokerImpl notifyBroker
-    
+    private var NotificationProviderService notifyBroker
+
     @Property
-    private var DataBrokerImpl dataBroker
-    
+    private var DataProviderService dataBroker
+
     @Property
     var BundleContext brokerBundleContext
-    
+
     ServiceRegistration<NotificationProviderService> notifyProviderRegistration
-    
+
     ServiceRegistration<NotificationService> notifyConsumerRegistration
-    
+
     ServiceRegistration<DataProviderService> dataProviderRegistration
-    
+
     ServiceRegistration<DataBrokerService> dataConsumerRegistration
-    
-    ConnectorActivator connectorActivator
-   
-    
+
+    private val proxyGenerationLock = new ReentrantLock;
+
+    private val routerGenerationLock = new ReentrantLock;
+
     public new(BundleContext bundleContext) {
         _brokerBundleContext = bundleContext;
     }
@@ -99,27 +101,13 @@ class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
         initGenerator();
 
         val executor = Executors.newCachedThreadPool;
+
         // Initialization of notificationBroker
         log.info("Starting MD-SAL: Binding Aware Notification Broker");
-        notifyBroker = new NotificationBrokerImpl(executor);
-        notifyBroker.invokerFactory = generator.invokerFactory;
 
         log.info("Starting MD-SAL: Binding Aware Data Broker");
-        dataBroker = new DataBrokerImpl();
-        dataBroker.executor = executor;
 
-        val brokerProperties = newProperties();
-        
-        
         log.info("Starting MD-SAL: Binding Aware Data Broker");
-        notifyProviderRegistration = brokerBundleContext.registerService(NotificationProviderService, notifyBroker,
-            brokerProperties)
-        notifyConsumerRegistration = brokerBundleContext.registerService(NotificationService, notifyBroker, brokerProperties)
-        dataProviderRegistration = brokerBundleContext.registerService(DataProviderService, dataBroker, brokerProperties)
-        dataConsumerRegistration = brokerBundleContext.registerService(DataBrokerService, dataBroker, brokerProperties)
-
-        connectorActivator = new ConnectorActivator(dataBroker,brokerBundleContext);
-        connectorActivator.start();
         log.info("MD-SAL: Binding Aware Broker Started");
     }
 
@@ -163,20 +151,37 @@ class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
      * If proxy class does not exist for supplied service class it will be generated automatically.
      */
     private def <T extends RpcService> getManagedDirectProxy(Class<T> service) {
-
         var RpcProxyContext existing = null
+
         if ((existing = managedProxies.get(service)) != null) {
             return existing.proxy
         }
-        val proxyInstance = generator.getDirectProxyFor(service)
-        val rpcProxyCtx = new RpcProxyContext(proxyInstance.class)
-        val properties = new Hashtable<String, String>()
-        rpcProxyCtx.proxy = proxyInstance as RpcService
-
-        properties.salServiceType = SAL_SERVICE_TYPE_CONSUMER_PROXY
-        rpcProxyCtx.registration = brokerBundleContext.registerService(service, rpcProxyCtx.proxy as T, properties)
-        managedProxies.put(service, rpcProxyCtx)
-        return rpcProxyCtx.proxy
+        return withLock(proxyGenerationLock) [ |
+            val maybeProxy = managedProxies.get(service);
+            if (maybeProxy !== null) {
+                return maybeProxy.proxy;
+            }
+            
+            
+            val proxyInstance = generator.getDirectProxyFor(service)
+            val rpcProxyCtx = new RpcProxyContext(proxyInstance.class)
+            val properties = new Hashtable<String, String>()
+            rpcProxyCtx.proxy = proxyInstance as RpcService
+            properties.salServiceType = SAL_SERVICE_TYPE_CONSUMER_PROXY
+            rpcProxyCtx.registration = brokerBundleContext.registerService(service, rpcProxyCtx.proxy as T, properties)
+            managedProxies.put(service, rpcProxyCtx)
+            return rpcProxyCtx.proxy
+        ]
+    }
+
+    private static def <T> T withLock(ReentrantLock lock, Callable<T> method) {
+        try {
+            lock.lock();
+            val ret = method.call;
+            return ret;
+        } finally {
+            lock.unlock();
+        }
     }
 
     /**
@@ -190,7 +195,7 @@ class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
 
         val osgiReg = context.bundleContext.registerService(type, service, properties);
         proxy.delegate = service;
-        return new RpcServiceRegistrationImpl<T>(type, service, osgiReg,this);
+        return new RpcServiceRegistrationImpl<T>(type, service, osgiReg, this);
     }
 
     def <T extends RpcService> RoutedRpcRegistration<T> registerRoutedRpcImplementation(Class<T> type, T service,
@@ -208,14 +213,20 @@ class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
         }
 
         // We created Router
-        val newRouter = generator.getRouterFor(type);
-        checkState(newRouter !== null);
-        rpcRouters.put(type, newRouter);
-
-        // We create / update Direct Proxy for router
-        val proxy = getManagedDirectProxy(type);
-        proxy.delegate = newRouter.invocationProxy
-        return newRouter;
+        return withLock(routerGenerationLock) [ |
+            val maybeRouter = rpcRouters.get(type);
+            if (maybeRouter !== null) {
+                return maybeRouter as RpcRouter<T>;
+            }
+            
+            val newRouter = generator.getRouterFor(type);
+            checkState(newRouter !== null);
+            rpcRouters.put(type, newRouter);
+            // We create / update Direct Proxy for router
+            val proxy = getManagedDirectProxy(type);
+            proxy.delegate = newRouter.invocationProxy
+            return newRouter;
+        ]
 
     }
 
@@ -230,8 +241,8 @@ class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
 
         // Updating internal structure of registration
         routingTable.updateRoute(path, registration.instance)
+
         // Update routing table / send announce to message bus
-        
         val success = paths.put(context, path);
     }
 
@@ -263,32 +274,32 @@ class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
             routingTable.removeRoute(path)
         }
     }
-    
+
     protected def <T extends RpcService> void unregisterRpcService(RpcServiceRegistrationImpl<T> registration) {
 
         val type = registration.serviceType;
-        
+
         val proxy = managedProxies.get(type);
-        if(proxy.proxy.delegate === registration.instance) {
+        if (proxy.proxy.delegate === registration.instance) {
             proxy.proxy.delegate = null;
         }
     }
-    
+
     def createDelegate(Class<? extends RpcService> type) {
         getManagedDirectProxy(type);
     }
-    
+
     def getRpcRouters() {
         return Collections.unmodifiableMap(rpcRouters);
     }
-    
+
     override close() {
         dataConsumerRegistration.unregister()
         dataProviderRegistration.unregister()
         notifyConsumerRegistration.unregister()
         notifyProviderRegistration.unregister()
     }
-    
+
 }
 
 class RoutedRpcRegistrationImpl<T extends RpcService> extends AbstractObjectRegistration<T> implements RoutedRpcRegistration<T> {
@@ -332,7 +343,7 @@ class RoutedRpcRegistrationImpl<T extends RpcService> extends AbstractObjectRegi
         checkClosed()
         broker.unregisterPath(this, context, path);
     }
-    
+
     override getServiceType() {
         return router.serviceType;
     }
@@ -343,24 +354,25 @@ class RoutedRpcRegistrationImpl<T extends RpcService> extends AbstractObjectRegi
     }
 
 }
-class RpcServiceRegistrationImpl<T extends RpcService> extends AbstractObjectRegistration<T> implements RpcRegistration<T>  {
+
+class RpcServiceRegistrationImpl<T extends RpcService> extends AbstractObjectRegistration<T> implements RpcRegistration<T> {
 
     val ServiceRegistration<T> osgiRegistration;
     private var BindingAwareBrokerImpl broker;
-    
+
     @Property
     val Class<T> serviceType;
 
-    public new(Class<T> type, T service, ServiceRegistration<T> osgiReg,BindingAwareBrokerImpl broker) {
+    public new(Class<T> type, T service, ServiceRegistration<T> osgiReg, BindingAwareBrokerImpl broker) {
         super(service);
         this._serviceType = type;
         this.osgiRegistration = osgiReg;
-        this.broker= broker;
+        this.broker = broker;
     }
 
     override protected removeRegistration() {
         broker.unregisterRpcService(this);
         broker = null;
     }
-    
+
 }
index 7a1ca11fb67b918e55403c9edada58fc2844ed3d..2f4510d5b4f035e98e9351bcba8775a126f1f8a1 100644 (file)
@@ -2,6 +2,7 @@ package org.opendaylight.controller.sal.binding.impl;
 
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicLong;
 
 import org.opendaylight.controller.md.sal.common.api.data.DataReader;
 import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker;
@@ -17,77 +18,85 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 
 
 public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> implements
-        DataProviderService {
+        DataProviderService, AutoCloseable {
 
+    
+    
+    private final AtomicLong nextTransaction = new AtomicLong();
+    
     public DataBrokerImpl() {
         setDataReadRouter(new BindingAwareDataReaderRouter());
     }
 
     @Override
     public DataTransactionImpl beginTransaction() {
-        return new DataTransactionImpl(this);
+        String transactionId = "BA-" + nextTransaction.getAndIncrement();
+        return new DataTransactionImpl(transactionId,this);
     }
 
     @Override
+    @Deprecated
     public <T extends DataRoot> T getData(DataStoreIdentifier store, Class<T> rootType) {
-        // TODO Auto-generated method stub
-        return null;
+        throw new UnsupportedOperationException("Deprecated");
     }
 
     @Override
+    @Deprecated
     public <T extends DataRoot> T getData(DataStoreIdentifier store, T filter) {
-        // TODO Auto-generated method stub
-        return null;
+        throw new UnsupportedOperationException("Deprecated");
     }
 
     @Override
+    @Deprecated
     public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, Class<T> rootType) {
-        // TODO Auto-generated method stub
-        return null;
+        throw new UnsupportedOperationException("Deprecated");
     }
 
     @Override
+    @Deprecated
     public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, T filter) {
-        // TODO Auto-generated method stub
-        return null;
+        throw new UnsupportedOperationException("Deprecated");
     }
 
     @Override
+    @Deprecated
     public RpcResult<DataRoot> editCandidateData(DataStoreIdentifier store, DataRoot changeSet) {
-        // TODO Auto-generated method stub
-        return null;
+        throw new UnsupportedOperationException("Deprecated");
     }
 
     @Override
+    @Deprecated
     public Future<RpcResult<Void>> commit(DataStoreIdentifier store) {
-        // TODO Auto-generated method stub
-        return null;
+        throw new UnsupportedOperationException("Deprecated");
     }
 
     @Override
+    @Deprecated
     public DataObject getData(InstanceIdentifier<? extends DataObject> data) {
-        // TODO Auto-generated method stub
-        return null;
+        throw new UnsupportedOperationException("Deprecated");
     }
 
     @Override
+    @Deprecated
     public DataObject getConfigurationData(InstanceIdentifier<?> data) {
-        // TODO Auto-generated method stub
-        return null;
+        throw new UnsupportedOperationException("Deprecated");
     }
 
     @Override
+    @Deprecated
     public void registerChangeListener(InstanceIdentifier<? extends DataObject> path, DataChangeListener changeListener) {
-        // TODO Auto-generated method stub
-        
+        throw new UnsupportedOperationException("Deprecated");
     }
 
     @Override
+    @Deprecated
     public void unregisterChangeListener(InstanceIdentifier<? extends DataObject> path,
             DataChangeListener changeListener) {
-        // TODO Auto-generated method stub
-        
+        throw new UnsupportedOperationException("Deprecated");
     }
     
-    
+    @Override
+    public void close() throws Exception {
+        
+    }
 }
\ No newline at end of file
index f7967beaae6471a482885535e02d2aae26a06536..b0eb9eeb42a9fedae6286082ccf4ae127aec25a2 100644 (file)
@@ -15,8 +15,8 @@ public class DataTransactionImpl extends AbstractDataTransaction<InstanceIdentif
     
     
     
-    public DataTransactionImpl(DataBrokerImpl dataBroker) {
-        super(dataBroker);
+    public DataTransactionImpl(Object identifier,DataBrokerImpl dataBroker) {
+        super(identifier,dataBroker);
     }
 
     @Override
index 887ef82ca90c459d6ed4e8d12bc7c52903442919..cf339ee4f474e032ff8aca805f58eb5fe1f97d3b 100644 (file)
@@ -24,19 +24,13 @@ import java.util.Collections
 import org.slf4j.LoggerFactory
 import java.util.concurrent.Callable
 
-class NotificationBrokerImpl implements NotificationProviderService {
+class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable {
 
     val Multimap<Class<? extends Notification>, NotificationListener<?>> listeners;
 
     @Property
     var ExecutorService executor;
 
-    @Property
-    var RuntimeCodeGenerator generator;
-
-    @Property
-    var NotificationInvokerFactory invokerFactory;
-
     new(ExecutorService executor) {
         listeners = HashMultimap.create()
         this.executor = executor;
@@ -108,7 +102,7 @@ class NotificationBrokerImpl implements NotificationProviderService {
 
     override registerNotificationListener(
         org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
-        val invoker = invokerFactory.invokerFor(listener);
+        val invoker = BindingAwareBrokerImpl.generator.invokerFactory.invokerFor(listener);
         for (notifyType : invoker.supportedNotifications) {
             listeners.put(notifyType, invoker.invocationProxy)
         }
@@ -125,6 +119,11 @@ class NotificationBrokerImpl implements NotificationProviderService {
             listeners.remove(notifyType, reg.invoker.invocationProxy)
         }
     }
+    
+    override close()  {
+        //FIXME: implement properly.
+    }
+    
 }
 
 class GenericNotificationRegistration<T extends Notification> extends AbstractObjectRegistration<NotificationListener<T>> implements ListenerRegistration<NotificationListener<T>> {
@@ -177,7 +176,9 @@ class NotifyTask implements Callable<Object> {
 
     override call() {
         try {
+            log.info("Delivering notification {} to {}",notification,listener);
             listener.onNotification(notification);
+            log.info("Notification delivered {} to {}",notification,listener);
         } catch (Exception e) {
             log.error("Unhandled exception thrown by listener: {}", listener, e);
         }
index ff897aa41de0a6e474bb1db876c1cdfbca3a920c..7a72afc88550b3871ea72286f5b791b4a90f568c 100644 (file)
@@ -1,65 +1,85 @@
 package org.opendaylight.controller.sal.binding.impl.connect.dom;
 
+import java.util.Collection;
 import java.util.Collections;
+import java.util.Map;
 import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
-import org.opendaylight.controller.config.api.jmx.CommitStatus;
+import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
-import org.opendaylight.controller.md.sal.common.api.data.DataReader;
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
 import org.opendaylight.controller.sal.common.util.Rpcs;
-import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-
-import com.google.common.base.Preconditions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class BindingIndependentDataServiceConnector implements //
         RuntimeDataProvider, //
-        DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+        Provider, AutoCloseable {
+
+    private final Logger LOG = LoggerFactory.getLogger(BindingIndependentDataServiceConnector.class);
 
     private static final InstanceIdentifier<? extends DataObject> ROOT = InstanceIdentifier.builder().toInstance();
 
+    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+            .builder().toInstance();
+
     private BindingIndependentMappingService mappingService;
 
-    private DataBrokerService biDataService;
+    private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService;
 
     private DataProviderService baDataService;
 
+    private ConcurrentMap<Object, BindingToDomTransaction> domOpenedTransactions = new ConcurrentHashMap<>();
+    private ConcurrentMap<Object, DomToBindingTransaction> bindingOpenedTransactions = new ConcurrentHashMap<>();
+
+    private BindingToDomCommitHandler bindingToDomCommitHandler = new BindingToDomCommitHandler();
+    private DomToBindingCommitHandler domToBindingCommitHandler = new DomToBindingCommitHandler();
+
+    private Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> baCommitHandlerRegistration;
+
+    private Registration<DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode>> biCommitHandlerRegistration;
+
     @Override
     public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
-        // TODO Auto-generated method stub
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
-        CompositeNode result = biDataService.readOperationalData(biPath);
-        return mappingService.dataObjectFromDataDom(path, result);
+        try {
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
+            CompositeNode result = biDataService.readOperationalData(biPath);
+            return mappingService.dataObjectFromDataDom(path, result);
+        } catch (DeserializationException e) {
+            throw new IllegalStateException(e);
+        }
     }
 
     @Override
     public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
-        CompositeNode result = biDataService.readConfigurationData(biPath);
-        return mappingService.dataObjectFromDataDom(path, result);
-    }
-
-    @Override
-    public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
-            DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
-
-        DataModificationTransaction translated = translateTransaction(modification);
-        return new WrappedTransaction(translated, modification);
+        try {
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
+            CompositeNode result = biDataService.readConfigurationData(biPath);
+            return mappingService.dataObjectFromDataDom(path, result);
+        } catch (DeserializationException e) {
+            throw new IllegalStateException(e);
+        }
     }
 
-    private DataModificationTransaction translateTransaction(
+    private DataModificationTransaction createBindingToDomTransaction(
             DataModification<InstanceIdentifier<? extends DataObject>, DataObject> source) {
         DataModificationTransaction target = biDataService.beginTransaction();
         for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedConfigurationData()
@@ -74,27 +94,164 @@ public class BindingIndependentDataServiceConnector implements //
                     .toDataDom(entry);
             target.putOperationalData(biEntry.getKey(), biEntry.getValue());
         }
-        for(InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
+        for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
             org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
             target.removeConfigurationData(biEntry);
         }
-        for(InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
+        for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
             org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
             target.removeOperationalData(biEntry);
         }
         return target;
     }
 
-    private class WrappedTransaction implements
+    private org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction createDomToBindingTransaction(
+            DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> source) {
+        org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction target = baDataService
+                .beginTransaction();
+        for (Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> entry : source
+                .getUpdatedConfigurationData().entrySet()) {
+            try {
+                InstanceIdentifier<?> baKey = mappingService.fromDataDom(entry.getKey());
+                DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
+                target.putConfigurationData(baKey, baData);
+            } catch (DeserializationException e) {
+                LOG.error("Ommiting from BA transaction: {}. Reason{}.", entry.getKey(), e);
+            }
+        }
+        for (Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> entry : source
+                .getUpdatedOperationalData().entrySet()) {
+            try {
+
+                InstanceIdentifier<?> baKey = mappingService.fromDataDom(entry.getKey());
+                DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
+                target.putOperationalData(baKey, baData);
+            } catch (DeserializationException e) {
+                LOG.error("Ommiting from BA transaction: {}. Reason{}.", entry.getKey(), e);
+            }
+        }
+        for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedConfigurationData()) {
+            try {
+
+                InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
+                target.removeConfigurationData(baEntry);
+            } catch (DeserializationException e) {
+                LOG.error("Ommiting from BA transaction: {}. Reason{}.", entry, e);
+            }
+        }
+        for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedOperationalData()) {
+            try {
+
+                InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
+                target.removeOperationalData(baEntry);
+            } catch (DeserializationException e) {
+                LOG.error("Ommiting from BA transaction: {}. Reason{}.", entry, e);
+            }
+        }
+        return target;
+    }
+
+    public org.opendaylight.controller.sal.core.api.data.DataProviderService getBiDataService() {
+        return biDataService;
+    }
+
+    public void setBiDataService(org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
+        this.biDataService = biDataService;
+    }
+
+    public DataProviderService getBaDataService() {
+        return baDataService;
+    }
+
+    public void setBaDataService(DataProviderService baDataService) {
+        this.baDataService = baDataService;
+    }
+
+    public void start() {
+        baDataService.registerDataReader(ROOT, this);
+        baCommitHandlerRegistration = baDataService.registerCommitHandler(ROOT, bindingToDomCommitHandler);
+        biCommitHandlerRegistration = biDataService.registerCommitHandler(ROOT_BI, domToBindingCommitHandler);
+        baDataService.registerCommitHandlerListener(domToBindingCommitHandler);
+    }
+
+    public void setMappingService(BindingIndependentMappingService mappingService) {
+        this.mappingService = mappingService;
+    }
+
+    @Override
+    public Collection<ProviderFunctionality> getProviderFunctionality() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public void onSessionInitiated(ProviderSession session) {
+        setBiDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
+        start();
+    }
+
+    @Override
+    public void close() throws Exception {
+
+        if (baCommitHandlerRegistration != null) {
+            baCommitHandlerRegistration.close();
+        }
+        if (biCommitHandlerRegistration != null) {
+            biCommitHandlerRegistration.close();
+        }
+
+    }
+
+    private class DomToBindingTransaction implements
+            DataCommitTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
+
+        private final org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing;
+        private final DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> modification;
+
+        public DomToBindingTransaction(
+                org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing,
+                DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> modification) {
+            super();
+            this.backing = backing;
+            this.modification = modification;
+            bindingOpenedTransactions.put(backing.getIdentifier(), this);
+        }
+
+        @Override
+        public DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getModification() {
+            return modification;
+        }
+
+        @Override
+        public RpcResult<Void> rollback() throws IllegalStateException {
+            // backing.cancel();
+            return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+        }
+
+        @Override
+        public RpcResult<Void> finish() throws IllegalStateException {
+            Future<RpcResult<TransactionStatus>> result = backing.commit();
+            try {
+                RpcResult<TransactionStatus> baResult = result.get();
+                return Rpcs.<Void> getRpcResult(baResult.isSuccessful(), null, baResult.getErrors());
+            } catch (InterruptedException e) {
+                throw new IllegalStateException("", e);
+            } catch (ExecutionException e) {
+                throw new IllegalStateException("", e);
+            }
+        }
+    }
+
+    private class BindingToDomTransaction implements
             DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
 
         private DataModificationTransaction backing;
         private DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
 
-        public WrappedTransaction(DataModificationTransaction backing,
+        public BindingToDomTransaction(DataModificationTransaction backing,
                 DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
             this.backing = backing;
             this.modification = modification;
+            domOpenedTransactions.put(backing.getIdentifier(), this);
         }
 
         @Override
@@ -106,46 +263,85 @@ public class BindingIndependentDataServiceConnector implements //
         public RpcResult<Void> finish() throws IllegalStateException {
             Future<RpcResult<TransactionStatus>> result = backing.commit();
             try {
-                RpcResult<TransactionStatus> biresult = result.get();
+                RpcResult<TransactionStatus> biResult = result.get();
+                return Rpcs.<Void> getRpcResult(biResult.isSuccessful(), null, biResult.getErrors());
             } catch (InterruptedException e) {
                 throw new IllegalStateException("", e);
             } catch (ExecutionException e) {
                 throw new IllegalStateException("", e);
+            } finally {
+                domOpenedTransactions.remove(backing.getIdentifier());
             }
-            return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
         }
 
         @Override
         public RpcResult<Void> rollback() throws IllegalStateException {
-            // backing.cancel();
+            domOpenedTransactions.remove(backing.getIdentifier());
             return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
         }
-
     }
 
-    public DataBrokerService getBiDataService() {
-        return biDataService;
-    }
+    private class BindingToDomCommitHandler implements
+            DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
 
-    public void setBiDataService(DataBrokerService biDataService) {
-        this.biDataService = biDataService;
-    }
+        @Override
+        public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
+                DataModification<InstanceIdentifier<? extends DataObject>, DataObject> bindingTransaction) {
 
-    public DataProviderService getBaDataService() {
-        return baDataService;
-    }
+            /**
+             * Transaction was created as DOM transaction, in that case we do
+             * not need to forward it back.
+             */
+            if (bindingOpenedTransactions.containsKey(bindingTransaction.getIdentifier())) {
 
-    public void setBaDataService(DataProviderService baDataService) {
-        this.baDataService = baDataService;
+                return CommitHandlersTransactions.allwaysSuccessfulTransaction(bindingTransaction);
+            }
+            DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction);
+            BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction);
+            LOG.info("Forwarding Binding Transaction: {} as DOM Transaction: {} .", bindingTransaction.getIdentifier(),
+                    domTransaction.getIdentifier());
+            return wrapped;
+        }
     }
 
-    public void start() {
-        baDataService.registerDataReader(ROOT, this);
-        baDataService.registerCommitHandler(ROOT, this);
-    }
+    private class DomToBindingCommitHandler implements //
+            RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject>>, //
+            DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
 
-    public void setMappingService(BindingIndependentMappingService mappingService) {
-        this.mappingService = mappingService;
-    }
+        @Override
+        public void onRegister(DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject> registration) {
+
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(registration
+                    .getPath());
+            // FIXME: do registration based on only active commit handlers.
+
+        }
 
+        @Override
+        public void onUnregister(DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject> registration) {
+            // NOOP for now
+            // FIXME: do registration based on only active commit handlers.
+        }
+
+        public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> requestCommit(
+                DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> domTransaction) {
+            Object identifier = domTransaction.getIdentifier();
+
+            /**
+             * We checks if the transcation was originated in this mapper. If it
+             * was originated in this mapper we are returing allways success
+             * commit hanlder to prevent creating loop in two-phase commit and
+             * duplicating data.
+             */
+            if (domOpenedTransactions.containsKey(identifier)) {
+                return CommitHandlersTransactions.allwaysSuccessfulTransaction(domTransaction);
+            }
+
+            org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction baTransaction = createDomToBindingTransaction(domTransaction);
+            DomToBindingTransaction forwardedTransaction = new DomToBindingTransaction(baTransaction, domTransaction);
+            LOG.info("Forwarding DOM Transaction: {} as Binding Transaction: {}.", domTransaction.getIdentifier(),
+                    baTransaction.getIdentifier());
+            return forwardedTransaction;
+        }
+    }
 }
index 8e61c9b3eeb8c131d81d30c8446b460c297eda95..b1983fe224d89da96f4445efa86469cc0e0e6b9d 100644 (file)
@@ -16,7 +16,8 @@ public interface BindingIndependentMappingService {
 
     org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(InstanceIdentifier<? extends DataObject> path);
 
-    DataObject dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode result);
-    
-    
+    DataObject dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode result) throws DeserializationException;
+
+    InstanceIdentifier<?> fromDataDom(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry)  throws DeserializationException;
+
 }
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CommitHandlersTransactions.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CommitHandlersTransactions.java
new file mode 100644 (file)
index 0000000..ea48374
--- /dev/null
@@ -0,0 +1,40 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.Collections;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.yangtools.concepts.Path;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+public class CommitHandlersTransactions {
+
+    private static class AllwaysSuccessfulTransaction<P,D> implements DataCommitTransaction<P, D> {
+        
+        private final  DataModification<P, D> modification;
+
+        public AllwaysSuccessfulTransaction(DataModification<P, D> modification) {
+            this.modification = modification;
+        }
+        @Override
+        public RpcResult<Void> rollback() throws IllegalStateException {
+            return Rpcs.<Void>getRpcResult(true, null, Collections.<RpcError>emptyList());
+        }
+        @Override
+        public RpcResult<Void> finish() throws IllegalStateException {
+            return Rpcs.<Void>getRpcResult(true, null, Collections.<RpcError>emptyList());
+        }
+        
+        @Override
+        public DataModification<P, D> getModification() {
+            return modification;
+        }
+    }
+    
+    
+    public static final <P extends Path<P>,D> AllwaysSuccessfulTransaction<P, D> allwaysSuccessfulTransaction(DataModification<P, D> modification)  {
+        return new AllwaysSuccessfulTransaction<>(modification);
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/ConnectorActivator.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/ConnectorActivator.java
deleted file mode 100644 (file)
index f69e664..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.opendaylight.controller.sal.binding.impl.connect.dom;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import javassist.ClassPool;
-
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
-import org.opendaylight.controller.sal.binding.dom.serializer.impl.RuntimeGeneratedMappingServiceImpl;
-import org.opendaylight.controller.sal.binding.dom.serializer.impl.TransformerGenerator;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.controller.sal.core.api.Provider;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-
-public class ConnectorActivator implements Provider, ServiceTrackerCustomizer<Broker, Broker> {
-
-    BindingIndependentDataServiceConnector dataConnector;
-    BindingIndependentMappingService mappingService;
-
-    private final DataProviderService baDataService;
-    private BundleContext context;
-
-    private ServiceTracker<Broker, Broker> brokerTracker;
-
-    public ConnectorActivator(DataProviderService dataService, BundleContext context) {
-        baDataService = dataService;
-        this.context = context;
-        brokerTracker = new ServiceTracker<>(context, Broker.class, this);
-    }
-
-    @Override
-    public Collection<ProviderFunctionality> getProviderFunctionality() {
-        return Collections.emptySet();
-    }
-
-    @Override
-    public void onSessionInitiated(ProviderSession session) {
-
-        RuntimeGeneratedMappingServiceImpl mappingImpl = new RuntimeGeneratedMappingServiceImpl();
-        mappingImpl.setPool(new ClassPool());
-        SchemaService schemaService = (session.getService(SchemaService.class));
-        ClassPool pool = new ClassPool();
-        mappingImpl.setBinding(new TransformerGenerator(pool));
-        mappingImpl.start();
-        schemaService.registerSchemaServiceListener(mappingImpl);
-        mappingService = mappingImpl;
-        dataConnector = new BindingIndependentDataServiceConnector();
-        dataConnector.setBaDataService(baDataService);
-        dataConnector.setBiDataService(session.getService(DataBrokerService.class));
-        dataConnector.setMappingService(mappingService);
-        dataConnector.start();
-    }
-
-    @Override
-    public Broker addingService(ServiceReference<Broker> reference) {
-        Broker br= context.getService(reference);
-        br.registerProvider(this, context);
-        return br;
-    }
-
-    @Override
-    public void modifiedService(ServiceReference<Broker> reference, Broker service) {
-        // NOOP
-    }
-
-    @Override
-    public void removedService(ServiceReference<Broker> reference, Broker service) {
-        // NOOP
-    }
-
-    public void start() {
-        brokerTracker.open();
-    }
-}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DataModificationTracker.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DataModificationTracker.java
new file mode 100644 (file)
index 0000000..3fc377f
--- /dev/null
@@ -0,0 +1,25 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.yangtools.concepts.Path;
+
+import com.google.common.util.concurrent.JdkFutureAdapters;
+
+public final class DataModificationTracker<P extends Path<P>,D> {
+
+    ConcurrentMap<Object, DataModification<P,D>> trackedTransactions = new ConcurrentHashMap<>();
+    
+    
+    public void startTrackingModification(DataModification<P,D> modification) {
+        trackedTransactions.putIfAbsent(modification.getIdentifier(), modification);
+        
+        
+    }
+    
+    public boolean containsIdentifier(Object identifier) {
+        return trackedTransactions.containsKey(identifier);
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DeserializationException.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DeserializationException.java
new file mode 100644 (file)
index 0000000..9331899
--- /dev/null
@@ -0,0 +1,24 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+public class DeserializationException extends Exception {
+
+    public DeserializationException() {
+    }
+
+    public DeserializationException(String message) {
+        super(message);
+    }
+
+    public DeserializationException(Throwable cause) {
+        super(cause);
+    }
+
+    public DeserializationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public DeserializationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingContext.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingContext.java
new file mode 100644 (file)
index 0000000..e3a7235
--- /dev/null
@@ -0,0 +1,10 @@
+package org.opendaylight.controller.sal.binding.spi;
+
+import org.opendaylight.yangtools.yang.binding.BaseIdentity;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+public interface RpcRoutingContext<C extends BaseIdentity,S extends RpcService> {
+
+    Class<C> getContextType();
+    Class<S> getServiceType();
+}
index 72bae68d4c759aa48af9cb50ebc9559c2e8c8fb7..38770c193c94096323280024856ef2f1bf14dfbd 100644 (file)
@@ -3,8 +3,10 @@ module opendaylight-sal-binding-broker-impl {
     namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl";
     prefix "binding-impl";
 
-       import config { prefix config; revision-date 2013-04-05; }
-       import opendaylight-md-sal-binding {prefix sal;}
+    import config { prefix config; revision-date 2013-04-05; }
+    import opendaylight-md-sal-binding {prefix sal;}
+    import opendaylight-md-sal-dom {prefix dom;}
+    import opendaylight-md-sal-common {prefix common;}
 
     description
         "Service definition for Binding Aware MD-SAL.";
@@ -14,39 +16,123 @@ module opendaylight-sal-binding-broker-impl {
             "Initial revision";
     }
 
-    identity binding-broker-impl-singleton {
+    identity binding-dom-mapping-service {
+        base config:service-type;
+        config:java-class "org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService";
+    }
+
+
+    identity binding-broker-impl {
         base config:module-type;
         config:provided-service sal:binding-broker-osgi-registry;
-        config:java-name-prefix BindingBrokerImplSingleton;
+        config:java-name-prefix BindingBrokerImpl;
+    }
+    
+    identity binding-data-broker {
+        base config:module-type;
+        config:provided-service sal:binding-data-broker;
+        config:provided-service sal:binding-data-consumer-broker;
+        config:java-name-prefix DataBrokerImpl;
     }
-
-    grouping rpc-routing-table {
-        
     
+    identity binding-rpc-broker {
+        base config:module-type;
+        config:provided-service sal:binding-rpc-registry;
+        config:java-name-prefix RpcBrokerImpl;
+    }
+    
+    identity binding-notification-broker {
+        base config:module-type;
+        config:provided-service sal:binding-notification-service;
+        config:provided-service sal:binding-notification-subscription-service;
+        config:java-name-prefix NotificationBrokerImpl;
     }
 
+    identity runtime-generated-mapping {
+        base config:module-type;
+        config:provided-service binding-dom-mapping-service;
+        config:java-name-prefix RuntimeMapping;
+    }
 
-    grouping rpc-router {
-        leaf module {
-            type string;
+    augment "/config:modules/config:module/config:configuration" {
+        case binding-broker-impl {
+            when "/config:modules/config:module/config:type = 'binding-broker-impl'";
+            
+            /*
+            container rpc-registry {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity sal:binding-rpc-registry;
+                    }
+                }
+            }*/
+            
+            container data-broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity sal:binding-data-broker;
+                    }
+                }
+            }
+            
+            container notification-service {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity sal:binding-notification-service;
+                    }
+                }
+            } 
         }
-        container routing-tables {
-            list routing-table {
-                uses rpc-routing-table;
+    }
+    
+    augment "/config:modules/config:module/config:configuration" {
+        case binding-data-broker {
+            when "/config:modules/config:module/config:type = 'binding-data-broker'";
+            container dom-broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity dom:dom-broker-osgi-registry;
+                    }
+                }
             }
+            container mapping-service {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity binding-dom-mapping-service;
+                    }
+                }
+            } 
         }
     }
+    
 
+    augment "/config:modules/config:module/config:state" {
+        case runtime-generated-mapping {
+            when "/config:modules/config:module/config:type = 'runtime-generated-mapping'";
+        }
+    }
 
     augment "/config:modules/config:module/config:state" {
-        case binding-broker-impl-singleton {
-            when "/config:modules/config:module/config:type = 'binding-broker-impl-singleton'";
-            
-            container rpc-routers {
-                list rpc-router {
-                    uses rpc-router;
-                }
-            }
+        case binding-data-broker {
+            when "/config:modules/config:module/config:type = 'binding-data-broker'";
+            uses common:data-state;
+        }
+    }
+    augment "/config:modules/config:module/config:state" {
+        case binding-rpc-broker {
+            when "/config:modules/config:module/config:type = 'binding-rpc-broker'";
+            uses common:rpc-state;
+        }
+    }
+    augment "/config:modules/config:module/config:state" {
+        case binding-notification-broker {
+            when "/config:modules/config:module/config:type = 'binding-notification-broker'";
+            uses common:notification-state;
         }
     }
 }
\ No newline at end of file
index 7d8a8f1fffa7703c2d1b567cbc372f694e4cdba0..9f3a6e8652f8c3d47dc65c2aafce56061d26aace 100644 (file)
@@ -8,6 +8,7 @@ import java.util.Set;
 
 import javassist.ClassPool;
 
+import org.junit.After;
 import org.junit.Before;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
@@ -15,78 +16,96 @@ import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndepende
 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
 import org.opendaylight.controller.sal.binding.dom.serializer.impl.RuntimeGeneratedMappingServiceImpl;
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.core.api.data.DataStore;
+import org.opendaylight.controller.sal.dom.broker.impl.DataStoreStatsWrapper;
 import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 import org.reflections.Reflections;
 import org.reflections.scanners.ResourcesScanner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Predicate;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 
-public  abstract class AbstractDataServiceTest {
-    protected DataBrokerService biDataService;
+public abstract class AbstractDataServiceTest {
+    private static Logger log = LoggerFactory.getLogger(AbstractDataServiceTest.class);
+
+    protected org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService;
     protected DataProviderService baDataService;
-    
+
     /**
      * Workaround for JUNIT sharing classloaders
      * 
      */
     protected static final ClassPool POOL = new ClassPool();
-    
+
     protected RuntimeGeneratedMappingServiceImpl mappingServiceImpl;
     protected BindingIndependentMappingService mappingService;
     protected DataBrokerImpl baDataImpl;
     protected org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
     protected ListeningExecutorService executor;
     protected BindingIndependentDataServiceConnector connectorServiceImpl;
-    protected HashMapDataStore dataStore;
-    
-    
+    protected HashMapDataStore rawDataStore;
+    private SchemaAwareDataStoreAdapter schemaAwareDataStore;
+    private DataStoreStatsWrapper dataStoreStats;
+
+    protected DataStore dataStore;
+
     @Before
     public void setUp() {
         executor = MoreExecutors.sameThreadExecutor();
         baDataImpl = new DataBrokerImpl();
         baDataService = baDataImpl;
         baDataImpl.setExecutor(executor);
-        
+
         biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl();
-        biDataService =  biDataImpl;
+        biDataService = biDataImpl;
         biDataImpl.setExecutor(executor);
-        
-        dataStore = new HashMapDataStore();
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier treeRoot = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder().toInstance();
+
+        rawDataStore = new HashMapDataStore();
+        schemaAwareDataStore = new SchemaAwareDataStoreAdapter();
+        schemaAwareDataStore.changeDelegate(rawDataStore);
+        dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore);
+        dataStore = dataStoreStats;
+
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier treeRoot = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+                .builder().toInstance();
         biDataImpl.registerConfigurationReader(treeRoot, dataStore);
         biDataImpl.registerOperationalReader(treeRoot, dataStore);
         biDataImpl.registerCommitHandler(treeRoot, dataStore);
-        
+
         mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl();
         mappingServiceImpl.setPool(POOL);
         mappingService = mappingServiceImpl;
         File pathname = new File("target/gen-classes-debug");
-        //System.out.println("Generated classes are captured in " + pathname.getAbsolutePath());
-        mappingServiceImpl.start();
-        //mappingServiceImpl.getBinding().setClassFileCapturePath(pathname);
-        
+        // System.out.println("Generated classes are captured in " +
+        // pathname.getAbsolutePath());
+        mappingServiceImpl.start(null);
+        // mappingServiceImpl.getBinding().setClassFileCapturePath(pathname);
+
         connectorServiceImpl = new BindingIndependentDataServiceConnector();
         connectorServiceImpl.setBaDataService(baDataService);
         connectorServiceImpl.setBiDataService(biDataService);
         connectorServiceImpl.setMappingService(mappingServiceImpl);
         connectorServiceImpl.start();
-        
-        String[] yangFiles= getModelFilenames();
-        if(yangFiles != null && yangFiles.length > 0) {
-            mappingServiceImpl.onGlobalContextUpdated(getContext(yangFiles));
+
+        String[] yangFiles = getModelFilenames();
+        if (yangFiles != null && yangFiles.length > 0) {
+            SchemaContext context = getContext(yangFiles);
+            mappingServiceImpl.onGlobalContextUpdated(context);
+            schemaAwareDataStore.onGlobalContextUpdated(context);
         }
     }
 
-
-    protected  String[] getModelFilenames() {
+    protected String[] getModelFilenames() {
         return getAllModelFilenames();
     }
-    
+
     public static String[] getAllModelFilenames() {
         Predicate<String> predicate = new Predicate<String>() {
             @Override
@@ -94,11 +113,11 @@ public  abstract class AbstractDataServiceTest {
                 return input.endsWith(".yang");
             }
         };
-        Reflections reflection= new Reflections("META-INF.yang", new ResourcesScanner());
+        Reflections reflection = new Reflections("META-INF.yang", new ResourcesScanner());
         Set<String> result = reflection.getResources(predicate);
         return (String[]) result.toArray(new String[result.size()]);
     }
-    
+
     public static SchemaContext getContext(String[] yangFiles) {
 
         ClassLoader loader = AbstractDataServiceTest.class.getClassLoader();
@@ -114,4 +133,21 @@ public  abstract class AbstractDataServiceTest {
         Set<Module> modules = parser.parseYangModelsFromStreams(streams);
         return parser.resolveSchemaContext(modules);
     }
+
+    @After
+    public void afterTest() {
+
+        log.info("BIDataStore Statistics: Configuration Read Count: {} TotalTime: {} ns AverageTime (ns): {} ns",
+                dataStoreStats.getConfigurationReadCount(), dataStoreStats.getConfigurationReadTotalTime(),
+                dataStoreStats.getConfigurationReadAverageTime());
+
+        log.info("BIDataStore Statistics: Operational Read Count: {} TotalTime: {} ns AverageTime (ns): {} ns",
+                dataStoreStats.getOperationalReadCount(), dataStoreStats.getOperationalReadTotalTime(),
+                dataStoreStats.getOperationalReadAverageTime());
+
+        log.info("BIDataStore Statistics: Request Commit Count: {} TotalTime: {} ns AverageTime (ns): {} ns",
+                dataStoreStats.getRequestCommitCount(), dataStoreStats.getRequestCommitTotalTime(),
+                dataStoreStats.getRequestCommitAverageTime());
+
+    }
 }
index 4e7628fd06cc87254c2ce2df71a7b844070678d6..f60ddb991dfc54017e8df463bcb14d0642ee144b 100644 (file)
@@ -1,22 +1,21 @@
 package org.opendaylight.controller.sal.binding.test.bugfix;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
+
+
 
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
@@ -24,9 +23,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
@@ -35,10 +32,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -46,7 +44,6 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
-import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -68,17 +65,7 @@ public class DOMCodecBug01Test extends AbstractDataServiceTest {
     private static final Map<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
             NODE_ID);
 
-    private static final InstanceIdentifier<Nodes> NODES_INSTANCE_ID_BA = InstanceIdentifier.builder() //
-            .node(Nodes.class) //
-            .toInstance();
-
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODES_INSTANCE_ID_BI = //
-    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
-            .node(Nodes.QNAME) //
-            .toInstance();
-
-    private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder() //
-            .node(Nodes.class) //
+    private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
             .child(Node.class, NODE_KEY).toInstance();
 
     private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
@@ -99,9 +86,8 @@ public class DOMCodecBug01Test extends AbstractDataServiceTest {
             .nodeWithKey(Flow.QNAME, FLOW_KEY_BI) //
             .toInstance();
     private static final InstanceIdentifier<? extends DataObject> FLOW_INSTANCE_ID_BA = //
-    InstanceIdentifier.builder() //
-            .node(Flows.class) //
-            .node(Flow.class, FLOW_KEY) //
+    InstanceIdentifier.builder(Flows.class) //
+            .child(Flow.class, FLOW_KEY) //
             .toInstance();
 
 
@@ -142,6 +128,7 @@ public class DOMCodecBug01Test extends AbstractDataServiceTest {
         ListenableFuture<Void> task3Future = listenablePool.submit(task3);
 
 
+        @SuppressWarnings("unchecked")
         ListenableFuture<List<Void>> compositeFuture = Futures.allAsList(task1Future,task2Future,task3Future);
 
         Thread.sleep(500);
@@ -180,8 +167,6 @@ public class DOMCodecBug01Test extends AbstractDataServiceTest {
         flow.setKey(FLOW_KEY);
         flow.setMatch(match.build());
         flow.setNode(NODE_REF);
-
-
         InstructionsBuilder instructions = new InstructionsBuilder();
         InstructionBuilder instruction = new InstructionBuilder();
         ApplyActionsBuilder applyActions = new ApplyActionsBuilder();
@@ -191,6 +176,7 @@ public class DOMCodecBug01Test extends AbstractDataServiceTest {
         actionList.add(new ActionBuilder().setAction(popMplsAction.build()).build());
 
         applyActions.setAction(actionList );
+        
 
 
         instruction.setInstruction(applyActions.build());
@@ -205,13 +191,37 @@ public class DOMCodecBug01Test extends AbstractDataServiceTest {
         assertNotNull(ret);
         assertEquals(TransactionStatus.COMMITED, ret.getResult());
     }
+    
+    private void createFlow2() throws Exception {
+        DataModificationTransaction modification = baDataService.beginTransaction();
+        long id = 123;
+        FlowKey key = new FlowKey(id, new NodeRef(NODE_INSTANCE_ID_BA));
+        InstanceIdentifier<?> path1;
+        FlowBuilder flow = new FlowBuilder();
+        flow.setKey(key);
+        MatchBuilder match = new MatchBuilder();
+        Ipv4MatchBuilder ipv4Match = new Ipv4MatchBuilder();
+        // ipv4Match.setIpv4Destination(new Ipv4Prefix(cliInput.get(4)));
+        match.setLayer4Match(new TcpMatchBuilder().build());
+        flow.setMatch(match.build());
+        DropAction dropAction = new DropActionBuilder().build();
+        //   ActionBuilder action = new ActionBuilder();
+
+        //  List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow.Action> actions = Collections
+             //   .singletonList(action.build());
+        //   flow.setAction(actions);
+        flow.setPriority(2);
+        System.out.println("Putting the configuration Data................");
+        path1 = InstanceIdentifier.builder(Flows.class).child(Flow.class, key).toInstance();
+       // DataObject cls = (DataObject) modification.readConfigurationData(path1);
+        modification.putConfigurationData(path1, flow.build());
+        modification.commit();
+
+    }
 
     private class CreateFlowTask implements Callable<Void> {
 
-        final Object startSyncObject;
-
         public CreateFlowTask(Object startSync) {
-            startSyncObject = startSync;
         }
 
         @Override
@@ -220,6 +230,7 @@ public class DOMCodecBug01Test extends AbstractDataServiceTest {
                 //startSyncObject.wait();
                 //Thread.sleep(500);
                 createFlow();
+                createFlow2();
             } catch (Exception e) {
                 throw new RuntimeException(e);
             }
@@ -228,10 +239,10 @@ public class DOMCodecBug01Test extends AbstractDataServiceTest {
     }
 
     private void verifyDataAreStoredProperly() {
-        CompositeNode biFlow = biDataService.readConfigurationData(FLOW_INSTANCE_ID_BI);
+        CompositeNode biFlows = biDataService.readConfigurationData(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.of(Flows.QNAME));
+        assertNotNull(biFlows);
+        CompositeNode biFlow = biFlows.getFirstCompositeByName(Flow.QNAME);
         assertNotNull(biFlow);
-        CompositeNode biMatch = biFlow.getFirstCompositeByName(QName.create(Flow.QNAME, Match.QNAME.getLocalName()));
-        assertNotNull(biMatch);
     }
 
 
index 773bab80f1669c9a1c5736cbe2dc25784ffb716b..4df10bc135e51082169c9cd7c8072c6422e4de02 100644 (file)
@@ -1,8 +1,6 @@
 package org.opendaylight.controller.sal.binding.test.bugfix;
 
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
@@ -13,43 +11,22 @@ import org.junit.Test;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
 
 import static org.junit.Assert.*;
 
 public class DOMCodecBug02Test extends AbstractDataServiceTest {
 
     private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
-    private static final QName FLOW_ID_QNAME = QName.create(Flow.QNAME, "id");
-    private static final QName FLOW_NODE_QNAME = QName.create(Flow.QNAME, "node");
-
-    private static final String FLOW_ID = "foo";
     private static final String NODE_ID = "node:1";
 
     private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID));
@@ -57,8 +34,7 @@ public class DOMCodecBug02Test extends AbstractDataServiceTest {
     private static final Map<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
             NODE_ID);
 
-    private static final InstanceIdentifier<Nodes> NODES_INSTANCE_ID_BA = InstanceIdentifier.builder() //
-            .node(Nodes.class) //
+    private static final InstanceIdentifier<Nodes> NODES_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
             .toInstance();
 
     private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODES_INSTANCE_ID_BI = //
@@ -66,8 +42,7 @@ public class DOMCodecBug02Test extends AbstractDataServiceTest {
             .node(Nodes.QNAME) //
             .toInstance();
 
-    private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder() //
-            .node(Nodes.class) //
+    private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
             .child(Node.class, NODE_KEY).toInstance();
 
     private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
index ae54591a2303725a04cbb6c4a19c4bee7d2399c5..2cd396dedc091076e08a28fe964a984619698eb9 100644 (file)
@@ -1,13 +1,7 @@
 package org.opendaylight.controller.sal.binding.test.bugfix;
-
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.List;
 import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
+
 
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
@@ -15,36 +9,24 @@ import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
 import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
 import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
+
 
 import static org.junit.Assert.*;
 
@@ -58,17 +40,11 @@ public class DOMCodecBug03Test extends AbstractDataServiceTest implements DataCh
     private static final Map<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
             NODE_ID);
 
-    private static final InstanceIdentifier<Nodes> NODES_INSTANCE_ID_BA = InstanceIdentifier.builder() //
-            .node(Nodes.class) //
+    private static final InstanceIdentifier<Nodes> NODES_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
             .toInstance();
 
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODES_INSTANCE_ID_BI = //
-    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
-            .node(Nodes.QNAME) //
-            .toInstance();
 
-    private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder() //
-            .node(Nodes.class) //
+    private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder(NODES_INSTANCE_ID_BA) //
             .child(Node.class, NODE_KEY).toInstance();
 
     private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
@@ -76,7 +52,6 @@ public class DOMCodecBug03Test extends AbstractDataServiceTest implements DataCh
             .node(Nodes.QNAME) //
             .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
             .toInstance();
-    private static final NodeRef NODE_REF = new NodeRef(NODE_INSTANCE_ID_BA);
     private DataChangeEvent<InstanceIdentifier<?>, DataObject> receivedChangeEvent;
 
     
@@ -120,6 +95,49 @@ public class DOMCodecBug03Test extends AbstractDataServiceTest implements DataCh
         verifyNodes(nodes,original);
         
         
+        
+        testAddingNodeConnector();
+        
+        
+        
+        testNodeRemove();
+        
+        
+    }
+
+    private void testAddingNodeConnector() throws Exception {
+        
+        NodeConnectorId ncId = new NodeConnectorId("openflow:1:bar");
+        NodeConnectorKey nodeKey = new NodeConnectorKey(ncId );
+        InstanceIdentifier<NodeConnector> ncInstanceId = InstanceIdentifier.builder(NODE_INSTANCE_ID_BA).child(NodeConnector.class, nodeKey).toInstance();
+        NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder();
+        ncBuilder.setId(ncId);
+        ncBuilder.setKey(nodeKey);
+        NodeConnector connector = ncBuilder.build();
+        DataModificationTransaction transaction = baDataService.beginTransaction();
+        transaction.putOperationalData(ncInstanceId, connector);
+        RpcResult<TransactionStatus> result = transaction.commit().get();
+        assertEquals(TransactionStatus.COMMITED, result.getResult());
+        Node node = (Node) baDataService.readOperationalData(NODE_INSTANCE_ID_BA);
+        assertNotNull(node);
+        assertNotNull(node.getNodeConnector());
+        assertFalse(node.getNodeConnector().isEmpty());
+        NodeConnector readedNc = node.getNodeConnector().get(0);
+        assertNotNull(readedNc);
+        
+        
+        
+        
+    }
+
+    private void testNodeRemove() throws Exception {
+        DataModificationTransaction transaction = baDataService.beginTransaction();
+        transaction.removeOperationalData(NODE_INSTANCE_ID_BA);
+        RpcResult<TransactionStatus> result = transaction.commit().get();
+        assertEquals(TransactionStatus.COMMITED, result.getResult());
+        
+        Node node = (Node) baDataService.readOperationalData(NODE_INSTANCE_ID_BA);
+        assertNull(node);
     }
 
     private void verifyNodes(Nodes nodes,Node original) {
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/RpcRegistrationNullPointer.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/RpcRegistrationNullPointer.java
new file mode 100644 (file)
index 0000000..0c7f039
--- /dev/null
@@ -0,0 +1,8 @@
+package org.opendaylight.controller.sal.binding.test.bugfix;
+
+public class RpcRegistrationNullPointer {
+
+    
+    
+    
+}
index 7706cda750bd342555da2a95dc5b4e635daf6099..e326fd093116d4e7d3d45f5ba046c0bffb5f28a4 100644 (file)
@@ -63,7 +63,7 @@ public class BrokerIntegrationTest extends AbstractDataServiceTest {
         assertNotNull(result2.getResult());
         assertEquals(TransactionStatus.COMMITED, result.getResult());
 
-        Nodes allNodes = (Nodes) baDataService.readConfigurationData(InstanceIdentifier.builder().node(Nodes.class)
+        Nodes allNodes = (Nodes) baDataService.readConfigurationData(InstanceIdentifier.builder(Nodes.class)
                 .toInstance());
         assertNotNull(allNodes);
         assertNotNull(allNodes.getNode());
@@ -100,7 +100,7 @@ public class BrokerIntegrationTest extends AbstractDataServiceTest {
 
     private static NodeRef createNodeRef(String string) {
         NodeKey key = new NodeKey(new NodeId(string));
-        InstanceIdentifier<Node> path = InstanceIdentifier.builder().node(Nodes.class).node(Node.class, key)
+        InstanceIdentifier<Node> path = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
                 .toInstance();
         return new NodeRef(path);
     }
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java
new file mode 100644 (file)
index 0000000..63368bd
--- /dev/null
@@ -0,0 +1,190 @@
+package org.opendaylight.controller.sal.binding.test.connect.dom;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+
+
+
+
+
+
+
+
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Future;
+
+
+
+
+
+
+
+
+
+
+
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.CommitHandlersTransactions;
+import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
+import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+import com.google.common.collect.ImmutableMap;
+
+public class ChangeOriginatedInDomBrokerTest extends AbstractDataServiceTest {
+
+    private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
+    private static final QName FLOW_ID_QNAME = QName.create(Flow.QNAME, "id");
+    private static final QName FLOW_NODE_QNAME = QName.create(Flow.QNAME, "node");
+    private static final long FLOW_ID = 1234;
+    private static final String NODE_ID = "node:1";
+    
+    private DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modificationCapture;
+
+
+    private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID));
+
+    private static final Map<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
+            NODE_ID);
+
+    private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
+            .child(Node.class, NODE_KEY).toInstance();
+
+    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
+    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+            .node(Nodes.QNAME) //
+            .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
+            .toInstance();
+    private static final NodeRef NODE_REF = new NodeRef(NODE_INSTANCE_ID_BA);
+
+    private static final FlowKey FLOW_KEY = new FlowKey(FLOW_ID, NODE_REF);
+
+    private static final Map<QName, Object> FLOW_KEY_BI = //
+    ImmutableMap.<QName, Object> of(FLOW_ID_QNAME, FLOW_ID, FLOW_NODE_QNAME, NODE_INSTANCE_ID_BI);
+
+    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier FLOW_INSTANCE_ID_BI = //
+    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+            .node(Flows.QNAME) //
+            .nodeWithKey(Flow.QNAME, FLOW_KEY_BI) //
+            .toInstance();
+    
+    private static final InstanceIdentifier<Flows> FLOWS_PATH_BA = //
+            InstanceIdentifier.builder(Flows.class) //
+                    .toInstance();
+            
+    
+    private static final InstanceIdentifier<Flow> FLOW_INSTANCE_ID_BA = //
+    InstanceIdentifier.builder(Flows.class) //
+            .child(Flow.class, FLOW_KEY) //
+            .toInstance();
+    
+    @Test
+    public void simpleModifyOperation() throws Exception {
+        
+        registerCommitHandler();
+        
+        CompositeNode domflow = createXmlFlow();
+        DataModificationTransaction biTransaction = biDataService.beginTransaction();
+        biTransaction.putConfigurationData(FLOW_INSTANCE_ID_BI, domflow);
+        RpcResult<TransactionStatus> biResult = biTransaction.commit().get();
+        
+        assertNotNull(modificationCapture);
+        Flow flow = (Flow) modificationCapture.getCreatedConfigurationData().get(FLOW_INSTANCE_ID_BA);
+        assertNotNull(flow);
+        assertNotNull(flow.getMatch());
+        assertEquals(TransactionStatus.COMMITED, biResult.getResult());
+        
+    }
+
+    
+
+    private void registerCommitHandler() {
+        DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> flowTestCommitHandler = new DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>() {
+            
+            
+            @Override
+            public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
+                    DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+                modificationCapture = modification;
+                return CommitHandlersTransactions.allwaysSuccessfulTransaction(modification);
+            }
+            
+            
+        };
+        Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> registration = baDataService.registerCommitHandler(FLOWS_PATH_BA, flowTestCommitHandler);
+        assertNotNull(registration);
+    }
+    
+    private CompositeNode createXmlFlow() {
+        
+        FlowBuilder flow = new FlowBuilder();
+        MatchBuilder match = new MatchBuilder();
+        VlanMatchBuilder vlanBuilder = new VlanMatchBuilder();
+        VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
+        VlanId vlanId = new VlanId(10);
+        vlanBuilder.setVlanId(vlanIdBuilder.setVlanId(vlanId).build());
+        match.setVlanMatch(vlanBuilder.build());
+
+        flow.setKey(FLOW_KEY);
+        flow.setMatch(match.build());
+        flow.setNode(NODE_REF);
+        InstructionsBuilder instructions = new InstructionsBuilder();
+        InstructionBuilder instruction = new InstructionBuilder();
+        ApplyActionsBuilder applyActions = new ApplyActionsBuilder();
+        List<Action> actionList = new ArrayList<>();
+        PopMplsActionBuilder popMplsAction = new PopMplsActionBuilder();
+        popMplsAction.setEthernetType(34);
+        actionList.add(new ActionBuilder().setAction(popMplsAction.build()).build());
+
+        applyActions.setAction(actionList );
+        
+
+
+        instruction.setInstruction(applyActions.build());
+
+
+        List<Instruction> instructionList = Collections.<Instruction>singletonList(instruction.build());
+        instructions.setInstruction(instructionList );
+
+        flow.setInstructions(instructions.build());
+        
+        CompositeNode domFlow = mappingService.toDataDom(flow.build());
+        return domFlow;
+    }
+}
index bf3d7abd1ed0433c3f6c334ec8f2de595def2bb1..38f0da3ccc92711dc46a56865a4afb4e03a176c5 100644 (file)
@@ -23,6 +23,11 @@ module opendaylight-md-sal-binding {
         config:java-class "org.opendaylight.controller.sal.binding.api.data.DataProviderService";
     }
 
+    identity binding-data-consumer-broker {
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.sal.binding.api.data.DataBrokerService";
+    }
+
     identity binding-rpc-registry {
         base "config:service-type";
         config:java-class "org.opendaylight.controller.sal.binding.api.RpcProviderRegistry";
@@ -33,4 +38,9 @@ module opendaylight-md-sal-binding {
         config:java-class "org.opendaylight.controller.sal.binding.api.NotificationProviderService";
     }
 
+    identity binding-notification-subscription-service {
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.sal.binding.api.NotificationService";
+    }
+
 }
\ No newline at end of file
index e242b9ecee2c3e8f9cc8ff1d9b777a036d1f07eb..27d426791f5c65f6fe01aac0a5e51fb2228b1032 100644 (file)
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <artifactId>sal-parent</artifactId>
-    <groupId>org.opendaylight.controller</groupId>
-    <version>1.0-SNAPSHOT</version>
-  </parent>
-  <artifactId>sal-binding-it</artifactId>
-  <scm>
-    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
-    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
-    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
-  </scm>
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>sal-parent</artifactId>
+        <groupId>org.opendaylight.controller</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>sal-binding-it</artifactId>
+    <scm>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+        <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+    </scm>
 
-  <properties>
-    <exam.version>3.0.0</exam.version>
-    <url.version>1.5.0</url.version>
-    <!-- Sonar jacoco plugin to get integration test coverage info -->
-    <sonar.jacoco.reportPath>../sal-binding-broker/target/jacoco.exec</sonar.jacoco.reportPath>
-    <sonar.jacoco.itReportPath>../sal-binding-broker/target/jacoco-it.exec</sonar.jacoco.itReportPath>
-  </properties>
+    <properties>
+        <exam.version>3.0.0</exam.version>
+        <url.version>1.5.0</url.version>
+        <!-- Sonar jacoco plugin to get integration test coverage info -->
+        <sonar.jacoco.reportPath>../sal-binding-broker/target/jacoco.exec</sonar.jacoco.reportPath>
+        <sonar.jacoco.itReportPath>../sal-binding-broker/target/jacoco-it.exec</sonar.jacoco.itReportPath>
+        <netconf.version>0.2.3-SNAPSHOT</netconf.version>
+        <config.version>0.2.3-SNAPSHOT</config.version>
+    </properties>
 
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.ops4j.pax.exam</groupId>
-        <artifactId>maven-paxexam-plugin</artifactId>
-        <version>1.2.4</version>
-        <executions>
-          <execution>
-            <id>generate-config</id>
-            <goals>
-              <goal>generate-depends-file</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-           <groupId>org.jacoco</groupId>
-           <artifactId>jacoco-maven-plugin</artifactId>
-           <configuration>
-             <includes>org.opendaylight.controller.*</includes>
-           </configuration>
-           <executions>
-             <execution>
-               <id>pre-test</id>
-               <goals>
-                 <goal>prepare-agent</goal>
-               </goals>
-             </execution>
-             <execution>
-               <id>post-test</id>
-               <phase>test</phase>
-               <goals>
-                 <goal>report</goal>
-               </goals>
-             </execution>
-           </executions>
-     </plugin>
-    </plugins>
-    <pluginManagement>
-      <plugins>
-        <!--This plugin's configuration is used to store Eclipse m2e settings
-          only. It has no influence on the Maven build itself. -->
-        <plugin>
-          <groupId>org.eclipse.m2e</groupId>
-          <artifactId>lifecycle-mapping</artifactId>
-          <version>1.0.0</version>
-          <configuration>
-            <lifecycleMappingMetadata>
-              <pluginExecutions>
-                <pluginExecution>
-                  <pluginExecutionFilter>
-                    <groupId>
-                      org.ops4j.pax.exam
-                    </groupId>
-                    <artifactId>
-                      maven-paxexam-plugin
-                    </artifactId>
-                    <versionRange>
-                      [1.2.4,)
-                    </versionRange>
-                    <goals>
-                      <goal>
-                        generate-depends-file
-                      </goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore></ignore>
-                  </action>
-                </pluginExecution>
-              </pluginExecutions>
-            </lifecycleMappingMetadata>
-          </configuration>
-        </plugin>
-        <plugin>
-          <groupId>org.jacoco</groupId>
-          <artifactId>jacoco-maven-plugin</artifactId>
-          <version>${jacoco.version}</version>
-          <configuration>
-            <destFile>../sal-binding-broker/target/jacoco-it.exec</destFile>
-            <includes>org.opendaylight.controller.*</includes>
-          </configuration>
-          <executions>
-            <execution>
-              <id>pre-test</id>
-              <goals>
-                <goal>prepare-agent</goal>
-              </goals>
-            </execution>
-            <execution>
-              <id>post-test</id>
-              <configuration>
-                <skip>true</skip>
-              </configuration>
-            </execution>
-          </executions>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-  </build>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.ops4j.pax.exam</groupId>
+                <artifactId>maven-paxexam-plugin</artifactId>
+                <version>1.2.4</version>
+                <executions>
+                    <execution>
+                        <id>generate-config</id>
+                        <goals>
+                            <goal>generate-depends-file</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <configuration>
+                    <includes>org.opendaylight.controller.*</includes>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>pre-test</id>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>post-test</id>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <pluginManagement>
+            <plugins>
+                <!--This plugin's configuration is used to store Eclipse 
+                    m2e settings only. It has no influence on the Maven build itself. -->
+                <plugin>
+                    <groupId>org.eclipse.m2e</groupId>
+                    <artifactId>lifecycle-mapping</artifactId>
+                    <version>1.0.0</version>
+                    <configuration>
+                        <lifecycleMappingMetadata>
+                            <pluginExecutions>
+                                <pluginExecution>
+                                    <pluginExecutionFilter>
+                                        <groupId>
+                                            org.ops4j.pax.exam
+                                        </groupId>
+                                        <artifactId>
+                                            maven-paxexam-plugin
+                                        </artifactId>
+                                        <versionRange>
+                                            [1.2.4,)
+                                        </versionRange>
+                                        <goals>
+                                            <goal>
+                                                generate-depends-file
+                                            </goal>
+                                        </goals>
+                                    </pluginExecutionFilter>
+                                    <action>
+                                        <ignore></ignore>
+                                    </action>
+                                </pluginExecution>
+                            </pluginExecutions>
+                        </lifecycleMappingMetadata>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.jacoco</groupId>
+                    <artifactId>jacoco-maven-plugin</artifactId>
+                    <version>${jacoco.version}</version>
+                    <configuration>
+                        <destFile>../sal-binding-broker/target/jacoco-it.exec</destFile>
+                        <includes>org.opendaylight.controller.*</includes>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <id>pre-test</id>
+                            <goals>
+                                <goal>prepare-agent</goal>
+                            </goals>
+                        </execution>
+                        <execution>
+                            <id>post-test</id>
+                            <configuration>
+                                <skip>true</skip>
+                            </configuration>
+                        </execution>
+                    </executions>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
 
-  <dependencies>
-    <dependency>
-      <groupId>org.opendaylight.yangtools.thirdparty</groupId>
-      <artifactId>xtend-lib-osgi</artifactId>
-      <version>2.4.3</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-binding-broker-impl</artifactId>
-      <version>1.0-SNAPSHOT</version>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.ops4j.pax.exam</groupId>
-      <artifactId>pax-exam-container-native</artifactId>
-      <version>${exam.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.ops4j.pax.exam</groupId>
-      <artifactId>pax-exam-junit4</artifactId>
-      <version>${exam.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.ops4j.pax.exam</groupId>
-      <artifactId>pax-exam</artifactId>
-      <version>${exam.version}</version>
-      <!--  Compile scope here is intentional, it is used
-            in TestHelper class which could be downloaded
-            via nexus and reused in other integration tests.
-      -->
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.ops4j.pax.exam</groupId>
-      <artifactId>pax-exam-link-mvn</artifactId>
-      <version>${exam.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.osgi</artifactId>
-      <version>3.8.1.v20120830-144521</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>log4j-over-slf4j</artifactId>
-      <version>1.7.2</version>
-    </dependency>
-    <dependency>
-      <groupId>ch.qos.logback</groupId>
-      <artifactId>logback-core</artifactId>
-      <version>1.0.9</version>
-    </dependency>
-    <dependency>
-      <groupId>ch.qos.logback</groupId>
-      <artifactId>logback-classic</artifactId>
-      <version>1.0.9</version>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller.model</groupId>
-      <artifactId>model-flow-service</artifactId>
-      <version>1.0-SNAPSHOT</version>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>config-manager</artifactId>
-      <version>0.2.3-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller.model</groupId>
-      <artifactId>model-flow-management</artifactId>
-      <version>1.0-SNAPSHOT</version>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.yangtools.thirdparty</groupId>
+            <artifactId>xtend-lib-osgi</artifactId>
+            <version>2.4.3</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-broker-impl</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-container-native</artifactId>
+            <version>${exam.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-junit4</artifactId>
+            <version>${exam.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-netconf-connector</artifactId>
+            <version>${netconf.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>yang-store-impl</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>logback-config</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-persister-impl</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-persister-file-adapter</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+                <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>netconf-impl</artifactId>
+            <version>${netconf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>netconf-client</artifactId>
+            <version>${netconf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam</artifactId>
+            <version>${exam.version}</version>
+            <!-- Compile scope here is intentional, it is used in TestHelper 
+                class which could be downloaded via nexus and reused in other integration 
+                tests. -->
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-link-mvn</artifactId>
+            <version>${exam.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>equinoxSDK381</groupId>
+            <artifactId>org.eclipse.osgi</artifactId>
+            <version>3.8.1.v20120830-144521</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>log4j-over-slf4j</artifactId>
+            <version>1.7.2</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
+            <version>1.0.9</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>1.0.9</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-flow-service</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-manager</artifactId>
+            <version>0.2.3-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-flow-management</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.opendaylight.yangtools.thirdparty</groupId>
             <artifactId>antlr4-runtime-osgi-nohead</artifactId>
             <version>4.0</version>
-    </dependency>
-  </dependencies>
+        </dependency>
+    </dependencies>
 </project>
index 2f9c397632795d334799f32030be734fe38ae113..0eace4daaca15973e76e056cb1b923627dfd51b6 100644 (file)
@@ -4,9 +4,12 @@ import static org.ops4j.pax.exam.CoreOptions.frameworkProperty;
 import static org.ops4j.pax.exam.CoreOptions.junitBundles;
 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
 import static org.ops4j.pax.exam.CoreOptions.repository;
+import static org.ops4j.pax.exam.CoreOptions.repositories;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
 
 import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.options.DefaultCompositeOption;
+import org.ops4j.pax.exam.util.PathUtils;
 
 public class TestHelper {
 
@@ -15,62 +18,107 @@ public class TestHelper {
 
     public static final String CONTROLLER_MODELS = "org.opendaylight.controller.model";
     public static final String YANGTOOLS_MODELS = "org.opendaylight.yangtools.model";
+    private static final String OPENDAYLIGHT_SNAPSHOT = "http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/";
+    private static final String OPENDAYLIGHT_RELEASE = "http://nexus.opendaylight.org/content/repositories/opendaylight.release/";
 
     public static Option mdSalCoreBundles() {
         return new DefaultCompositeOption( //
-                mavenBundle(YANGTOOLS, "concepts").versionAsInProject(), //
-                mavenBundle(YANGTOOLS, "yang-binding").versionAsInProject(), //
-                mavenBundle(YANGTOOLS, "yang-common").versionAsInProject(), //
-                mavenBundle(CONTROLLER, "sal-common").versionAsInProject(), //
-                mavenBundle(CONTROLLER, "sal-common-api").versionAsInProject(), //
-                mavenBundle(CONTROLLER, "sal-common-impl").versionAsInProject(), //
-                
-                mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(),
-                mavenBundle("com.google.guava", "guava").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "concepts").versionAsInProject(), // //
+                mavenBundle(YANGTOOLS, "yang-binding").versionAsInProject(), // //
+                mavenBundle(YANGTOOLS, "yang-common").versionAsInProject(), // //
+                mavenBundle(CONTROLLER, "sal-common").versionAsInProject(), // //
+                mavenBundle(CONTROLLER, "sal-common-api").versionAsInProject(), // //
+                mavenBundle(CONTROLLER, "sal-common-impl").versionAsInProject(), // //
+
+                mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(), //
+                mavenBundle("com.google.guava", "guava").versionAsInProject(), // //
                 mavenBundle(YANGTOOLS + ".thirdparty", "xtend-lib-osgi").versionAsInProject() //
         );
     }
 
     public static Option configMinumumBundles() {
         return new DefaultCompositeOption(
-            mavenBundle(CONTROLLER, "config-api").versionAsInProject(), //
-            mavenBundle(CONTROLLER, "config-manager").versionAsInProject(), //
-            mavenBundle("commons-io", "commons-io").versionAsInProject()
-        );
+                mavenBundle("org.opendaylight.bgpcep", "framework").versionAsInProject(), //
+                mavenBundle("org.opendaylight.bgpcep", "util").versionAsInProject(), //
+                mavenBundle("commons-codec", "commons-codec").versionAsInProject(),
+                
+                mavenBundle(CONTROLLER, "config-api").versionAsInProject(), // //
+                mavenBundle(CONTROLLER, "config-manager").versionAsInProject(), // //
+                mavenBundle("commons-io", "commons-io").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "config-api").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "config-manager").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "config-util").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "yang-jmx-generator").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "yang-store-api").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "yang-store-impl").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "logback-config").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "config-persister-api").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "netconf-api").versionAsInProject(), //
+               
+                mavenBundle(CONTROLLER, "netconf-client").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "netconf-util").versionAsInProject(), //
+                mavenBundle(CONTROLLER + ".thirdparty", "ganymed", "1.0-SNAPSHOT"), //
+                mavenBundle(CONTROLLER, "netconf-mapping-api").versionAsInProject(), //
+
+                mavenBundle(CONTROLLER, "config-persister-impl").versionAsInProject(), //
+                
+                mavenBundle("io.netty", "netty-handler").versionAsInProject(), //
+                mavenBundle("io.netty", "netty-codec").versionAsInProject(), //
+                mavenBundle("io.netty", "netty-buffer").versionAsInProject(), //
+                mavenBundle("io.netty", "netty-transport").versionAsInProject(), //
+                mavenBundle("io.netty", "netty-common").versionAsInProject(), //
+                
+                mavenBundle("org.opendaylight.controller.thirdparty", "exificient", "0.9.2-SNAPSHOT"), //
+                
+                mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.xerces", "2.11.0_1"),
+                mavenBundle("org.eclipse.birt.runtime.3_7_1", "org.apache.xml.resolver", "1.2.0"),
+                
+                mavenBundle(CONTROLLER, "config-netconf-connector").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "netconf-impl").versionAsInProject(), //
+                
+                mavenBundle(CONTROLLER, "config-persister-file-adapter").versionAsInProject().noStart());
+            
     }
-    
+
     public static Option bindingAwareSalBundles() {
         return new DefaultCompositeOption( //
-                mavenBundle(CONTROLLER, "sal-binding-api").versionAsInProject(), //
-                mavenBundle(CONTROLLER, "sal-binding-config").versionAsInProject(),
-                mavenBundle(CONTROLLER, "sal-binding-broker-impl").versionAsInProject(), //
-                mavenBundle("org.javassist", "javassist").versionAsInProject(), //
-                mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), //
-        
-                mavenBundle(YANGTOOLS, "yang-data-api").versionAsInProject(), //
-                mavenBundle(YANGTOOLS, "yang-data-impl").versionAsInProject(), //
-                mavenBundle(YANGTOOLS, "yang-model-api").versionAsInProject(), //
-                mavenBundle(YANGTOOLS, "yang-model-util").versionAsInProject(), //
-                mavenBundle(YANGTOOLS, "yang-parser-api").versionAsInProject(),
-                mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
-                
-                
-                mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(), //
-                mavenBundle(YANGTOOLS, "binding-model-api").versionAsInProject(), //
-                mavenBundle(YANGTOOLS, "binding-generator-util").versionAsInProject(),
+                mavenBundle(CONTROLLER, "sal-binding-api").versionAsInProject(), // //
+                mavenBundle(CONTROLLER, "sal-binding-config").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "sal-binding-broker-impl").versionAsInProject(), // //
+                mavenBundle("org.javassist", "javassist").versionAsInProject(), // //
+                mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), // //
+
+                mavenBundle(YANGTOOLS, "yang-data-api").versionAsInProject(), // //
+                mavenBundle(YANGTOOLS, "yang-data-impl").versionAsInProject(), // //
+                mavenBundle(YANGTOOLS, "yang-model-api").versionAsInProject(), // //
+                mavenBundle(YANGTOOLS, "yang-model-util").versionAsInProject(), // //
+                mavenBundle(YANGTOOLS, "yang-parser-api").versionAsInProject(), //
                 mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
-                mavenBundle(YANGTOOLS, "binding-type-provider").versionAsInProject(),
-                mavenBundle(YANGTOOLS, "binding-generator-api").versionAsInProject(),
-                mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(),
+
+                mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(), // //
+                mavenBundle(YANGTOOLS, "binding-model-api").versionAsInProject(), // //
+                mavenBundle(YANGTOOLS, "binding-generator-util").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "binding-type-provider").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "binding-generator-api").versionAsInProject(), mavenBundle(YANGTOOLS,
+                        "binding-generator-spi").versionAsInProject(), //
                 mavenBundle(YANGTOOLS, "binding-generator-impl").versionAsInProject(),
-                
-                
+
                 mavenBundle(CONTROLLER, "sal-core-api").versionAsInProject().update(), //
-                mavenBundle(CONTROLLER, "sal-broker-impl").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "sal-broker-impl").versionAsInProject(), // //
                 mavenBundle(CONTROLLER, "sal-core-spi").versionAsInProject().update(), //
-                
-                mavenBundle(YANGTOOLS + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject() //
-       );
+
+                mavenBundle(YANGTOOLS + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), // //
+
+                systemProperty("netconf.tcp.address").value("0.0.0.0"), //
+                systemProperty("netconf.tcp.port").value("18383"), //
+                systemProperty("netconf.config.persister.storageAdapterClass").value(
+                        "org.opendaylight.controller.config.persist.storage.file.FileStorageAdapter"), //
+                systemProperty("fileStorage").value(PathUtils.getBaseDir() + "/src/test/resources/controller.config"), //
+                systemProperty("numberOfBackups").value("1") //
+                //systemProperty("yangstore.blacklist").value(".*controller.model.*") //
+
+        );
 
     }
 
@@ -83,8 +131,8 @@ public class TestHelper {
 
     public static Option flowCapableModelBundles() {
         return new DefaultCompositeOption( //
-                mavenBundle(CONTROLLER_MODELS, "model-flow-base").versionAsInProject(), //
-                mavenBundle(CONTROLLER_MODELS, "model-flow-service").versionAsInProject(), //
+                mavenBundle(CONTROLLER_MODELS, "model-flow-base").versionAsInProject(), // //
+                mavenBundle(CONTROLLER_MODELS, "model-flow-service").versionAsInProject(), // //
                 mavenBundle(CONTROLLER_MODELS, "model-inventory").versionAsInProject() //
         );
 
@@ -92,22 +140,18 @@ public class TestHelper {
 
     public static Option baseModelBundles() {
         return new DefaultCompositeOption( //
-                mavenBundle(YANGTOOLS_MODELS, "yang-ext").versionAsInProject(), //
-                mavenBundle(YANGTOOLS_MODELS, "ietf-inet-types").versionAsInProject(), //
-                mavenBundle(YANGTOOLS_MODELS, "ietf-yang-types").versionAsInProject(), //
-                mavenBundle(YANGTOOLS_MODELS, "opendaylight-l2-types").versionAsInProject(), //
+                mavenBundle(YANGTOOLS_MODELS, "yang-ext").versionAsInProject(), // //
+                mavenBundle(YANGTOOLS_MODELS, "ietf-inet-types").versionAsInProject(), // //
+                mavenBundle(YANGTOOLS_MODELS, "ietf-yang-types").versionAsInProject(), // //
+                mavenBundle(YANGTOOLS_MODELS, "opendaylight-l2-types").versionAsInProject(), // //
                 mavenBundle(CONTROLLER_MODELS, "model-inventory").versionAsInProject());
     }
 
     public static Option junitAndMockitoBundles() {
         return new DefaultCompositeOption(
-                // Repository required to load harmcrest (OSGi-fied version).
-                repository("http://repository.springsource.com/maven/bundles/external").id(
-                        "com.springsource.repository.bundles.external"),
-
-                // Mockito
-                mavenBundle("org.mockito", "mockito-all", "1.9.5"),
-                junitBundles(),
+        // Repository required to load harmcrest (OSGi-fied version).
+        // Mockito
+                mavenBundle("org.mockito", "mockito-all", "1.9.5"), junitBundles(),
 
                 /*
                  * Felix has implicit boot delegation enabled by default. It
index 41b1e310a06e6812d954cee64e7db3c895e8f996..338561ab48c950da06951c81bdccd033c25869ab 100644 (file)
@@ -11,6 +11,7 @@ import org.ops4j.pax.exam.Configuration;
 import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.junit.PaxExam;
 import org.ops4j.pax.exam.options.DefaultCompositeOption;
+import org.ops4j.pax.exam.util.Filter;
 import org.ops4j.pax.exam.util.PathUtils;
 import org.osgi.framework.BundleContext;
 
@@ -24,8 +25,9 @@ public abstract class AbstractTest {
     public static final String YANGTOOLS_MODELS = "org.opendaylight.yangtools.model";
 
     @Inject
+    @Filter(timeout=60*1000)
     BindingAwareBroker broker;
-
+    
     @Inject
     BundleContext bundleContext;
 
@@ -55,13 +57,14 @@ public abstract class AbstractTest {
                 mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(), //
                 mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(), //
                 mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(), //
+                systemProperty("osgi.bundles.defaultStartLevel").value("4"),
 
-                configMinumumBundles(),
+                
                 
                 mdSalCoreBundles(),
 
                 bindingAwareSalBundles(),
-
+                configMinumumBundles(),
                 // BASE Models
                 baseModelBundles(), flowCapableModelBundles(), junitAndMockitoBundles());
     }
diff --git a/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.config b/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.config
new file mode 100644 (file)
index 0000000..28c3bec
--- /dev/null
@@ -0,0 +1,123 @@
+//START OF CONFIG-LAST
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+<modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+       <module>
+               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</type>
+               <name>yang-schema-service</name>
+       </module>
+       <module>
+               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:hash-map-data-store</type>
+               <name>hash-map-data-store</name>
+       </module>
+       <module>
+               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
+               <name>dom-broker</name>
+               <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
+                       <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
+                       <name>ref_hash-map-data-store</name>
+               </data-store>
+       </module>
+       <module>
+               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
+               <name>binding-broker-impl</name>
+               <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                       <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+                       <name>ref_binding-notification-broker</name>
+               </notification-service>
+               <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                       <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+                       <name>ref_binding-data-broker</name>
+               </data-broker>
+       </module>
+       <module>
+               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
+               <name>runtime-mapping-singleton</name>
+       </module>
+       <module>
+               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
+               <name>binding-notification-broker</name>
+       </module>
+       <module>
+               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-broker</type>
+               <name>binding-data-broker</name>
+               <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                       <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+                       <name>ref_dom-broker</name>
+               </dom-broker>
+               <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
+               <name>ref_runtime-mapping-singleton</name>
+               </mapping-service>
+       </module>
+</modules>
+<services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+       <service>
+       <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+               <instance>
+               <name>ref_yang-schema-service</name>
+               <provider>/config/modules/module[name='schema-service-singleton']/instance[name='yang-schema-service']</provider>
+               </instance>
+       </service>
+       <service>
+               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+               <instance>
+                       <name>ref_binding-notification-broker</name>
+                       <provider>/config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker']</provider>
+               </instance>
+       </service>
+       <service>
+               <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
+               <instance>
+                       <name>ref_hash-map-data-store</name>
+                       <provider>/config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store']</provider>
+               </instance>
+       </service>
+       <service>
+               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
+               <instance>
+                       <name>ref_binding-broker-impl</name>
+                       <provider>/config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl']</provider>
+               </instance>
+       </service>
+       <service>
+               <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
+               <instance>
+                       <name>ref_runtime-mapping-singleton</name>
+                       <provider>/config/modules/module[name='runtime-generated-mapping']/instance[name='runtime-mapping-singleton']</provider>
+               </instance>
+       </service>
+       <service>
+       <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+               <instance>
+                       <name>ref_dom-broker</name>
+                       <provider>/config/modules/module[name='dom-broker-impl']/instance[name='dom-broker']</provider>
+               </instance>
+       </service>
+       <service>
+               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+               <instance>
+               <name>ref_binding-data-broker</name>
+               <provider>/config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker']</provider>
+       </instance>
+       </service>
+</services>
+</data>
+
+
+//END OF SNAPSHOT
+urn:opendaylight:l2:types?module=opendaylight-l2-types&revision=2013-08-27
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05
+urn:ietf:params:netconf:capability:candidate:1.0
+urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04
+urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&revision=2013-06-17
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28
+urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2010-09-24
+urn:ietf:params:netconf:capability:rollback-on-error:1.0
+urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&revision=2010-09-24
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:logback:config?module=config-logging&revision=2013-07-16
+urn:opendaylight:yang:extension:yang-ext?module=yang-ext&revision=2013-07-09
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28
+//END OF CONFIG
index 2d63ce57448f88b77a39b1bcb0525b9721c08370..1d177963738d49d7f7f6224545bfabea32d01341 100644 (file)
@@ -7,7 +7,10 @@
     </encoder>
   </appender>
 
-  <root level="error">
+
+  <logger name="org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort" level="ERROR"/>
+
+  <root level="info">
     <appender-ref ref="STDOUT" />
   </root>
 </configuration>
diff --git a/opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/RegistrationListener.java b/opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/RegistrationListener.java
new file mode 100644 (file)
index 0000000..f6efd57
--- /dev/null
@@ -0,0 +1,12 @@
+package org.opendaylight.controller.md.sal.common.api;
+
+import java.util.EventListener;
+
+import org.opendaylight.yangtools.concepts.Registration;
+
+public interface RegistrationListener<T extends Registration<?>> extends EventListener {
+
+    void onRegister(T registration);
+    
+    void onUnregister(T registration);
+}
index 144a81b2566f549c56e7cbb00bb0e9567db644f2..d62e176e62d1beeb22c934f7c82aa3a713909b91 100644 (file)
@@ -11,15 +11,31 @@ import org.opendaylight.yangtools.concepts.Immutable;
 
 public interface DataChangeEvent<P,D> extends DataChange<P, D>, Immutable {
 
+    /**
+     * Returns a orignal subtree of data, which starts at the path
+     * where listener was registered.
+     * 
+     */
+    D getOriginalConfigurationSubtree();
+
     /**
      * Returns a new subtree of data, which starts at the path
      * where listener was registered.
      * 
      */
+    D getOriginalOperationalSubtree();
+    
+    
+    
+    /**
+     * Returns a updated subtree of data, which starts at the path
+     * where listener was registered.
+     * 
+     */
     D getUpdatedConfigurationSubtree();
 
     /**
-     * Returns a new subtree of data, which starts at the path
+     * Returns a udpated subtree of data, which starts at the path
      * where listener was registered.
      * 
      */
diff --git a/opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataCommitHandlerRegistration.java b/opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataCommitHandlerRegistration.java
new file mode 100644 (file)
index 0000000..85db5a0
--- /dev/null
@@ -0,0 +1,9 @@
+package org.opendaylight.controller.md.sal.common.api.data;
+
+import org.opendaylight.yangtools.concepts.Path;
+import org.opendaylight.yangtools.concepts.Registration;
+
+public interface DataCommitHandlerRegistration<P extends Path<P>,D> extends Registration<DataCommitHandler<P, D>>{
+
+    P getPath();
+}
index 264d076b69be8074e443a0052e28eafbbfbe8f61..7d78fd283d169d16cc11510d4b68750ecb5c5733 100644 (file)
@@ -7,13 +7,17 @@
  */
 package org.opendaylight.controller.md.sal.common.api.data;
 
-// FIXME: After 0.6 Release of YANGTools refactor to use Path marker interface for arguments.
-// import org.opendaylight.yangtools.concepts.Path;
+import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Path;
 import org.opendaylight.yangtools.concepts.Registration;
 
 
-public interface DataProvisionService<P/* extends Path<P> */, D> {
+public interface DataProvisionService<P extends Path<P> , D> {
 
     public Registration<DataCommitHandler<P, D>> registerCommitHandler(P path, DataCommitHandler<P, D> commitHandler);
+    
+    public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<P, D>>> 
+        registerCommitHandlerListener(RegistrationListener<DataCommitHandlerRegistration<P, D>> commitHandlerListener);
 
 }
index c9e1d6e330e38324f21e26b510cb548f5298a562..bee863321fdb1055887c35ff4a3c72e68939ca7e 100644 (file)
@@ -179,7 +179,7 @@ public abstract class AbstractDataModification<P /* extends Path<P> */, D> imple
         if (operationalOriginal.containsKey(path)) {
             return true;
         }
-        D data = reader.readConfigurationData(path);
+        D data = reader.readOperationalData(path);
         if (data != null) {
             operationalOriginal.putIfAbsent(path, data);
             return true;
index 74c4e0a148640a2278deee8a87bf67c4c27eb334..a18e5a9c824a675af339d93e02d770e4ccbaf285 100644 (file)
@@ -34,12 +34,19 @@ import java.util.Collection
 import com.google.common.collect.FluentIterable;
 import java.util.Set
 import com.google.common.collect.ImmutableList
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration
+import org.opendaylight.controller.md.sal.common.api.RegistrationListener
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry
+import java.util.concurrent.atomic.AtomicLong
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent
 
 abstract class AbstractDataBroker<P extends Path<P>, D, DCL extends DataChangeListener<P, D>> implements DataModificationTransactionFactory<P, D>, //
 DataReader<P, D>, //
 DataChangePublisher<P, D, DCL>, //
 DataProvisionService<P, D> {
 
+    private static val LOG = LoggerFactory.getLogger(AbstractDataBroker);
+
     @Property
     var ExecutorService executor;
 
@@ -47,17 +54,17 @@ DataProvisionService<P, D> {
     var AbstractDataReadRouter<P, D> dataReadRouter;
 
     Multimap<P, DataChangeListenerRegistration<P, D, DCL>> listeners = HashMultimap.create();
-    Multimap<P, DataCommitHandlerRegistration<P, D>> commitHandlers = HashMultimap.create();
-
+    Multimap<P, DataCommitHandlerRegistrationImpl<P, D>> commitHandlers = HashMultimap.create();
+    
+    val ListenerRegistry<RegistrationListener<DataCommitHandlerRegistration<P,D>>> commitHandlerRegistrationListeners = new ListenerRegistry();
     public new() {
     }
 
     protected def /*Iterator<Entry<Collection<DataChangeListenerRegistration<P,D,DCL>>,D>>*/ affectedCommitHandlers(
         HashSet<P> paths) {
-        return FluentIterable.from(commitHandlers.asMap.entrySet)
-            .filter[key.isAffectedBy(paths)] //
-            .transformAndConcat [value] //
-            .transform[instance].toList()
+        return FluentIterable.from(commitHandlers.asMap.entrySet).filter[key.isAffectedBy(paths)] //
+        .transformAndConcat[value] //
+        .transform[instance].toList()
     }
 
     override final readConfigurationData(P path) {
@@ -69,14 +76,26 @@ DataProvisionService<P, D> {
     }
 
     override final registerCommitHandler(P path, DataCommitHandler<P, D> commitHandler) {
-        val registration = new DataCommitHandlerRegistration(path, commitHandler, this);
+        val registration = new DataCommitHandlerRegistrationImpl(path, commitHandler, this);
         commitHandlers.put(path, registration)
+        LOG.info("Registering Commit Handler {} for path: {}",commitHandler,path);
+        for(listener : commitHandlerRegistrationListeners) {
+            try {
+                listener.instance.onRegister(registration);
+            } catch (Exception e) {
+                LOG.error("Unexpected exception in listener {} during invoking onRegister",listener.instance,e);
+            }
+        }
         return registration;
     }
 
     override final def registerDataChangeListener(P path, DCL listener) {
         val reg = new DataChangeListenerRegistration(path, listener, this);
         listeners.put(path, reg);
+        val initialConfig = dataReadRouter.readConfigurationData(path);
+        val initialOperational = dataReadRouter.readOperationalData(path);
+        val event = createInitialListenerEvent(path,initialConfig,initialOperational);
+        listener.onDataChanged(event);
         return reg;
     }
 
@@ -87,13 +106,33 @@ DataProvisionService<P, D> {
 
         return new CompositeObjectRegistration(reader, Arrays.asList(confReg, dataReg));
     }
+    
+    override registerCommitHandlerListener(RegistrationListener<DataCommitHandlerRegistration<P, D>> commitHandlerListener) {
+        val ret = commitHandlerRegistrationListeners.register(commitHandlerListener);
+        
+        return ret;
+    }
+    
+    protected  def DataChangeEvent<P,D> createInitialListenerEvent(P path,D initialConfig,D initialOperational) {
+        return new InitialDataChangeEventImpl<P, D>(initialConfig,initialOperational);
+        
+    }
 
     protected final def removeListener(DataChangeListenerRegistration<P, D, DCL> registration) {
         listeners.remove(registration.path, registration);
     }
 
-    protected final def removeCommitHandler(DataCommitHandlerRegistration<P, D> registration) {
+    protected final def removeCommitHandler(DataCommitHandlerRegistrationImpl<P, D> registration) {
         commitHandlers.remove(registration.path, registration);
+        
+         LOG.info("Removing Commit Handler {} for path: {}",registration.instance,registration.path);
+        for(listener : commitHandlerRegistrationListeners) {
+            try {
+                listener.instance.onUnregister(registration);
+            } catch (Exception e) {
+                LOG.error("Unexpected exception in listener {} during invoking onUnregister",listener.instance,e);
+            }
+        }
     }
 
     protected final def getActiveCommitHandlers() {
@@ -132,7 +171,7 @@ DataProvisionService<P, D> {
 }
 
 @Data
-package class ListenerStateCapture<P extends Path<P>, D,DCL extends DataChangeListener<P, D>> {
+package class ListenerStateCapture<P extends Path<P>, D, DCL extends DataChangeListener<P, D>> {
 
     @Property
     P path;
@@ -167,7 +206,9 @@ package class DataChangeListenerRegistration<P extends Path<P>, D, DCL extends D
 
 }
 
-package class DataCommitHandlerRegistration<P extends Path<P>, D> extends AbstractObjectRegistration<DataCommitHandler<P, D>> {
+package class DataCommitHandlerRegistrationImpl<P extends Path<P>, D> //
+extends AbstractObjectRegistration<DataCommitHandler<P, D>> //
+implements DataCommitHandlerRegistration<P, D> {
 
     AbstractDataBroker<P, D, ?> dataBroker;
 
@@ -184,10 +225,9 @@ package class DataCommitHandlerRegistration<P extends Path<P>, D> extends Abstra
         dataBroker.removeCommitHandler(this);
         dataBroker = null;
     }
-
 }
 
-package class TwoPhaseCommit<P extends Path<P>, D,DCL extends DataChangeListener<P, D>> implements Callable<RpcResult<TransactionStatus>> {
+package class TwoPhaseCommit<P extends Path<P>, D, DCL extends DataChangeListener<P, D>> implements Callable<RpcResult<TransactionStatus>> {
 
     private static val log = LoggerFactory.getLogger(TwoPhaseCommit);
 
@@ -214,15 +254,18 @@ package class TwoPhaseCommit<P extends Path<P>, D,DCL extends DataChangeListener
 
         val listeners = dataBroker.affectedListenersWithInitialState(affectedPaths);
 
+        val transactionId = transaction.identifier;
+
+        log.info("Transaction: {} Started.",transactionId);
         // requesting commits
-        val Iterable<DataCommitHandler<P, D>> commitHandlers =   dataBroker.affectedCommitHandlers(affectedPaths);
+        val Iterable<DataCommitHandler<P, D>> commitHandlers = dataBroker.affectedCommitHandlers(affectedPaths);
         val List<DataCommitTransaction<P, D>> handlerTransactions = new ArrayList();
         try {
             for (handler : commitHandlers) {
                 handlerTransactions.add(handler.requestCommit(transaction));
             }
         } catch (Exception e) {
-            log.error("Request Commit failded", e);
+            log.error("Transaction: {} Request Commit failed", transactionId,e);
             return rollback(handlerTransactions, e);
         }
         val List<RpcResult<Void>> results = new ArrayList();
@@ -232,25 +275,25 @@ package class TwoPhaseCommit<P extends Path<P>, D,DCL extends DataChangeListener
             }
             listeners.publishDataChangeEvent();
         } catch (Exception e) {
-            log.error("Finish Commit failed", e);
+            log.error("Transaction: {} Finish Commit failed",transactionId, e);
             return rollback(handlerTransactions, e);
         }
-
-        
+        log.info("Transaction: {} Finished succesfully.",transactionId);
         return Rpcs.getRpcResult(true, TransactionStatus.COMMITED, Collections.emptySet());
 
     }
-    
-    def void publishDataChangeEvent(ImmutableList<ListenerStateCapture<P, D,DCL>> listeners) {
-        for(listenerSet : listeners) {
+
+    def void publishDataChangeEvent(ImmutableList<ListenerStateCapture<P, D, DCL>> listeners) {
+        for (listenerSet : listeners) {
             val updatedConfiguration = dataBroker.readConfigurationData(listenerSet.path);
             val updatedOperational = dataBroker.readOperationalData(listenerSet.path);
-            
-            val changeEvent = new DataChangeEventImpl(transaction,listenerSet.initialConfigurationState,listenerSet.initialOperationalState,updatedOperational,updatedConfiguration);
-            for(listener : listenerSet.listeners) {
+
+            val changeEvent = new DataChangeEventImpl(transaction, listenerSet.initialConfigurationState,
+                listenerSet.initialOperationalState, updatedOperational, updatedConfiguration);
+            for (listener : listenerSet.listeners) {
                 try {
                     listener.instance.onDataChanged(changeEvent);
-                    
+
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
@@ -267,6 +310,7 @@ package class TwoPhaseCommit<P extends Path<P>, D,DCL extends DataChangeListener
         return Rpcs.getRpcResult(false, TransactionStatus.FAILED, Collections.emptySet());
     }
 }
+
 public abstract class AbstractDataTransaction<P extends Path<P>, D> extends AbstractDataModification<P, D> {
 
     @Property
@@ -276,9 +320,9 @@ public abstract class AbstractDataTransaction<P extends Path<P>, D> extends Abst
 
     var AbstractDataBroker<P, D, ?> broker;
 
-    protected new(AbstractDataBroker<P, D, ?> dataBroker) {
+    protected new(Object identifier,AbstractDataBroker<P, D, ?> dataBroker) {
         super(dataBroker);
-        _identifier = new Object();
+        _identifier = identifier;
         broker = dataBroker;
         status = TransactionStatus.NEW;
 
index 4eb9586fdf94a8b1a1ffa8388f7a699d3fbd60b1..68f9506c56425e29ad91e6b2c42a1fd9059542f1 100644 (file)
@@ -11,6 +11,8 @@ public class DataChangeEventImpl<P, D> implements DataChangeEvent<P, D> {
     private final DataChange<P, D> dataChange;
 
     private final D originalConfigurationSubtree;
+
+
     private final D originalOperationalSubtree;
     private final D updatedOperationalSubtree;
     private final D updatedConfigurationSubtree;
@@ -28,6 +30,16 @@ public class DataChangeEventImpl<P, D> implements DataChangeEvent<P, D> {
         this.updatedConfigurationSubtree = updatedConfigurationSubtree;
     }
 
+    @Override
+    public D getOriginalConfigurationSubtree() {
+        return originalConfigurationSubtree;
+    }
+
+    @Override
+    public D getOriginalOperationalSubtree() {
+        return originalOperationalSubtree;
+    }
+
     @Override
     public D getUpdatedOperationalSubtree() {
         return updatedOperationalSubtree;
diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/InitialDataChangeEventImpl.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/InitialDataChangeEventImpl.java
new file mode 100644 (file)
index 0000000..2764635
--- /dev/null
@@ -0,0 +1,75 @@
+package org.opendaylight.controller.md.sal.common.impl.service;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+
+public class InitialDataChangeEventImpl<P,D> implements DataChangeEvent<P, D> {
+
+    private final D originalOperationalTree;
+    private final D originalConfigurationTree;
+
+    public InitialDataChangeEventImpl(D configTree, D operTree) {
+        originalConfigurationTree = configTree;
+        originalOperationalTree = operTree;
+    }
+    
+    @Override
+    public Map<P, D> getCreatedConfigurationData() {
+        return Collections.emptyMap();
+    }
+    
+    @Override
+    public Map<P, D> getCreatedOperationalData() {
+        return Collections.emptyMap();
+    }
+    
+    @Override
+    public Map<P, D> getOriginalConfigurationData() {
+        return Collections.emptyMap();
+    }
+    @Override
+    public Map<P, D> getOriginalOperationalData() {
+        return Collections.emptyMap();
+    }
+    @Override
+    public Set<P> getRemovedConfigurationData() {
+        return Collections.emptySet();
+    }
+    @Override
+    public Set<P> getRemovedOperationalData() {
+        return Collections.emptySet();
+    }
+    @Override
+    public Map<P, D> getUpdatedConfigurationData() {
+        return Collections.emptyMap();
+    }
+    
+    @Override
+    public D getUpdatedConfigurationSubtree() {
+        return originalConfigurationTree;
+    }
+    @Override
+    public D getUpdatedOperationalSubtree() {
+        return originalOperationalTree;
+    }
+    
+    @Override
+    public D getOriginalConfigurationSubtree() {
+        return originalConfigurationTree;
+    }
+    
+    @Override
+    public D getOriginalOperationalSubtree() {
+        return originalOperationalTree;
+    }
+    
+    @Override
+    public Map<P, D> getUpdatedOperationalData() {
+        return Collections.emptyMap();
+    }
+    
+
+}
diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/AbstractLockableDelegator.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/AbstractLockableDelegator.java
new file mode 100644 (file)
index 0000000..61abe66
--- /dev/null
@@ -0,0 +1,76 @@
+package org.opendaylight.controller.md.sal.common.impl.util;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
+
+import org.opendaylight.yangtools.concepts.Delegator;
+
+import com.google.common.base.Preconditions;
+
+public class AbstractLockableDelegator<T> implements Delegator<T> {
+
+    private final ReentrantReadWriteLock delegateLock = new ReentrantReadWriteLock();
+    private final ReadLock delegateReadLock = delegateLock.readLock();
+    private final WriteLock delegateWriteLock = delegateLock.writeLock();
+    
+    
+    protected Lock getDelegateReadLock() {
+        return delegateReadLock;
+    }
+
+    private T delegate;
+
+    public AbstractLockableDelegator() {
+        // NOOP
+    }
+
+    public AbstractLockableDelegator(T initialDelegate) {
+        delegate = initialDelegate;
+    }
+
+    @Override
+    public T getDelegate() {
+        try {
+            delegateReadLock.lock();
+            return delegate;
+        } finally {
+            delegateReadLock.unlock();
+        }
+    }
+
+    public T retrieveDelegate() {
+        try {
+            delegateReadLock.lock();
+            Preconditions.checkState(delegate != null,"Delegate is null");
+            return delegate;
+        } finally {
+            delegateReadLock.unlock();
+        }
+    }
+
+    /**
+     * 
+     * @param newDelegate
+     * @return oldDelegate
+     */
+    public final T changeDelegate(T newDelegate) {
+        try {
+            delegateWriteLock.lock();
+            T oldDelegate = delegate;
+            delegate = newDelegate;
+            onDelegateChanged(oldDelegate, newDelegate);
+            return oldDelegate;
+        } finally {
+            delegateWriteLock.unlock();
+        }
+    }
+    
+    
+    protected void onDelegateChanged(T oldDelegate, T newDelegate) {
+        // NOOP in abstract calss;
+    }
+}
index ca923f6baa2a8327152bd40890bb3d17c4ec93e3..e52a7c302dc0aa378310a68874c37904e3698fdd 100644 (file)
@@ -8,11 +8,73 @@
     </parent>
     <artifactId>sal-core-api</artifactId>
     <scm>
-      <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
-      <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
-      <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+        <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
     </scm>
-
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+            </plugin>
+            <plugin>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-maven-plugin</artifactId>
+                <version>0.5.9-SNAPSHOT</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate-sources</goal>
+                        </goals>
+                        <configuration>
+                            <codeGenerators>
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+                                    </codeGeneratorClass>
+                                    <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+                                    <additionalConfiguration>
+                                        <namespaceToPackage1>
+                                            urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
+                                        </namespaceToPackage1>
+                                    </additionalConfiguration>
+                                </generator>
+                            </codeGenerators>
+                            <inspectDependencies>true</inspectDependencies>
+                        </configuration>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.opendaylight.controller</groupId>
+                        <artifactId>yang-jmx-generator-plugin</artifactId>
+                        <version>0.2.3-SNAPSHOT</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>1.8</version>
+                <executions>
+                    <execution>
+                        <id>add-source</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>${project.build.directory}/generated-sources/config</source>
+                            </sources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
     <dependencies>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
 
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-api</artifactId>
+            <version>0.2.3-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-data-api</artifactId>
-            <version>0.5.9-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataStore.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataStore.java
new file mode 100644 (file)
index 0000000..87129d6
--- /dev/null
@@ -0,0 +1,19 @@
+package org.opendaylight.controller.sal.core.api.data;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public interface DataStore extends //
+    DataReader<InstanceIdentifier, CompositeNode>,
+    DataCommitHandler<InstanceIdentifier, CompositeNode> {
+    
+    
+    Iterable<InstanceIdentifier> getStoredConfigurationPaths();
+    Iterable<InstanceIdentifier> getStoredOperationalPaths();
+    
+    boolean containsConfigurationPath(InstanceIdentifier path);
+    boolean containsOperationalPath(InstanceIdentifier path);
+
+}
diff --git a/opendaylight/md-sal/sal-dom-api/src/main/yang/opendaylight-md-sal-common.yang b/opendaylight/md-sal/sal-dom-api/src/main/yang/opendaylight-md-sal-common.yang
new file mode 100644 (file)
index 0000000..004574d
--- /dev/null
@@ -0,0 +1,68 @@
+module opendaylight-md-sal-common {
+       yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:common";
+    prefix "md-sal-common";
+    
+    description
+        "Common definition for MD-SAL.";
+    revision "2013-10-28" {
+        description
+            "Initial revision";
+    }
+    
+    grouping rpc-routing-table {
+        
+        leaf routing-context {
+            type string;
+        }
+        list routes {
+            leaf path {
+                type string;
+            }
+            leaf destination {
+                type string;
+            }
+        }
+    
+    }
+
+    grouping rpc-router {
+        leaf module {
+            type string;
+        }
+        container routing-tables {
+            list routing-table {
+                uses rpc-routing-table;
+            }
+        }
+    }
+    
+    grouping rpc-state {
+        list rpc-router {
+            uses rpc-router;
+        }
+    }
+    
+    grouping notification-state {
+        container notifications {
+            leaf published {
+                type uint32;
+            }
+        }
+    }
+    
+    grouping data-state {
+        container transactions {
+            leaf created {
+                type uint32;
+            }
+            leaf successful {
+                type uint32;
+            }
+            leaf failed {
+                type uint32;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-dom-api/src/main/yang/opendaylight-md-sal-dom.yang b/opendaylight/md-sal/sal-dom-api/src/main/yang/opendaylight-md-sal-dom.yang
new file mode 100644 (file)
index 0000000..b0417eb
--- /dev/null
@@ -0,0 +1,35 @@
+module opendaylight-md-sal-dom {
+       yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom";
+    prefix "md-sal-dom";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    description
+        "Service definition for Binding Aware MD-SAL.";
+    revision "2013-10-28" {
+        description
+            "Initial revision";
+    }
+
+    identity dom-broker-osgi-registry {
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.sal.core.api.Broker";
+    }
+
+    identity dom-data-broker {
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.sal.core.api.data.DataProviderService";
+    }
+
+    identity dom-data-store {
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.sal.core.api.data.DataStore";
+    }
+    
+    identity schema-service {
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.sal.core.api.model.SchemaService";
+    }
+}
\ No newline at end of file
index 62dbe16e4135de42001f6fde721799128b8dbebd..14ab0573989887d2431f9d2262c2dbee8e6a215b 100644 (file)
 
     <build>
         <plugins>
+            <plugin>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-maven-plugin</artifactId>
+                <version>0.5.9-SNAPSHOT</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate-sources</goal>
+                        </goals>
+                        <configuration>
+                            <codeGenerators>
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+                                    </codeGeneratorClass>
+                                    <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+                                    <additionalConfiguration>
+                                        <namespaceToPackage1>
+                                            urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
+                                        </namespaceToPackage1>
+                                    </additionalConfiguration>
+                                </generator>
+                            </codeGenerators>
+                            <inspectDependencies>true</inspectDependencies>
+                        </configuration>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.opendaylight.controller</groupId>
+                        <artifactId>yang-jmx-generator-plugin</artifactId>
+                        <version>0.2.3-SNAPSHOT</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            
+            
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
                 <configuration>
                     <instructions>
                         <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
-                        <Bundle-Activator>org.opendaylight.controller.sal.dom.broker.BrokerActivator</Bundle-Activator>
                         <Private-Package>
-                            org.opendaylight.controller.sal.dom.broker.*
+                            org.opendaylight.controller.sal.dom.broker.*,
+                            org.opendaylight.controller.config.yang.md.sal.dom.impl
                         </Private-Package>
                     </instructions>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>1.8</version>
+                <executions>
+                    <execution>
+                        <id>add-source</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>${project.build.directory}/generated-sources/config</source>
+                            </sources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
             <plugin>
                 <groupId>org.eclipse.xtend</groupId>
                 <artifactId>xtend-maven-plugin</artifactId>
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomBrokerImplModule.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomBrokerImplModule.java
new file mode 100644 (file)
index 0000000..050966f
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-dom-broker-impl  yang module local name: dom-broker-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:04:41 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.dom.impl;
+
+import org.opendaylight.controller.sal.core.api.data.DataStore;
+import org.opendaylight.controller.sal.dom.broker.BrokerConfigActivator;
+import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
+import org.osgi.framework.BundleContext;
+import static com.google.common.base.Preconditions.*;
+
+/**
+*
+*/
+public final class DomBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractDomBrokerImplModule
+{
+
+    private BundleContext bundleContext;
+
+    public DomBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public DomBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, DomBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void validate(){
+        super.validate();
+        checkArgument(getDataStore() != null, "Data Store needs to be provided for DomBroker");
+    }
+    
+    
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        BrokerImpl broker = new BrokerImpl();
+        BrokerConfigActivator activator = new BrokerConfigActivator();
+        DataStore store = getDataStoreDependency();
+        activator.start(broker, store,getBundleContext());
+        return broker;
+    }
+
+    private BundleContext getBundleContext() {
+        return this.bundleContext;
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomBrokerImplModuleFactory.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomBrokerImplModuleFactory.java
new file mode 100644 (file)
index 0000000..8e9e9f6
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * Generated file
+
+ * Generated from: yang module name: opendaylight-sal-dom-broker-impl  yang module local name: dom-broker-impl
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 20 17:04:41 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.md.sal.dom.impl;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
+/**
+*
+*/
+public class DomBrokerImplModuleFactory extends
+        org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractDomBrokerImplModuleFactory {
+
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
+        DomBrokerImplModule module = (DomBrokerImplModule) super.createModule(instanceName, dependencyResolver, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
+
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver,
+            DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
+        DomBrokerImplModule module = (DomBrokerImplModule) super.createModule(instanceName, dependencyResolver, old, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/HashMapDataStoreModule.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/HashMapDataStoreModule.java
new file mode 100644 (file)
index 0000000..4bcbb08
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-dom-broker-impl  yang module local name: hash-map-data-store
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:01:31 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.dom.impl;
+
+import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
+
+/**
+*
+*/
+public final class HashMapDataStoreModule extends org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractHashMapDataStoreModule
+{
+
+    public HashMapDataStoreModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public HashMapDataStoreModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, HashMapDataStoreModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void validate(){
+        super.validate();
+        // Add custom validation for module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        HashMapDataStore store = new HashMapDataStore();
+        return store;
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/HashMapDataStoreModuleFactory.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/HashMapDataStoreModuleFactory.java
new file mode 100644 (file)
index 0000000..b9b6816
--- /dev/null
@@ -0,0 +1,19 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-dom-broker-impl  yang module local name: hash-map-data-store
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:01:31 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.dom.impl;
+
+/**
+*
+*/
+public class HashMapDataStoreModuleFactory extends org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractHashMapDataStoreModuleFactory
+{
+
+
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java
new file mode 100644 (file)
index 0000000..6b597de
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-dom-broker-impl  yang module local name: schema-service-singleton
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:01:31 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.dom.impl;
+
+import org.opendaylight.controller.sal.dom.broker.SchemaServiceImpl;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.osgi.framework.BundleContext;
+
+/**
+*
+*/
+public final class SchemaServiceImplSingletonModule extends org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractSchemaServiceImplSingletonModule
+{
+
+    BundleContext bundleContext;
+    
+    public SchemaServiceImplSingletonModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public SchemaServiceImplSingletonModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, SchemaServiceImplSingletonModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+    
+    @Override
+    public boolean canReuseInstance(AbstractSchemaServiceImplSingletonModule oldModule) {
+        return true;
+    }
+
+    public BundleContext getBundleContext() {
+        return bundleContext;
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+
+    @Override
+    public void validate(){
+        super.validate();
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        SchemaServiceImpl newInstance = new SchemaServiceImpl();
+        newInstance.setContext(getBundleContext());
+        newInstance.setParser(new YangParserImpl());
+        newInstance.start();
+        return newInstance;
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModuleFactory.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModuleFactory.java
new file mode 100644 (file)
index 0000000..4b73656
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * Generated file
+
+ * Generated from: yang module name: opendaylight-sal-dom-broker-impl  yang module local name: schema-service-singleton
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 20 17:01:31 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.md.sal.dom.impl;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DependencyResolverFactory;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
+/**
+*
+*/
+public class SchemaServiceImplSingletonModuleFactory extends
+        org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractSchemaServiceImplSingletonModuleFactory {
+
+    private static final ModuleIdentifier IDENTIFIER = new ModuleIdentifier(NAME, "yang-schema-service");
+    public static SchemaServiceImplSingletonModule SINGLETON;
+
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
+        throw new UnsupportedOperationException("Only default instance supported.");
+    }
+
+    @Override
+    public Set<SchemaServiceImplSingletonModule> getDefaultModules(DependencyResolverFactory dependencyResolverFactory,
+            BundleContext bundleContext) {
+        DependencyResolver dependencyResolver = dependencyResolverFactory.createDependencyResolver(IDENTIFIER);
+
+        if (SINGLETON == null) {
+            SINGLETON = new SchemaServiceImplSingletonModule(IDENTIFIER, dependencyResolver);
+            SINGLETON.setBundleContext(bundleContext);
+        }
+        return Collections.singleton(SINGLETON);
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerActivator.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerActivator.java
deleted file mode 100644 (file)
index 3af645a..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-package org.opendaylight.controller.sal.dom.broker;
-
-import java.util.Hashtable;
-
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.core.api.data.DataProviderService;
-import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
-import org.opendaylight.controller.sal.core.api.mount.MountService;
-import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-
-public class BrokerActivator implements BundleActivator {
-
-    private static final InstanceIdentifier ROOT = InstanceIdentifier.builder().toInstance();
-    BrokerImpl broker;
-    private ServiceRegistration<Broker> brokerReg;
-    private ServiceRegistration<SchemaService> schemaReg;
-    private ServiceRegistration<DataBrokerService> dataReg;
-    private ServiceRegistration<DataProviderService> dataProviderReg;
-    private SchemaServiceImpl schemaService;
-    private DataBrokerImpl dataService;
-    private MountPointManagerImpl mountService;
-    private ServiceRegistration<MountService> mountReg;
-    private ServiceRegistration<MountProvisionService> mountProviderReg;
-    private HashMapDataStore hashMapStore;
-
-    @Override
-    public void start(BundleContext context) throws Exception {
-        Hashtable<String, String> emptyProperties = new Hashtable<String, String>();
-        broker = new BrokerImpl();
-        broker.setBundleContext(context);
-        
-
-        schemaService = new SchemaServiceImpl();
-        schemaService.setContext(context);
-        schemaService.setParser(new YangParserImpl());
-        schemaService.start();
-        schemaReg = context.registerService(SchemaService.class, schemaService, new Hashtable<String, String>());
-        
-        dataService = new DataBrokerImpl();
-        dataService.setExecutor(broker.getExecutor());
-        
-        dataReg = context.registerService(DataBrokerService.class, dataService, emptyProperties);
-        dataProviderReg = context.registerService(DataProviderService.class, dataService, emptyProperties);
-        
-        hashMapStore = new HashMapDataStore();
-        
-        dataService.registerConfigurationReader(ROOT, hashMapStore);
-        dataService.registerCommitHandler(ROOT, hashMapStore);
-        dataService.registerOperationalReader(ROOT, hashMapStore);
-        
-        mountService = new MountPointManagerImpl();
-        mountService.setDataBroker(dataService);
-        
-        mountReg = context.registerService(MountService.class, mountService, emptyProperties);
-        mountProviderReg =  context.registerService(MountProvisionService.class, mountService, emptyProperties);
-        
-        brokerReg = context.registerService(Broker.class, broker, emptyProperties);
-    }
-
-    @Override
-    public void stop(BundleContext context) throws Exception {
-        if (brokerReg != null) {
-            brokerReg.unregister();
-        }
-    }
-}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.xtend
new file mode 100644 (file)
index 0000000..54c94dc
--- /dev/null
@@ -0,0 +1,74 @@
+package org.opendaylight.controller.sal.dom.broker
+
+import org.osgi.framework.ServiceRegistration
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService
+import org.opendaylight.controller.sal.core.api.data.DataProviderService
+import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
+import org.opendaylight.controller.sal.core.api.mount.MountService
+import org.osgi.framework.BundleContext
+import java.util.Hashtable
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.controller.sal.core.api.data.DataStore
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter
+
+class BrokerConfigActivator implements AutoCloseable {
+    
+    
+    private static val ROOT = InstanceIdentifier.builder().toInstance();
+    
+    private var ServiceRegistration<SchemaService> schemaReg;
+    private var ServiceRegistration<DataBrokerService> dataReg;
+    private var ServiceRegistration<DataProviderService> dataProviderReg;
+    private var ServiceRegistration<MountService> mountReg;
+    private var ServiceRegistration<MountProvisionService> mountProviderReg;
+    
+    private var SchemaServiceImpl schemaService;
+    private var DataBrokerImpl dataService;
+    private var MountPointManagerImpl mountService;
+    
+    SchemaAwareDataStoreAdapter wrappedStore
+
+    public def void start(BrokerImpl broker,DataStore store,BundleContext context) {
+        val emptyProperties = new Hashtable<String, String>();
+        broker.setBundleContext(context);
+        
+
+        schemaService = new SchemaServiceImpl();
+        schemaService.setContext(context);
+        schemaService.setParser(new YangParserImpl());
+        schemaService.start();
+        schemaReg = context.registerService(SchemaService, schemaService, emptyProperties);
+        
+        dataService = new DataBrokerImpl();
+        dataService.setExecutor(broker.getExecutor());
+        
+        dataReg = context.registerService(DataBrokerService, dataService, emptyProperties);
+        dataProviderReg = context.registerService(DataProviderService, dataService, emptyProperties);
+
+        wrappedStore = new SchemaAwareDataStoreAdapter();
+        wrappedStore.changeDelegate(store);
+        wrappedStore.setValidationEnabled(false);
+        
+        dataService.registerConfigurationReader(ROOT, wrappedStore);
+        dataService.registerCommitHandler(ROOT, wrappedStore);
+        dataService.registerOperationalReader(ROOT, wrappedStore);
+        
+        mountService = new MountPointManagerImpl();
+        mountService.setDataBroker(dataService);
+        
+        mountReg = context.registerService(MountService, mountService, emptyProperties);
+        mountProviderReg =  context.registerService(MountProvisionService, mountService, emptyProperties);
+    }
+
+    override def close() {
+        schemaReg?.unregister();
+        dataReg?.unregister();
+        dataProviderReg?.unregister();
+        mountReg?.unregister();
+        mountProviderReg?.unregister();
+    }
+    
+}
\ No newline at end of file
index 26fecef688d3cfc748bc1367a5a1e4e5a9d40ac1..7ef594bad94cddd77db1136f6a2e9a311d4203e9 100644 (file)
@@ -30,7 +30,7 @@ import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter
 import org.opendaylight.yangtools.concepts.ListenerRegistration
 import org.opendaylight.controller.sal.core.api.RpcRegistrationListener
 
-public class BrokerImpl implements Broker {
+public class BrokerImpl implements Broker, AutoCloseable {
     private static val log = LoggerFactory.getLogger(BrokerImpl);
 
     // Broker Generic Context
@@ -43,6 +43,9 @@ public class BrokerImpl implements Broker {
     private var ExecutorService executor = Executors.newFixedThreadPool(5);
     @Property
     private var BundleContext bundleContext;
+    
+    @Property
+    private var AutoCloseable deactivator;
 
     @Property
     private var RpcRouter router;
@@ -107,4 +110,9 @@ public class BrokerImpl implements Broker {
         sessions.remove(consumerContextImpl);
         providerSessions.remove(consumerContextImpl);
     }
+    
+    override close() throws Exception {
+        deactivator?.close();
+    }
+    
 }
index d95fdcc53dbc68019704b876c7a2ea7bdb34051e..ac5313a9caa99fdaf4fdb5c29fd7690b08e3589c 100644 (file)
@@ -1,5 +1,8 @@
 package org.opendaylight.controller.sal.dom.broker;
 
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
 import org.opendaylight.controller.md.sal.common.api.data.DataReader;
 import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker;
 import org.opendaylight.controller.sal.common.DataStoreIdentifier;
@@ -18,9 +21,12 @@ public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier, Compo
         setDataReadRouter(new DataReaderRouter());
     }
 
+    private AtomicLong nextTransaction = new AtomicLong();
+    
     @Override
     public DataTransactionImpl beginTransaction() {
-        return new DataTransactionImpl(this);
+        String transactionId = "DOM-" + nextTransaction.getAndIncrement();
+        return new DataTransactionImpl(transactionId,this);
     }
 
     @Override
@@ -38,29 +44,26 @@ public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier, Compo
     @Deprecated
     @Override
     public void addValidator(DataStoreIdentifier store, DataValidator validator) {
-        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException("Deprecated");
 
     }
 
     @Deprecated
     @Override
     public void removeValidator(DataStoreIdentifier store, DataValidator validator) {
-        // TODO Auto-generated method stub
-
+        throw new UnsupportedOperationException("Deprecated");
     }
 
     @Deprecated
     @Override
     public void addRefresher(DataStoreIdentifier store, DataRefresher refresher) {
-        // TODO Auto-generated method stub
-
+        throw new UnsupportedOperationException("Deprecated");
     }
 
     @Deprecated
     @Override
     public void removeRefresher(DataStoreIdentifier store, DataRefresher refresher) {
-        // TODO Auto-generated method stub
-
+        throw new UnsupportedOperationException("Deprecated");
     }
 
 }
\ No newline at end of file
index 5cb01c9a1064eeaa024ae68cbc20c0e2d440bbcf..8c289f05082e0b7c45fbabff30d51e0ef9f753fa 100644 (file)
@@ -14,8 +14,8 @@ public class DataTransactionImpl extends AbstractDataTransaction<InstanceIdentif
     
     
     
-    public DataTransactionImpl(DataBrokerImpl dataBroker) {
-        super(dataBroker);
+    public DataTransactionImpl(Object identifier,DataBrokerImpl dataBroker) {
+        super(identifier,dataBroker);
     }
 
     @Override
index eafc402ddcea6987b82980b5a2d92ffec5443108..7509a38a1429308029f25bcc85d90a32b6ed8f2d 100644 (file)
@@ -4,7 +4,9 @@ import java.util.List;
 import java.util.Set;
 import java.util.concurrent.Future;
 
+import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration;
 import org.opendaylight.controller.md.sal.common.api.data.DataReader;
 import org.opendaylight.controller.sal.common.DataStoreIdentifier;
 import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
@@ -191,4 +193,11 @@ public class MountPointImpl implements MountProvisionInstance {
             return MountPointImpl.this.readOperationalData(newPath);
         }
     }
+
+    @Override
+    public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>>> registerCommitHandlerListener(
+            RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>> commitHandlerListener) {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }
index ba558c51fdd039990a8a7a7e8c5eda4629476c0b..531f9e86c2dd76f55116a46a8d347d9b2daa1f6a 100644 (file)
@@ -13,6 +13,8 @@ import java.util.zip.Checksum;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.osgi.util.tracker.BundleTracker;
 import org.osgi.util.tracker.BundleTrackerCustomizer;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
@@ -20,6 +22,7 @@ import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
+import org.osgi.framework.ServiceReference;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
@@ -34,9 +37,13 @@ import com.google.common.collect.Collections2;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Sets;
+
 import static com.google.common.base.Preconditions.*;
 
-public class SchemaServiceImpl implements SchemaService, AutoCloseable {
+public class SchemaServiceImpl implements //
+SchemaService, //
+ServiceTrackerCustomizer<SchemaServiceListener, SchemaServiceListener>, //
+AutoCloseable {
     private static final Logger logger = LoggerFactory.getLogger(SchemaServiceImpl.class);
 
     private ListenerRegistry<SchemaServiceListener> listeners;
@@ -54,6 +61,8 @@ public class SchemaServiceImpl implements SchemaService, AutoCloseable {
     private BundleTracker<Object> bundleTracker;
     private final YangStoreCache cache = new YangStoreCache();
 
+    private ServiceTracker<SchemaServiceListener,SchemaServiceListener> listenerTracker;
+
     public ListenerRegistry<SchemaServiceListener> getListeners() {
         return listeners;
     }
@@ -84,9 +93,11 @@ public class SchemaServiceImpl implements SchemaService, AutoCloseable {
         if (listeners == null) {
             listeners = new ListenerRegistry<>();
         }
-
+        
+        listenerTracker = new ServiceTracker<>(context, SchemaServiceListener.class, this);
         bundleTracker = new BundleTracker<Object>(context, BundleEvent.RESOLVED | BundleEvent.UNRESOLVED, scanner);
         bundleTracker.open();
+        listenerTracker.open();
     }
 
     public SchemaContext getGlobalContext() {
@@ -185,6 +196,18 @@ public class SchemaServiceImpl implements SchemaService, AutoCloseable {
 
     private void updateCache(SchemaContext snapshot) {
         cache.cacheYangStore(consistentBundlesToYangURLs, snapshot);
+        
+        Object[] services = listenerTracker.getServices();
+        if(services != null) {
+            for(Object rawListener : services) {
+                SchemaServiceListener listener = (SchemaServiceListener) rawListener;
+                try {
+                    listener.onGlobalContextUpdated(snapshot);
+                } catch (Exception e) {
+                    logger.error("Exception occured during invoking listener",e);
+                }
+            }
+        }
         for (ListenerRegistration<SchemaServiceListener> listener : listeners) {
             try {
                 listener.getInstance().onGlobalContextUpdated(snapshot);
@@ -220,6 +243,7 @@ public class SchemaServiceImpl implements SchemaService, AutoCloseable {
                     proposedNewState.putAll(inconsistentBundlesToYangURLs);
                     proposedNewState.putAll(bundle, addedURLs);
                     boolean adding = true;
+                    
                     if (tryToUpdateState(addedURLs, proposedNewState, adding) == false) {
                         inconsistentBundlesToYangURLs.putAll(bundle, addedURLs);
                     }
@@ -276,6 +300,26 @@ public class SchemaServiceImpl implements SchemaService, AutoCloseable {
             this.cachedUrls = setFromMultimapValues(urls);
             this.cachedContextSnapshot = ctx;
         }
-
+    }
+    
+    @Override
+    public SchemaServiceListener addingService(ServiceReference<SchemaServiceListener> reference) {
+        
+        SchemaServiceListener listener = context.getService(reference);
+        SchemaContext _ctxContext = getGlobalContext();
+        if(getContext() != null) {
+            listener.onGlobalContextUpdated(_ctxContext);
+        }
+        return listener;
+    }
+    
+    @Override
+    public void modifiedService(ServiceReference<SchemaServiceListener> reference, SchemaServiceListener service) {
+        // NOOP
+    }
+    
+    @Override
+    public void removedService(ServiceReference<SchemaServiceListener> reference, SchemaServiceListener service) {
+        context.ungetService(reference);
     }
 }
index fbed2ca113621c728dd00a5fa4b9ae932344d7db..504a3d639413f7f6b1b901297bbf215aa9825842 100644 (file)
@@ -4,15 +4,100 @@ import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRo
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
 import org.opendaylight.yangtools.yang.data.api.CompositeNode
 import org.opendaylight.controller.md.sal.common.api.data.DataReader
+import org.opendaylight.yangtools.yang.common.QName
+import java.net.URI
+import java.util.List
+import org.opendaylight.yangtools.yang.data.api.Node
+import java.util.ArrayList
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import java.util.Map
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
+import org.opendaylight.yangtools.yang.data.api.SimpleNode
+import java.util.Collections
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
+import java.util.HashMap
+import static com.google.common.base.Preconditions.*;
+import java.util.Collection
+import java.util.Set
+import java.util.Map.Entry
+import org.slf4j.LoggerFactory
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
 
 class DataReaderRouter extends AbstractDataReadRouter<InstanceIdentifier, CompositeNode> {
+    private static val LOG = LoggerFactory.getLogger(DataReaderRouter);
+    private static val NETCONF_NAMESPACE = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0")
+    private static val NETCONF_DATA = new QName(NETCONF_NAMESPACE,"data");
 
     override protected merge(InstanceIdentifier path, Iterable<CompositeNode> data) {
+        val pathArgument = path.path.last;
+        var empty = true;
+        var name = pathArgument?.nodeType;
+        val nodes = new ArrayList<Node<?>>();
+        val keyNodes = new HashMap<QName, SimpleNode<?>>();
         val iterator = data.iterator;
-        if(iterator.hasNext) {
-            return data.iterator.next
+        for(dataBit : data) {
+            try {
+                if(pathArgument != null && dataBit != null) {
+                    empty = false;
+                    val keyNodesLocal = getKeyNodes(pathArgument,dataBit);
+                    nodes.addAll(dataBit.childrenWithout(keyNodesLocal.entrySet));
+                } else if (dataBit != null) {
+                    empty = false;
+                    nodes.addAll(dataBit.children)
+                }
+            }   catch (IllegalStateException e) {
+                LOG.error("BUG: Readed data for path {} was invalid",path,e);
+            }
         }
-        return null;
+        if(empty) {
+            return null;
+        }
+        /**
+         * Reading from Root
+         * 
+         */
+        if(pathArgument == null) {
+            return new CompositeNodeTOImpl(NETCONF_DATA,null,nodes);
+        }
+        val finalNodes = new ArrayList<Node<?>>();
+        finalNodes.addAll(keyNodes.values);
+        finalNodes.addAll(nodes);
+        return new CompositeNodeTOImpl(name,null,finalNodes);
     }
-
+    
+    
+    
+    dispatch def Map<QName, SimpleNode<?>> getKeyNodes(PathArgument argument, CompositeNode node) {
+        return Collections.emptyMap();
+    }
+    
+    dispatch def getKeyNodes(NodeIdentifierWithPredicates argument, CompositeNode node) {
+        val ret = new HashMap<QName, SimpleNode<?>>();
+        for (keyValue : argument.keyValues.entrySet) {
+            val simpleNode = node.getSimpleNodesByName(keyValue.key);
+            if(simpleNode !== null && !simpleNode.empty) {
+                checkState(simpleNode.size <= 1,"Only one simple node for key $s is allowed in node $s",keyValue.key,node);
+                checkState(simpleNode.get(0).value == keyValue.value,"Key node must equals to instance identifier value");
+                ret.put(keyValue.key,simpleNode.get(0));
+            }
+            val compositeNode = node.getCompositesByName(keyValue.key);
+            checkState(compositeNode === null || compositeNode.empty,"Key node must be Simple Node, not composite node.");
+        }
+        return ret;
+    }
+    
+    def Collection<? extends Node<?>> childrenWithout(CompositeNode node, Set<Entry<QName, SimpleNode<?>>> entries) {
+        if(entries.empty) {
+            return node.children;
+        }
+        val filteredNodes = new ArrayList<Node<?>>();
+        for(scannedNode : node.children) {
+            if(!entries.contains(scannedNode.nodeType)) {
+                filteredNodes.add(scannedNode);
+            }
+        }
+        return filteredNodes;
+    }
+    
 }
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataStoreStatsWrapper.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataStoreStatsWrapper.java
new file mode 100644 (file)
index 0000000..9116d50
--- /dev/null
@@ -0,0 +1,137 @@
+package org.opendaylight.controller.sal.dom.broker.impl;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.sal.core.api.data.DataStore;
+import org.opendaylight.yangtools.concepts.Delegator;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public class DataStoreStatsWrapper implements Delegator<DataStore>, DataStore {
+
+    private final DataStore delegate;
+
+    private AtomicLong cfgReadCount = new AtomicLong();
+    private AtomicLong cfgReadTimeTotal = new AtomicLong();
+
+    private AtomicLong operReadCount = new AtomicLong();
+    private AtomicLong operReadTimeTotal = new AtomicLong();
+
+    private AtomicLong requestCommitCount = new AtomicLong();
+    private AtomicLong requestCommitTimeTotal = new AtomicLong();
+
+    public DataStoreStatsWrapper(DataStore store) {
+        delegate = store;
+    }
+
+    @Override
+    public DataStore getDelegate() {
+        return delegate;
+    }
+
+    @Override
+    public CompositeNode readConfigurationData(InstanceIdentifier path) {
+        cfgReadCount.incrementAndGet();
+        final long startTime = System.nanoTime();
+        try {
+            return delegate.readConfigurationData(path);
+        } finally {
+            final long endTime = System.nanoTime();
+            final long runTime = endTime - startTime;
+            cfgReadTimeTotal.addAndGet(runTime);
+        }
+    }
+
+    @Override
+    public CompositeNode readOperationalData(InstanceIdentifier path) {
+        operReadCount.incrementAndGet();
+        final long startTime = System.nanoTime();
+        try {
+            return delegate.readOperationalData(path);
+        } finally {
+            final long endTime = System.nanoTime();
+            final long runTime = endTime - startTime;
+            cfgReadTimeTotal.addAndGet(runTime);
+        }
+    }
+
+    public DataCommitTransaction<InstanceIdentifier, CompositeNode> requestCommit(
+            DataModification<InstanceIdentifier, CompositeNode> modification) {
+        requestCommitCount.incrementAndGet();
+        final long startTime = System.nanoTime();
+        try {
+            return delegate.requestCommit(modification);
+        } finally {
+            final long endTime = System.nanoTime();
+            final long runTime = endTime - startTime;
+            requestCommitTimeTotal.addAndGet(runTime);
+        }
+    };
+
+    @Override
+    public boolean containsConfigurationPath(InstanceIdentifier path) {
+        return delegate.containsConfigurationPath(path);
+    }
+
+    public Iterable<InstanceIdentifier> getStoredConfigurationPaths() {
+        return delegate.getStoredConfigurationPaths();
+    }
+
+    public Iterable<InstanceIdentifier> getStoredOperationalPaths() {
+        return delegate.getStoredOperationalPaths();
+    }
+
+    public boolean containsOperationalPath(InstanceIdentifier path) {
+        return delegate.containsOperationalPath(path);
+    }
+
+    public final long getConfigurationReadCount() {
+        return cfgReadCount.get();
+    }
+
+    public final long getOperationalReadCount() {
+        return operReadCount.get();
+    }
+
+    public final long getRequestCommitCount() {
+        return requestCommitCount.get();
+    }
+
+    public final long getConfigurationReadTotalTime() {
+        return cfgReadTimeTotal.get();
+    }
+
+    public final long getOperationalReadTotalTime() {
+        return operReadTimeTotal.get();
+    }
+
+    public final long getRequestCommitTotalTime() {
+        return requestCommitTimeTotal.get();
+    }
+
+    public final long getConfigurationReadAverageTime() {
+        long readCount = cfgReadCount.get();
+        if(readCount == 0) {
+            return 0;
+        }
+        return cfgReadTimeTotal.get() / readCount;
+    }
+
+    public final long getOperationalReadAverageTime() {
+        long readCount = operReadCount.get();
+        if(readCount == 0) {
+            return 0;
+        }
+        return operReadTimeTotal.get() / readCount;
+    }
+
+    public final long getRequestCommitAverageTime() {
+        long count = requestCommitCount.get();
+        if(count == 0) {
+            return 0;
+        }
+        return requestCommitTimeTotal.get() / count;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataUtils.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataUtils.xtend
deleted file mode 100644 (file)
index 1a2f947..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-package org.opendaylight.controller.sal.dom.broker.impl
-
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import java.util.Map
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-import java.util.Map.Entry
-import java.util.HashSet
-import java.util.ArrayList
-import org.opendaylight.yangtools.yang.data.api.Node
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
-
-class DataUtils {
-
-    static def CompositeNode read(Map<InstanceIdentifier, CompositeNode> map, InstanceIdentifier path) {
-        val root = map.get(path);
-        val childs = map.getChilds(path);
-        if(root === null && childs.empty) {
-            return null;
-        }
-        
-        return merge(path, root, childs);
-    }
-
-    static def CompositeNode merge(InstanceIdentifier path, CompositeNode node,
-        HashSet<Entry<InstanceIdentifier, CompositeNode>> entries) {
-        val it = new ArrayList<Node<?>>();
-        val qname = path.path.last.nodeType;
-        if (node != null) {
-            addAll(node.children);
-        }
-        for (entry : entries) {
-            val nesting = entry.key.path.size - path.path.size;
-            if (nesting === 1) {
-                add(entry.value);
-            }
-        }
-        return new CompositeNodeTOImpl(qname, null, it);
-    }
-
-    static def getChilds(Map<InstanceIdentifier, CompositeNode> map, InstanceIdentifier path) {
-        val it = new HashSet<Entry<InstanceIdentifier, CompositeNode>>();
-        for (entry : map.entrySet) {
-            if (path.contains(entry.key)) {
-                add(entry);
-            }
-        }
-        return it;
-    }
-
-}
index 7d57819cbf0ac3a1775c4eedc026719740a8fce7..e9ed71a05287982faad6438962b3324c66c5cb6c 100644 (file)
@@ -1,7 +1,5 @@
 package org.opendaylight.controller.sal.dom.broker.impl
 
-import org.opendaylight.controller.md.sal.common.api.data.DataReader
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
 import org.opendaylight.controller.md.sal.common.api.data.DataModification
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
 import org.opendaylight.yangtools.yang.common.RpcResult
@@ -11,23 +9,41 @@ import org.opendaylight.controller.sal.common.util.Rpcs
 import java.util.Collections
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
 import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import static extension org.opendaylight.controller.sal.dom.broker.impl.DataUtils.*;
+import org.opendaylight.controller.sal.core.api.data.DataStore
+import java.util.HashSet
+
+class HashMapDataStore implements DataStore, AutoCloseable {
 
-class HashMapDataStore //
-implements //
-DataReader<InstanceIdentifier, CompositeNode>, DataCommitHandler<InstanceIdentifier, CompositeNode> {
 
     val Map<InstanceIdentifier, CompositeNode> configuration = new ConcurrentHashMap();
     val Map<InstanceIdentifier, CompositeNode> operational = new ConcurrentHashMap();
+    
+    
+    
+    override containsConfigurationPath(InstanceIdentifier path) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        
+    }
+    
+    override containsOperationalPath(InstanceIdentifier path) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+    }
+    
+    override getStoredConfigurationPaths() {
+        configuration.keySet
+    }
+    
+    override getStoredOperationalPaths() {
+        operational.keySet
+    }
 
     override readConfigurationData(InstanceIdentifier path) {
-        configuration.read(path);
+        configuration.get(path);
     }
 
     override readOperationalData(InstanceIdentifier path) {
-        operational.read(path);
+        operational.get(path);
     }
-    
 
 
 
@@ -45,14 +61,32 @@ DataReader<InstanceIdentifier, CompositeNode>, DataCommitHandler<InstanceIdentif
         operational.putAll(modification.updatedOperationalData);
 
         for (removal : modification.removedConfigurationData) {
-            configuration.remove(removal);
+            remove(configuration,removal);
         }
         for (removal : modification.removedOperationalData) {
-            operational.remove(removal);
+            remove(operational,removal);
         }
         return Rpcs.getRpcResult(true, null, Collections.emptySet);
     }
+    
+    def remove(Map<InstanceIdentifier, CompositeNode> map, InstanceIdentifier identifier) {
+        val affected = new HashSet<InstanceIdentifier>();
+        for(path : map.keySet) {
+            if(identifier.contains(path)) {
+                affected.add(path);
+            }
+        }
+        for(pathToRemove : affected) {
+            map.remove(pathToRemove);
+        }
+        
+    }
+
 
+    override close()  {
+        // NOOP
+    }
+    
 }
 
 class HashMapDataStoreTransaction implements // 
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataMerger.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataMerger.xtend
new file mode 100644 (file)
index 0000000..8cdbf92
--- /dev/null
@@ -0,0 +1,13 @@
+package org.opendaylight.controller.sal.dom.broker.impl
+
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+
+class SchemaAwareDataMerger {
+
+    private SchemaContext schema;
+    
+    
+    
+    
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java
new file mode 100644 (file)
index 0000000..1f90814
--- /dev/null
@@ -0,0 +1,245 @@
+package org.opendaylight.controller.sal.dom.broker.impl;
+
+import java.awt.PageAttributes.OriginType;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.impl.util.AbstractLockableDelegator;
+import org.opendaylight.controller.sal.core.api.data.DataStore;
+import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+
+import static com.google.common.base.Preconditions.*;
+
+public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataStore> implements //
+        DataStore, //
+        SchemaServiceListener, //
+        AutoCloseable {
+
+    private final static Logger LOG = LoggerFactory.getLogger(SchemaAwareDataStoreAdapter.class);
+
+    private SchemaContext schema = null;
+    private boolean validationEnabled = false;
+    private SchemaAwareDataMerger dataMerger = null;
+    private DataReader<InstanceIdentifier, CompositeNode> reader = new MergeFirstLevelReader();
+
+    @Override
+    public boolean containsConfigurationPath(InstanceIdentifier path) {
+        try {
+            getDelegateReadLock().lock();
+            return getDelegate().containsConfigurationPath(path);
+
+        } finally {
+            getDelegateReadLock().unlock();
+        }
+    }
+
+    @Override
+    public boolean containsOperationalPath(InstanceIdentifier path) {
+        try {
+            getDelegateReadLock().lock();
+            return getDelegate().containsOperationalPath(path);
+
+        } finally {
+            getDelegateReadLock().unlock();
+        }
+    }
+
+    @Override
+    public Iterable<InstanceIdentifier> getStoredConfigurationPaths() {
+        try {
+            getDelegateReadLock().lock();
+            return getDelegate().getStoredConfigurationPaths();
+
+        } finally {
+            getDelegateReadLock().unlock();
+        }
+    }
+
+    @Override
+    public Iterable<InstanceIdentifier> getStoredOperationalPaths() {
+        try {
+            getDelegateReadLock().lock();
+            return getDelegate().getStoredOperationalPaths();
+
+        } finally {
+            getDelegateReadLock().unlock();
+        }
+    }
+
+    @Override
+    public CompositeNode readConfigurationData(InstanceIdentifier path) {
+        return reader.readConfigurationData(path);
+    }
+
+    @Override
+    public CompositeNode readOperationalData(InstanceIdentifier path) {
+        return reader.readOperationalData(path);
+    }
+
+    @Override
+    public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier, CompositeNode> requestCommit(
+            DataModification<InstanceIdentifier, CompositeNode> modification) {
+        validateAgainstSchema(modification);
+        DataModification<InstanceIdentifier, CompositeNode> cleanedUp = prepareMergedTransaction(modification);
+        return retrieveDelegate().requestCommit(cleanedUp);
+    }
+
+    public boolean isValidationEnabled() {
+        return validationEnabled;
+    }
+
+    public void setValidationEnabled(boolean validationEnabled) {
+        this.validationEnabled = validationEnabled;
+    }
+
+    private void validateAgainstSchema(DataModification<InstanceIdentifier, CompositeNode> modification) {
+        if (!validationEnabled) {
+            return;
+        }
+
+        if (schema == null) {
+            LOG.info("Validation not performed for {}. Reason: YANG Schema not present.", modification.getIdentifier());
+            return;
+        }
+    }
+
+    @Override
+    protected void onDelegateChanged(DataStore oldDelegate, DataStore newDelegate) {
+        // NOOP
+    }
+
+    @Override
+    public void onGlobalContextUpdated(SchemaContext context) {
+        this.schema = context;
+    }
+
+    @Override
+    public void close() throws Exception {
+        this.schema = null;
+    }
+
+    private DataModification<InstanceIdentifier, CompositeNode> prepareMergedTransaction(
+            DataModification<InstanceIdentifier, CompositeNode> original) {
+        // NOOP for now
+        return original;
+    }
+
+    private final Comparator<Entry<InstanceIdentifier, CompositeNode>> preparationComparator = new Comparator<Entry<InstanceIdentifier, CompositeNode>>() {
+        @Override
+        public int compare(Entry<InstanceIdentifier, CompositeNode> o1, Entry<InstanceIdentifier, CompositeNode> o2) {
+            InstanceIdentifier o1Key = o1.getKey();
+            InstanceIdentifier o2Key = o2.getKey();
+            return Integer.compare(o1Key.getPath().size(), o2Key.getPath().size());
+        }
+    };
+
+    private class MergeFirstLevelReader implements DataReader<InstanceIdentifier, CompositeNode> {
+
+        @Override
+        public CompositeNode readConfigurationData(final InstanceIdentifier path) {
+            getDelegateReadLock().lock();
+            try {
+                if (path.getPath().isEmpty()) {
+                    return null;
+                }
+                QName qname = null;
+                CompositeNode original = getDelegate().readConfigurationData(path);
+                ArrayList<Node<?>> childNodes = new ArrayList<Node<?>>();
+                if (original != null) {
+                    childNodes.addAll(original.getChildren());
+                    qname = original.getNodeType();
+                } else {
+                    qname = path.getPath().get(path.getPath().size() - 1).getNodeType();
+                }
+
+                FluentIterable<InstanceIdentifier> directChildren = FluentIterable.from(getStoredConfigurationPaths())
+                        .filter(new Predicate<InstanceIdentifier>() {
+                            @Override
+                            public boolean apply(InstanceIdentifier input) {
+                                if (path.contains(input)) {
+                                    int nesting = input.getPath().size() - path.getPath().size();
+                                    if (nesting == 1) {
+                                        return true;
+                                    }
+                                }
+                                return false;
+                            }
+                        });
+                for (InstanceIdentifier instanceIdentifier : directChildren) {
+                    childNodes.add(getDelegate().readConfigurationData(instanceIdentifier));
+                }
+                if (original == null && childNodes.isEmpty()) {
+                    return null;
+                }
+
+                return new CompositeNodeTOImpl(qname, null, childNodes);
+            } finally {
+                getDelegateReadLock().unlock();
+            }
+        }
+
+        @Override
+        public CompositeNode readOperationalData(final InstanceIdentifier path) {
+            getDelegateReadLock().lock();
+            try {
+                if (path.getPath().isEmpty()) {
+                    return null;
+                }
+                QName qname = null;
+                CompositeNode original = getDelegate().readOperationalData(path);
+                ArrayList<Node<?>> childNodes = new ArrayList<Node<?>>();
+                if (original != null) {
+                    childNodes.addAll(original.getChildren());
+                    qname = original.getNodeType();
+                } else {
+                    qname = path.getPath().get(path.getPath().size() - 1).getNodeType();
+                }
+
+                FluentIterable<InstanceIdentifier> directChildren = FluentIterable.from(getStoredOperationalPaths())
+                        .filter(new Predicate<InstanceIdentifier>() {
+                            @Override
+                            public boolean apply(InstanceIdentifier input) {
+                                if (path.contains(input)) {
+                                    int nesting = input.getPath().size() - path.getPath().size();
+                                    if (nesting == 1) {
+                                        return true;
+                                    }
+                                }
+                                return false;
+                            }
+                        });
+
+                for (InstanceIdentifier instanceIdentifier : directChildren) {
+                    childNodes.add(getDelegate().readOperationalData(instanceIdentifier));
+                }
+                if (original == null && childNodes.isEmpty()) {
+                    return null;
+                }
+
+                return new CompositeNodeTOImpl(qname, null, childNodes);
+            } finally {
+                getDelegateReadLock().unlock();
+            }
+        }
+    }
+}
index 2fded87981e8fa2fa67651b8c4182f034d73156e..329219ebb0dc7e90583d5fd76984653513bcbcf8 100644 (file)
@@ -1,6 +1,8 @@
 package org.opendaylight.controller.sal.dom.broker.osgi;
 
+import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration;
 import org.opendaylight.controller.md.sal.common.api.data.DataReader;
 import org.opendaylight.controller.sal.common.DataStoreIdentifier;
 import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
@@ -74,4 +76,10 @@ public class DataProviderServiceProxy extends AbstractBrokerServiceProxy<DataPro
     public void removeValidator(DataStoreIdentifier store, DataValidator validator) {
         getDelegate().removeValidator(store, validator);
     }
+    
+    @Override
+    public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>>> registerCommitHandlerListener(
+            RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>> commitHandlerListener) {
+        return addRegistration(getDelegate().registerCommitHandlerListener(commitHandlerListener));
+    }
 }
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/yang/opendaylight-dom-broker-impl.yang b/opendaylight/md-sal/sal-dom-broker/src/main/yang/opendaylight-dom-broker-impl.yang
new file mode 100644 (file)
index 0000000..bf12ac4
--- /dev/null
@@ -0,0 +1,61 @@
+module opendaylight-sal-dom-broker-impl {
+       yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl";
+    prefix "binding-impl";
+
+       import config { prefix config; revision-date 2013-04-05; }
+       import opendaylight-md-sal-dom {prefix sal;}
+
+    description
+        "Service definition for Binding Aware MD-SAL.";
+    revision "2013-10-28" {
+        description
+            "Initial revision";
+    }
+
+    identity dom-broker-impl {
+        base config:module-type;
+        config:provided-service sal:dom-broker-osgi-registry;
+        config:java-name-prefix DomBrokerImpl;
+    }
+    
+    identity hash-map-data-store {
+        base config:module-type;
+        config:provided-service sal:dom-data-store;
+        config:java-name-prefix HashMapDataStore;
+    }
+    
+    identity schema-service-singleton {
+        base config:module-type;
+        config:provided-service sal:schema-service;
+        config:java-name-prefix SchemaServiceImplSingleton;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case dom-broker-impl {
+            when "/config:modules/config:module/config:type = 'dom-broker-impl'";
+            container data-store {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity sal:dom-data-store;
+                    }
+                }
+            }
+        }
+    }
+    
+    augment "/config:modules/config:module/config:state" {
+        case hash-map-data-store {
+            when "/config:modules/config:module/config:type = 'hash-map-data-store'";
+        }
+    }
+    
+    augment "/config:modules/config:module/config:state" {
+        case schema-service-singleton {
+            when "/config:modules/config:module/config:type = 'schema-service-singleton'";
+        }
+    }
+    
+}
\ No newline at end of file
index 6ef5780c8a577c1bc93c97bd95420a50d608f5fc..e790a9dbb1bbd396570445e0e58da1eee105e443 100644 (file)
             <groupId>org.eclipse.xtend</groupId>
             <artifactId>org.eclipse.xtend.lib</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>netty-threadgroup-config</artifactId>
+            <version>0.2.3-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>netconf-client</artifactId>
@@ -62,7 +67,7 @@
             <groupId>${project.groupId}</groupId>
             <artifactId>config-api</artifactId>
             <version>${netconf.version}</version>
-            <scope>test</scope>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <version>${netconf.version}</version>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>netconf-api</artifactId>
-            <version>${netconf.version}</version>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.bgpcep</groupId>
             <artifactId>util</artifactId>
@@ -91,7 +90,6 @@
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>netconf-client</artifactId>
-            <scope>test</scope>
             <version>${netconf.version}</version>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools.model</groupId>
+            <artifactId>ietf-inet-types</artifactId>
+            <version>2010.09.24.2-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>threadpool-config-api</artifactId>
+            <version>0.2.3-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>netty-config-api</artifactId>
+            <version>0.2.3-SNAPSHOT</version>
+        </dependency>
     </dependencies>
 
     <packaging>bundle</packaging>
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
-                <configuration>
-                    <instructions>
-                        <Bundle-Activator>org.opendaylight.controller.sal.connect.netconf.NetconfProvider</Bundle-Activator>
-                    </instructions>
-                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-maven-plugin</artifactId>
+                <version>0.5.9-SNAPSHOT</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate-sources</goal>
+                        </goals>
+                        <configuration>
+                            <codeGenerators>
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+                                    </codeGeneratorClass>
+                                    <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+                                    <additionalConfiguration>
+                                        <namespaceToPackage1>
+                                            urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
+                                        </namespaceToPackage1>
+                                    </additionalConfiguration>
+                                </generator>
+                            </codeGenerators>
+                            <inspectDependencies>true</inspectDependencies>
+                        </configuration>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.opendaylight.controller</groupId>
+                        <artifactId>yang-jmx-generator-plugin</artifactId>
+                        <version>0.2.3-SNAPSHOT</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>1.8</version>
+                <executions>
+                    <execution>
+                        <id>add-source</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>${project.build.directory}/generated-sources/config</source>
+                            </sources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.eclipse.xtend</groupId>
+                <artifactId>xtend-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java
new file mode 100644 (file)
index 0000000..2a556c9
--- /dev/null
@@ -0,0 +1,89 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-netconf-connector  yang module local name: sal-netconf-connector
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Mon Nov 18 09:44:16 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.connector.netconf;
+
+import io.netty.channel.EventLoopGroup;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+
+import javax.net.ssl.SSLContext;
+
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
+import org.osgi.framework.BundleContext;
+
+import static com.google.common.base.Preconditions.*;
+
+import com.google.common.base.Optional;
+import com.google.common.net.InetAddresses;
+
+/**
+*
+*/
+public final class NetconfConnectorModule extends org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModule
+{
+
+    private BundleContext bundleContext;
+
+    public NetconfConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public NetconfConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, NetconfConnectorModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void validate(){
+        super.validate();
+        checkState(getAddress() != null,"Address must be set.");
+        //checkState(getAddress().getIpv4Address() != null || getAddress().getIpv6Address() != null,"Address must be set.");
+        checkState(getPort() != null,"Port must be set.");
+        checkState(getDomRegistry() != null,"Dom Registry must be provided.");
+    }
+
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        
+        getDomRegistryDependency();
+        NetconfDevice device = new NetconfDevice(getIdentifier().getInstanceName());
+        String addressValue = getAddress();
+        
+        
+        /*
+         * Uncomment after Switch to IP Address
+        if(getAddress().getIpv4Address() != null) {
+            addressValue = getAddress().getIpv4Address().getValue();
+        } else {
+            addressValue = getAddress().getIpv6Address().getValue();
+        }
+        
+        */
+        InetAddress addr = InetAddresses.forString(addressValue);
+        InetSocketAddress socketAddress = new InetSocketAddress(addr , getPort().intValue());
+        device.setSocketAddress(socketAddress);
+        
+        EventLoopGroup bossGroup = getBossThreadGroupDependency();
+        EventLoopGroup workerGroup = getWorkerThreadGroupDependency();
+        Optional<SSLContext> maybeContext = Optional.absent();
+        NetconfClientDispatcher dispatcher = new NetconfClientDispatcher(maybeContext , bossGroup, workerGroup);
+        
+        getDomRegistryDependency().registerProvider(device, bundleContext);
+        
+        device.start(dispatcher);
+        return device;
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java
new file mode 100644 (file)
index 0000000..51e288d
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+ * Generated file
+
+ * Generated from: yang module name: opendaylight-sal-netconf-connector  yang module local name: sal-netconf-connector
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Mon Nov 18 09:44:16 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.md.sal.connector.netconf;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
+/**
+*
+*/
+public class NetconfConnectorModuleFactory extends
+        org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModuleFactory {
+
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver,
+            DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
+        NetconfConnectorModule module = (NetconfConnectorModule) super.createModule(instanceName, dependencyResolver,
+                old, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
+
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
+        NetconfConnectorModule module = (NetconfConnectorModule) super.createModule(instanceName, dependencyResolver,
+                bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
+}
index 0171c1f9e312b5020f26ee4dec1d0b23a8f34cf2..49d9757f421058cb05ffed90f81922f6509ff688 100644 (file)
@@ -14,8 +14,16 @@ import org.opendaylight.yangtools.yang.common.QName
 import java.util.Collections
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher
 import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.controller.sal.core.api.Provider
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
+import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService
+import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
 
-class NetconfDevice implements DataReader<InstanceIdentifier, CompositeNode>, RpcImplementation {
+class NetconfDevice implements Provider, DataReader<InstanceIdentifier, CompositeNode>, RpcImplementation, AutoCloseable {
 
     var NetconfClient client;
 
@@ -23,25 +31,29 @@ class NetconfDevice implements DataReader<InstanceIdentifier, CompositeNode>, Rp
     var InetSocketAddress socketAddress;
 
     @Property
-    val MountProvisionInstance mountInstance;
+    var MountProvisionInstance mountInstance;
 
     @Property
-    val InstanceIdentifier path;
-    
-    Registration<DataReader<InstanceIdentifier,CompositeNode>> operReaderReg
-    
-    Registration<DataReader<InstanceIdentifier,CompositeNode>> confReaderReg
-    
-    public new(MountProvisionInstance mount,InstanceIdentifier path) {
-        _mountInstance = mount;
-        _path = path;
+    var InstanceIdentifier path;
+
+    Registration<DataReader<InstanceIdentifier, CompositeNode>> operReaderReg
+
+    Registration<DataReader<InstanceIdentifier, CompositeNode>> confReaderReg
+
+    String name
+
+    MountProvisionService mountService
+
+    public new(String name) {
+        this.name = name;
+        this.path = InstanceIdentifier.builder(INVENTORY_PATH).nodeWithKey(INVENTORY_NODE,
+            Collections.singletonMap(INVENTORY_ID, name)).toInstance;
     }
 
     def start(NetconfClientDispatcher dispatcher) {
-        client = new NetconfClient("sal-netconf-connector", socketAddress, dispatcher);
-        
-        confReaderReg = mountInstance.registerConfigurationReader(path,this);
-        operReaderReg = mountInstance.registerOperationalReader(path,this);
+        client = new NetconfClient(name, socketAddress, dispatcher);
+        confReaderReg = mountInstance.registerConfigurationReader(path, this);
+        operReaderReg = mountInstance.registerOperationalReader(path, this);
     }
 
     override readConfigurationData(InstanceIdentifier path) {
@@ -66,6 +78,40 @@ class NetconfDevice implements DataReader<InstanceIdentifier, CompositeNode>, Rp
         return result.toRpcResult();
     }
 
+    override getProviderFunctionality() {
+        Collections.emptySet
+    }
+
+    override onSessionInitiated(ProviderSession session) {
+        val dataBroker = session.getService(DataBrokerService);
+        
+        
+        
+        val transaction = dataBroker.beginTransaction
+        if(transaction.operationalNodeNotExisting) {
+            transaction.putOperationalData(path,nodeWithId)
+        }
+        if(transaction.configurationNodeNotExisting) {
+            transaction.putConfigurationData(path,nodeWithId)
+        }
+        transaction.commit().get();
+        mountService = session.getService(MountProvisionService);
+        mountInstance = mountService.createOrGetMountPoint(path);
+    }
+    
+    def getNodeWithId() {
+        val id = new SimpleNodeTOImpl(INVENTORY_ID,null,name);
+        return new CompositeNodeTOImpl(INVENTORY_NODE,null,Collections.singletonList(id));
+    }
+    
+    def boolean configurationNodeNotExisting(DataModificationTransaction transaction) {
+        return null === transaction.readConfigurationData(path);
+    }
+    
+    def boolean operationalNodeNotExisting(DataModificationTransaction transaction) {
+        return null === transaction.readOperationalData(path);
+    }
+
     def Node<?> findNode(CompositeNode node, InstanceIdentifier identifier) {
 
         var Node<?> current = node;
@@ -86,10 +132,11 @@ class NetconfDevice implements DataReader<InstanceIdentifier, CompositeNode>, Rp
         }
         return current;
     }
-    
-    public def stop() {
+
+    override close() {
         confReaderReg?.close()
         operReaderReg?.close()
+        client?.close()
     }
 
 }
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceManager.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceManager.xtend
deleted file mode 100644 (file)
index 2fe145e..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.opendaylight.controller.sal.connect.netconf
-
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
-import org.opendaylight.controller.md.sal.common.api.data.DataProvisionService
-import org.opendaylight.controller.sal.core.api.data.DataProviderService
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-import org.opendaylight.yangtools.yang.common.QName
-import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*;
-import static extension org.opendaylight.controller.sal.connect.netconf.NetconfInventoryUtils.*;
-
-import org.opendaylight.controller.sal.core.api.data.DataChangeListener
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent
-import java.util.Map
-import java.util.concurrent.ConcurrentHashMap
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcher
-import java.io.OptionalDataException
-import com.google.common.base.Optional
-import java.net.SocketAddress
-import java.net.InetSocketAddress
-
-class NetconfDeviceManager {
-
-    val Map<InstanceIdentifier, NetconfDevice> devices = new ConcurrentHashMap;
-
-    var ProviderSession session;
-
-    @Property
-    var DataProviderService dataService;
-    
-    @Property
-    var MountProvisionService mountService;
-    
-    val nodeUpdateListener = new NetconfInventoryListener(this);
-
-
-    @Property
-    var NetconfClientDispatcher dispatcher;
-
-    def void start() {
-        dataService?.registerDataChangeListener(INVENTORY_PATH, nodeUpdateListener);
-        if(dispatcher == null) {
-        dispatcher = new NetconfClientDispatcher(Optional.absent);
-        }
-    }
-
-    def netconfNodeAdded(InstanceIdentifier path, CompositeNode node) {
-        val address = node.endpointAddress;
-        val port = Integer.parseInt(node.endpointPort);
-        netconfNodeAdded(path,new InetSocketAddress(address,port))
-
-    }
-    
-    def netconfNodeAdded(InstanceIdentifier path, InetSocketAddress address) {
-    
-        val mountPointPath = path;
-        val mountPoint = mountService.createOrGetMountPoint(mountPointPath);
-        val localPath = InstanceIdentifier.builder().toInstance;
-        val netconfDevice = new NetconfDevice(mountPoint,localPath);
-        netconfDevice.setSocketAddress(address);
-        netconfDevice.start(dispatcher);
-    }
-
-    def netconfNodeRemoved(InstanceIdentifier path) {
-    
-    }
-
-}
-
-class NetconfInventoryListener implements DataChangeListener {
-
-    val NetconfDeviceManager manager;
-
-    new(NetconfDeviceManager manager) {
-        this.manager = manager;
-    }
-
-    override onDataChanged(DataChangeEvent<InstanceIdentifier, CompositeNode> change) {
-        
-        //manager.netconfNodeAdded(path, change);
-    }
-}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfProvider.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfProvider.java
deleted file mode 100644 (file)
index 8cf5f02..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.opendaylight.controller.sal.connect.netconf;
-
-import java.util.Hashtable;
-
-import org.opendaylight.controller.sal.core.api.AbstractProvider;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.controller.sal.core.api.data.DataProviderService;
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
-import org.osgi.framework.BundleContext;
-
-public class NetconfProvider extends AbstractProvider {
-
-    private NetconfDeviceManager netconfDeviceManager;
-
-    @Override
-    protected void startImpl(BundleContext context) {
-        netconfDeviceManager = new NetconfDeviceManager();
-        context.registerService(NetconfDeviceManager.class, netconfDeviceManager, new Hashtable<String,String>());
-    }
-    
-    
-    @Override
-    public void onSessionInitiated(ProviderSession session) {
-        MountProvisionService mountService = session.getService(MountProvisionService.class);
-        
-        
-        netconfDeviceManager.setMountService(mountService);
-        netconfDeviceManager.start();
-    }
-
-    @Override
-    protected void stopImpl(BundleContext context) {
-        
-    }
-}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang b/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang
new file mode 100644 (file)
index 0000000..45f1016
--- /dev/null
@@ -0,0 +1,75 @@
+module odl-sal-netconf-connector-cfg {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf";
+    prefix "sal-netconf";
+
+       import config { prefix config; revision-date 2013-04-05; }
+       import threadpool {prefix th;}
+       import netty {prefix netty;}
+       import ietf-inet-types {prefix inet;}
+       import opendaylight-md-sal-dom {prefix dom;}
+
+    description
+        "Service definition for Binding Aware MD-SAL.";
+    revision "2013-10-28" {
+        description
+            "Initial revision";
+    }
+
+    identity sal-netconf-connector {
+        base config:module-type;
+        config:java-name-prefix NetconfConnector;
+    }
+
+
+    grouping server {
+        leaf address {
+            type string;
+        }
+    
+        leaf port {
+            type uint32;
+        }
+    }
+
+
+    augment "/config:modules/config:module/config:configuration" {
+        case sal-netconf-connector {
+            when "/config:modules/config:module/config:type = 'sal-netconf-connector'";
+            
+            leaf address {
+                type string;
+            }
+
+            leaf port {
+                type uint32;
+            }
+
+            container dom-registry {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity dom:dom-broker-osgi-registry;
+                    }
+                }
+            }
+
+            container boss-thread-group {
+                uses config:service-ref {
+                    refine type {
+                        config:required-identity netty:netty-threadgroup;
+                    }
+                }
+            }
+
+            container worker-thread-group {
+                uses config:service-ref {
+                    refine type {
+                        config:required-identity netty:netty-threadgroup;
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft01.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft01.java
new file mode 100644 (file)
index 0000000..557adb6
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * 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.sal.rest.api;
+
+public class Draft01 {
+    public static class MediaTypes {
+        public static final String API = "application/vnd.yang.api";
+        public static final String DATASTORE = "application/vnd.yang.datastore";
+        public static final String DATA = "application/vnd.yang.data";
+        public static final String EVENT = "application/vnd.yang.event";
+        public static final String OPERATION = "application/vnd.yang.operation";
+        public static final String PATCH = "application/vnd.yang.patch";
+    }
+}
index a22ea623975049cd3bd37c8af3103fecce4317e4..5d08b3e7b6cb27bec3e2bbb68c5c1f9927f603aa 100644 (file)
@@ -7,14 +7,13 @@
  */
 package org.opendaylight.controller.sal.rest.api;
 
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
@@ -58,42 +57,51 @@ public interface RestconfService extends RestconfServiceLegacy {
 
     @GET
     @Path("/modules")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft01.MediaTypes.API+JSON,Draft01.MediaTypes.API+XML,
+               Draft02.MediaTypes.API+JSON,Draft02.MediaTypes.API+XML})
     public StructuredData getModules();
 
     @POST
     @Path("/operations/{identifier}")
-    @Produces({Draft02.MediaTypes.API+JSON,Draft02.MediaTypes.API+XML,API+JSON,API+XML})
+    @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML,
+               Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public StructuredData invokeRpc(@PathParam("identifier") String identifier, CompositeNode payload);
     
     @GET
     @Path("/config/{identifier:.+}")
-    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML})
+    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public StructuredData readConfigurationData(@PathParam("identifier") String identifier);
     
-    @PUT
+    @POST
     @Path("/config/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public Response createConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
 
-    @POST
+    @PUT
     @Path("/config/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public Response updateConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
 
     @GET
     @Path("/operational/{identifier:.+}")
-    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML})
+    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public StructuredData readOperationalData(@PathParam("identifier") String identifier);
 
-    @PUT
+    @POST
     @Path("/operational/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public Response createOperationalData(@PathParam("identifier") String identifier, CompositeNode payload);
 
-    @POST
+    @PUT
     @Path("/operational/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public Response updateOperationalData(@PathParam("identifier") String identifier, CompositeNode payload);
 
 }
index 242e7f3150d4b775ce56d957ae62ba947a080eba..35da98b1a0db82e72d6cb32de8e0e34c858e1a41 100644 (file)
@@ -1,13 +1,12 @@
 package org.opendaylight.controller.sal.rest.api;
 
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
@@ -21,25 +20,28 @@ public interface RestconfServiceLegacy {
     @Deprecated
     @GET
     @Path("/datastore")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft01.MediaTypes.DATASTORE+JSON,Draft01.MediaTypes.DATASTORE+XML})
     public StructuredData readAllData();
 
     @Deprecated
     @GET
     @Path("/datastore/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public StructuredData readData(@PathParam("identifier") String identifier);
 
     @Deprecated
-    @PUT
+    @POST
     @Path("/datastore/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public Response createConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
 
     @Deprecated
-    @POST
+    @PUT
     @Path("/datastore/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public Response updateConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
 
 }
index 5a1b42fd8009d074613407088c94359bac5dc6d9..351ae6ebbee085614943d7608ec51669a204f1ff 100644 (file)
@@ -3,70 +3,57 @@ package org.opendaylight.controller.sal.rest.impl;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.io.IOException;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 import javax.activation.UnsupportedDataTypeException;
 
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.model.api.*;
+import org.opendaylight.yangtools.yang.model.api.type.*;
 
 import com.google.common.base.Preconditions;
 import com.google.gson.stream.JsonWriter;
 
 class JsonMapper {
-    
+
     private final Set<LeafListSchemaNode> foundLeafLists = new HashSet<>();
     private final Set<ListSchemaNode> foundLists = new HashSet<>();
-    
+
     public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema) throws IOException {
         Preconditions.checkNotNull(writer);
         Preconditions.checkNotNull(data);
         Preconditions.checkNotNull(schema);
 
         writer.beginObject();
-        
+
         if (schema instanceof ContainerSchemaNode) {
             writeContainer(writer, data, (ContainerSchemaNode) schema);
         } else if (schema instanceof ListSchemaNode) {
-            writeList(writer, data, (ListSchemaNode) schema);
+            writeList(writer, null, data, (ListSchemaNode) schema);
         } else {
             throw new UnsupportedDataTypeException(
                     "Schema can be ContainerSchemaNode or ListSchemaNode. Other types are not supported yet.");
         }
-        
+
         writer.endObject();
-        
+
         foundLeafLists.clear();
         foundLists.clear();
     }
 
-    private void writeChildrenOfParent(JsonWriter writer, CompositeNode parent, DataNodeContainer parentSchema) throws IOException {
+    private void writeChildrenOfParent(JsonWriter writer, CompositeNode parent, DataNodeContainer parentSchema)
+            throws IOException {
         checkNotNull(parent);
         checkNotNull(parentSchema);
-        
+
         for (Node<?> child : parent.getChildren()) {
             DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes());
             if (childSchema == null) {
                 throw new UnsupportedDataTypeException("Probably the data node \"" + child.getNodeType().getLocalName()
                         + "\" is not conform to schema");
             }
-            
+
             if (childSchema instanceof ContainerSchemaNode) {
                 Preconditions.checkState(child instanceof CompositeNode,
                         "Data representation of Container should be CompositeNode - " + child.getNodeType());
@@ -76,14 +63,14 @@ class JsonMapper {
                     Preconditions.checkState(child instanceof CompositeNode,
                             "Data representation of List should be CompositeNode - " + child.getNodeType());
                     foundLists.add((ListSchemaNode) childSchema);
-                    writeList(writer, (CompositeNode) child, (ListSchemaNode) childSchema);
+                    writeList(writer, parent, (CompositeNode) child, (ListSchemaNode) childSchema);
                 }
             } else if (childSchema instanceof LeafListSchemaNode) {
                 if (!foundLeafLists.contains(childSchema)) {
                     Preconditions.checkState(child instanceof SimpleNode<?>,
                             "Data representation of LeafList should be SimpleNode - " + child.getNodeType());
                     foundLeafLists.add((LeafListSchemaNode) childSchema);
-                    writeLeafList(writer, (SimpleNode<?>) child, (LeafListSchemaNode) childSchema);
+                    writeLeafList(writer, parent, (SimpleNode<?>) child, (LeafListSchemaNode) childSchema);
                 }
             } else if (childSchema instanceof LeafSchemaNode) {
                 Preconditions.checkState(child instanceof SimpleNode<?>,
@@ -94,7 +81,7 @@ class JsonMapper {
                         + "LeafListSchemaNode, or LeafSchemaNode. Other types are not supported yet.");
             }
         }
-        
+
         for (Node<?> child : parent.getChildren()) {
             DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes());
             if (childSchema instanceof LeafListSchemaNode) {
@@ -104,7 +91,7 @@ class JsonMapper {
             }
         }
     }
-    
+
     private DataSchemaNode findFirstSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode) {
         for (DataSchemaNode dsn : dataSchemaNode) {
             if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) {
@@ -113,84 +100,166 @@ class JsonMapper {
         }
         return null;
     }
-    
+
     private void writeContainer(JsonWriter writer, CompositeNode node, ContainerSchemaNode schema) throws IOException {
-        writer.name(node.getNodeType().getLocalName());
+        writeName(node, schema, writer);
         writer.beginObject();
         writeChildrenOfParent(writer, node, schema);
         writer.endObject();
     }
-    
-    private void writeList(JsonWriter writer, CompositeNode node, ListSchemaNode schema) throws IOException {
-            writer.name(node.getNodeType().getLocalName());
-            writer.beginArray();
-            
-            if (node.getParent() != null) {
-                CompositeNode parent = node.getParent();
-                List<CompositeNode> nodeLists = parent.getCompositesByName(node.getNodeType());
-                for (CompositeNode nodeList : nodeLists) {
-                    writer.beginObject();
-                    writeChildrenOfParent(writer, nodeList, schema);
-                    writer.endObject();
-                }
-            } else {
+
+    private void writeList(JsonWriter writer, CompositeNode nodeParent, CompositeNode node, ListSchemaNode schema)
+            throws IOException {
+        writeName(node, schema, writer);
+        writer.beginArray();
+
+        if (nodeParent != null) {
+            List<CompositeNode> nodeLists = nodeParent.getCompositesByName(node.getNodeType());
+            for (CompositeNode nodeList : nodeLists) {
                 writer.beginObject();
-                writeChildrenOfParent(writer, node, schema);
+                writeChildrenOfParent(writer, nodeList, schema);
                 writer.endObject();
             }
-            
-            writer.endArray();
-    }
-    
-    private void writeLeafList(JsonWriter writer, SimpleNode<?> node, LeafListSchemaNode schema) throws IOException {
-            writer.name(node.getNodeType().getLocalName());
-            writer.beginArray();
-            
-            CompositeNode parent = node.getParent();
-            List<SimpleNode<?>> nodeLeafLists = parent.getSimpleNodesByName(node.getNodeType());
-            for (SimpleNode<?> nodeLeafList : nodeLeafLists) {
-                writeValueOfNodeByType(writer, nodeLeafList, schema.getType());
-            }
-            
-            writer.endArray();
+        } else {
+            writer.beginObject();
+            writeChildrenOfParent(writer, node, schema);
+            writer.endObject();
+        }
+
+        writer.endArray();
+    }
+
+    private void writeLeafList(JsonWriter writer, CompositeNode nodeParent, SimpleNode<?> node,
+            LeafListSchemaNode schema) throws IOException {
+        writeName(node, schema, writer);
+        writer.beginArray();
+
+        List<SimpleNode<?>> nodeLeafLists = nodeParent.getSimpleNodesByName(node.getNodeType());
+        for (SimpleNode<?> nodeLeafList : nodeLeafLists) {
+            writeValueOfNodeByType(writer, nodeLeafList, schema.getType());
+        }
+
+        writer.endArray();
     }
-    
+
     private void writeLeaf(JsonWriter writer, SimpleNode<?> node, LeafSchemaNode schema) throws IOException {
-        writer.name(node.getNodeType().getLocalName());
+        writeName(node, schema, writer);
         writeValueOfNodeByType(writer, node, schema.getType());
     }
-    
-    private void writeValueOfNodeByType(JsonWriter writer, SimpleNode<?> node, TypeDefinition<?> type) throws IOException {
-        if (!(node.getValue() instanceof String)) {
-            throw new IllegalStateException("Value in SimpleNode should be type String");
-        }
-        
-        String value = (String) node.getValue();
-        // TODO check Leafref, InstanceIdentifierTypeDefinition, IdentityrefTypeDefinition, UnionTypeDefinition
-        if (type.getBaseType() != null) {
-            writeValueOfNodeByType(writer, node, type.getBaseType());
-        } else if (type instanceof InstanceIdentifierTypeDefinition) {
-            writer.value(((InstanceIdentifierTypeDefinition) type).getPathStatement().toString());
-        } else if (type instanceof DecimalTypeDefinition 
-                || type instanceof IntegerTypeDefinition
-                || type instanceof UnsignedIntegerTypeDefinition) {
+
+    private void writeValueOfNodeByType(JsonWriter writer, SimpleNode<?> node, TypeDefinition<?> type)
+            throws IOException {
+
+        String value = String.valueOf(node.getValue());
+        // TODO check Leafref, InstanceIdentifierTypeDefinition,
+        // IdentityrefTypeDefinition, UnionTypeDefinition
+        TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
+        if (baseType instanceof InstanceIdentifierTypeDefinition) {
+            writer.value(((InstanceIdentifierTypeDefinition) baseType).getPathStatement().toString());
+        } else if (baseType instanceof UnionTypeDefinition) {
+            processTypeIsUnionType(writer, (UnionTypeDefinition) baseType, value);
+        } else if (baseType instanceof DecimalTypeDefinition || baseType instanceof IntegerTypeDefinition
+                || baseType instanceof UnsignedIntegerTypeDefinition) {
+            writer.value(new NumberForJsonWriter(value));
+        } else if (baseType instanceof BooleanTypeDefinition) {
+            writer.value(Boolean.parseBoolean(value));
+        } else if (baseType instanceof EmptyTypeDefinition) {
+            writeEmptyDataTypeToJson(writer);
+        } else {
+            writer.value(value.equals("null") ? "" : value);
+        }
+    }
+
+    private void processTypeIsUnionType(JsonWriter writer, UnionTypeDefinition unionType, String value)
+            throws IOException {
+        if (value == null) {
+            writeEmptyDataTypeToJson(writer);
+        } else if ((isNumber(value))
+                && containsType(unionType, UnsignedIntegerTypeDefinition.class, IntegerTypeDefinition.class,
+                        DecimalTypeDefinition.class)) {
             writer.value(new NumberForJsonWriter(value));
-        } else if (type instanceof BooleanTypeDefinition) {
+        } else if (isBoolean(value) && containsType(unionType, BooleanTypeDefinition.class)) {
             writer.value(Boolean.parseBoolean(value));
-        } else if (type instanceof EmptyTypeDefinition) {
-            writer.beginArray();
-            writer.nullValue();
-            writer.endArray();
         } else {
-            writer.value(value != null ? value : "");
+            writer.value(value);
         }
     }
-    
+
+    private boolean isBoolean(String value) {
+        if (value.equals("true") || value.equals("false")) {
+            return true;
+        }
+        return false;
+    }
+
+    private void writeEmptyDataTypeToJson(JsonWriter writer) throws IOException {
+        writer.beginArray();
+        writer.nullValue();
+        writer.endArray();
+    }
+
+    private boolean isNumber(String value) {
+        try {
+            Double.valueOf(value);
+        } catch (NumberFormatException e) {
+            return false;
+        }
+        return true;
+    }
+
+    private boolean containsType(UnionTypeDefinition unionType, Class<?>... searchedTypes) {
+        List<TypeDefinition<?>> allUnionSubtypes = resolveAllUnionSubtypesFrom(unionType);
+
+        for (TypeDefinition<?> unionSubtype : allUnionSubtypes) {
+            for (Class<?> searchedType : searchedTypes) {
+                if (searchedType.isInstance(unionSubtype)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private List<TypeDefinition<?>> resolveAllUnionSubtypesFrom(UnionTypeDefinition inputType) {
+        List<TypeDefinition<?>> result = new ArrayList<>();
+        for (TypeDefinition<?> subtype : inputType.getTypes()) {
+            TypeDefinition<?> resolvedSubtype = subtype;
+
+            resolvedSubtype = resolveBaseTypeFrom(subtype);
+
+            if (resolvedSubtype instanceof UnionTypeDefinition) {
+                List<TypeDefinition<?>> subtypesFromRecursion = resolveAllUnionSubtypesFrom((UnionTypeDefinition) resolvedSubtype);
+                result.addAll(subtypesFromRecursion);
+            } else {
+                result.add(resolvedSubtype);
+            }
+        }
+
+        return result;
+    }
+
+    private TypeDefinition<?> resolveBaseTypeFrom(TypeDefinition<?> type) {
+        return type.getBaseType() != null ? resolveBaseTypeFrom(type.getBaseType()) : type;
+    }
+
+    private void writeName(Node<?> node, DataSchemaNode schema, JsonWriter writer) throws IOException {
+        String nameForOutput = node.getNodeType().getLocalName();
+        if (schema.isAugmenting()) {
+            ControllerContext contContext = ControllerContext.getInstance();
+            CharSequence moduleName;
+            moduleName = contContext.toRestconfIdentifier(schema.getQName());
+            if (moduleName != null) {
+                nameForOutput = moduleName.toString();
+            }
+        }
+        writer.name(nameForOutput);
+    }
+
     private static final class NumberForJsonWriter extends Number {
-        
+
         private static final long serialVersionUID = -3147729419814417666L;
         private final String value;
-        
+
         public NumberForJsonWriter(String value) {
             this.value = value;
         }
@@ -219,7 +288,7 @@ class JsonMapper {
         public String toString() {
             return value;
         }
-        
+
     }
 
 }
index dea4a73cd17d23f53f7c88d9b2ace669b285a2a6..2b1abaa987a6488a5626b8c0e2d48f5517abf80a 100644 (file)
@@ -1,7 +1,5 @@
 package org.opendaylight.controller.sal.rest.impl;
 
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
@@ -15,14 +13,17 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.Provider;
 
+import org.opendaylight.controller.sal.rest.api.Draft01;
+import org.opendaylight.controller.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 @Provider
-@Consumes({API+RestconfService.JSON})
+@Consumes({ Draft01.MediaTypes.DATA + RestconfService.JSON, Draft02.MediaTypes.DATA + RestconfService.JSON,
+        MediaType.APPLICATION_JSON })
 public enum JsonToCompositeNodeProvider implements MessageBodyReader<CompositeNode> {
     INSTANCE;
-    
+
     @Override
     public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
         return true;
@@ -36,8 +37,8 @@ public enum JsonToCompositeNodeProvider implements MessageBodyReader<CompositeNo
         try {
             return jsonReader.read(entityStream);
         } catch (UnsupportedFormatException e) {
-            throw new WebApplicationException(e,Response.status(Response.Status.BAD_REQUEST)
-                    .entity(e.getMessage()).build());
+            throw new WebApplicationException(e, Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage())
+                    .build());
         }
     }
 
index 90e6d2affc5cde925d4adc941b24d42005aad117..7022db2bc9bba631b2b21f50f2bb2a20d395d7d5 100644 (file)
@@ -1,7 +1,5 @@
 package org.opendaylight.controller.sal.rest.impl;
 
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
@@ -16,6 +14,8 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.MessageBodyWriter;
 import javax.ws.rs.ext.Provider;
 
+import org.opendaylight.controller.sal.rest.api.Draft01;
+import org.opendaylight.controller.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
@@ -24,10 +24,11 @@ import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import com.google.gson.stream.JsonWriter;
 
 @Provider
-@Produces({API+RestconfService.JSON})
+@Produces({ Draft01.MediaTypes.DATA + RestconfService.JSON, Draft02.MediaTypes.DATA + RestconfService.JSON,
+        MediaType.APPLICATION_JSON })
 public enum StructuredDataToJsonProvider implements MessageBodyWriter<StructuredData> {
     INSTANCE;
-    
+
     @Override
     public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
         return true;
index 9f41b571dade2dc5eb806e350a6e229d17598ded..d0c007795263be5d8777ebd9af29774a8b47d0d9 100644 (file)
@@ -1,7 +1,5 @@
 package org.opendaylight.controller.sal.rest.impl;
 
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
 import java.io.IOException;
 import java.io.OutputStream;
 import java.lang.annotation.Annotation;
@@ -21,7 +19,10 @@ import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
+import org.opendaylight.controller.sal.rest.api.Draft01;
+import org.opendaylight.controller.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.impl.NodeUtils;
@@ -30,10 +31,11 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 
 @Provider
-@Produces({API+RestconfService.XML})
+@Produces({ Draft01.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.DATA + RestconfService.XML,
+        MediaType.APPLICATION_XML, MediaType.TEXT_XML })
 public enum StructuredDataToXmlProvider implements MessageBodyWriter<StructuredData> {
     INSTANCE;
-    
+
     private final static Logger logger = LoggerFactory.getLogger(StructuredDataToXmlProvider.class);
 
     @Override
@@ -52,9 +54,9 @@ public enum StructuredDataToXmlProvider implements MessageBodyWriter<StructuredD
             throws IOException, WebApplicationException {
         CompositeNode data = t.getData();
         if (data == null) {
-            throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build());
+            throw new ResponseException(Response.Status.NOT_FOUND, "No data exists.");
         }
-        
+
         Document domTree = NodeUtils.buildShadowDomTree(data);
         try {
             TransformerFactory tf = TransformerFactory.newInstance();
@@ -67,7 +69,7 @@ public enum StructuredDataToXmlProvider implements MessageBodyWriter<StructuredD
             transformer.transform(new DOMSource(domTree), new StreamResult(entityStream));
         } catch (TransformerException e) {
             logger.error("Error during translation of Document to OutputStream", e);
-            throw new WebApplicationException(Response.status(Response.Status.INTERNAL_SERVER_ERROR).build());
+            throw new ResponseException(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage());
         }
     }
 
index 9f31eb46d52e9a722bffdc7d742859adba09cfc6..bf7ff7d43524732f067982042fb46e19f3d35134 100644 (file)
@@ -18,13 +18,13 @@ import org.opendaylight.controller.sal.restconf.impl.NodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
 
 public class XmlReader {
-    
+
     private final static XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
     private XMLEventReader eventReader;
 
     public CompositeNodeWrapper read(InputStream entityStream) throws XMLStreamException, UnsupportedFormatException {
         eventReader = xmlInputFactory.createXMLEventReader(entityStream);
-        
+
         if (eventReader.hasNext()) {
             XMLEvent element = eventReader.peek();
             if (element.isStartDocument()) {
@@ -35,7 +35,7 @@ public class XmlReader {
         if (eventReader.hasNext() && !isCompositeNodeEvent(eventReader.peek())) {
             throw new UnsupportedFormatException("Root element of XML has to be composite element.");
         }
-        
+
         final Stack<NodeWrapper<?>> processingQueue = new Stack<>();
         CompositeNodeWrapper root = null;
         NodeWrapper<?> element = null;
@@ -73,14 +73,14 @@ public class XmlReader {
                 element = processingQueue.pop();
             }
         }
-        
+
         if (!root.getLocalName().equals(element.getLocalName())) {
             throw new UnsupportedFormatException("XML should contain only one root element");
         }
-        
+
         return root;
     }
-    
+
     private boolean isSimpleNodeEvent(final XMLEvent event) throws XMLStreamException {
         checkArgument(event != null, "XML Event cannot be NULL!");
         if (event.isStartElement()) {
@@ -99,7 +99,7 @@ public class XmlReader {
         }
         return false;
     }
-    
+
     private boolean isCompositeNodeEvent(final XMLEvent event) throws XMLStreamException {
         checkArgument(event != null, "XML Event cannot be NULL!");
         if (event.isStartElement()) {
@@ -120,8 +120,9 @@ public class XmlReader {
         }
         return false;
     }
-    
-    private SimpleNodeWrapper resolveSimpleNodeFromStartElement(final StartElement startElement) throws XMLStreamException {
+
+    private SimpleNodeWrapper resolveSimpleNodeFromStartElement(final StartElement startElement)
+            throws XMLStreamException {
         checkArgument(startElement != null, "Start Element cannot be NULL!");
         String data = null;
 
@@ -133,25 +134,29 @@ public class XmlReader {
                     data = innerEvent.asCharacters().getData();
                 }
             } else if (innerEvent.isEndElement()) {
-                data = "";
+                if (startElement.getLocation().getCharacterOffset() == innerEvent.getLocation().getCharacterOffset()) {
+                    data = null;
+                } else {
+                    data = "";
+                }
             }
         }
-        
+
         return new SimpleNodeWrapper(getNamespaceFrom(startElement), getLocalNameFrom(startElement), data);
     }
-    
+
     private CompositeNodeWrapper resolveCompositeNodeFromStartElement(final StartElement startElement) {
         checkArgument(startElement != null, "Start Element cannot be NULL!");
         return new CompositeNodeWrapper(getNamespaceFrom(startElement), getLocalNameFrom(startElement));
     }
-    
+
     private String getLocalNameFrom(StartElement startElement) {
         return startElement.getName().getLocalPart();
     }
-    
+
     private URI getNamespaceFrom(StartElement startElement) {
         String namespaceURI = startElement.getName().getNamespaceURI();
         return namespaceURI.isEmpty() ? null : URI.create(namespaceURI);
     }
-    
+
 }
index 19720107d3b2e12a63e10cedec8ec173b7ea52e8..f09c3b4cc1769dfd02ff1b5e8666b14571673451 100644 (file)
@@ -1,7 +1,5 @@
 package org.opendaylight.controller.sal.rest.impl;
 
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
@@ -16,11 +14,15 @@ import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.Provider;
 import javax.xml.stream.XMLStreamException;
 
+import org.opendaylight.controller.sal.rest.api.Draft01;
+import org.opendaylight.controller.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 @Provider
-@Consumes({ API + RestconfService.XML })
+@Consumes({ Draft01.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.DATA + RestconfService.XML,
+        MediaType.APPLICATION_XML, MediaType.TEXT_XML })
 public enum XmlToCompositeNodeProvider implements MessageBodyReader<CompositeNode> {
     INSTANCE;
 
@@ -37,8 +39,7 @@ public enum XmlToCompositeNodeProvider implements MessageBodyReader<CompositeNod
         try {
             return xmlReader.read(entityStream);
         } catch (XMLStreamException | UnsupportedFormatException e) {
-            throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage())
-                    .build());
+            throw new ResponseException(Response.Status.BAD_REQUEST, e.getMessage());
         }
     }
 
index f5b913253201ee3d045bfbc00d3af994fdf8cba0..29ad7522c43436891ec6cb717ee6cbc713a04abd 100644 (file)
@@ -22,7 +22,7 @@ class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
     private DataBrokerService dataService;
     
     private new() {
-        if (INSTANCE != null) {
+        if (INSTANCE !== null) {
             throw new IllegalStateException("Already instantiated");
         }
     }
@@ -32,9 +32,8 @@ class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
     }
 
     private def void checkPreconditions() {
-        if (context == null || dataService == null) {
-            throw new WebApplicationException(Response.status(Response.Status.SERVICE_UNAVAILABLE)
-                    .entity(RestconfProvider::NOT_INITALIZED_MSG).build())
+        if (context === null || dataService === null) {
+            throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
         }
     }
 
index c1ee611e07c77241b1346f0683387d503111e1e9..065d01e8e9405058f563189e6f5117d30eed4857 100644 (file)
@@ -9,7 +9,6 @@ import java.util.HashMap
 import java.util.List
 import java.util.Map
 import java.util.concurrent.ConcurrentHashMap
-import javax.ws.rs.WebApplicationException
 import javax.ws.rs.core.Response
 import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
 import org.opendaylight.controller.sal.rest.impl.RestconfProvider
@@ -46,7 +45,7 @@ class ControllerContext implements SchemaServiceListener {
     
 
     private new() {
-        if (INSTANCE != null) {
+        if (INSTANCE !== null) {
             throw new IllegalStateException("Already instantiated");
         }
     }
@@ -56,9 +55,8 @@ class ControllerContext implements SchemaServiceListener {
     }
     
     private def void checkPreconditions() {
-        if (schemas == null) {
-            throw new WebApplicationException(Response.status(Response.Status.SERVICE_UNAVAILABLE)
-                    .entity(RestconfProvider::NOT_INITALIZED_MSG).build())
+        if (schemas === null) {
+            throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
         }
     }
 
@@ -72,7 +70,7 @@ class ControllerContext implements SchemaServiceListener {
             pathArgs.remove(0)
         }
         val schemaNode = ret.collectPathArguments(pathArgs, restconfInstance.findModule);
-        if (schemaNode == null) {
+        if (schemaNode === null) {
             return null
         }
         new InstanceIdWithSchemaNode(ret.toInstance, schemaNode)
@@ -92,7 +90,7 @@ class ControllerContext implements SchemaServiceListener {
 
     private def getLatestModule(SchemaContext schema, String moduleName) {
         checkNotNull(schema)
-        checkArgument(moduleName != null && !moduleName.empty)
+        checkArgument(moduleName !== null && !moduleName.empty)
         val modules = schema.modules.filter[m|m.name == moduleName]
         var latestModule = modules.head
         for (module : modules) {
@@ -134,9 +132,9 @@ class ControllerContext implements SchemaServiceListener {
     def CharSequence toRestconfIdentifier(QName qname) {
         checkPreconditions
         var module = uriToModuleName.get(qname.namespace)
-        if (module == null) {
+        if (module === null) {
             val moduleSchema = schemas.findModuleByNamespaceAndRevision(qname.namespace, qname.revision);
-            if(moduleSchema == null) throw new IllegalArgumentException()
+            if(moduleSchema === null) throw new IllegalArgumentException()
             uriToModuleName.put(qname.namespace, moduleSchema.name)
             module = moduleSchema.name;
         }
@@ -189,13 +187,16 @@ class ControllerContext implements SchemaServiceListener {
     }
 
     private def toUriString(Object object) {
-        if(object == null) return "";
+        if(object === null) return "";
         return URLEncoder.encode(object.toString)
     }
 
     private def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List<String> strings,
         DataNodeContainer parentNode) {
         checkNotNull(strings)
+        if (parentNode === null) {
+            return null;
+        }
         if (strings.empty) {
             return parentNode as DataSchemaNode;
         }
@@ -203,14 +204,14 @@ class ControllerContext implements SchemaServiceListener {
 
         val nodeName = nodeRef.toNodeName();
         val targetNode = parentNode.getDataChildByName(nodeName);
-        if (targetNode == null) {
+        if (targetNode === null) {
             val children = parentNode.childNodes
             for (child : children) {
                 if (child instanceof ChoiceNode) {
                     val choice = child as ChoiceNode
                     for (caze : choice.cases) {
                         val result = builder.collectPathArguments(strings, caze as DataNodeContainer);
-                        if (result != null)
+                        if (result !== null)
                             return result
                     }
                 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/MediaTypes.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/MediaTypes.java
deleted file mode 100644 (file)
index af18828..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.restconf.impl;
-
-public class MediaTypes {
-    public static final String API = "application/vnd.yang.api";
-    public static final String DATASTORE = "application/vnd.yang.datastore";
-    public static final String DATA = "application/vnd.yang.data";
-    public static final String EVENT = "application/vnd.yang.event";
-    public static final String OPERATION = "application/vnd.yang.operation";
-    public static final String PATCH = "application/vnd.yang.patch";
-}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ResponseException.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ResponseException.java
new file mode 100644 (file)
index 0000000..e2edd5d
--- /dev/null
@@ -0,0 +1,15 @@
+package org.opendaylight.controller.sal.restconf.impl;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+public class ResponseException extends WebApplicationException {
+
+    private static final long serialVersionUID = -5320114450593021655L;
+
+    public ResponseException(Status status, String msg) {
+        super(Response.status(status).type(MediaType.TEXT_PLAIN_TYPE).entity(msg).build());
+    }
+}
index d9ac53589fa5415bcba3e59467576fcbb98d069e..8f6ca1685bbb4b0c6f81ec2dc85ae4fd4c92d5f2 100644 (file)
@@ -7,6 +7,7 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus
+import javax.ws.rs.WebApplicationException
 
 class RestconfImpl implements RestconfService {
     
@@ -19,7 +20,7 @@ class RestconfImpl implements RestconfService {
     extension ControllerContext controllerContext
     
     private new() {
-        if (INSTANCE != null) {
+        if (INSTANCE !== null) {
             throw new IllegalStateException("Already instantiated");
         }
     }
@@ -42,13 +43,13 @@ class RestconfImpl implements RestconfService {
     }
 
     override readData(String identifier) {
-        val instanceIdentifierWithSchemaNode = identifier.toInstanceIdentifier
+        val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
         val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
         return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
     }
 
     override createConfigurationData(String identifier, CompositeNode payload) {
-        val identifierWithSchemaNode = identifier.toInstanceIdentifier
+        val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
         val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
         val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
         switch status.result {
@@ -58,7 +59,7 @@ class RestconfImpl implements RestconfService {
     }
 
     override updateConfigurationData(String identifier, CompositeNode payload) {
-        val identifierWithSchemaNode = identifier.toInstanceIdentifier
+        val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
         val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
         val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
         switch status.result {
@@ -76,13 +77,13 @@ class RestconfImpl implements RestconfService {
     }
     
     override readConfigurationData(String identifier) {
-        val instanceIdentifierWithSchemaNode = identifier.toInstanceIdentifier
+        val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
         val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
         return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
     }
     
     override readOperationalData(String identifier) {
-        val instanceIdentifierWithSchemaNode = identifier.toInstanceIdentifier
+        val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
         val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
         return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
     }
@@ -96,7 +97,7 @@ class RestconfImpl implements RestconfService {
     }
     
     override createOperationalData(String identifier, CompositeNode payload) {
-        val identifierWithSchemaNode = identifier.toInstanceIdentifier
+        val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
         val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
         val status = broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
         switch status.result {
@@ -106,7 +107,7 @@ class RestconfImpl implements RestconfService {
     }
     
     override updateOperationalData(String identifier, CompositeNode payload) {
-        val identifierWithSchemaNode = identifier.toInstanceIdentifier
+        val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
         val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
         val status = broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
         switch status.result {
@@ -115,6 +116,14 @@ class RestconfImpl implements RestconfService {
         }
     }
     
+    private def InstanceIdWithSchemaNode resolveInstanceIdentifier(String identifier) {
+        val identifierWithSchemaNode = identifier.toInstanceIdentifier
+        if (identifierWithSchemaNode === null) {
+            throw new ResponseException(Response.Status.BAD_REQUEST, "URI has bad format");
+        }
+        return identifierWithSchemaNode
+    }
+    
     private def CompositeNode resolveNodeNamespaceBySchema(CompositeNode node, DataSchemaNode schema) {
         if (node instanceof CompositeNodeWrapper) {
             addNamespaceToNodeFromSchemaRecursively(node as CompositeNodeWrapper, schema)
@@ -124,7 +133,7 @@ class RestconfImpl implements RestconfService {
     }
 
     private def void addNamespaceToNodeFromSchemaRecursively(NodeWrapper<?> nodeBuilder, DataSchemaNode schema) {
-        if (nodeBuilder.namespace == null) {
+        if (nodeBuilder.namespace === null) {
             nodeBuilder.namespace = schema.QName.namespace
         }
         if (nodeBuilder instanceof CompositeNodeWrapper) {
index 12f33d4562526b25feef31e8dd9e7c6a9dfa352c..62a9ae05814b3a2d7a7d259c0811d484c580f99e 100644 (file)
@@ -1,13 +1,13 @@
 package org.opendaylight.controller.sal.restconf.impl;
 
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.*;
 
 public class StructuredData {
-    
+
     private final CompositeNode data;
     private final DataSchemaNode schema;
-    
+
     public StructuredData(CompositeNode data, DataSchemaNode schema) {
         this.data = data;
         this.schema = schema;
@@ -20,5 +20,4 @@ public class StructuredData {
     public DataSchemaNode getSchema() {
         return schema;
     }
-    
 }
index ede225c709ea89f53b411ecf14fc366dda27522b..2e8b07151914b12c9b0c2a360b1c9b075c0a880a 100644 (file)
@@ -90,7 +90,7 @@ public class FromJsonToCompositeNodeTest {
     }
 
     @Test
-    public void nullArrayToCompositeNodeWithNullValueTest() {
+    public void nullArrayToSimpleNodeWithNullValueTest() {
         CompositeNode compositeNode = compositeContainerFromJson("/json-to-composite-node/array-with-null.json", true);
         assertNotNull(compositeNode);
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
index 6249d2a5b0d3a475fa6435714a24fc57d901a554..ef122dd8d7f68cba55088831d9ebe639c869b646 100644 (file)
@@ -11,7 +11,7 @@ import javax.ws.rs.WebApplicationException;
 
 import org.junit.*;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
-import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.*;
 import org.opendaylight.yangtools.yang.data.api.*;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.slf4j.*;
@@ -41,9 +41,36 @@ public class FromXmlToCompositeNodeTest {
         String nameSpace = "data:container:yang";
         assertEquals(nameSpace, compNode.getNodeType().getNamespace().toString());
 
+        verifyNullAndEmptyStringSingleNode(compNode, nameSpace);
         verifyCommonPartAOfXml(compNode, "", nameSpace);
     }
 
+    private void verifyNullAndEmptyStringSingleNode(CompositeNode compNode, String nameSpace) {
+        assertEquals("cont", compNode.getNodeType().getLocalName());
+
+        SimpleNode<?> lf2 = null;
+        SimpleNode<?> lf3 = null;
+        int found = 0;
+        for (Node<?> child : compNode.getChildren()) {
+            if (found == 0x3)
+                break;
+            if (child instanceof SimpleNode<?>) {
+                SimpleNode<?> childSimple = (SimpleNode<?>) child;
+                if (childSimple.getNodeType().getLocalName().equals("lf3")) {
+                    lf3 = childSimple;
+                    found = found | (1 << 0);
+                } else if (childSimple.getNodeType().getLocalName().equals("lf2")) {
+                    lf2 = childSimple;
+                    found = found | (1 << 1);
+                }
+            }
+            assertEquals(nameSpace, child.getNodeType().getNamespace().toString());
+        }
+
+        assertEquals("", lf2.getValue());
+        assertEquals(null, lf3.getValue());
+    }
+
     @Test
     public void testXmlDataList() {
         CompositeNode compNode = compositeContainerFromXml("/xml-to-composite-node/data-list.xml", false);
index 1d8d7495f9dfabae21bdddb737401032af34724b..bc941b997e35dd63c8a3250cb52e8ccf66e27314 100644 (file)
@@ -13,9 +13,7 @@ import java.util.*;
 import java.util.concurrent.Future;
 
 import javax.ws.rs.WebApplicationException;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.*;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.transform.*;
 import javax.xml.transform.dom.DOMSource;
@@ -24,8 +22,7 @@ import javax.xml.transform.stream.StreamResult;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
 import org.opendaylight.controller.sal.restconf.impl.*;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.*;
 import org.opendaylight.yangtools.yang.data.api.*;
 import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
 import org.opendaylight.yangtools.yang.model.api.*;
@@ -99,7 +96,7 @@ final class TestUtils {
         }
         return (CompositeNode) dataTree;
     }
-    
+
     public static Document loadDocumentFrom(InputStream inputStream) {
         try {
             DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
@@ -135,6 +132,11 @@ final class TestUtils {
     }
 
     static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath, String outputPath) {
+        return convertCompositeNodeDataAndYangToJson(compositeNode, yangPath, outputPath, null, null);
+    }
+
+    static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath,
+            String outputPath, String searchedModuleName, String searchedDataSchemaName) {
         String jsonResult = null;
         Set<Module> modules = null;
 
@@ -145,30 +147,54 @@ final class TestUtils {
         }
         assertNotNull("modules can't be null.", modules);
 
+        Module module = null;
+        if (searchedModuleName != null) {
+            for (Module m : modules) {
+                if (m.getName().equals(searchedModuleName)) {
+                    module = m;
+                    break;
+                }
+            }
+        } else if (modules.size() == 1) {
+            module = modules.iterator().next();
+        }
+        assertNotNull("Module is missing", module);
+
         assertNotNull("Composite node can't be null", compositeNode);
 
         StructuredDataToJsonProvider structuredDataToJsonProvider = StructuredDataToJsonProvider.INSTANCE;
-        for (Module module : modules) {
-            ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
-            for (DataSchemaNode dataSchemaNode : module.getChildNodes()) {
-                StructuredData structuredData = new StructuredData(compositeNode, dataSchemaNode);
-                try {
-                    structuredDataToJsonProvider.writeTo(structuredData, null, null, null, null, null, byteArrayOS);
-                } catch (WebApplicationException | IOException e) {
-                    e.printStackTrace();
+        ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
+        DataSchemaNode dataSchemaNode = null;
+        if (searchedDataSchemaName != null) {
+            for (DataSchemaNode dsn : module.getChildNodes()) {
+                if (dsn.getQName().getLocalName().equals(searchedDataSchemaName)) {
+                    dataSchemaNode = dsn;
                 }
-                assertFalse(
-                        "Returning JSON string can't be empty for node " + dataSchemaNode.getQName().getLocalName(),
-                        byteArrayOS.toString().isEmpty());
-            }
-            jsonResult = byteArrayOS.toString();
-            try {
-                outputToFile(byteArrayOS, outputPath);
-            } catch (IOException e) {
-                System.out.println("Output file wasn't cloased sucessfuly.");
             }
+        } else if (module.getChildNodes().size() == 1) {
+            dataSchemaNode = module.getChildNodes().iterator().next();
+        }
+        assertNotNull(dataSchemaNode);
+        // SchemaContextUtil.
+
+        ControllerContext controllerContext = ControllerContext.getInstance();
+        controllerContext.setSchemas(loadSchemaContext(modules));
+        StructuredData structuredData = new StructuredData(compositeNode, dataSchemaNode);
+        try {
+            structuredDataToJsonProvider.writeTo(structuredData, null, null, null, null, null, byteArrayOS);
+        } catch (WebApplicationException | IOException e) {
+            e.printStackTrace();
+        }
+        assertFalse("Returning JSON string can't be empty for node " + dataSchemaNode.getQName().getLocalName(),
+                byteArrayOS.toString().isEmpty());
 
+        jsonResult = byteArrayOS.toString();
+        try {
+            outputToFile(byteArrayOS, outputPath);
+        } catch (IOException e) {
+            System.out.println("Output file wasn't cloased sucessfuly.");
         }
+
         return jsonResult;
     }
 
@@ -296,7 +322,8 @@ final class TestUtils {
         RpcResult<TransactionStatus> rpcResult = DummyRpcResult.builder().result(TransactionStatus.COMMITED).build();
         Future<RpcResult<TransactionStatus>> future = DummyFuture.builder().rpcResult(rpcResult).build();
         when(controllerContext.toInstanceIdentifier(any(String.class))).thenReturn(instIdAndSchema);
-        when(broker.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(future);
+        when(broker.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(
+                future);
 
         restconf.setControllerContext(controllerContext);
         restconf.setBroker(broker);
@@ -320,15 +347,15 @@ final class TestUtils {
         if (modules.size() < 1) {
             return null;
         }
-        
-        Module moduleRes = null;        
+
+        Module moduleRes = null;
         if (modules.size() > 1) {
             if (moduleName == null) {
                 return null;
             } else {
-                for (Module module: modules) {
+                for (Module module : modules) {
                     if (module.getName().equals(moduleName)) {
-                        moduleRes = module; 
+                        moduleRes = module;
                     }
                 }
                 if (moduleRes == null) {
@@ -338,7 +365,7 @@ final class TestUtils {
         } else {
             moduleRes = modules.iterator().next();
         }
-        
+
         if (moduleRes.getChildNodes() == null) {
             return null;
         }
index f88a335f18c9ac37927f34e973ab469ebaa0315c..69de9f86c1defa491003d13db1a4825183deb521 100644 (file)
@@ -18,10 +18,6 @@ public class ToJsonBasicDataTypesTest {
     @Test
     public void simpleYangDataTest() {
         String jsonOutput;
-        // jsonOutput =
-        // TestUtils.readJsonFromFile("/yang-to-json-conversion/simple-yang-types/xml/awaited_output.json",
-        // false);
-
         jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
                 TestUtils.loadCompositeNode("/yang-to-json-conversion/simple-data-types/xml/data.xml"),
                 "/yang-to-json-conversion/simple-data-types", "/yang-to-json-conversion/simple-data-types/xml");
@@ -73,7 +69,7 @@ public class ToJsonBasicDataTypesTest {
         // boolean lfref1Checked = false;
         boolean lfemptyChecked = false;
         boolean lfstr1Checked = false;
-        
+
         while (jReader.hasNext()) {
             String keyName = jReader.nextName();
             JsonToken peek = null;
@@ -148,10 +144,8 @@ public class ToJsonBasicDataTypesTest {
                 jReader.nextNull();
                 jReader.endArray();
                 lfemptyChecked = true;
-                // TODO: test will be implemented when functionality will be
-                // implemented
-            } else if (keyName.equals("lflstunion")) {
-                jReader.skipValue();
+            } else if (keyName.startsWith("lfunion")) {
+                checkLfUnion(jReader, keyName, peek);
             } else {
                 assertTrue("Key " + keyName + " doesn't exists in yang file.", false);
             }
@@ -180,4 +174,44 @@ public class ToJsonBasicDataTypesTest {
         jReader.endObject();
 
     }
+
+    private void checkLfUnion(JsonReader jReader, String keyName, JsonToken peek) throws IOException {
+        if (keyName.equals("lfunion1")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+            jReader.nextString();
+        } else if (keyName.equals("lfunion2")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+            jReader.nextString();
+        } else if (keyName.equals("lfunion3")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            jReader.nextInt();
+        } else if (keyName.equals("lfunion4")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
+            jReader.nextBoolean();
+        } else if (keyName.equals("lfunion5")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            jReader.nextString();
+        } else if (keyName.equals("lfunion6")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            jReader.nextString();
+        } else if (keyName.equals("lfunion7")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            jReader.nextString();
+        } else if (keyName.equals("lfunion8")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            jReader.nextString();
+        } else if (keyName.equals("lfunion9")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            jReader.nextString();
+        } else if (keyName.equals("lfunion10")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            jReader.nextString();
+        } else if (keyName.equals("lfunion11")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+            jReader.nextString();
+        } else if (keyName.equals("lfunion12")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
+            jReader.nextBoolean();
+        }
+    }
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonWithAugmentTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonWithAugmentTest.java
new file mode 100644 (file)
index 0000000..994916d
--- /dev/null
@@ -0,0 +1,27 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class ToJsonWithAugmentTest {
+
+    /**
+     * Test of json output when as input are specified composite node with empty
+     * data + YANG file
+     */
+    @Test
+    public void augmentedElementsToJson() {
+        String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
+                TestUtils.loadCompositeNode("/yang-to-json-conversion/augmentation/xml/data.xml"),
+                "/yang-to-json-conversion/augmentation", "/yang-to-json-conversion/augmentation/xml", "yang", "cont");
+
+        assertTrue(jsonOutput.contains("\"augment-leaf:lf2\": \"lf2\""));
+        assertTrue(jsonOutput.contains("\"augment-container:cont1\": {"));
+        assertTrue(jsonOutput.contains("\"augment-container:lf11\": \"lf11\""));
+        assertTrue(jsonOutput.contains("\"augment-list:lst1\": ["));
+        assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_1\""));
+        assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_2\""));
+        assertTrue(jsonOutput.contains("\"augment-leaflist:lflst1\": ["));
+    }
+}
index 7b63c5fd9422e5bb3abd0060be1ba57dc9643389..4336ac8a8325b14ab883834a7e9b91a0a6fb7655 100644 (file)
@@ -29,12 +29,12 @@ import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.rest.api.Draft01;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
-import org.opendaylight.controller.sal.restconf.impl.MediaTypes;
 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
@@ -49,7 +49,8 @@ public class XmlProvidersTest extends JerseyTest {
     private static ControllerContext controllerContext;
     private static BrokerFacade brokerFacade;
     private static RestconfImpl restconfImpl;
-    private static final MediaType MEDIA_TYPE = new MediaType("application", "vnd.yang.api+xml");
+    private static final MediaType MEDIA_TYPE = new MediaType("application", "vnd.yang.data+xml");
+    private static final MediaType MEDIA_TYPE_DRAFT02 = new MediaType("application", "yang.data+xml");
 
     @BeforeClass
     public static void init() throws FileNotFoundException {
@@ -87,11 +88,11 @@ public class XmlProvidersTest extends JerseyTest {
     public void testBadFormatXmlToCompositeNodeProvider() throws UnsupportedEncodingException, URISyntaxException {
         String uri = createUri("/operations/", "ietf-interfaces:interfaces/interface/eth0");
         
-        Response response = target(uri).request(MediaTypes.API + RestconfService.XML).post(
+        Response response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).post(
                 Entity.entity("<SimpleNode/>", MEDIA_TYPE));
         assertEquals(400, response.getStatus());
         
-        response = target(uri).request(MediaTypes.API + RestconfService.XML).post(
+        response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).post(
                 Entity.entity("<SimpleNode>", MEDIA_TYPE));
         assertEquals(400, response.getStatus());
     }
@@ -102,59 +103,69 @@ public class XmlProvidersTest extends JerseyTest {
         
         when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
         
-        Response response = target(uri).request(MediaTypes.API+RestconfService.XML).get();
+        Response response = target(uri).request(Draft01.MediaTypes.DATA+RestconfService.XML).get();
         assertEquals(404, response.getStatus());
     }
     
+    @Test
+    public void testXmlToCompositeNode400() throws UnsupportedEncodingException, URISyntaxException {
+        String uri = createUri("/datastore/", "simple-nodes:user/name");
+        
+        when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
+        
+        Response response = target(uri).request(Draft01.MediaTypes.DATA+RestconfService.XML).get();
+        assertEquals(400, response.getStatus());
+    }
+    
     @Test
     public void testRpcResultCommitedToStatusCodes() throws UnsupportedEncodingException {
         InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
         String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
-        Entity<String> entity = Entity.entity(xml, MEDIA_TYPE);
+        Entity<String> entity = Entity.entity(xml, MEDIA_TYPE_DRAFT02);
         RpcResult<TransactionStatus> rpcResult = DummyRpcResult.builder().result(TransactionStatus.COMMITED).build();
         Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
         when(brokerFacade.commitOperationalDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
         when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
         
         String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
-        Response response = target(uri).request(MEDIA_TYPE).put(entity);
-        assertEquals(200, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE).post(entity);
+        Response response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
         assertEquals(204, response.getStatus());
+        response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
+        assertEquals(200, response.getStatus());
         
         uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
-        response = target(uri).request(MEDIA_TYPE).put(entity);
-        assertEquals(200, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE).post(entity);
+        response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
         assertEquals(204, response.getStatus());
+        response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
+        assertEquals(200, response.getStatus());
         
         uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
         response = target(uri).request(MEDIA_TYPE).put(entity);
-        assertEquals(200, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE).post(entity);
         assertEquals(204, response.getStatus());
+        response = target(uri).request(MEDIA_TYPE).post(entity);
+        assertEquals(200, response.getStatus());
     }
     
     @Test
     public void testRpcResultOtherToStatusCodes() throws UnsupportedEncodingException {
         InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
         String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
-        Entity<String> entity = Entity.entity(xml, MEDIA_TYPE);
+        Entity<String> entity = Entity.entity(xml, MEDIA_TYPE_DRAFT02);
         RpcResult<TransactionStatus> rpcResult = DummyRpcResult.builder().result(TransactionStatus.FAILED).build();
         Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
         when(brokerFacade.commitOperationalDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
         when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
         
         String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
-        Response response = target(uri).request(MEDIA_TYPE).put(entity);
+        Response response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
         assertEquals(500, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE).post(entity);
+        response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
         assertEquals(500, response.getStatus());
         
         uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
-        response = target(uri).request(MEDIA_TYPE).put(entity);
+        response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
         assertEquals(500, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE).post(entity);
+        response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
         assertEquals(500, response.getStatus());
         
         uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
index 7c17bf9fdf3b240290595fecb734c33db87b7552..b038eb193ccbc882c2e0c218a27e4531a75e2342 100644 (file)
@@ -2,13 +2,22 @@ module data-container-yang {
   namespace "data:container:yang";  
 
   prefix "dtconyg";
-  revision 2013-11-19 {    
+       revision 2013-11-19 {    
   }
   
   container cont {
        leaf lf1 {
                type string;
        }
+       
+       leaf lf2 {
+               type string;
+       }
+       
+       leaf lf3 {
+               type empty;
+       }
+       
        leaf-list lflst1 {
                type string;
        }
index 0c60fbcff3903fb64ab3fc8165758948f546d107..ce97dd1715c51e8f96b54ca90da5a4d9f6d88ef7 100644 (file)
@@ -1,5 +1,7 @@
 <cont>
        <lf1>str0</lf1>
+       <lf2></lf2>
+       <lf3/>
        <lflst1>121</lflst1>
        <lflst1>131</lflst1>
        <lflst1>str1</lflst1>
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-container.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-container.yang
new file mode 100644 (file)
index 0000000..7efe4f7
--- /dev/null
@@ -0,0 +1,22 @@
+module augment-container {
+  namespace "ns:augment:container";  
+  prefix "augcont";
+
+  
+  import yang {prefix yng; revision-date 2013-11-26;}  
+
+
+  revision "2013-11-26" {    
+  }
+  
+       augment "/yng:cont" {
+               container cont1 {
+                       leaf lf11 {
+                               type string;
+                       }
+               }
+       }
+       
+
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaf.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaf.yang
new file mode 100644 (file)
index 0000000..248d3bb
--- /dev/null
@@ -0,0 +1,18 @@
+module augment-leaf {
+  namespace "ns:augment:leaf";  
+  prefix "auglf";
+
+  
+  import yang {prefix yng; revision-date 2013-11-26;}  
+
+
+  revision "2013-11-26" {    
+  }
+  
+       augment "/yng:cont" {
+               leaf lf2 {
+                       type string;
+               }
+       }
+       
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaflist.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaflist.yang
new file mode 100644 (file)
index 0000000..1f4b937
--- /dev/null
@@ -0,0 +1,20 @@
+module augment-leaflist {
+  namespace "ns:augment:leaflist";  
+  prefix "auglflst";
+
+  
+  import yang {prefix yng; revision-date 2013-11-26;}  
+
+
+  revision "2013-11-26" {    
+  }
+  
+       augment "/yng:cont" {
+               leaf-list lflst1 {
+                       type string;
+               }
+       }
+       
+
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-list.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-list.yang
new file mode 100644 (file)
index 0000000..a35a87e
--- /dev/null
@@ -0,0 +1,22 @@
+module augment-list {
+  namespace "ns:augment:list";  
+  prefix "auglst";
+
+  
+  import yang {prefix yng; revision-date 2013-11-26;}  
+
+
+  revision "2013-11-26" {    
+  }
+  
+       augment "/yng:cont" {
+               list lst1 {
+                       leaf lf11 {
+                               type string;
+                       }
+               }
+       }
+       
+
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/xml/data.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/xml/data.xml
new file mode 100644 (file)
index 0000000..08cdb34
--- /dev/null
@@ -0,0 +1,16 @@
+<cont>
+       <lf1>lf1</lf1>
+       <lf2>lf2</lf2>
+       <cont1>
+               <lf11>lf11</lf11>
+       </cont1>
+       <lst1>
+               <lf11>lf1_1</lf11>
+       </lst1>
+       <lst1>
+               <lf11>lf1_2</lf11>
+       </lst1>
+       <lflst1>lflst1_1</lflst1>
+       <lflst1>lflst1_2</lflst1>
+       <lflst1>lflst1_3</lflst1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/yang.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/yang.yang
new file mode 100644 (file)
index 0000000..aeb9737
--- /dev/null
@@ -0,0 +1,17 @@
+module yang {
+  namespace "ns:yang";  
+
+  prefix "yng";
+  revision 2013-11-26 {    
+  }
+  
+       container cont {
+               leaf lf1 {
+                       type string;
+               }
+               
+       }
+       
+
+         
+}
\ No newline at end of file
index 010d3b1c2b374c1a9002877700bac6787ea6b676..759b3ecf71cd564a8702bb694f7b9177748b8c30 100644 (file)
@@ -5,6 +5,45 @@ module simple-data-types {
   revision 2013-11-12 {    
   }
   
+  typedef tpdfempty {
+       type empty;
+  }
+  
+  typedef tpdfbit {
+       type bits {
+               bit b1;
+               bit b2;
+               bit b3;
+       }
+  }
+  
+  typedef tpdfun4 {
+       type boolean;
+  }
+  
+  typedef tpdfun3 {
+       type union {
+               type tpdfbit;
+               type tpdfempty;
+       }
+  }  
+  
+  typedef tpdfun2 {
+       type union {
+               type tpdfun3;
+               type tpdfun4;
+       }
+  }
+  
+  typedef tpdfun1 {
+       type union {
+               type uint8;
+               type decimal64 {
+                       fraction-digits 2;
+               }
+       }
+  }
+  
   container cont {
          leaf lfnint8Min {
                type int8; 
@@ -125,12 +164,87 @@ module simple-data-types {
        type empty;
     }
     
-    leaf-list lflstunion {
+    leaf lfunion1 {
        type union {
                type uint16;
                type string;
        }
     }
+    leaf lfunion2 {
+       type union {
+               type decimal64 {
+                               fraction-digits 2;              
+               }
+               type string;
+       }
+    }
+    
+    leaf lfunion3 {
+       type union {
+               type empty;
+               type string;
+       }
+    }
+    
+    leaf lfunion4 {
+       type union {
+               type boolean;
+               type string;
+       }
+    }
+    
+    leaf lfunion5 {
+       type union {
+               type uint16;
+               type string;
+       }
+    }
+    
+    leaf lfunion6 {
+       type union {
+               type uint16;
+               type empty;
+       }
+    }
+    
+    leaf lfunion7 {
+               type tpdfun3;
+    }
+    
+    leaf lfunion8 {
+       type union {
+               type uint16;
+               type string;
+       }
+    }
+    
+    leaf lfunion9 {
+       type union {
+               type uint16;
+               type boolean;                   
+       }
+    }
+    
+    leaf lfunion10 {
+       type union {
+               type bits {
+                       bit bt1;
+                       bit bt2;
+               }
+               type boolean;                   
+       }
+    }
+    
+    leaf lfunion11 {
+               type union {
+                       type tpdfun1;
+                       type tpdfun2;
+               }
+    }
+    
+    leaf lfunion12 {
+               type tpdfun2;
+    }
          
          
   }
index df00ca917e7d16f1e5f8a65bdaec9f10671cecc8..0d31e9037a763b3732274da5eddc2512a8c8ecb4 100644 (file)
        <lfbits>bit3</lfbits>   
        <lfbinary>AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%%-#^</lfbinary>
        <lfempty></lfempty>
-       <lflstunion>324</lflstunion>
-       <lflstunion>33.3</lflstunion>
-       <lflstunion>lfunion</lflstunion>
-       <lflstunion>true</lflstunion>
+       <lfunion1>324</lfunion1>
+       <lfunion2>33.3</lfunion2>
+       <lfunion3>55</lfunion3>
+       <lfunion4>true</lfunion4>
+       <lfunion5>true</lfunion5>
+       <lfunion6>false</lfunion6>
+       <lfunion7></lfunion7>
+       <lfunion8></lfunion8>
+       <lfunion9></lfunion9>
+       <lfunion10>bt1</lfunion10>
+       <lfunion11>33</lfunion11>
+       <lfunion12>false</lfunion12>
 </cont>
\ No newline at end of file
index 04e0a32ffbe3e93946a31f2a27cdce23d0b800c2..6b87a224180bbd49713d9f26eb6c6f7dfcd1820d 100644 (file)
@@ -27,7 +27,7 @@
           <activeByDefault>false</activeByDefault>
         </activation>
         <modules>
-          <module>toaster-it</module>
+          <!--module>toaster-it</module -->
         </modules>
       </profile>
     </profiles>
index 7cbd2314b60265e04626ba4d2409a4f2912be559..521de7e394ee69fd3d5dfdda4bf8f546a1b513c0 100644 (file)
@@ -28,6 +28,7 @@ public class StatisticsManagerActivator extends AbstractBindingAwareProvider {
     @Override
     public void onSessionInitiated(ProviderContext session) {
         
+        pSession = session;
         DataProviderService dps = session.<DataProviderService>getSALService(DataProviderService.class);
         StatisticsManagerActivator.statsProvider.setDataService(dps);
         NotificationProviderService nps = session.<NotificationProviderService>getSALService(NotificationProviderService.class);
index 5218d051fa2cdb40ec9fa47f58114abf5c334dc6..d1ab3515035dfb0b5597c263c5f23ac29656d659 100644 (file)
@@ -100,8 +100,6 @@ public class StatisticsProvider implements AutoCloseable {
             public void run() {
                 while(true){
                     try {
-                        spLogger.info("Statistics requester thread started with timer interval : {}",5000);
-                        
                         statsRequestSender();
                         
                         Thread.sleep(5000);
@@ -111,6 +109,11 @@ public class StatisticsProvider implements AutoCloseable {
                 }
             }
         });
+        
+        spLogger.debug("Statistics requester thread started with timer interval : {}",5000);
+        
+        statisticsRequesterThread.start();
+        
         spLogger.info("Statistics Provider started.");
     }
     
@@ -124,6 +127,9 @@ public class StatisticsProvider implements AutoCloseable {
         
         //Need to call API to receive all the nodes connected to controller.
         List<Node> targetNodes = getAllConnectedNodes();
+        
+        if(targetNodes == null)
+            return;
 
         for (Node targetNode : targetNodes){
             spLogger.info("Send request for stats collection to node : {})",targetNode.getId());
@@ -212,6 +218,9 @@ public class StatisticsProvider implements AutoCloseable {
     private List<Node> getAllConnectedNodes(){
         
         Nodes nodes = (Nodes) dps.readOperationalData(nodesIdentifier);
+        if(nodes == null)
+            return null;
+        
         spLogger.info("Number of connected nodes : {}",nodes.getNode().size());
         return nodes.getNode();
     }
index 23ba8aaea41e5866fc1934290bfd17f6154aadd9..41ae52b3bf0ff5da3cfb3adcffb6ccfbeb4ac491 100644 (file)
@@ -21,7 +21,6 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.connect.netconf.InventoryUtils;
-import org.opendaylight.controller.sal.connect.netconf.NetconfDeviceManager;
 import org.opendaylight.controller.sal.connect.netconf.NetconfInventoryUtils;
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
@@ -61,9 +60,6 @@ public class ServiceProviderController {
     @Inject
     DataBrokerService dataBroker;
 
-    @Inject
-    NetconfDeviceManager netconfManager;
-
     @Test
     public void properInitialized() throws Exception {
 
@@ -72,8 +68,6 @@ public class ServiceProviderController {
         InstanceIdentifier path = InstanceIdentifier.builder(InventoryUtils.INVENTORY_PATH)
                 .nodeWithKey(InventoryUtils.INVENTORY_NODE, InventoryUtils.INVENTORY_ID, "foo").toInstance();
 
-        netconfManager.netconfNodeAdded(path, new InetSocketAddress("127.0.0.1", 8383));
-
         
         InstanceIdentifier mountPointPath = path;
         
diff --git a/opendaylight/md-sal/topology-manager/pom.xml b/opendaylight/md-sal/topology-manager/pom.xml
new file mode 100644 (file)
index 0000000..6e50f9c
--- /dev/null
@@ -0,0 +1,75 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>sal-parent</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <groupId>org.opendaylight.controller.md</groupId>
+    <artifactId>topology-manager</artifactId>
+    <packaging>bundle</packaging>
+    <scm>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+        <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+    </scm>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-api</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-util</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-flow-service</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-inventory</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-topology-view</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.xtend</groupId>
+            <artifactId>org.eclipse.xtend.lib</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-Activator>org.opendaylight.controller.md.inventory.manager.InventoryActivator</Bundle-Activator>
+                        <Private-Package>org.opendaylight.controller.md.inventory.manager</Private-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.eclipse.xtend</groupId>
+                <artifactId>xtend-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-clean-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend
new file mode 100644 (file)
index 0000000..46f5d2b
--- /dev/null
@@ -0,0 +1,45 @@
+package org.opendaylight.md.controller.topology.manager
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnector
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId
+
+class FlowCapableNodeMapping {
+
+    static def NodeKey getNodeKey(NodeRef ref) {
+        (ref?.value?.path?.get(1) as IdentifiableItem<Node,NodeKey>).key
+    }
+
+    static def NodeKey getNodeKey(NodeConnectorRef ref) {
+        (ref?.value?.path?.get(1) as IdentifiableItem<Node,NodeKey>).key
+    }
+
+    static def NodeConnectorKey getNodeConnectorKey(NodeConnectorRef ref) {
+        (ref?.value?.path?.get(2) as IdentifiableItem<NodeConnector,NodeConnectorKey>).key
+    }
+
+    static def TerminationPoint toTerminationPoint(NodeConnectorUpdated updated) {
+        val it = new TerminationPointBuilder
+        key = new TerminationPointKey(new TpId(updated.id));
+        return it.build()
+    }
+
+    static def NodeId toToplogyNodeId(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId nodeId) {
+        return new NodeId(nodeId);
+    }
+
+    static def toTerminationPointId(NodeConnectorId id) {
+        return new TpId(id);
+    }
+}
diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend
new file mode 100644 (file)
index 0000000..fb129e4
--- /dev/null
@@ -0,0 +1,132 @@
+package org.opendaylight.md.controller.topology.manager
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkOverutilized
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemoved
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkUtilizationNormal
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Node
+
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
+import static extension org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.*
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import com.google.common.collect.FluentIterable
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
+
+class FlowCapableTopologyExporter implements //
+FlowTopologyDiscoveryListener, //
+OpendaylightInventoryListener //
+{
+
+    var TopologyKey topology;
+
+    @Property
+    var DataProviderService dataService;
+
+    override onNodeRemoved(NodeRemoved notification) {
+        val invNodeKey = notification.nodeRef.nodeKey
+        val tpNodeId = invNodeKey.id.toToplogyNodeId()
+        val tpNodeInstance = notification.nodeRef.toNodeIdentifier()
+
+        val it = dataService.beginTransaction
+        removeRuntimeData(tpNodeInstance);
+        removeAffectedLinks(tpNodeId)
+        commit()
+
+    }
+
+    override onNodeUpdated(NodeUpdated notification) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+    }
+
+    override onNodeConnectorRemoved(NodeConnectorRemoved notification) {
+        val tpRef = notification.nodeConnectorRef.toTerminationPointIdentifier();
+        val it = dataService.beginTransaction
+        removeRuntimeData(tpRef);
+        commit()
+
+    }
+
+    override onNodeConnectorUpdated(NodeConnectorUpdated notification) {
+        val nodeId = notification.nodeConnectorRef.nodeKey.id.toToplogyNodeId();
+        val TerminationPoint point = notification.toTerminationPoint();
+        val path = tpPath(nodeId, point.key.tpId);
+
+        val it = dataService.beginTransaction
+        putRuntimeData(path, point);
+        commit()
+    }
+
+    override onLinkDiscovered(LinkDiscovered notification) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+    }
+
+    override onLinkOverutilized(LinkOverutilized notification) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+    }
+
+    override onLinkRemoved(LinkRemoved notification) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+
+    }
+
+    override onLinkUtilizationNormal(LinkUtilizationNormal notification) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+    }
+
+    def InstanceIdentifier<Node> toNodeIdentifier(NodeRef ref) {
+        val invNodeKey = ref.nodeKey
+
+        val nodeKey = new NodeKey(invNodeKey.id.toToplogyNodeId);
+        return InstanceIdentifier.builder.node(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
+            toInstance;
+    }
+
+    def InstanceIdentifier<TerminationPoint> toTerminationPointIdentifier(NodeConnectorRef ref) {
+        val invNodeKey = ref.nodeKey
+        val invNodeConnectorKey = ref.nodeConnectorKey
+        return tpPath(invNodeKey.id.toToplogyNodeId(), invNodeConnectorKey.id.toTerminationPointId())
+    }
+
+    private def void removeAffectedLinks(DataModificationTransaction transaction, NodeId id) {
+        val reader = TypeSafeDataReader.forReader(transaction)
+        val topologyPath = InstanceIdentifier.builder().node(NetworkTopology).child(Topology, topology).toInstance;
+        val topologyData = reader.readOperationalData(topologyPath);
+        if (topologyData === null) {
+            return;
+        }
+        val affectedLinkInstances = FluentIterable.from(topologyData.link).filter[
+            source.sourceNode == id || destination.destNode == id].transform [
+            //
+            InstanceIdentifier.builder().node(NetworkTopology).child(Topology, topology).child(Link, key).toInstance
+        //
+        ]
+        for(affectedLink : affectedLinkInstances) {
+            transaction.removeRuntimeData(affectedLink);
+        }
+    }
+    
+    private def InstanceIdentifier<TerminationPoint> tpPath(NodeId nodeId, TpId tpId) {
+        val nodeKey = new NodeKey(nodeId);
+        val tpKey = new TerminationPointKey(tpId)
+        return InstanceIdentifier.builder.node(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
+            child(TerminationPoint, tpKey).toInstance;
+    }
+}
index 2242101f5b12ab1cbdf940576dc6a60d530a7c25..f96b3acf20c0f2d518ed042f9191fe33b7de798a 100644 (file)
@@ -87,9 +87,9 @@ public class Config {
     }
 
     private void addServices(Services serviceTracker, Collection<ObjectName> instances,
-            Map<String, String> providedServices) {
+            Multimap<String, String> providedServices) {
         for (ObjectName instanceOn : instances) {
-            for (Entry<String, String> serviceName : providedServices.entrySet()) {
+            for (Entry<String, String> serviceName : providedServices.entries()) {
                 serviceTracker.addServiceEntry(serviceName.getKey(), serviceName.getValue(), instanceOn);
             }
         }
@@ -243,7 +243,7 @@ public class Config {
 
             checkState(moduleConfig != null, "Cannot find ModuleConfig with name " + factoryName + " in " + moduleNamesToConfigs);
             // Set<String> services = ;
-            for (Entry<String, String> serviceName : moduleConfig.getProvidedServices().entrySet()) {
+            for (Entry<String, String> serviceName : moduleConfig.getProvidedServices().entries()) {
 
                 services.addServiceEntry(serviceName.getKey(), serviceName.getValue(), existingON);
             }
index 064cd9fe6f332cb01124c7243a3e25430b8be6a9..2e2a26400f19899b3f172e80f0de00f7c46ce1c6 100644 (file)
@@ -8,8 +8,8 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
@@ -21,15 +21,12 @@ import org.w3c.dom.Element;
 
 import javax.management.ObjectName;
 import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
 
 public class ModuleConfig {
 
     private final String moduleName;
     private final InstanceConfig instanceConfig;
-    // TODO 2 services from same namespace ?
-    private final Map<String, String> providedServices;
+    private final Multimap<String, String> providedServices;
 
     public ModuleConfig(String moduleName, InstanceConfig mbeanMapping, Collection<QName> providedServices) {
         this.moduleName = moduleName;
@@ -37,12 +34,11 @@ public class ModuleConfig {
         this.providedServices = mapServices(providedServices);
     }
 
-    private Map<String, String> mapServices(Collection<QName> providedServices) {
-        HashMap<String, String> mapped = Maps.newHashMap();
+    private Multimap<String, String> mapServices(Collection<QName> providedServices) {
+        Multimap<String, String> mapped = HashMultimap.create();
 
         for (QName providedService : providedServices) {
             String key = providedService.getNamespace().toString();
-            Preconditions.checkState(mapped.containsKey(key) == false);
             mapped.put(key, providedService.getLocalName());
         }
 
@@ -53,7 +49,7 @@ public class ModuleConfig {
         return instanceConfig;
     }
 
-    public Map<String, String> getProvidedServices() {
+    public Multimap<String, String> getProvidedServices() {
         return providedServices;
     }
 
index 556541ab22009d6f5cfb5aee439d453e6320b3ac..ef286ac862912ea0bf58f8250bf1264d8ddd3f6d 100644 (file)
@@ -24,8 +24,9 @@ public class Rpcs {
     public ModuleRpcs getRpcMapping(RuntimeRpcElementResolved id) {
         Map<String, ModuleRpcs> modules = mappedRpcs.get(id.getNamespace());
         Preconditions.checkState(modules != null, "No modules found for namespace %s", id.getNamespace());
-        ModuleRpcs rpcMapping = modules.get(id.getModuleName());
-        Preconditions.checkState(modules != null, "No module %s found for namespace %s", id.getModuleName(),
+        String moduleName = id.getModuleName();
+        ModuleRpcs rpcMapping = modules.get(moduleName);
+        Preconditions.checkState(rpcMapping != null, "No module %s found for namespace %s", moduleName,
                 id.getNamespace());
 
         return rpcMapping;
index 9d348d0985518c2595445f89c73a69e74bcb93ca..70b10d00191cd04c01e83dee8be44fd0c4db0f9d 100644 (file)
@@ -12,7 +12,6 @@ import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.Sets;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
-import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -83,15 +82,14 @@ public class InstanceRuntime {
         }));
     }
 
-    public Element toXml(ObjectName rootOn, Set<ObjectName> childRbeOns, Document document) {
-        return toXml(rootOn, childRbeOns, document, null, null);
+    public Element toXml(ObjectName rootOn, Set<ObjectName> childRbeOns, Document document, Element parentElement, String namespace) {
+        return toXml(rootOn, childRbeOns, document, null, parentElement, namespace);
     }
 
     public Element toXml(ObjectName rootOn, Set<ObjectName> childRbeOns, Document document, String instanceIndex,
-            String keyName) {
-        Element xml = document.createElement(keyName == null ? XmlNetconfConstants.DATA_KEY : keyName);
+                         Element parentElement, String namespace) {
         // TODO namespace
-        xml = instanceMapping.toXml(rootOn, null, "namespace", document, xml);
+        Element xml = instanceMapping.toXml(rootOn, null, namespace, document, parentElement);
 
         if (instanceIndex != null) {
             xml.setAttribute(KEY_ATTRIBUTE_KEY, instanceIndex);
@@ -106,8 +104,11 @@ public class InstanceRuntime {
                 String runtimeInstanceIndex = objectName.getKeyProperty(childMappingEntry.getKey());
 
                 String elementName = jmxToYangChildRbeMapping.get(childMappingEntry.getKey());
-                xml.appendChild(childMappingEntry.getValue().toXml(objectName, innerChildRbeOns, document,
-                        runtimeInstanceIndex, elementName));
+
+                Element innerXml = document.createElement(elementName);
+                childMappingEntry.getValue().toXml(objectName, innerChildRbeOns, document,
+                        runtimeInstanceIndex, innerXml, namespace);
+                xml.appendChild(innerXml);
             }
         }
 
index 07da65ed19b548646234b11f8aa2a7cbb9c7e70d..4dbfba119f865980daf18ac49b3564bfddff996c 100644 (file)
@@ -8,7 +8,6 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime;
 
-import com.google.common.collect.Multimap;
 import com.google.common.collect.Sets;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
@@ -41,31 +40,30 @@ public class ModuleRuntime {
         throw new IllegalStateException("Root runtime bean not found among " + runtimeBeanOns);
     }
 
-    public Element toXml(String namespace, Multimap<String, ObjectName> instances, Document document) {
-        Element root = document.createElement(XmlNetconfConstants.MODULE_KEY);
-        XmlUtil.addNamespaceAttr(root, namespace);
+    public Element toXml(String namespace, String instanceName, Collection<ObjectName> runtimeBeanOns, Document document) {
+        Element moduleElement = document.createElement(XmlNetconfConstants.MODULE_KEY);
 
-        Element nameElement = XmlUtil.createTextElement(document, XmlNetconfConstants.NAME_KEY, moduleName);
-        root.appendChild(nameElement);
+        final String prefix = getPrefix(namespace);
+        Element typeElement = XmlUtil.createPrefixedTextElement(document, XmlNetconfConstants.TYPE_KEY, prefix,
+                moduleName);
+        XmlUtil.addPrefixedNamespaceAttr(typeElement, prefix, namespace);
+        moduleElement.appendChild(typeElement);
 
-        for (String instanceName : instances.keySet()) {
-            Element instance = document.createElement(XmlNetconfConstants.INSTANCE_KEY);
+        Element nameElement = XmlUtil.createTextElement(document, XmlNetconfConstants.NAME_KEY, instanceName);
+        moduleElement.appendChild(nameElement);
 
-            Element innerNameElement = XmlUtil.createTextElement(document, XmlNetconfConstants.NAME_KEY, instanceName);
-            instance.appendChild(innerNameElement);
+        ObjectName rootName = findRoot(runtimeBeanOns);
 
-            Collection<ObjectName> runtimeBeanOns = instances.get(instanceName);
-            ObjectName rootName = findRoot(runtimeBeanOns);
+        Set<ObjectName> childrenRuntimeBeans = Sets.newHashSet(runtimeBeanOns);
+        childrenRuntimeBeans.remove(rootName);
 
-            Set<ObjectName> childrenRuntimeBeans = Sets.newHashSet(runtimeBeanOns);
-            childrenRuntimeBeans.remove(rootName);
+        instanceRuntime.toXml(rootName, childrenRuntimeBeans, document, moduleElement, namespace);
 
-            instance.appendChild(instanceRuntime.toXml(rootName, childrenRuntimeBeans, document));
-
-            root.appendChild(instance);
-        }
+        return moduleElement;
+    }
 
-        return root;
+    private String getPrefix(String namespace) {
+        return XmlNetconfConstants.PREFIX;
     }
 
 }
index da281269e63275b3b11c55f3aa4d439784f83469..8af1e0ee90e94fe7c009eb93ece4b1f478b16d4f 100644 (file)
@@ -66,9 +66,12 @@ public class Runtime {
                 if (instanceToRbe == null)
                     continue;
 
-                ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName);
-                Element innerXml = moduleRuntime.toXml(localNamespace, instanceToRbe, document);
-                modulesElement.appendChild(innerXml);
+                for (String instanceName : instanceToRbe.keySet()) {
+                    ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName);
+                    Element innerXml = moduleRuntime.toXml(localNamespace, instanceName, instanceToRbe.get(instanceName), document);
+                    modulesElement.appendChild(innerXml);
+                }
+
             }
         }
 
index f838c6f9f5e69160b4c889d799f7e42ed2c7338c..7463bdd429e4dc9552dfc390d59bcaba32fe5e5b 100644 (file)
@@ -127,6 +127,7 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation {
         if (contextInstanceElement.isPresent() == false)
             return HandlingPriority.CANNOT_HANDLE;
 
+        // FIXME update xpath to instance to conform to config-api yang
         final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath(contextInstanceElement.get()
                 .getTextContent(), netconfOperationName, netconfOperationNamespace);
 
index 838e5d87317fd503ba545019e93c38a8c56000a0..0f0b1227a625cd717840f2841dcb4706b270e47c 100644 (file)
@@ -33,11 +33,11 @@ public final class RuntimeRpcElementResolved {
 
     private RuntimeRpcElementResolved(String namespace, String moduleName, String instanceName, String runtimeBeanName,
             Map<String, String> additionalAttributes) {
-        this.moduleName = moduleName;
-        this.instanceName = instanceName;
+        this.moduleName = Preconditions.checkNotNull(moduleName, "Module name");
+        this.instanceName =  Preconditions.checkNotNull(instanceName, "Instance name");
         this.additionalAttributes = additionalAttributes;
-        this.namespace = namespace;
-        this.runtimeBeanName = runtimeBeanName;
+        this.namespace = Preconditions.checkNotNull(namespace, "Namespace");
+        this.runtimeBeanName = Preconditions.checkNotNull(runtimeBeanName, "Runtime bean name");
     }
 
     public String getModuleName() {
@@ -68,12 +68,22 @@ public final class RuntimeRpcElementResolved {
         return ObjectNameUtil.createRuntimeBeanName(moduleName, instanceName, additionalAttributesJavaNames);
     }
 
-    private static final String xpathPatternBlueprint = "/" + XmlNetconfConstants.DATA_KEY + "/"
-            + XmlNetconfConstants.MODULES_KEY + "/" + XmlNetconfConstants.MODULE_KEY + "\\["
-            + XmlNetconfConstants.NAME_KEY + "='(.+)'\\]/" + XmlNetconfConstants.INSTANCE_KEY + "\\["
-            + XmlNetconfConstants.NAME_KEY + "='([^']+)'\\](.*)";
+    private static final String xpathPatternBlueprint =
+            "/" + XmlNetconfConstants.MODULES_KEY
+            + "/" + XmlNetconfConstants.MODULE_KEY
+            + "\\["
+
+            + "(?<key1>type|name)"
+            + "='(?<value1>[^']+)'"
+            + "( and |\\]\\[)"
+            + "(?<key2>type|name)"
+            + "='(?<value2>[^']+)'"
+
+            + "\\]"
+            + "(?<additional>.*)";
+
     private static final Pattern xpathPattern = Pattern.compile(xpathPatternBlueprint);
-    private static final String additionalPatternBlueprint = "(.+)\\[(.+)='(.+)'\\]";
+    private static final String additionalPatternBlueprint = "(?<additionalKey>.+)\\[(.+)='(?<additionalValue>.+)'\\]";
     private static final Pattern additionalPattern = Pattern.compile(additionalPatternBlueprint);
 
     public static RuntimeRpcElementResolved fromXpath(String xpath, String elementName, String namespace) {
@@ -82,26 +92,65 @@ public final class RuntimeRpcElementResolved {
                 "Node %s with value '%s' not in required form on rpc element %s, required format is %s",
                 RuntimeRpc.CONTEXT_INSTANCE, xpath, elementName, xpathPatternBlueprint);
 
-        String moduleName = matcher.group(1);
-        String instanceName = matcher.group(2);
-        String additionalString = matcher.group(3);
-        HashMap<String, String> additionalAttributes = Maps.<String, String> newHashMap();
-        String runtimeBeanYangName = moduleName;
-        for (String additionalKeyValue : additionalString.split("/")) {
-            if (Strings.isNullOrEmpty(additionalKeyValue))
-                continue;
-            matcher = additionalPattern.matcher(additionalKeyValue);
-            Preconditions
-                    .checkState(
-                            matcher.matches(),
-                            "Attribute %s not in required form on rpc element %s, required format for additional attributes is  %s",
-                            additionalKeyValue, elementName, additionalPatternBlueprint);
-            String name = matcher.group(1);
-            runtimeBeanYangName = name;
-            additionalAttributes.put(name, matcher.group(3));
-        }
+        PatternGroupResolver groups = new PatternGroupResolver(matcher.group("key1"), matcher.group("value1"),
+                matcher.group("key2"), matcher.group("value2"), matcher.group("additional"));
+
+        String moduleName = groups.getModuleName();
+        String instanceName = groups.getInstanceName();
+
+        HashMap<String, String> additionalAttributes = groups.getAdditionalKeys(elementName, moduleName);
 
-        return new RuntimeRpcElementResolved(namespace, moduleName, instanceName, runtimeBeanYangName,
+        return new RuntimeRpcElementResolved(namespace, moduleName, instanceName, groups.getRuntimeBeanYangName(),
                 additionalAttributes);
     }
+
+    private static final class PatternGroupResolver {
+
+        private final String key1, key2, value1, value2;
+        private final String additional;
+        private String runtimeBeanYangName;
+
+        PatternGroupResolver(String key1, String value1, String key2, String value2, String additional) {
+            this.key1 = Preconditions.checkNotNull(key1);
+            this.value1 = Preconditions.checkNotNull(value1);
+
+            this.key2 = Preconditions.checkNotNull(key2);
+            this.value2 = Preconditions.checkNotNull(value2);
+
+            this.additional = Preconditions.checkNotNull(additional);
+        }
+
+        String getModuleName() {
+            return key1.equals(XmlNetconfConstants.TYPE_KEY) ? value1 : value2;
+        }
+
+        String getInstanceName() {
+            return key1.equals(XmlNetconfConstants.NAME_KEY) ? value1 : value2;
+        }
+
+        HashMap<String, String> getAdditionalKeys(String elementName, String moduleName) {
+            HashMap<String, String> additionalAttributes = Maps.newHashMap();
+
+            runtimeBeanYangName = moduleName;
+            for (String additionalKeyValue : additional.split("/")) {
+                if (Strings.isNullOrEmpty(additionalKeyValue))
+                    continue;
+                Matcher matcher = additionalPattern.matcher(additionalKeyValue);
+                Preconditions
+                        .checkState(
+                                matcher.matches(),
+                                "Attribute %s not in required form on rpc element %s, required format for additional attributes is  %s",
+                                additionalKeyValue, elementName, additionalPatternBlueprint);
+                String name = matcher.group("additionalKey");
+                runtimeBeanYangName = name;
+                additionalAttributes.put(name, matcher.group("additionalValue"));
+            }
+            return additionalAttributes;
+        }
+
+        private String getRuntimeBeanYangName() {
+            Preconditions.checkState(runtimeBeanYangName!=null);
+            return runtimeBeanYangName;
+        }
+    }
 }
index de0ecdbf1e2a448a82c001462b3dd9db46f2aba1..296b224fffbbc2e33fccc898dd78dcd204267d46 100644 (file)
@@ -441,7 +441,9 @@ public class NetconfMappingTest extends AbstractConfigTest {
 
         Element response = get();
 
-        assertEquals(2, getElementsSize(response, "instance"));
+        System.err.println(XmlUtil.toString(response));
+
+        assertEquals(2, getElementsSize(response, "module"));
         assertEquals(2, getElementsSize(response, "asdf"));
         assertEquals(5, getElementsSize(response, "inner-running-data"));
         assertEquals(5, getElementsSize(response, "deep2"));
index 0d68e25f67071b1505b2ab4a54e836e6cfe78e2d..25d2ad6abd09943278d28262a7184649a0688f4f 100644 (file)
@@ -41,6 +41,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.net.InetSocketAddress;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.Set;
 
 /**
@@ -152,9 +153,11 @@ public class ConfigPersisterNotificationHandler implements NotificationListener,
 
             Thread.sleep(delay);
         }
-
-        throw new RuntimeException("Netconf server did not provide required capabilities " + expectedCaps
-                + " in time, provided capabilities " + currentCapabilities);
+        Set<String> allNotFound = new HashSet<>(expectedCaps);
+        allNotFound.removeAll(currentCapabilities);
+        logger.error("Netconf server did not provide required capabilities. Expected but not found: {}, all expected {}, current {}",
+                allNotFound, expectedCaps ,currentCapabilities);
+        throw new RuntimeException("Netconf server did not provide required capabilities. Expected but not found:" + allNotFound);
 
     }
 
index 3dd6e6803bda9662b7e54a95849db368931a8452..11b8dc623c8a07903df1d05da46407aef1770a47 100644 (file)
@@ -7,14 +7,9 @@
  */
 package org.opendaylight.controller.netconf.impl.osgi;
 
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfOperationRouter;
 import org.opendaylight.controller.netconf.api.NetconfSession;
@@ -36,9 +31,14 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
 
 public class NetconfOperationRouterImpl implements NetconfOperationRouter {
 
@@ -116,9 +116,53 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
     @Override
     public synchronized Document onNetconfMessage(Document message,
             NetconfSession session) throws NetconfDocumentedException {
-        NetconfOperationExecution netconfOperationExecution = getNetconfOperationWithHighestPriority(
-                message, session);
-        logger.debug("Forwarding netconf message {} to {}", XmlUtil.toString(message),
+        NetconfOperationExecution netconfOperationExecution = null;
+
+        String messageAsString = XmlUtil.toString(message);
+
+        try {
+            netconfOperationExecution = getNetconfOperationWithHighestPriority(message, session);
+        } catch (IllegalArgumentException | IllegalStateException e) {
+            logger.warn("Unable to handle rpc {} on session {}", messageAsString, session, e);
+
+            String errorMessage = String.format("Unable to handle rpc %s on session %s", messageAsString, session);
+            Map<String, String> errorInfo = Maps.newHashMap();
+
+            NetconfDocumentedException.ErrorTag tag = null;
+            if (e instanceof IllegalArgumentException) {
+                errorInfo.put(NetconfDocumentedException.ErrorTag.operation_not_supported.toString(), e.getMessage());
+                tag = NetconfDocumentedException.ErrorTag.operation_not_supported;
+            } else if (e instanceof IllegalStateException) {
+                errorInfo.put(NetconfDocumentedException.ErrorTag.operation_failed.toString(), e.getMessage());
+                tag = NetconfDocumentedException.ErrorTag.operation_failed;
+            }
+
+            throw new NetconfDocumentedException(errorMessage, e, NetconfDocumentedException.ErrorType.application,
+                    tag, NetconfDocumentedException.ErrorSeverity.error, errorInfo);
+        } catch (RuntimeException e) {
+            throw handleUnexpectedEx("Unexpected exception during netconf operation sort", e);
+        }
+
+        try {
+            return executeOperationWithHighestPriority(message, netconfOperationExecution, messageAsString);
+        } catch (RuntimeException e) {
+            throw handleUnexpectedEx("Unexpected exception during netconf operation execution", e);
+        }
+    }
+
+    private NetconfDocumentedException handleUnexpectedEx(String s, Exception e) throws NetconfDocumentedException {
+        logger.error(s, e);
+
+        Map<String, String> info = Maps.newHashMap();
+        info.put(NetconfDocumentedException.ErrorSeverity.error.toString(), e.toString());
+        return new NetconfDocumentedException("Unexpected error",
+                NetconfDocumentedException.ErrorType.application,
+                NetconfDocumentedException.ErrorTag.operation_failed,
+                NetconfDocumentedException.ErrorSeverity.error, info);
+    }
+
+    private Document executeOperationWithHighestPriority(Document message, NetconfOperationExecution netconfOperationExecution, String messageAsString) throws NetconfDocumentedException {
+        logger.debug("Forwarding netconf message {} to {}", messageAsString,
                 netconfOperationExecution.operationWithHighestPriority);
 
         final LinkedList<NetconfOperationFilterChain> chain = new LinkedList<>();
@@ -147,7 +191,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
         TreeMap<HandlingPriority, Set<NetconfOperation>> sortedPriority = getSortedNetconfOperationsWithCanHandle(
                 message, session);
 
-        Preconditions.checkState(sortedPriority.isEmpty() == false, "No %s available to handle message %s",
+        Preconditions.checkArgument(sortedPriority.isEmpty() == false, "No %s available to handle message %s",
                 NetconfOperation.class.getName(), XmlUtil.toString(message));
 
         HandlingPriority highestFoundPriority = sortedPriority.lastKey();
index 5f6e046929b4a5183f3e4cce1932db9f61c538bd..c03254dba2bbda03677efc89c4eadd39e2024acc 100644 (file)
@@ -275,7 +275,7 @@ public class NetconfITTest extends AbstractConfigTest {
                     + "<no-arg xmlns=\""
                     + expectedNamespace
                     + "\">    "
-                    + "<context-instance>/data/modules/module[name='impl-netconf']/instance[name='instance']</context-instance>"
+                    + "<context-instance>/modules/module[type='impl-netconf'][name='instance']</context-instance>"
                     + "<arg1>argument1</arg1>" + "</no-arg>" + "</rpc>";
             final Document doc = XmlUtil.readXmlToDocument(rpc);
             final NetconfMessage message = netconfClient.sendMessage(new NetconfMessage(doc));
index b2a2ee30c815a6a0ac6b1b57f236dc0dd819d7de..413b78c5d344bae7cceec2ec6752206a4cf01a46 100644 (file)
@@ -1,6 +1,6 @@
 <rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <no-arg xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
-        <context-instance>/data/modules/module[name='impl-netconf']/instance[name='instance']</context-instance>
+        <context-instance>/modules/module[type='impl-netconf' and name='instance']</context-instance>
         <arg1>
             testarg1
         </arg1>
index 8bc504a56e87f71c1990dcb926fe294b88e40cd0..cf15000b1a3473678d6f98906981d8ce68707444 100644 (file)
@@ -1,7 +1,7 @@
 <rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <noArgInner xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
         <context-instance>
-            /data/modules/module[name='impl-netconf']/instance[name='instance2']/inner-running-data-additional[key='randomString_1003']
+            /modules/module[name='instance2'][type='impl-netconf']/inner-running-data-additional[key='randomString_1003']
         </context-instance>
     </noArgInner>
 </rpc>
index 2356398e64d232ee0abc666cb65d8c73cf6ea3c9..31f417e879dd813e558e60a2a46524100027fb32 100644 (file)
@@ -2,7 +2,7 @@
     <noArgInnerInner
             xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
         <context-instance>
-            /data/modules/module[name='impl-netconf']/instance[name='instance2']/inner-running-data[key='1015']/inner-inner-running-data[key='1017']
+            /modules/module[type='impl-netconf'][name='instance2']/inner-running-data[key='1015']/inner-inner-running-data[key='1017']
         </context-instance>
 
         <arg1>
index 209c382252d81f693c525278224e1d232bc9fe6a..af0835b5dfc7216a840557f231af108a43b2edee 100644 (file)
@@ -2,7 +2,7 @@
     <leaf-list-output
             xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
         <context-instance>
-            /data/modules/module[name='impl-netconf']/instance[name='instance2']/inner-running-data[key='1015']/inner-inner-running-data[key='1017']
+            /modules/module[type='impl-netconf'][name='instance2']/inner-running-data[key='1015']/inner-inner-running-data[key='1017']
         </context-instance>
     </leaf-list-output>
 </rpc>
index eecc19f2167b71a77d5c381a99bb365dd6b28ed7..582c0766dd35360c6517460ba67f0d340970c7ee 100644 (file)
@@ -20,10 +20,10 @@ import javax.xml.bind.annotation.XmlRootElement;
 import org.opendaylight.controller.containermanager.ContainerConfig;
 
 
-@XmlRootElement(name = "container-config-list")
+@XmlRootElement(name = "containerConfig-list")
 @XmlAccessorType(XmlAccessType.NONE)
 public class ContainerConfigs {
-        @XmlElement(name = "container-config")
+        @XmlElement(name = "containerConfig")
     List<ContainerConfig> containerConfig;
 
     //To satisfy JAXB
index 518fc4692f0d6e11c7a24a0f0551803791708945..fe38361cca246465bf514686b0beb872e72dd9f5 100644 (file)
@@ -114,8 +114,8 @@ public class ContainerManagerNorthbound {
      * http://localhost:8080/controller/nb/v2/containermanager/containers
      *
      * Response body in XML:
-     * &lt;container-config-list&gt;
-     *    &#x20;&#x20;&#x20;&lt;container-config&gt;
+     * &lt;containerConfig-list&gt;
+     *    &#x20;&#x20;&#x20;&lt;containerConfig&gt;
      *    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&lt;container&gt;black&lt;/container&gt;
      *    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&lt;staticVlan&gt;10&lt;/staticVlan&gt;
      *    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&lt;nodeConnectors&gt;OF|1@OF|00:00:00:00:00:00:00:01&lt;/nodeConnectors&gt;
@@ -124,8 +124,8 @@ public class ContainerManagerNorthbound {
      *    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&lt;name&gt;tcp&lt;/name&gt;
      *    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&lt;protocol&gt;TCP&lt;/protocol&gt;
      *    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&lt;/flowSpecs&gt;
-     *    &#x20;&#x20;&#x20;&#x20;&lt;/container-config&gt;
-     *    &#x20;&#x20;&#x20;&#x20;&lt;container-config&gt;
+     *    &#x20;&#x20;&#x20;&#x20;&lt;/containerConfig&gt;
+     *    &#x20;&#x20;&#x20;&#x20;&lt;containerConfig&gt;
      *    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&lt;container&gt;red&lt;/container&gt;
      *    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&lt;staticVlan&gt;20&lt;/staticVlan&gt;
      *    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&lt;nodeConnectors&gt;OF|1@OF|00:00:00:00:00:00:00:01&lt;/nodeConnectors&gt;
@@ -134,11 +134,11 @@ public class ContainerManagerNorthbound {
      *    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&lt;name&gt;udp&lt;/name&gt;
      *    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&lt;protocol&gt;UDP&lt;/protocol&gt;
      *    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&lt;/flowSpecs&gt;
-     *  &#x20;&#x20;&#x20;&#x20;&lt;/container-config&gt;
-     * &lt;/container-config-list&gt;
+     *  &#x20;&#x20;&#x20;&#x20;&lt;/containerConfig&gt;
+     * &lt;/containerConfig-list&gt;
      *
      * Response body in JSON:
-     * { "container-config" : [
+     * { "containerConfig" : [
      *     { "container" : "black",
      *       "nodeConnectors" : [
      *          "OF|1@OF|00:00:00:00:00:00:00:01", "OF|23@OF|00:00:00:00:00:00:20:21"
@@ -196,16 +196,16 @@ public class ContainerManagerNorthbound {
      * http://localhost:8080/controller/nb/v2/containermanager/container/blue
      *
      * Response body in XML:
-     * &lt;container-config&gt;
+     * &lt;containerConfig&gt;
      *  &#x20;&#x20;&#x20;&#x20;&lt;container&gt;blue&lt;/container&gt;
      *  &#x20;&#x20;&#x20;&#x20;&lt;staticVlan&gt;10&lt;/staticVlan&gt;
      *  &#x20;&#x20;&#x20;&#x20;&lt;nodeConnectors&gt;OF|1@OF|00:00:00:00:00:00:00:01&lt;/nodeConnectors&gt;
      *  &#x20;&#x20;&#x20;&#x20;&lt;nodeConnectors&gt;OF|23@OF|00:00:00:00:00:00:20:21&lt;/nodeConnectors&gt;
-     * &lt;/container-config&gt;
+     * &lt;/containerConfig&gt;
      *
      * Response body in JSON:
      * {
-     *    "container-config": [
+     *    "containerConfig": [
      *       {
      *        "container": "yellow",
      *        "staticVlan": "10",
@@ -259,11 +259,11 @@ public class ContainerManagerNorthbound {
      * http://localhost:8080/controller/nb/v2/containermanager/container/yellow
      *
      * Request body in XML:
-     * &lt;container-config&gt;
+     * &lt;containerConfig&gt;
      *   &#x20;&#x20;&#x20;&#x20;&lt;container&gt;yellow&lt;/container&gt;
      *   &#x20;&#x20;&#x20;&#x20;&lt;staticVlan&gt;10&lt;/staticVlan&gt;
      *   &#x20;&#x20;&#x20;&#x20;&lt;nodeConnectors&gt;&lt;/nodeConnectors&gt;
-     * &lt;/container-config&gt;
+     * &lt;/containerConfig&gt;
      *
      * Request body in JSON:
      * {
index 040484e6951c14fcca8a020ab8d1746f79dbfab7..541dfcfe2d9b20919995332dafa7d8098e2cfac5 100644 (file)
@@ -79,7 +79,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 4b79865ca95753a114c2212316e67680512b83ff..b4e0b34d091c570d3ceb90a0da52df23927ae4a7 100644 (file)
@@ -69,7 +69,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwarding.staticrouting</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${forwarding.staticrouting}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
@@ -99,7 +99,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>arphandler</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${arphandler.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker.implementation</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index a869519c58bb62e316f852d663d03c35d85d6091..d169de9f2af44372d4099adb6015c82b14d8d85e 100644 (file)
@@ -84,7 +84,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwarding.staticrouting</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${forwarding.staticrouting}</version>
     </dependency>
     <dependency>
       <groupId>org.codehaus.enunciate</groupId>
index 69163c6939f40c141325a10cc881c095976e8b07..cf7a18ea659e6d126f43b868d8cf996cee6253dc 100644 (file)
@@ -15,7 +15,7 @@
   </scm>
 
   <artifactId>samples.loadbalancer</artifactId>
-  <version>0.4.1-SNAPSHOT</version>
+  <version>0.5.1-SNAPSHOT</version>
   <packaging>bundle</packaging>
 
   <build>
@@ -90,7 +90,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 1e3b845b86c6fcb81e8719a8e7f98ccd1c4c8049..b2229cb022016b3e95fb3876474b8d221ae6be0d 100644 (file)
@@ -17,6 +17,8 @@ import java.util.Set;
 import org.apache.felix.dm.Component;
 import org.opendaylight.controller.forwardingrulesmanager.FlowEntry;
 import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager;
+import org.opendaylight.controller.hosttracker.HostIdFactory;
+import org.opendaylight.controller.hosttracker.IHostId;
 import org.opendaylight.controller.hosttracker.IfIptoHost;
 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
 import org.opendaylight.controller.sal.action.Action;
@@ -56,35 +58,36 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * This class is the main class that represents the load balancer service.
- * This is a sample load balancer application that balances traffic to backend servers
- * based on the source address and source port on each incoming packet.  The service
- * reactively installs OpenFlow rules to direct all packets with a specific source address
- * and source port to one of the appropriate backend servers.  The servers may be chosen
- * using a round robin policy or a random policy. This service can be configured via a
- * REST APIs which are similar to the OpenStack Quantum LBaaS (Load-balancer-as-a-Service)
- * v1.0 API proposal (http://wiki.openstack.org/Quantum/LBaaS)
+ * This class is the main class that represents the load balancer service. This
+ * is a sample load balancer application that balances traffic to backend
+ * servers based on the source address and source port on each incoming packet.
+ * The service reactively installs OpenFlow rules to direct all packets with a
+ * specific source address and source port to one of the appropriate backend
+ * servers. The servers may be chosen using a round robin policy or a random
+ * policy. This service can be configured via a REST APIs which are similar to
+ * the OpenStack Quantum LBaaS (Load-balancer-as-a-Service) v1.0 API proposal
+ * (http://wiki.openstack.org/Quantum/LBaaS)
  *
- * To use this service, a virtual IP (or VIP) should be exposed to the clients of this service
- * and used as the destination address. A VIP is a entity that comprises of a virtual IP, port
- * and protocol (TCP or UDP).
- * Assumptions:
- *      1. One or more VIPs may be mapped to the same server pool. All VIPs that share the same
- *      pool must also share the same load balancing policy (random or round robin).
+ * To use this service, a virtual IP (or VIP) should be exposed to the clients
+ * of this service and used as the destination address. A VIP is a entity that
+ * comprises of a virtual IP, port and protocol (TCP or UDP). Assumptions: 1.
+ * One or more VIPs may be mapped to the same server pool. All VIPs that share
+ * the same pool must also share the same load balancing policy (random or round
+ * robin).
  *
- *      2. Only one server pool can be be assigned to a VIP.
+ * 2. Only one server pool can be be assigned to a VIP.
  *
- *      3. All flow rules are installed with an idle timeout of 5 seconds.
+ * 3. All flow rules are installed with an idle timeout of 5 seconds.
  *
- *      4. Packets to a VIP must leave the OpenFlow  cluster from the same switch from where
- *      it entered it.
+ * 4. Packets to a VIP must leave the OpenFlow cluster from the same switch from
+ * where it entered it.
  *
- *      5. When you delete a VIP or a server pool or a server from a pool, the service does not
- *      delete the flow rules it has already installed. The flow rules should automatically
- *      time out after the idle timeout of 5 seconds.
+ * 5. When you delete a VIP or a server pool or a server from a pool, the
+ * service does not delete the flow rules it has already installed. The flow
+ * rules should automatically time out after the idle timeout of 5 seconds.
  *
  */
-public class LoadBalancerService implements IListenDataPacket, IConfigManager{
+public class LoadBalancerService implements IListenDataPacket, IConfigManager {
 
     /*
      * Logger instance
@@ -92,8 +95,8 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{
     private static Logger lbsLogger = LoggerFactory.getLogger(LoadBalancerService.class);
 
     /*
-     * Single instance of the configuration manager. Application passes this reference to all
-     * the new policies implemented for load balancing.
+     * Single instance of the configuration manager. Application passes this
+     * reference to all the new policies implemented for load balancing.
      */
     private static ConfigManager configManager = new ConfigManager();
 
@@ -101,12 +104,12 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{
      * Round robing policy instance. Need to implement factory patterns to get
      * policy instance.
      */
-    private static RoundRobinLBPolicy rrLBMethod= new RoundRobinLBPolicy(configManager);
+    private static RoundRobinLBPolicy rrLBMethod = new RoundRobinLBPolicy(configManager);
 
     /*
      * Random policy instance.
      */
-    private static RandomLBPolicy ranLBMethod= new RandomLBPolicy(configManager);
+    private static RandomLBPolicy ranLBMethod = new RandomLBPolicy(configManager);
 
     /*
      * Reference to the data packet service
@@ -139,8 +142,8 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{
     private String containerName = null;
 
     /*
-     * Set/unset methods for the service instance that load balancer
-     * service requires
+     * Set/unset methods for the service instance that load balancer service
+     * requires
      */
     public String getContainerName() {
         if (containerName == null)
@@ -179,32 +182,30 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{
         }
     }
 
-    public void setForwardingRulesManager(
-            IForwardingRulesManager forwardingRulesManager) {
+    public void setForwardingRulesManager(IForwardingRulesManager forwardingRulesManager) {
         lbsLogger.debug("Setting ForwardingRulesManager");
         this.ruleManager = forwardingRulesManager;
     }
 
-    public void unsetForwardingRulesManager(
-            IForwardingRulesManager forwardingRulesManager) {
+    public void unsetForwardingRulesManager(IForwardingRulesManager forwardingRulesManager) {
         if (this.ruleManager == forwardingRulesManager) {
             this.ruleManager = null;
         }
     }
 
     /**
-     * This method receives first packet of flows for which there is no
-     * matching flow rule installed on the switch. IP addresses used for VIPs
-     * are not supposed to be used by any real/virtual host in the network.
-     * Hence, any forwarding/routing service will not install any flows rules matching
-     * these VIPs. This ensures that all the flows destined for VIPs will not find a match
-     * in the switch and will be forwarded to the load balancing service.
-     * Service will decide where to route this traffic based on the load balancing
-     * policy of the VIP's attached pool and will install appropriate flow rules
-     * in a reactive manner.
+     * This method receives first packet of flows for which there is no matching
+     * flow rule installed on the switch. IP addresses used for VIPs are not
+     * supposed to be used by any real/virtual host in the network. Hence, any
+     * forwarding/routing service will not install any flows rules matching
+     * these VIPs. This ensures that all the flows destined for VIPs will not
+     * find a match in the switch and will be forwarded to the load balancing
+     * service. Service will decide where to route this traffic based on the
+     * load balancing policy of the VIP's attached pool and will install
+     * appropriate flow rules in a reactive manner.
      */
     @Override
-    public PacketResult receiveDataPacket(RawPacket inPkt){
+    public PacketResult receiveDataPacket(RawPacket inPkt) {
 
         if (inPkt == null) {
             return PacketResult.IGNORED;
@@ -218,88 +219,89 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{
 
             if (ipPkt instanceof IPv4) {
 
-                lbsLogger.debug("Packet recieved from switch : {}",inPkt.getIncomingNodeConnector().getNode().toString());
-                IPv4 ipv4Pkt = (IPv4)ipPkt;
-                if(IPProtocols.getProtocolName(ipv4Pkt.getProtocol()).equals(IPProtocols.TCP.toString())
-                        || IPProtocols.getProtocolName(ipv4Pkt.getProtocol()).equals(IPProtocols.UDP.toString())){
+                lbsLogger.debug("Packet recieved from switch : {}", inPkt.getIncomingNodeConnector().getNode()
+                        .toString());
+                IPv4 ipv4Pkt = (IPv4) ipPkt;
+                if (IPProtocols.getProtocolName(ipv4Pkt.getProtocol()).equals(IPProtocols.TCP.toString())
+                        || IPProtocols.getProtocolName(ipv4Pkt.getProtocol()).equals(IPProtocols.UDP.toString())) {
 
-                    lbsLogger.debug("Packet protocol : {}",IPProtocols.getProtocolName(ipv4Pkt.getProtocol()));
+                    lbsLogger.debug("Packet protocol : {}", IPProtocols.getProtocolName(ipv4Pkt.getProtocol()));
                     Client client = new LBUtil().getClientFromPacket(ipv4Pkt);
                     VIP vip = new LBUtil().getVIPFromPacket(ipv4Pkt);
 
-                    if(configManager.vipExists(vip)){
+                    if (configManager.vipExists(vip)) {
                         VIP vipWithPoolName = configManager.getVIPWithPoolName(vip);
                         String poolMemberIp = null;
-                        if(vipWithPoolName.getPoolName() == null){
-                            lbsLogger.error("No pool attached. Please attach pool with the VIP -- {}",vip);
+                        if (vipWithPoolName.getPoolName() == null) {
+                            lbsLogger.error("No pool attached. Please attach pool with the VIP -- {}", vip);
                             return PacketResult.IGNORED;
                         }
-                        if(configManager.getPool(vipWithPoolName.getPoolName()).getLbMethod().equalsIgnoreCase(LBConst.ROUND_ROBIN_LB_METHOD)){
+                        if (configManager.getPool(vipWithPoolName.getPoolName()).getLbMethod()
+                                .equalsIgnoreCase(LBConst.ROUND_ROBIN_LB_METHOD)) {
 
-                            poolMemberIp = rrLBMethod.getPoolMemberForClient(client,vipWithPoolName);
+                            poolMemberIp = rrLBMethod.getPoolMemberForClient(client, vipWithPoolName);
                         }
 
-                        if(configManager.getPool(vipWithPoolName.getPoolName()).getLbMethod().equalsIgnoreCase(LBConst.RANDOM_LB_METHOD)){
-                            poolMemberIp = ranLBMethod.getPoolMemberForClient(client,vipWithPoolName);
+                        if (configManager.getPool(vipWithPoolName.getPoolName()).getLbMethod()
+                                .equalsIgnoreCase(LBConst.RANDOM_LB_METHOD)) {
+                            poolMemberIp = ranLBMethod.getPoolMemberForClient(client, vipWithPoolName);
                         }
 
                         try {
 
                             Node clientNode = inPkt.getIncomingNodeConnector().getNode();
-                            HostNodeConnector hnConnector = this.hostTracker.hostFind(InetAddress.getByName(poolMemberIp));
+                            // HostTracker hosts db key scheme implementation
+                            IHostId id = HostIdFactory.create(InetAddress.getByName(poolMemberIp), null);
+                            HostNodeConnector hnConnector = this.hostTracker.hostFind(id);
 
                             Node destNode = hnConnector.getnodeconnectorNode();
 
-                            lbsLogger.debug("Client is connected to switch : {}",clientNode.toString());
-                            lbsLogger.debug("Destination pool machine is connected to switch : {}",destNode.toString());
+                            lbsLogger.debug("Client is connected to switch : {}", clientNode.toString());
+                            lbsLogger
+                                    .debug("Destination pool machine is connected to switch : {}", destNode.toString());
 
-                            //Get path between both the nodes
+                            // Get path between both the nodes
                             NodeConnector forwardPort = null;
 
-                            if(clientNode.getNodeIDString().equals(destNode.getNodeIDString())){
+                            if (clientNode.getNodeIDString().equals(destNode.getNodeIDString())) {
 
                                 forwardPort = hnConnector.getnodeConnector();
 
-                                lbsLogger.info("Both source (client) and destination pool machine is connected to same switch nodes. Respective ports are - {},{}",forwardPort,inPkt.getIncomingNodeConnector());
+                                lbsLogger
+                                        .info("Both source (client) and destination pool machine is connected to same switch nodes. Respective ports are - {},{}",
+                                                forwardPort, inPkt.getIncomingNodeConnector());
 
-                            }else{
+                            } else {
 
                                 Path route = this.routing.getRoute(clientNode, destNode);
 
-                                lbsLogger.info("Path between source (client) and destination switch nodes : {}",route.toString());
+                                lbsLogger.info("Path between source (client) and destination switch nodes : {}",
+                                        route.toString());
 
                                 forwardPort = route.getEdges().get(0).getTailNodeConnector();
 
                             }
 
-                            if(installLoadBalancerFlow(client,
-                                                            vip,
-                                                            clientNode,
-                                                            poolMemberIp,
-                                                            hnConnector.getDataLayerAddressBytes(),
-                                                            forwardPort,
-                                                            LBConst.FORWARD_DIRECTION_LB_FLOW)){
-                                lbsLogger.info("Traffic from client : {} will be routed " +
-                                                            "to pool machine : {}",client,poolMemberIp);
-                            }else{
-                                lbsLogger.error("Not able to route traffic from client : {}",client );
+                            if (installLoadBalancerFlow(client, vip, clientNode, poolMemberIp,
+                                    hnConnector.getDataLayerAddressBytes(), forwardPort,
+                                    LBConst.FORWARD_DIRECTION_LB_FLOW)) {
+                                lbsLogger.info("Traffic from client : {} will be routed " + "to pool machine : {}",
+                                        client, poolMemberIp);
+                            } else {
+                                lbsLogger.error("Not able to route traffic from client : {}", client);
                             }
 
-                            if(installLoadBalancerFlow(client,
-                                                            vip,
-                                                            clientNode,
-                                                            poolMemberIp,
-                                                            vipMacAddr,
-                                                            inPkt.getIncomingNodeConnector(),
-                                                            LBConst.REVERSE_DIRECTION_LB_FLOW)){
-                                lbsLogger.info("Flow rule installed to change the source ip/mac from " +
-                                                            "pool machine ip {} to VIP {} for traffic coming pool machine",poolMemberIp,vip);
-                            }else{
-                                lbsLogger.error("Not able to route traffic from client : {}",client );
+                            if (installLoadBalancerFlow(client, vip, clientNode, poolMemberIp, vipMacAddr,
+                                    inPkt.getIncomingNodeConnector(), LBConst.REVERSE_DIRECTION_LB_FLOW)) {
+                                lbsLogger.info("Flow rule installed to change the source ip/mac from "
+                                        + "pool machine ip {} to VIP {} for traffic coming pool machine", poolMemberIp,
+                                        vip);
+                            } else {
+                                lbsLogger.error("Not able to route traffic from client : {}", client);
                             }
-                        }catch (UnknownHostException e) {
-                            lbsLogger.error("Pool member not found  in the network : {}",e.getMessage());
-                            lbsLogger.error("",e);
+                        } catch (UnknownHostException e) {
+                            lbsLogger.error("Pool member not found  in the network : {}", e.getMessage());
+                            lbsLogger.error("", e);
                         }
                     }
                 }
@@ -309,30 +311,37 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{
     }
 
     /*
-     * This method installs the flow rule for routing the traffic between two hosts.
-     * @param source    Traffic is sent by this source
-     * @param dest      Traffic is destined to this destination (VIP)
-     * @param sourceSwitch      Switch from where controller received the packet
-     * @param destMachineIp     IP address of the pool member where traffic needs to be routed
-     * @param destMachineMac    MAC address of the pool member where traffic needs to be routed
-     * @param outport   Use this port to send out traffic
-     * @param flowDirection     FORWARD_DIRECTION_LB_FLOW or REVERSE_DIRECTION_LB_FLOW
-     * @return  true     If flow installation was successful
-     *          false   else
-     *          @throws UnknownHostException
+     * This method installs the flow rule for routing the traffic between two
+     * hosts.
+     *
+     * @param source Traffic is sent by this source
+     *
+     * @param dest Traffic is destined to this destination (VIP)
+     *
+     * @param sourceSwitch Switch from where controller received the packet
+     *
+     * @param destMachineIp IP address of the pool member where traffic needs to
+     * be routed
+     *
+     * @param destMachineMac MAC address of the pool member where traffic needs
+     * to be routed
+     *
+     * @param outport Use this port to send out traffic
+     *
+     * @param flowDirection FORWARD_DIRECTION_LB_FLOW or
+     * REVERSE_DIRECTION_LB_FLOW
+     *
+     * @return true If flow installation was successful false else
+     *
+     * @throws UnknownHostException
      */
-    private boolean installLoadBalancerFlow(Client source,
-                                            VIP dest,
-                                            Node sourceSwitch,
-                                            String destMachineIp,
-                                            byte[] destMachineMac,
-                                            NodeConnector outport,
-                                            int flowDirection) throws UnknownHostException{
+    private boolean installLoadBalancerFlow(Client source, VIP dest, Node sourceSwitch, String destMachineIp,
+            byte[] destMachineMac, NodeConnector outport, int flowDirection) throws UnknownHostException {
 
         Match match = new Match();
         List<Action> actions = new ArrayList<Action>();
 
-        if(flowDirection == LBConst.FORWARD_DIRECTION_LB_FLOW){
+        if (flowDirection == LBConst.FORWARD_DIRECTION_LB_FLOW) {
             match.setField(MatchType.DL_TYPE, EtherTypes.IPv4.shortValue());
             match.setField(MatchType.NW_SRC, InetAddress.getByName(source.getIp()));
             match.setField(MatchType.NW_DST, InetAddress.getByName(dest.getIp()));
@@ -344,13 +353,13 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{
             actions.add(new SetDlDst(destMachineMac));
         }
 
-        if(flowDirection == LBConst.REVERSE_DIRECTION_LB_FLOW){
+        if (flowDirection == LBConst.REVERSE_DIRECTION_LB_FLOW) {
             match.setField(MatchType.DL_TYPE, EtherTypes.IPv4.shortValue());
             match.setField(MatchType.NW_SRC, InetAddress.getByName(destMachineIp));
             match.setField(MatchType.NW_DST, InetAddress.getByName(source.getIp()));
             match.setField(MatchType.NW_PROTO, IPProtocols.getProtocolNumberByte(source.getProtocol()));
             match.setField(MatchType.TP_SRC, dest.getPort());
-            match.setField(MatchType.TP_DST,source.getPort());
+            match.setField(MatchType.TP_DST, source.getPort());
 
             actions.add(new SetNwSrc(InetAddress.getByName(dest.getIp())));
             actions.add(new SetDlSrc(destMachineMac));
@@ -366,30 +375,30 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{
         flow.setHardTimeout((short) 0);
         flow.setPriority(LB_IPSWITCH_PRIORITY);
 
-        String policyName = source.getIp()+":"+source.getProtocol()+":"+source.getPort();
-        String flowName =null;
+        String policyName = source.getIp() + ":" + source.getProtocol() + ":" + source.getPort();
+        String flowName = null;
 
-        if(flowDirection == LBConst.FORWARD_DIRECTION_LB_FLOW){
-            flowName = "["+policyName+":"+source.getIp() + ":"+dest.getIp()+"]";
+        if (flowDirection == LBConst.FORWARD_DIRECTION_LB_FLOW) {
+            flowName = "[" + policyName + ":" + source.getIp() + ":" + dest.getIp() + "]";
         }
 
-        if(flowDirection == LBConst.REVERSE_DIRECTION_LB_FLOW){
+        if (flowDirection == LBConst.REVERSE_DIRECTION_LB_FLOW) {
 
-            flowName = "["+policyName+":"+dest.getIp() + ":"+source.getIp()+"]";
+            flowName = "[" + policyName + ":" + dest.getIp() + ":" + source.getIp() + "]";
         }
 
         FlowEntry fEntry = new FlowEntry(policyName, flowName, flow, sourceSwitch);
 
-        lbsLogger.info("Install flow entry {} on node {}",fEntry.toString(),sourceSwitch.toString());
+        lbsLogger.info("Install flow entry {} on node {}", fEntry.toString(), sourceSwitch.toString());
 
-        if(!this.ruleManager.checkFlowEntryConflict(fEntry)){
-            if(this.ruleManager.installFlowEntry(fEntry).isSuccess()){
+        if (!this.ruleManager.checkFlowEntryConflict(fEntry)) {
+            if (this.ruleManager.installFlowEntry(fEntry).isSuccess()) {
                 return true;
-            }else{
-                lbsLogger.error("Error in installing flow entry to node : {}",sourceSwitch);
+            } else {
+                lbsLogger.error("Error in installing flow entry to node : {}", sourceSwitch);
             }
-        }else{
-            lbsLogger.error("Conflicting flow entry exists : {}",fEntry.toString());
+        } else {
+            lbsLogger.error("Conflicting flow entry exists : {}", fEntry.toString());
         }
         return false;
     }
@@ -405,45 +414,45 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{
             this.containerName = (String) props.get("containerName");
 
             lbsLogger.info("Running container name:" + this.containerName);
-        }else {
+        } else {
 
             // In the Global instance case the containerName is empty
             this.containerName = "";
         }
         lbsLogger.info(configManager.toString());
+
     }
 
     /**
-     * Function called by the dependency manager when at least one
-     * dependency become unsatisfied or when the component is shutting
-     * down because for example bundle is being stopped.
+     * Function called by the dependency manager when at least one dependency
+     * become unsatisfied or when the component is shutting down because for
+     * example bundle is being stopped.
      *
      */
     void destroy() {
     }
 
     /**
-     * Function called by dependency manager after "init ()" is called
-     * and after the services provided by the class are registered in
-     * the service registry
+     * Function called by dependency manager after "init ()" is called and after
+     * the services provided by the class are registered in the service registry
      *
      */
     void start() {
     }
 
     /**
-     * Function called by the dependency manager before the services
-     * exported by the component are unregistered, this will be
-     * followed by a "destroy ()" calls
+     * Function called by the dependency manager before the services exported by
+     * the component are unregistered, this will be followed by a "destroy ()"
+     * calls
      *
      */
     void stop() {
     }
 
     /*
-     * All the methods below are just proxy methods to direct the REST API requests to configuration
-     * manager. We need this redirection as currently, opendaylight supports only one
-     * implementation of the service.
+     * All the methods below are just proxy methods to direct the REST API
+     * requests to configuration manager. We need this redirection as currently,
+     * opendaylight supports only one implementation of the service.
      */
     @Override
     public Set<VIP> getAllVIPs() {
@@ -451,8 +460,7 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{
     }
 
     @Override
-    public boolean vipExists(String name, String ip, String protocol,
-                                short protocolPort, String poolName) {
+    public boolean vipExists(String name, String ip, String protocol, short protocolPort, String poolName) {
         return configManager.vipExists(name, ip, protocol, protocolPort, poolName);
     }
 
@@ -462,8 +470,7 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{
     }
 
     @Override
-    public VIP createVIP(String name, String ip, String protocol,
-                            short protocolPort, String poolName) {
+    public VIP createVIP(String name, String ip, String protocol, short protocolPort, String poolName) {
         return configManager.createVIP(name, ip, protocol, protocolPort, poolName);
     }
 
@@ -489,9 +496,7 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{
     }
 
     @Override
-    public PoolMember addPoolMember(String name,
-                                    String memberIP,
-                                    String poolName) {
+    public PoolMember addPoolMember(String name, String memberIP, String poolName) {
         return configManager.addPoolMember(name, memberIP, poolName);
     }
 
index a3f0ba122e0aa90822f2a0e56546c0f76ab1581b..543aa8ca54be34ed6bdd1f120b11235267801757 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>samples.loadbalancer</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${samples.loadbalancer}</version>
       </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index c9103994a03fb8910849e74ad50d54c9d39231e5..743c6784a51b607e57bd15b0d216593be274a6a0 100644 (file)
@@ -91,7 +91,7 @@
       <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 0f2138bf87df2b0ca42e46f5395abeb794c2dba7..d4d3d1c85764dd6be1439404cd6447c5f83d8d25 100644 (file)
@@ -91,7 +91,7 @@
       <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>0.4.0-SNAPSHOT</version>
+      <version>${hosttracker.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index f5605eaffe1510ecc60f1ac58327b182e11c0035..d66381f6ce737321c384f15c57aa9d64e19cf0bd 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwarding.staticrouting</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${forwarding.staticrouting}</version>
     </dependency>
     <dependency>
       <groupId>org.codehaus.jackson</groupId>