Merge "Fix for Bug 3"
authorEd Warnicke <eaw@cisco.com>
Sat, 18 Jan 2014 16:58:20 +0000 (16:58 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Sat, 18 Jan 2014 16:58:20 +0000 (16:58 +0000)
537 files changed:
.gitignore
.gitreview [new file with mode: 0644]
opendaylight/appauth/pom.xml
opendaylight/arphandler/pom.xml
opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/ArpHandler.java
opendaylight/clustering/services_implementation/pom.xml
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManager.java
opendaylight/clustering/stub/pom.xml
opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterManagerCommon.java
opendaylight/clustering/test/pom.xml
opendaylight/commons/opendaylight/pom.xml
opendaylight/config/config-api/pom.xml
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ValidationException.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java
opendaylight/config/config-persister-api/pom.xml
opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java [new file with mode: 0644]
opendaylight/config/config-persister-directory-adapter/pom.xml
opendaylight/config/config-persister-directory-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/DirectoryPersister.java
opendaylight/config/config-persister-directory-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/DirectoryStorageAdapterTest.java
opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersister.java [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryStorageAdapter.java [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileType.java [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersisterTest.java [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileTypeTest.java [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/1controller.txt.config [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/2controller.xml.config [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.txt.config [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.xml.config [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/unknown.config [new file with mode: 0644]
opendaylight/config/config-persister-directory-xml-adapter/pom.xml
opendaylight/config/config-persister-directory-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/xml/XmlDirectoryPersister.java
opendaylight/config/config-persister-directory-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/xml/DirectoryStorageAdapterTest.java
opendaylight/config/config-persister-file-adapter/pom.xml
opendaylight/config/config-persister-file-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/FileStorageAdapter.java
opendaylight/config/config-persister-file-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/FileStorageAdapterTest.java
opendaylight/config/config-persister-file-xml-adapter/pom.xml
opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/ConfigSnapshot.java
opendaylight/config/config-persister-file-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/xml/FileStorageAdapterTest.java
opendaylight/config/config-plugin-parent/pom.xml
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionClient.java
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionJMXClient.java
opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/ContextSetter.java
opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/ContextSetterImpl.java
opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackModule.java
opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleFactory.java
opendaylight/config/logback-config/src/main/java/org/opendaylight/controller/config/yang/logback/config/LogbackStatusListener.java
opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModule.java
opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleFactory.java
opendaylight/config/netty-event-executor-config/src/test/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleTest.java
opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModule.java
opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModuleFactory.java
opendaylight/config/netty-timer-config/src/main/java/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModule.java
opendaylight/config/netty-timer-config/src/main/java/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModuleFactory.java
opendaylight/config/netty-timer-config/src/test/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModuleTest.java
opendaylight/config/pom.xml
opendaylight/config/shutdown-api/pom.xml [new file with mode: 0644]
opendaylight/config/shutdown-api/src/main/java/org/opendaylight/controller/config/shutdown/ShutdownService.java [new file with mode: 0644]
opendaylight/config/shutdown-api/src/main/yang/shutdown.yang [new file with mode: 0644]
opendaylight/config/shutdown-impl/pom.xml [new file with mode: 0644]
opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownModule.java [new file with mode: 0644]
opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownModuleFactory.java [new file with mode: 0644]
opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownServiceImpl.java [new file with mode: 0644]
opendaylight/config/shutdown-impl/src/main/yang/shutdown-impl.yang [new file with mode: 0644]
opendaylight/config/shutdown-impl/src/test/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownTest.java [new file with mode: 0644]
opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/AsyncEventBusModule.java
opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/AsyncEventBusModuleFactory.java
opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/EventBusModule.java
opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/EventBusModuleFactory.java
opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/NamingThreadFactoryModule.java
opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/NamingThreadFactoryModuleFactory.java
opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/fixed/FixedThreadPoolModule.java
opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/fixed/FixedThreadPoolModuleFactory.java
opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/flexible/FlexibleThreadPoolModule.java
opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/flexible/FlexibleThreadPoolModuleFactory.java
opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/scheduled/ScheduledThreadPoolModule.java
opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/scheduled/ScheduledThreadPoolModuleFactory.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/async/AsyncEventBusConfigBeanTest.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/SyncEventBusConfigBeanTest.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/TestingEventBusModule.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/TestingFixedThreadPoolModule.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/flexible/FlexibleThreadPoolConfigBeanTest.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/NamingThreadPoolFactoryConfigBeanTest.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/TestingNamingThreadPoolFactoryModule.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/TestingScheduledThreadPoolModule.java
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGenerator.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ServiceInterfaceEntry.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/Dependency.java
opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java
opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntryTest.java
opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ServiceInterfaceEntryTest.java
opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java
opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/MbeParser.java
opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java [moved from opendaylight/config/yang-test/src/test/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java with 64% similarity]
opendaylight/configuration/api/pom.xml
opendaylight/configuration/implementation/pom.xml
opendaylight/configuration/integrationtest/pom.xml
opendaylight/connectionmanager/api/pom.xml
opendaylight/connectionmanager/implementation/pom.xml
opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/scheme/AbstractScheme.java
opendaylight/containermanager/api/pom.xml
opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerFlowConfig.java
opendaylight/containermanager/implementation/pom.xml
opendaylight/containermanager/it.implementation/pom.xml
opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked1.txt [deleted file]
opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked2.txt [deleted file]
opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked3.txt [deleted file]
opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked4.txt [deleted file]
opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked5.txt [deleted file]
opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/databaseinteractions/jolokia_config_bean_response.txt [deleted file]
opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/databaseinteractions/jolokia_lookupConfigBeans.txt [deleted file]
opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_commit.xml [deleted file]
opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_lock_candidate.xml [deleted file]
opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_lock_running.xml [deleted file]
opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_modify_candidate.xml [deleted file]
opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_unlock_candidate.xml [deleted file]
opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_unlock_running.xml [deleted file]
opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/server_error_missing_attribute.xml [deleted file]
opendaylight/distribution/opendaylight/opendaylight.target
opendaylight/distribution/opendaylight/pom.xml
opendaylight/distribution/opendaylight/src/assemble/bin.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/RSA.pk [moved from opendaylight/netconf/netconf-ssh/src/main/resources/RSA.pk with 100% similarity]
opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.conf [deleted file]
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml.conf [new file with mode: 0644]
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.conf [deleted file]
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml.conf [new file with mode: 0644]
opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml
opendaylight/distribution/opendaylight/src/main/resources/run.sh
opendaylight/forwarding/staticrouting/pom.xml
opendaylight/forwardingrulesmanager/api/pom.xml
opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java
opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowEntry.java
opendaylight/forwardingrulesmanager/implementation/pom.xml
opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java
opendaylight/hosttracker/api/pom.xml
opendaylight/hosttracker/implementation/pom.xml
opendaylight/hosttracker/implementation/src/test/java/org/opendaylight/controller/hosttracker/internal/HostTrackerTest.java
opendaylight/hosttracker_new/api/pom.xml
opendaylight/hosttracker_new/implementation/pom.xml
opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/Activator.java
opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/UncaughtExceptionHandler.java [deleted file]
opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/UncaughtExceptionPolicy.java [new file with mode: 0644]
opendaylight/md-sal/clustered-data-store/implementation/pom.xml
opendaylight/md-sal/clustered-data-store/integrationtest/pom.xml
opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml
opendaylight/md-sal/compatibility/inventory-topology-compatibility/pom.xml
opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/switchmanager/CompatibleSwitchManager.xtend
opendaylight/md-sal/compatibility/pom.xml
opendaylight/md-sal/compatibility/sal-compatibility/pom.xml
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FromSalConversionsUtils.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDSalNodeConnectorFactory.java [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDSalNodeFactory.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/DataPacketServiceAdapter.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowStatisticsAdapter.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.xtend
opendaylight/md-sal/model/model-flow-base/pom.xml
opendaylight/md-sal/model/model-flow-base/src/main/yang/group-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/match-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/meter-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-action-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang
opendaylight/md-sal/model/model-flow-management/pom.xml
opendaylight/md-sal/model/model-flow-service/pom.xml
opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-capable-transaction.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-node-inventory.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-service.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/group-service.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/meter-service.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/packet-processing.yang
opendaylight/md-sal/model/model-flow-statistics/pom.xml
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/flow-statistics.yang
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/group-statistics.yang
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/port-statistics.yang
opendaylight/md-sal/model/model-inventory/src/main/yang/netconf-node-inventory.yang [new file with mode: 0644]
opendaylight/md-sal/model/model-topology/pom.xml
opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology-inventory.yang
opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology.yang
opendaylight/md-sal/model/model-topology/src/main/yang/topology-view.yang
opendaylight/md-sal/model/pom.xml
opendaylight/md-sal/pom.xml
opendaylight/md-sal/remoterpc-routingtable/implementation/pom.xml
opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcConsumerRegistry.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcProviderRegistry.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/mount/MountProviderService.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcContextIdentifier.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcContextIdentifier.java with 97% similarity]
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRouter.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRouter.java with 98% similarity]
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingContext.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingContext.java with 82% similarity]
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRoutingTable.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRoutingTable.java with 96% similarity]
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
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/statistics/DataBrokerRuntimeMXBeanImpl.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRoutingTableImpl.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/api/AugmentationCodec.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/api/CodecRegistry.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/impl/BindingAwareBrokerImpl.xtend [deleted file]
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/MountPointManagerImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiProviderContext.xtend [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootBindingAwareBroker.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootDataBrokerImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBroker.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedDataBrokerImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardingUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/Constants.xtend [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/PropertiesUtils.xtend [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/package-info.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RoutingContext.java [deleted file]
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/RuntimeCodeGeneratorTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/FlagsSerializationTest.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/PutAugmentationTest.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java
opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java
opendaylight/md-sal/sal-binding-util/pom.xml
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalConsumerInstance.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/BindingContextUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java
opendaylight/md-sal/sal-common-util/pom.xml
opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Arguments.java
opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/CommitHandlerTransactions.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CommitHandlersTransactions.java with 89% similarity]
opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Futures.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcProvisionRegistry.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionService.java
opendaylight/md-sal/sal-dom-broker/pom.xml
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/$ModuleInfo.java [new file with mode: 0644]
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/MountPointImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/MountProviderServiceProxy.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/yangtools/yang/util/YangSchemaUtils.java
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
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/NetconfDeviceListener.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java [deleted file]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang
opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/RouteIdentifierImpl.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/RouteIdentifierImplTest.java
opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/pom.xml
opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/java/org/opendaylight/controller/sample/zeromq/test/it/RouterTest.java
opendaylight/md-sal/sal-rest-connector/pom.xml
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/RestconfProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/EmptyNodeWrapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/InstanceIdWithSchemaNode.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/NodeWrapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/SimpleNodeWrapper.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicYangTypesTest.java with 90% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonChoiceCaseTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.java with 86% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonBasicDataTypesTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.java with 56% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonIdentityrefTest.java with 56% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java [deleted file]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java [deleted file]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithDataFromSeveralModulesTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/NormalizeNodeTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java [deleted file]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestConfigDataTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestDeleteOperationTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestOperationUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPostOperationTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPutOperationTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java [deleted file]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlAndDataSchemaLoader.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang
opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data-rpc-input.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data-rpc-input.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data2.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-module/test-module [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/simple-nodes.yang
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/1/simple-list1.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list1.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/2/simple-list2.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list2.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/normalize-node/yang/normalize-node-module [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface2.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface3.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/yang1/test-interface.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/yang2/test-interface2.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-of-several-modules/yang/module1.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-of-several-modules/yang/module2.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsManagerActivator.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java
opendaylight/md-sal/test/sal-rest-connector-it/pom.xml
opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java
opendaylight/md-sal/topology-lldp-discovery/pom.xml [new file with mode: 0644]
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend [new file with mode: 0644]
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryListener.java [new file with mode: 0644]
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend [new file with mode: 0644]
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPLinkAger.java [new file with mode: 0644]
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/utils/LLDPDiscoveryUtils.java [new file with mode: 0644]
opendaylight/md-sal/topology-manager/pom.xml
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/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/editconfig/AbstractEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/Util.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/NetconfUtil.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ExiEncodeDecodeTest.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java
opendaylight/netconf/netconf-it/src/test/resources/RSA.pk [new file with mode: 0644]
opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/DefaultNetconfOperation.java
opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/xml/model/package-info.java
opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializerTest.java
opendaylight/netconf/netconf-ssh/pom.xml
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/osgi/NetconfSSHActivator.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/SSHServerTest.java
opendaylight/netconf/netconf-ssh/src/test/resources/RSA.pk [new file with mode: 0644]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/Invoker.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/virtualsocket/ChannelInputStream.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/ExiParameters.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/ExiUtil.java
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml [new file with mode: 0644]
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_expectedResult.xml
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml
opendaylight/netconf/pom.xml
opendaylight/networkconfiguration/neutron/implementation/pom.xml
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronFloatingIPInterface.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronNetworkInterface.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronPortInterface.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronRouterInterface.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSubnetInterface.java
opendaylight/networkconfiguration/neutron/pom.xml
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronFloatingIP.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_Interface.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_NetworkReference.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_HostRoute.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java
opendaylight/northbound/bundlescanner/implementation/pom.xml
opendaylight/northbound/commons/pom.xml
opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/JacksonJsonProcessingExceptionMapper.java
opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java
opendaylight/northbound/commons/src/test/java/org/opendaylight/controller/northbound/commons/exception/CommonsNorthboundExceptionTest.java
opendaylight/northbound/connectionmanager/pom.xml
opendaylight/northbound/containermanager/pom.xml
opendaylight/northbound/containermanager/src/main/java/org/opendaylight/controller/containermanager/northbound/ContainerManagerNorthboundRSApplication.java
opendaylight/northbound/controllermanager/pom.xml
opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerManagerNorthbound.java
opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerProperties.java
opendaylight/northbound/flowprogrammer/pom.xml
opendaylight/northbound/hosttracker/pom.xml
opendaylight/northbound/integrationtest/pom.xml
opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java
opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml
opendaylight/northbound/networkconfiguration/neutron/pom.xml
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java
opendaylight/northbound/staticrouting/pom.xml
opendaylight/northbound/statistics/pom.xml
opendaylight/northbound/subnets/pom.xml
opendaylight/northbound/switchmanager/pom.xml
opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeConnectorProperties.java
opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeProperties.java
opendaylight/northbound/topology/pom.xml
opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/EdgeProperties.java
opendaylight/northbound/usermanager/pom.xml
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/OFStatisticsManager.java
opendaylight/protocol_plugins/stub/pom.xml
opendaylight/protocol_plugins/stub/src/main/java/org/opendaylight/controller/protocol_plugins/stub/internal/InventoryService.java
opendaylight/routing/dijkstra_implementation/pom.xml
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ComponentActivatorAbstractBase.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/flowprogrammer/Flow.java
opendaylight/sal/connection/api/pom.xml
opendaylight/sal/connection/implementation/pom.xml
opendaylight/sal/networkconfiguration/api/pom.xml
opendaylight/sal/networkconfiguration/implementation/pom.xml
opendaylight/samples/loadbalancer/pom.xml
opendaylight/samples/loadbalancer/src/test/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerTest.java
opendaylight/samples/northbound/loadbalancer/pom.xml
opendaylight/samples/simpleforwarding/pom.xml
opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java
opendaylight/security/pom.xml
opendaylight/statisticsmanager/api/pom.xml
opendaylight/statisticsmanager/implementation/pom.xml
opendaylight/statisticsmanager/integrationtest/pom.xml
opendaylight/switchmanager/api/pom.xml
opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/Subnet.java
opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SubnetConfig.java
opendaylight/switchmanager/api/src/test/java/org/opendaylight/controller/switchmanager/SubnetTest.java
opendaylight/switchmanager/implementation/pom.xml
opendaylight/topologymanager/implementation/pom.xml
opendaylight/topologymanager/implementation/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java
opendaylight/topologymanager/integrationtest/pom.xml
opendaylight/usermanager/api/pom.xml
opendaylight/usermanager/implementation/pom.xml
opendaylight/web/devices/pom.xml
opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java
opendaylight/web/devices/src/main/resources/js/page.js
opendaylight/web/flows/pom.xml
opendaylight/web/flows/src/main/resources/js/page.js
opendaylight/web/root/pom.xml
opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWeb.java
opendaylight/web/root/src/main/resources/WEB-INF/web.xml
opendaylight/web/topology/pom.xml
opendaylight/web/troubleshoot/pom.xml

index 18817e7c359dbfbe526b0f37e379d859f0dfc97b..b079cba0a10d3a76e09c824bfeb8db16922756c7 100644 (file)
@@ -20,3 +20,4 @@ opendaylight/northbound/integrationtest/logs/*
 .idea
 xtend-gen
 classes
+out/
diff --git a/.gitreview b/.gitreview
new file mode 100644 (file)
index 0000000..5c4f71d
--- /dev/null
@@ -0,0 +1,4 @@
+[gerrit]
+host=git.opendaylight.org
+port=29418
+project=controller.git
index cba2bb89bae3452f85a73a0fc8db7a6416ff2650..f3a6a3bf4de5719fbc686a96c65906a7cbf6eb8b 100644 (file)
@@ -50,7 +50,7 @@
         <dependency>
          <groupId>org.opendaylight.controller</groupId>
            <artifactId>sal</artifactId>
-          <version>0.6.0-SNAPSHOT</version>
+          <version>0.7.0-SNAPSHOT</version>
         </dependency>
         <dependency>
          <groupId>org.opendaylight.controller</groupId>
index e3576e6ed86cc9284243be20f57358bbe7ce331b..8d3df87c58b0104194368f320ee2fe2a8e3bdc6a 100644 (file)
@@ -78,7 +78,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index 8c91c71533a19282c9f1c48e8697dd3f81d181ee..8ae038c30f38bb38410b1c093c7a7a6b791ca507 100644 (file)
@@ -461,6 +461,11 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
             log.debug("Can't find subnet matching {}, drop packet", dIP);
             return;
         }
+        // If packet is sent to the default gw (us), ignore it for now
+        if (subnet.getNetworkAddress().equals(dIP)) {
+            log.trace("Ignore IP packet destined to default gw");
+            return;
+        }
 
         // see if we know about the host
         // Hosttracker hosts db key implementation
index 90df7511e4c8050aadfbe42a40bae6a8eea8f821..536fb7dd2e61b2fdad57d661b5cb7b542868c557 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.jboss.jbossts.jta</groupId>
index fcf71a90ac5c3ae96940861df4296dd14dc8ef7e..65e7720dd3141734951cb7d51e2b69bf8619df7b 100644 (file)
@@ -68,7 +68,7 @@ public class ClusterManager implements IClusterServices {
     private HashSet<IListenRoleChange> roleChangeListeners;
     private ViewChangedListener cacheManagerListener;
 
-    private static String loopbackAddress = "127.0.0.1";
+    private static String loopbackAddress = InetAddress.getLoopbackAddress().getHostAddress();
 
     // defaultTransactionTimeout is 60 seconds
     private static int DEFAULT_TRANSACTION_TIMEOUT = 60;
index 8fe1a99a0df59d2e8573b9f2964fb413480457a6..26980e4ff574e4ea82c0b672d89e651afd9ca7f4 100644 (file)
@@ -53,7 +53,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index fe73e240f995acf3ff2b00dead4e9771bdb98fd5..f27e6f069f62e747a51d95992a484a9e2618ced1 100644 (file)
@@ -43,7 +43,7 @@ public abstract class ClusterManagerCommon implements IClusterServicesCommon {
     private ConcurrentMap<String, ConcurrentMap<?, ?>> caches = new ConcurrentHashMap<String, ConcurrentMap<?, ?>>();
 
     protected ClusterManagerCommon() throws UnknownHostException {
-        loopbackAddress = InetAddress.getByName("127.0.0.1");
+        loopbackAddress = InetAddress.getLoopbackAddress();
     }
 
     /**
index 4c00ba0db132feed4a3f6991c66e53d0b038114d..e6f889c478df909e3aa46734792197f507642034 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>equinoxSDK381</groupId>
index 5183165752446b8e38507d7dd3cc239394051cdb..24b1ed9cbcb0e6b32132d3433c55de5012345592 100644 (file)
@@ -46,7 +46,7 @@
     <sonar.skippedModules>org.openflow.openflowj,net.sf.jung2</sonar.skippedModules>
     <logback.version>1.0.9</logback.version>
     <slf4j.version>1.7.2</slf4j.version>
-    <jackson.version>1.9.8</jackson.version>
+    <jackson.version>2.3.0</jackson.version>
     <spring.version>3.1.3.RELEASE</spring.version>
     <spring-security.version>3.1.3.RELEASE</spring-security.version>
     <spring-osgi.version>1.2.1</spring-osgi.version>
@@ -61,6 +61,7 @@
     <osgi.core.version>5.0.0</osgi.core.version>
     <ietf-inet-types.version>2010.09.24.2-SNAPSHOT</ietf-inet-types.version>
     <ietf-yang-types.version>2010.09.24.2-SNAPSHOT</ietf-yang-types.version>
+    <ietf-topology.version>2013.10.21.0-SNAPSHOT</ietf-topology.version>
     <opendaylight-l2-types.version>2013.08.27.1</opendaylight-l2-types.version>
     <yang-ext.version>2013.09.07.1</yang-ext.version>
     <javassist.version>3.17.1-GA</javassist.version>
     <jolokia.bridge.version>0.0.1-SNAPSHOT</jolokia.bridge.version>
     <netty.version>4.0.10.Final</netty.version>
     <commons.io.version>2.4</commons.io.version>
-    <!-- Sonar properties using jacoco to retrieve integration test results -->
-    <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
-    <sonar.language>java</sonar.language>
+    <bundlescanner.version>0.4.1-SNAPSHOT</bundlescanner.version>
+    <usermanager.version>0.4.1-SNAPSHOT</usermanager.version>
     <forwardingrulesmanager.version>0.5.0-SNAPSHOT</forwardingrulesmanager.version>
     <statisticsmanager.version>0.5.0-SNAPSHOT</statisticsmanager.version>
     <clustering.services.version>0.5.0-SNAPSHOT</clustering.services.version>
+    <configuration.version>0.4.1-SNAPSHOT</configuration.version>
+    <topologymanager.version>0.4.1-SNAPSHOT</topologymanager.version>
+    <!-- Third party version -->
+    <jersey-servlet.version>1.18-SNAPSHOT</jersey-servlet.version>
+    <corsfilter.version>7.0.43-SNAPSHOT</corsfilter.version>
+    <!-- Northbound API version -->
+    <commons.northbound.version>0.4.1-SNAPSHOT</commons.northbound.version>
+    <!-- Sonar properties using jacoco to retrieve integration test results -->
+    <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
+    <sonar.language>java</sonar.language>
     <maven.compile.plugin.version>2.5.1</maven.compile.plugin.version>
     <java.version.source>1.7</java.version.source>
     <java.version.target>1.7</java.version.target>
         <artifactId>logback-classic</artifactId>
         <version>${logback.version}</version>
       </dependency>
-      <dependency>
-        <groupId>org.codehaus.jackson</groupId>
-        <artifactId>jackson-mapper-asl</artifactId>
-        <version>${jackson.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.codehaus.jackson</groupId>
-        <artifactId>jackson-core-asl</artifactId>
+
+     <dependency>
+       <groupId>com.fasterxml.jackson.core</groupId>
+       <artifactId>jackson-annotations</artifactId>
+       <version>${jackson.version}</version>
+     </dependency>
+
+     <dependency>
+       <groupId>com.fasterxml.jackson.core</groupId>
+       <artifactId>jackson-core</artifactId>
+       <version>${jackson.version}</version>
+     </dependency>
+
+     <dependency>
+       <groupId>com.fasterxml.jackson.core</groupId>
+       <artifactId>jackson-databind</artifactId>
+       <version>${jackson.version}</version>
+     </dependency>
+
+     <dependency>
+        <groupId>com.fasterxml.jackson.jaxrs</groupId>
+        <artifactId>jackson-jaxrs-base</artifactId>
         <version>${jackson.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.codehaus.jackson</groupId>
-        <artifactId>jackson-jaxrs</artifactId>
+     </dependency>
+
+    <dependency>
+        <groupId>com.fasterxml.jackson.jaxrs</groupId>
+        <artifactId>jackson-jaxrs-json-provider</artifactId>
         <version>${jackson.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.codehaus.jackson</groupId>
-        <artifactId>jackson-xc</artifactId>
+     </dependency>
+
+     <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-jaxb-annotations</artifactId>
         <version>${jackson.version}</version>
-      </dependency>
+     </dependency>
+
       <dependency>
         <groupId>org.codehaus.jettison</groupId>
         <artifactId>jettison</artifactId>
         <artifactId>jersey-client</artifactId>
         <version>${jersey.version}</version>
       </dependency>
-      <dependency>
-        <groupId>com.sun.jersey</groupId>
-        <artifactId>jersey-json</artifactId>
-        <version>${jersey.version}</version>
-      </dependency>
+
       <dependency>
         <groupId>org.ow2.asm</groupId>
         <artifactId>asm-all</artifactId>
       <dependency>
         <groupId>org.opendaylight.controller.thirdparty</groupId>
         <artifactId>com.sun.jersey.jersey-servlet</artifactId>
-        <version>1.17</version>
+        <version>${jersey-servlet.version}</version>
       </dependency>
       <dependency>
         <groupId>org.opendaylight.controller.thirdparty</groupId>
         <artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
-        <version>7.0.42</version>
+        <version>${corsfilter.version}</version>
       </dependency>
       <dependency>
         <groupId>org.opendaylight.controller.thirdparty</groupId>
        <artifactId>ietf-yang-types</artifactId>
        <version>${ietf-yang-types.version}</version>
       </dependency>
+      <dependency>
+       <groupId>org.opendaylight.yangtools.model</groupId>
+       <artifactId>ietf-topology</artifactId>
+       <version>${ietf-topology.version}</version>
+      </dependency>
       <dependency>
        <groupId>org.opendaylight.yangtools.model</groupId>
        <artifactId>opendaylight-l2-types</artifactId>
       <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>switchmanager</artifactId>
-        <version>0.5.1-SNAPSHOT</version>
+        <version>${switchmanager.api.version}</version>
       </dependency>
 
       <!-- equinox http service bridge -->
index 38fb8ed66be0424afe14ecd57f1e3f0693e683c4..10c9fad07ef2d1a55cdabd4101d4e668ba9698db 100644 (file)
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-maven-plugin</artifactId>
             </plugin>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>build-helper-maven-plugin</artifactId>
-            </plugin>
         </plugins>
     </build>
 </project>
index 90b8bb6d850b91adbe30a9ba9ff707307474cb1a..da54a8341a8b477a9ebf4ba8f7cc02238668297f 100644 (file)
@@ -21,7 +21,7 @@ import java.util.Map.Entry;
 public class ValidationException extends RuntimeException {
     private static final long serialVersionUID = -6072893219820274247L;
 
-    private final Map<String, Map<String, ExceptionMessageWithStackTrace>> failedValidations;
+    private final Map<String/* module name */, Map<String/* instance name */, ExceptionMessageWithStackTrace>> failedValidations;
 
     public ValidationException(
             Map<String /* module name */, Map<String /* instance name */, ExceptionMessageWithStackTrace>> failedValidations) {
@@ -70,7 +70,7 @@ public class ValidationException extends RuntimeException {
         return new ValidationException(failedValidations);
     }
 
-    public Map<String, Map<String, ExceptionMessageWithStackTrace>> getFailedValidations() {
+    public Map<String/* module name */, Map<String/* instance name */, ExceptionMessageWithStackTrace>> getFailedValidations() {
         return failedValidations;
     }
 
index 81b0921660539b822b4c0f3216b704f052500210..64ce14e8f1733b8ab28465a9edd4a191141a6a09 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.config.manager.impl;
 
 import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
 import junit.framework.Assert;
 import org.junit.After;
 import org.mockito.Matchers;
@@ -26,19 +25,25 @@ import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
+import javax.management.RuntimeMBeanException;
 import java.io.Closeable;
 import java.io.InputStream;
 import java.lang.management.ManagementFactory;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
 import java.util.Dictionary;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 import static org.junit.Assert.assertEquals;
@@ -66,8 +71,16 @@ public abstract class AbstractConfigTest extends
     protected BundleContext mockedContext = mock(BundleContext.class);
     protected ServiceRegistration<?> mockedServiceRegistration;
 
-    protected  Map<Class, BundleContextServiceRegistrationHandler> getBundleContextServiceRegistrationHandlers() {
-        return Maps.newHashMap();
+    private static final Logger logger = LoggerFactory.getLogger(AbstractConfigTest.class);
+
+    // Default handler for OSGi service registration
+    private static final BundleContextServiceRegistrationHandler noopServiceRegHandler = new BundleContextServiceRegistrationHandler() {
+        @Override
+        public void handleServiceRegistration(Object serviceInstance) {}
+    };
+
+    protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(Class<?> serviceType) {
+        return noopServiceRegHandler;
     }
 
     // this method should be called in @Before
@@ -166,9 +179,8 @@ public abstract class AbstractConfigTest extends
     protected ObjectName createTestConfigBean(
             ConfigTransactionJMXClient transaction, String implementationName,
             String name) throws InstanceAlreadyExistsException {
-        ObjectName nameCreated = transaction.createModule(implementationName,
+        return transaction.createModule(implementationName,
                 name);
-        return nameCreated;
     }
 
     protected void assertBeanCount(int i, String configMXBeanName) {
@@ -204,26 +216,68 @@ public abstract class AbstractConfigTest extends
     }
 
     private class RegisterServiceAnswer implements Answer {
+
         @Override
         public Object answer(InvocationOnMock invocation) throws Throwable {
             Object[] args = invocation.getArguments();
 
-            Preconditions.checkArgument(args.length == 3);
+            Preconditions.checkArgument(args.length == 3, "Unexpected arguments size (expected 3 was %s)", args.length);
 
-            Preconditions.checkArgument(args[0] instanceof Class);
-            Class<?> serviceType = (Class<?>) args[0];
+            Object serviceTypeRaw = args[0];
             Object serviceInstance = args[1];
 
-            BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandlers()
-                    .get(serviceType);
+            if (serviceTypeRaw instanceof Class) {
+                Class<?> serviceType = (Class<?>) serviceTypeRaw;
+                invokeServiceHandler(serviceInstance, serviceType);
+
+            } else if(serviceTypeRaw instanceof String[]) {
+                for (String className : (String[]) serviceTypeRaw) {
+                    try {
+                        Class<?> serviceType = Class.forName(className);
+                        invokeServiceHandler(serviceInstance, serviceType);
+                    } catch (ClassNotFoundException e) {
+                        logger.warn("Not handling service registration of type {} ", className, e);
+                    }
+                }
+
+            } else
+                logger.debug("Not handling service registration of type {}, Unknown type", serviceTypeRaw);
+
+            return mockedServiceRegistration;
+        }
 
-            Preconditions.checkArgument(serviceType.isAssignableFrom(serviceInstance.getClass()));
+        private void invokeServiceHandler(Object serviceInstance, Class<?> serviceType) {
+            BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandler(serviceType);
 
             if (serviceRegistrationHandler != null) {
                 serviceRegistrationHandler.handleServiceRegistration(serviceType.cast(serviceInstance));
             }
-
-            return mockedServiceRegistration;
         }
     }
+
+    /**
+     * Expand inner exception wrapped by JMX
+     *
+     * @param innerObject jmx proxy which will be wrapped and returned
+     */
+    protected <T> T rethrowCause(final T innerObject) {
+
+        Object proxy = Proxy.newProxyInstance(innerObject.getClass().getClassLoader(),
+                innerObject.getClass().getInterfaces(), new InvocationHandler() {
+            @Override
+            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+                try {
+                    return method.invoke(innerObject, args);
+                } catch (InvocationTargetException e) {
+                    try {
+                        throw e.getTargetException();
+                    } catch (RuntimeMBeanException e2) {
+                        throw e2.getTargetException();
+                    }
+                }
+            }
+        });
+        return (T) proxy;
+    }
+
 }
index 80016a804beca18cff5f3e1f9aabd45234a67d50..f622992bb57460966929d7c2b21aab0e9aa5d01f 100644 (file)
 
     <build>
         <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+            </plugin>
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
diff --git a/opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java b/opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java
new file mode 100644 (file)
index 0000000..2df07b1
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.persist.test;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.opendaylight.controller.config.persist.api.PropertiesProvider;
+
+public class PropertiesProviderTest implements PropertiesProvider {
+    private final Map<String,String> properties = new HashMap();
+
+    public void addProperty(String key,String value){
+        properties.put(key,value);
+    }
+    @Override
+    public String getProperty(String key) {
+        return properties.get(key);
+    }
+
+    @Override
+    public String getFullKeyForReporting(String key) {
+        return null;
+    }
+}
index b2da71eea2373198171645f58a5e3e44fc950290..c67a08c7af86ac341086f59e7b16eeaf0495c915 100644 (file)
             <artifactId>mockito-configuration</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>config-persister-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
 
     </dependencies>
 
index a123eb981ed9ca81d50baf0a6fa582b7ab6e3048..eb8ef8cddf46c98511db67e0423b23db38893f3f 100644 (file)
@@ -33,21 +33,23 @@ public class DirectoryPersister implements Persister {
     private static final Logger logger = LoggerFactory.getLogger(DirectoryPersister.class);
     private static final Charset ENCODING = Charsets.UTF_8;
 
-    static final String MODULES_START = "//MODULES START";
+    public static final String MODULES_START = "//MODULES START";
     static final String SERVICES_START = "//SERVICES START";
     static final String CAPABILITIES_START = "//CAPABILITIES START";
 
 
     private final File storage;
-    private final String header, middle, footer;
+    private static final String header, middle, footer;
 
-    public DirectoryPersister(File storage) {
-        checkArgument(storage.exists() && storage.isDirectory(), "Storage directory does not exist: " + storage);
-        this.storage = storage;
+    static {
         header = readResource("header.txt");
         middle = readResource("middle.txt");
         footer = readResource("footer.txt");
+    }
 
+    public DirectoryPersister(File storage) {
+        checkArgument(storage.exists() && storage.isDirectory(), "Storage directory does not exist: " + storage);
+        this.storage = storage;
     }
 
     private static String readResource(String resource) {
@@ -78,13 +80,18 @@ public class DirectoryPersister implements Persister {
         for (File file : sortedFiles) {
             logger.trace("Adding file '{}' to combined result", file);
 
-            final MyLineProcessor lineProcessor = new MyLineProcessor(file.getAbsolutePath());
-            Files.readLines(file, ENCODING, lineProcessor);
-            result.add(lineProcessor.getConfigSnapshotHolder(header, middle, footer));
+            ConfigSnapshotHolder configSnapshotHolder = loadLastConfig(file);
+            result.add(configSnapshotHolder);
         }
         return result;
     }
 
+    public static ConfigSnapshotHolder loadLastConfig(File file) throws IOException {
+        final MyLineProcessor lineProcessor = new MyLineProcessor(file.getAbsolutePath());
+        Files.readLines(file, ENCODING, lineProcessor);
+        return lineProcessor.getConfigSnapshotHolder(header, middle, footer);
+    }
+
 
     @Override
     public void close() {
index f17e414c495e376b7316f9fcc79a1891313ad1a6..72bd208ff31ed17eaf76d047e1a5eef83a935212 100644 (file)
@@ -8,28 +8,32 @@
 
 package org.opendaylight.controller.config.persist.storage.directory;
 
-import org.apache.commons.io.IOUtils;
-import org.junit.Test;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-
 import java.io.File;
 import java.util.Collections;
 import java.util.List;
 import java.util.SortedSet;
 import java.util.TreeSet;
-
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.test.PropertiesProviderTest;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 public class DirectoryStorageAdapterTest {
-    DirectoryPersister tested;
+    Persister tested;
 
     @Test
     public void testEmptyDirectory() throws Exception {
         File folder = new File("target/emptyFolder");
         folder.mkdir();
-        tested = new DirectoryPersister((folder));
+
+        PropertiesProviderTest pp = new PropertiesProviderTest();
+        pp.addProperty("directoryStorage",folder.getPath());
+        DirectoryStorageAdapter dsa = new DirectoryStorageAdapter();
+        tested = dsa.instantiate(pp);
         assertEquals(Collections.<ConfigSnapshotHolder>emptyList(), tested.loadLastConfigs());
 
         try {
@@ -60,7 +64,11 @@ public class DirectoryStorageAdapterTest {
     @Test
     public void testOneFile() throws Exception {
         File folder = getFolder("oneFile");
-        tested = new DirectoryPersister((folder));
+        PropertiesProviderTest pp = new PropertiesProviderTest();
+        pp.addProperty("directoryStorage",folder.getPath());
+        DirectoryStorageAdapter dsa = new DirectoryStorageAdapter();
+        tested = dsa.instantiate(pp);
+
         List<ConfigSnapshotHolder> results = tested.loadLastConfigs();
         assertEquals(1, results.size());
         ConfigSnapshotHolder result = results.get(0);
@@ -71,7 +79,11 @@ public class DirectoryStorageAdapterTest {
     @Test
     public void testTwoFiles() throws Exception {
         File folder = getFolder("twoFiles");
-        tested = new DirectoryPersister((folder));
+        PropertiesProviderTest pp = new PropertiesProviderTest();
+        pp.addProperty("directoryStorage",folder.getPath());
+        DirectoryStorageAdapter dsa = new DirectoryStorageAdapter();
+        tested = dsa.instantiate(pp);
+
         List<ConfigSnapshotHolder> results = tested.loadLastConfigs();
         assertEquals(2, results.size());
         assertSnapshot(results.get(0), "twoFilesExpected1");
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml b/opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml
new file mode 100644 (file)
index 0000000..0ec7726
--- /dev/null
@@ -0,0 +1,113 @@
+<?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>
+        <artifactId>config-subsystem</artifactId>
+        <groupId>org.opendaylight.controller</groupId>
+        <version>0.2.3-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+    <artifactId>config-persister-directory-autodetect-adapter</artifactId>
+    <name>${project.artifactId}</name>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <!-- compile dependencies -->
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>config-persister-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-persister-directory-adapter</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-persister-directory-xml-adapter</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+        <!-- test dependencies -->
+        <dependency>
+            <groupId>org.opendaylight.bgpcep</groupId>
+            <artifactId>mockito-configuration</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <!-- workaround for creating version according to OSGi specification (major.minor.micro[.qualifier] -->
+            <plugin>
+                <groupId>org.codehaus.groovy.maven</groupId>
+                <artifactId>gmaven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>execute</goal>
+                        </goals>
+                        <configuration>
+                            <source>
+                                System.setProperty("osgiversion", "${project.version}".replace('-', '.'))
+                            </source>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Fragment-Host>${project.groupId}.config-persister-impl;bundle-version=${osgiversion}
+                        </Fragment-Host>
+                        <Provide-Capability>org.opendaylight.controller.config.persister.storage.adapter
+                        </Provide-Capability>
+                        <Import-Package>
+                            com.google.common.base,
+                            com.google.common.io,
+                            org.apache.commons.io,
+                            org.opendaylight.controller.config.persist.api,
+                            org.slf4j,
+                            com.google.common.collect,
+                            javax.xml.bind,
+                            javax.xml.bind.annotation,
+                            javax.xml.transform,
+                            javax.xml.transform.stream,
+                            org.eclipse.persistence.jaxb,
+                            org.apache.commons.lang3
+                        </Import-Package>
+                        <Private-Package>
+                            org.opendaylight.controller.config.persist.storage.file.xml.model,
+                            org.opendaylight.controller.config.persist.storage.directory,
+                            org.opendaylight.controller.config.persist.storage.directory.xml,
+                        </Private-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersister.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersister.java
new file mode 100644 (file)
index 0000000..f262952
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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.persist.storage.directory.autodetect;
+
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.storage.directory.DirectoryPersister;
+import org.opendaylight.controller.config.persist.storage.directory.xml.XmlDirectoryPersister;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.JAXBException;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class AutodetectDirectoryPersister implements Persister {
+    private static final Logger logger = LoggerFactory.getLogger(AutodetectDirectoryPersister.class);
+
+    private final File storage;
+
+    public AutodetectDirectoryPersister(File storage) {
+        checkArgument(storage.exists() && storage.isDirectory(), "Storage directory does not exist: " + storage);
+        this.storage = storage;
+    }
+
+    @Override
+    public void persistConfig(ConfigSnapshotHolder holder) throws IOException {
+        throw new UnsupportedOperationException("This adapter is read only. Please set readonly=true on " + getClass());
+    }
+
+    @Override
+    public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
+        File[] filesArray = storage.listFiles();
+        if (filesArray == null || filesArray.length == 0) {
+            return Collections.emptyList();
+        }
+        List<File> sortedFiles = new ArrayList<>(Arrays.asList(filesArray));
+        Collections.sort(sortedFiles);
+
+        // combine all found files
+        logger.debug("Reading files in following order: {}", sortedFiles);
+
+        List<ConfigSnapshotHolder> result = new ArrayList<>();
+        for (File file : sortedFiles) {
+            logger.trace("Adding file '{}' to combined result", file);
+
+            FileType fileType = FileType.getFileType(file);
+            logger.trace("File '{}' detected as {} storage", file, fileType);
+
+            ConfigSnapshotHolder snapshot = loadLastConfig(file, fileType);
+            result.add(snapshot);
+        }
+        return result;
+    }
+
+    private ConfigSnapshotHolder loadLastConfig(File file, FileType fileType) throws IOException {
+        switch (fileType) {
+        case plaintext:
+            return DirectoryPersister.loadLastConfig(file);
+        case xml:
+            try {
+                return XmlDirectoryPersister.loadLastConfig(file);
+            } catch (JAXBException e) {
+                logger.warn("Unable to restore configuration snapshot from {}", file, e);
+                throw new IllegalStateException("Unable to restore configuration snapshot from " + file, e);
+            }
+        default:
+            throw new IllegalStateException("Unknown storage type " + fileType);
+        }
+    }
+
+    @Override
+    public void close() {
+
+    }
+
+    @Override
+    public String toString() {
+        final StringBuffer sb = new StringBuffer("AutodetectDirectoryPersister{");
+        sb.append("storage=").append(storage);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryStorageAdapter.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryStorageAdapter.java
new file mode 100644 (file)
index 0000000..f856ddd
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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.persist.storage.directory.autodetect;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.api.PropertiesProvider;
+import org.opendaylight.controller.config.persist.api.StorageAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+
+/**
+ * StorageAdapter that retrieves initial configuration from a directory. If multiple files are present, snapshot and
+ * required capabilities will be merged together. Writing to this persister is not supported.
+ */
+public class AutodetectDirectoryStorageAdapter implements StorageAdapter {
+    private static final Logger logger = LoggerFactory.getLogger(AutodetectDirectoryStorageAdapter.class);
+
+    public static final String DIRECTORY_STORAGE_PROP = "directoryStorage";
+
+
+    @Override
+    public Persister instantiate(PropertiesProvider propertiesProvider) {
+        String fileStorageProperty = propertiesProvider.getProperty(DIRECTORY_STORAGE_PROP);
+        Preconditions.checkNotNull(fileStorageProperty, "Unable to find " + propertiesProvider.getFullKeyForReporting(DIRECTORY_STORAGE_PROP));
+        File storage  = new File(fileStorageProperty);
+        logger.debug("Using {}", storage);
+        return new AutodetectDirectoryPersister(storage);
+    }
+
+}
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileType.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileType.java
new file mode 100644 (file)
index 0000000..779a887
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * 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.persist.storage.directory.autodetect;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+import org.apache.commons.lang3.StringUtils;
+import org.opendaylight.controller.config.persist.storage.directory.DirectoryPersister;
+import org.opendaylight.controller.config.persist.storage.file.xml.model.ConfigSnapshot;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+enum FileType {
+
+    plaintext, xml;
+
+    public static final String XML_STORAGE_FIRST_LINE = "<" + ConfigSnapshot.SNAPSHOT_ROOT_ELEMENT_NAME + ">";
+    private static final String XML_FILE_DEFINITION_LINE = "<?xml";
+
+    static FileType getFileType(File file) {
+        String firstLine = readFirstLine(file);
+        if(isPlaintextStorage(firstLine)) {
+            return plaintext;
+        } else if(isXmlStorage(firstLine))
+            return xml;
+
+        throw new IllegalArgumentException("File " + file + " is not of permitted storage type: " + Arrays.toString(FileType.values()));
+    }
+
+    private static boolean isXmlStorage(String firstLine) {
+        boolean isXml = false;
+        isXml |= firstLine.startsWith(XML_STORAGE_FIRST_LINE);
+        isXml |= firstLine.startsWith(XML_FILE_DEFINITION_LINE);
+        return isXml;
+    }
+
+    private static boolean isPlaintextStorage(String firstLine) {
+        return firstLine.startsWith(DirectoryPersister.MODULES_START);
+
+    }
+
+    @VisibleForTesting
+    static String readFirstLine(File file) {
+        FirstLineReadingProcessor callback = new FirstLineReadingProcessor();
+        try {
+            return Files.readLines(file, Charsets.UTF_8, callback);
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Unable to detect file type of file " + file, e);
+        }
+    }
+
+
+    private static class FirstLineReadingProcessor implements com.google.common.io.LineProcessor<String> {
+        private String firstNonBlankLine;
+
+        @Override
+        public boolean processLine(String line) throws IOException {
+            if(isEmptyLine(line)) {
+                return true;
+            } else {
+                firstNonBlankLine = line.trim();
+                return false;
+            }
+        }
+
+        private boolean isEmptyLine(String line) {
+            return StringUtils.isBlank(line);
+        }
+
+        @Override
+        public String getResult() {
+            return firstNonBlankLine;
+        }
+    }
+}
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersisterTest.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersisterTest.java
new file mode 100644 (file)
index 0000000..7e42391
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.persist.storage.directory.autodetect;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.junit.matchers.JUnitMatchers;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+
+import java.io.File;
+import java.util.List;
+
+public class AutodetectDirectoryPersisterTest {
+
+    @Test
+    public void testCombined() throws Exception {
+        File resourcePath = FileTypeTest.getResourceAsFile("/combined/1controller.txt.config");
+
+        AutodetectDirectoryPersister persister = new AutodetectDirectoryPersister(resourcePath.getParentFile());
+        List<ConfigSnapshotHolder> configs = persister.loadLastConfigs();
+
+        Assert.assertEquals(2, configs.size());
+        String snapFromTxt = configs.get(0).getConfigSnapshot();
+        org.junit.Assert.assertThat(snapFromTxt, JUnitMatchers.containsString("<config>txt</config>"));
+        org.junit.Assert.assertThat(snapFromTxt, JUnitMatchers.containsString("<service>txt</service>"));
+
+        String snapFromXml = configs.get(1).getConfigSnapshot();
+        org.junit.Assert.assertThat(snapFromXml, JUnitMatchers.containsString("<config>xml</config>"));
+
+        Assert.assertEquals(configs.get(0).getCapabilities(), configs.get(1).getCapabilities());
+    }
+}
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileTypeTest.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileTypeTest.java
new file mode 100644 (file)
index 0000000..bbc272d
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.persist.storage.directory.autodetect;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.junit.matchers.JUnitMatchers;
+
+import java.io.File;
+
+public class FileTypeTest {
+
+    @Test
+    public void testPlaintext() throws Exception {
+        File file = getResourceAsFile("/test.txt.config");
+
+        FileType type = FileType.getFileType(file);
+        Assert.assertEquals(FileType.plaintext, type);
+
+    }
+
+    @Test
+    public void testXml() throws Exception {
+        File file = getResourceAsFile("/test.xml.config");
+
+        FileType type = FileType.getFileType(file);
+        Assert.assertEquals(FileType.xml, type);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testUnknown() throws Exception {
+        File file = getResourceAsFile("/unknown.config");
+
+        try {
+            FileType.getFileType(file);
+        } catch (IllegalArgumentException e) {
+            org.junit.Assert.assertThat(e.getMessage(), JUnitMatchers.containsString("File " + file + " is not of permitted storage type"));
+            throw e;
+        }
+    }
+
+    static File getResourceAsFile(String resource) {
+        String f = FileTypeTest.class.getResource(resource).getFile();
+        return new File(f);
+    }
+
+}
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/1controller.txt.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/1controller.txt.config
new file mode 100644 (file)
index 0000000..f72cd1c
--- /dev/null
@@ -0,0 +1,8 @@
+//MODULES START
+        <config>txt</config>
+//SERVICES START
+        <service>txt</service>
+//CAPABILITIES START
+cap1&rev
+cap2
+capa a
\ No newline at end of file
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/2controller.xml.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/2controller.xml.config
new file mode 100644 (file)
index 0000000..988f866
--- /dev/null
@@ -0,0 +1,10 @@
+<snapshot>
+    <required-capabilities>
+        <capability>cap1&amp;rev</capability>
+        <capability>cap2</capability>
+        <capability>capa a</capability>
+    </required-capabilities>
+    <configuration>
+        <config>xml</config>
+    </configuration>
+</snapshot>
\ No newline at end of file
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.txt.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.txt.config
new file mode 100644 (file)
index 0000000..edf37ca
--- /dev/null
@@ -0,0 +1,2 @@
+//MODULES START
+configuration
\ No newline at end of file
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.xml.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.xml.config
new file mode 100644 (file)
index 0000000..fe94299
--- /dev/null
@@ -0,0 +1,2 @@
+
+<snapshot>
\ No newline at end of file
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/unknown.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/unknown.config
new file mode 100644 (file)
index 0000000..c4218c8
--- /dev/null
@@ -0,0 +1,2 @@
+unknown
+file type
\ No newline at end of file
index b2ea632834d56fdb9d3afbcb04974edea0bf3b06..96d3a71c30bc3903ede0e872e11885b0f82587eb 100644 (file)
             <artifactId>mockito-configuration</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>config-persister-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
 
     </dependencies>
 
index f6f6de9fd5d8370a11a29233c74dca1a20c4ba2e..0ca47edf0e5540cef5db8c2bcbb8f0d8f9dde611 100644 (file)
@@ -63,17 +63,21 @@ public class XmlDirectoryPersister implements Persister {
 
     private ConfigSnapshotHolder fromXmlSnapshot(File file) {
         try {
-            JAXBContext jaxbContext = JAXBContext.newInstance(ConfigSnapshot.class);
-            Unmarshaller um = jaxbContext.createUnmarshaller();
-
-            return asHolder((ConfigSnapshot) um.unmarshal(file));
+            return loadLastConfig(file);
         } catch (JAXBException e) {
             logger.warn("Unable to restore configuration snapshot from {}", file, e);
             throw new IllegalStateException("Unable to restore configuration snapshot from " + file, e);
         }
     }
 
-    private ConfigSnapshotHolder asHolder(final ConfigSnapshot unmarshalled) {
+    public static ConfigSnapshotHolder loadLastConfig(File file) throws JAXBException {
+        JAXBContext jaxbContext = JAXBContext.newInstance(ConfigSnapshot.class);
+        Unmarshaller um = jaxbContext.createUnmarshaller();
+
+        return asHolder((ConfigSnapshot) um.unmarshal(file));
+    }
+
+    private static ConfigSnapshotHolder asHolder(final ConfigSnapshot unmarshalled) {
         return new ConfigSnapshotHolder() {
             @Override
             public String getConfigSnapshot() {
index 73061f81de0d79ceae90b99852b9e8989faa0d45..825eb946c8ec8be817caf0c73470528531e15650 100644 (file)
@@ -8,20 +8,21 @@
 
 package org.opendaylight.controller.config.persist.storage.directory.xml;
 
-import org.junit.Test;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-
 import java.io.File;
 import java.util.Collections;
 import java.util.List;
 import java.util.SortedSet;
-
+import org.junit.Test;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 public class DirectoryStorageAdapterTest {
     XmlDirectoryPersister tested;
+    Logger logger = LoggerFactory.getLogger(DirectoryStorageAdapterTest.class.toString());
 
     @Test
     public void testEmptyDirectory() throws Exception {
@@ -58,7 +59,8 @@ public class DirectoryStorageAdapterTest {
     @Test
     public void testOneFile() throws Exception {
         File folder = getFolder("oneFile");
-        tested = new XmlDirectoryPersister((folder));
+        tested = new XmlDirectoryPersister(folder);
+        logger.info("Testing : "+tested.toString());
         List<ConfigSnapshotHolder> results = tested.loadLastConfigs();
         assertEquals(1, results.size());
         ConfigSnapshotHolder result = results.get(0);
@@ -77,6 +79,7 @@ public class DirectoryStorageAdapterTest {
     public void testTwoFiles() throws Exception {
         File folder = getFolder("twoFiles");
         tested = new XmlDirectoryPersister((folder));
+        logger.info("Testing : "+tested.toString());
         List<ConfigSnapshotHolder> results = tested.loadLastConfigs();
         assertEquals(2, results.size());
 
index b16cb2b6f366070b95a12ec7b61af3e36e343714..3cd3e907b3a63682e5bcb0f87df23df038e96a11 100644 (file)
             <artifactId>mockito-configuration</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>config-persister-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
index 3ec8713b476514349c001f1854a4b9c05cc00ccf..1b9948bf39ea74cc1da7508f1f48815d7600d211 100644 (file)
@@ -13,15 +13,6 @@ import com.google.common.base.Charsets;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.io.Files;
-import org.apache.commons.lang3.StringUtils;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolderImpl;
-import org.opendaylight.controller.config.persist.api.Persister;
-import org.opendaylight.controller.config.persist.api.PropertiesProvider;
-import org.opendaylight.controller.config.persist.api.StorageAdapter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import java.io.File;
 import java.io.IOException;
 import java.nio.charset.Charset;
@@ -31,9 +22,17 @@ import java.util.List;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
+import org.apache.commons.lang3.StringUtils;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolderImpl;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.api.PropertiesProvider;
+import org.opendaylight.controller.config.persist.api.StorageAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
- * StorageAdapter that stores configuration in a plan file.
+ * StorageAdapter that stores configuration in a plain file.
  */
 public class FileStorageAdapter implements StorageAdapter, Persister {
     private static final Logger logger = LoggerFactory.getLogger(FileStorageAdapter.class);
index 0236598f2b877d995639072266beb042e9673c2e..0366dbcaed26a52cbea110e4118bf9b5e6ff37b3 100644 (file)
@@ -11,18 +11,18 @@ package org.opendaylight.controller.config.persist.storage.file;
 import com.google.common.base.Charsets;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-
 import java.io.File;
 import java.nio.file.Files;
 import java.util.Collection;
 import java.util.List;
 import java.util.SortedSet;
 import java.util.TreeSet;
-
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.test.PropertiesProviderTest;
 import static junit.framework.Assert.assertFalse;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertEquals;
@@ -42,6 +42,49 @@ public class FileStorageAdapterTest {
         i = 1;
     }
 
+
+    @Test
+    public void testFileAdapterAsPersister() throws Exception {
+        FileStorageAdapter storage = new FileStorageAdapter();
+        PropertiesProviderTest pp = new PropertiesProviderTest();
+        pp.addProperty("fileStorage",file.getPath());
+        pp.addProperty("numberOfBackups",Integer.toString(Integer.MAX_VALUE));
+
+        Persister configPersister = storage.instantiate(pp);
+        final ConfigSnapshotHolder holder = new ConfigSnapshotHolder() {
+            @Override
+            public String getConfigSnapshot() {
+                return createConfig();
+            }
+
+            @Override
+            public SortedSet<String> getCapabilities() {
+                return createCaps();
+            }
+        };
+        configPersister.persistConfig(holder);
+
+        configPersister.persistConfig(holder);
+
+        Collection<String> readLines = Collections2.filter(com.google.common.io.Files.readLines(file, Charsets.UTF_8),
+                new Predicate<String>() {
+
+                    @Override
+                    public boolean apply(String input) {
+                        if (input.equals(""))
+                            return false;
+                        return true;
+                    }
+                });
+        assertEquals(14, readLines.size());
+
+        List<ConfigSnapshotHolder> lastConf = storage.loadLastConfigs();
+        assertEquals(1, lastConf.size());
+        ConfigSnapshotHolder configSnapshotHolder = lastConf.get(0);
+        assertEquals("<config>2</config>",
+                configSnapshotHolder.getConfigSnapshot().replaceAll("\\s", ""));
+        assertEquals(createCaps(), configSnapshotHolder.getCapabilities());
+    }
     @Test
     public void testFileAdapter() throws Exception {
         FileStorageAdapter storage = new FileStorageAdapter();
index abbec382b7a7e2e95e16387f7775912a8e4df855..d08a93e1148b4c00c2f1e794a62aa5846ceb0669 100644 (file)
             <artifactId>mockito-configuration</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>config-persister-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
index 41976000ba43d9e0e16ab26f4c2ab0f64020d265..cfc70858c328f42353bc8d502519f46cfd3d4a25 100644 (file)
@@ -15,9 +15,11 @@ import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 import java.util.SortedSet;
 
-@XmlRootElement(name = "snapshot")
+@XmlRootElement(name = ConfigSnapshot.SNAPSHOT_ROOT_ELEMENT_NAME)
 public class ConfigSnapshot {
 
+    public static final String SNAPSHOT_ROOT_ELEMENT_NAME = "snapshot";
+
     private String configSnapshot;
     private SortedSet<String> capabilities;
 
index d6bbeb31da2f3b3caa9a86acbadcd94452c070e1..0e4cce544f049dc361ccc0770d3161db46d5c482 100644 (file)
@@ -9,18 +9,17 @@
 package org.opendaylight.controller.config.persist.storage.file.xml;
 
 import com.google.common.base.Charsets;
-import junit.framework.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-
 import java.io.File;
 import java.nio.file.Files;
 import java.util.List;
 import java.util.SortedSet;
 import java.util.TreeSet;
-
+import junit.framework.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.test.PropertiesProviderTest;
 import static junit.framework.Assert.assertFalse;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertEquals;
@@ -43,8 +42,11 @@ public class FileStorageAdapterTest {
     @Test
     public void testFileAdapter() throws Exception {
         XmlFileStorageAdapter storage = new XmlFileStorageAdapter();
-        storage.setFileStorage(file);
-        storage.setNumberOfBackups(Integer.MAX_VALUE);
+        PropertiesProviderTest pp = new PropertiesProviderTest();
+        pp.addProperty("fileStorage",file.getPath());
+        pp.addProperty("numberOfBackups",Integer.toString(Integer.MAX_VALUE));
+        storage.instantiate(pp);
+
         final ConfigSnapshotHolder holder = new ConfigSnapshotHolder() {
             @Override
             public String getConfigSnapshot() {
@@ -89,8 +91,12 @@ public class FileStorageAdapterTest {
     @Test
     public void testFileAdapterOneBackup() throws Exception {
         XmlFileStorageAdapter storage = new XmlFileStorageAdapter();
-        storage.setFileStorage(file);
-        storage.setNumberOfBackups(1);
+
+        PropertiesProviderTest pp = new PropertiesProviderTest();
+        pp.addProperty("fileStorage",file.getPath());
+        pp.addProperty("numberOfBackups",Integer.toString(Integer.MAX_VALUE));
+        storage.instantiate(pp);
+
         final ConfigSnapshotHolder holder = new ConfigSnapshotHolder() {
             @Override
             public String getConfigSnapshot() {
@@ -106,7 +112,7 @@ public class FileStorageAdapterTest {
 
         storage.persistConfig(holder);
 
-        assertEquals(16, com.google.common.io.Files.readLines(file, Charsets.UTF_8).size());
+        assertEquals(27, com.google.common.io.Files.readLines(file, Charsets.UTF_8).size());
 
         List<ConfigSnapshotHolder> lastConf = storage.loadLastConfigs();
         assertEquals(1, lastConf.size());
index 7696ae55734d833a2439d53243b2dcabbaf75292..0117098ee1491b66b4011bfd62f669792c7bd29b 100644 (file)
@@ -72,6 +72,7 @@
                             <configuration>
                                 <sources>
                                     <source>${jmxGeneratorPath}</source>
+                                    <source>${salGeneratorPath}</source>
                                 </sources>
                             </configuration>
                         </execution>
index 75b180921acedc4158ec6e4dfafa1c1815c28283..4f02db5a3807095c0302ee1446eb765a2858ea77 100644 (file)
@@ -32,8 +32,13 @@ public interface ConfigTransactionClient extends
 
     void validateBean(ObjectName configBeanON) throws ValidationException;
 
-    void destroyConfigBean(String moduleName, String instanceName)
-            throws InstanceNotFoundException;
+    @Deprecated
+    /**
+     * Use {@link #destroyModule(String, String)}
+     */
+    void destroyConfigBean(String moduleName, String instanceName) throws InstanceNotFoundException;
+
+    void destroyModule(String moduleName, String instanceName) throws InstanceNotFoundException;
 
     void setAttribute(ObjectName on, String jmxName, Attribute attribute);
 }
index e683d915baea604db86b891e81dc9192b203c4aa..3583dafd0d46c3fcedb070e00b8cc175255bc4c8 100644 (file)
@@ -84,12 +84,23 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
     }
 
     @Override
+    @Deprecated
+    /**
+     * {@inheritDoc}
+     */
     public void destroyConfigBean(String moduleName, String instanceName)
             throws InstanceNotFoundException {
         destroyModule(ObjectNameUtil.createTransactionModuleON(
                 getTransactionName(), moduleName, instanceName));
     }
 
+    @Override
+    public void destroyModule(String moduleName, String instanceName)
+            throws InstanceNotFoundException {
+        destroyModule(ObjectNameUtil.createTransactionModuleON(
+                getTransactionName(), moduleName, instanceName));
+    }
+
     @Override
     public void abortConfig() {
         configTransactionControllerMXBeanProxy.abortConfig();
index 3241fb01af69b118c1a62ea6720c5e924a132990..4c83668ab6894052af3315325224885ba4ab8ee6 100644 (file)
@@ -1,11 +1,9 @@
-/**
- * Generated file
-
- * Generated from: yang module name: config-test  yang module local name: testing
- * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
- * Generated at: Fri Sep 27 14:06:33 CEST 2013
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
- * Do not modify this file unless it is present under src/main directory
+ * 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.logback.config;
 
index 02fba141b338872fe6a1fefa473d56110f9777d8..9837a04e7f903daf5c16b906d36e46f2f72cc6e7 100644 (file)
@@ -1,11 +1,9 @@
-/**
- * Generated file
-
- * Generated from: yang module name: config-test  yang module local name: testing
- * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
- * Generated at: Fri Sep 27 14:06:33 CEST 2013
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
- * Do not modify this file unless it is present under src/main directory
+ * 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.logback.config;
 
index d75bf6367a6d393d7ee2773a5d903733ae2b21aa..adc69fe31eb596797564ccfa46de81d5cdf264bc 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
  * Generated file
 
index 5e8612f7b94eae1fda8119ec7b25cafb98eafa0c..5a91796ed602d4f239dae51e9ffd14cbd9038f48 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
  * Generated file
 
index 9e63e574895879612858e3a65049d04a456c8395..e8d161afbbafdac3020c86524c36f482bf362adf 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
  * Generated file
 
index 02cbd247a71db70f8dee044771eb904fa67b3b0b..3c52d8c17af7bfadba1d49e42a4d72b0b11459be 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
  * Generated file
 
index 79a5121fa8bee24de0ab719d51ed6faccab26160..c03ade8b5fc63aded18e2540360723c639f82d11 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
 * Generated file
 
index 6af508829be93eb6b64157562806753596b2ae64..71c4b192e5ae3c0c64dcb0d1f43770ddf8fb9d89 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 package org.opendaylight.controller.config.yang.netty.eventexecutor;
 
 import javax.management.InstanceAlreadyExistsException;
index 9ceef3116ac5603219c019eb2fd21d340e23dcca..3d5a3bf4adf00e78ce5537a884eeb3ad9142d42c 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
 * Generated file
 
index 1dca38182da9c82b49f98848f263270b6ac172b0..c97bd566b07f98ac8ad9914e1db24308a081dd5a 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
 * Generated file
 
index cc78124680990d61474eaa9523e85c7aae0e23da..e65a4d335eb952a53fb68c2fd1e5ac374b351d49 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
  * Generated file
 
index e291ab54658e49b0e1ee0f40e805fff6156f8e88..c869413a5e1726349d894cb9ab140dbb8439cd31 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
  * Generated file
 
index 8bc4d95d60d4f32db07880b43d4f1f050492edbf..1b5668b6100170b8007407ce4840f4be64dc2836 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.config.yang.netty.timer;
 
 import javax.management.InstanceAlreadyExistsException;
index eba5e07c0f40cc3a2b0732dd4fab563934cb9426..acd4916a4b8e8fb9f0905ceb59c6cb1ce5cf75fa 100644 (file)
         <module>netty-timer-config</module>
         <module>config-persister-directory-adapter</module>
         <module>config-persister-directory-xml-adapter</module>
+        <module>config-persister-directory-autodetect-adapter</module>
         <module>yang-test-plugin</module>
+        <module>shutdown-api</module>
+        <module>shutdown-impl</module>
     </modules>
 
     <profiles>
         <java.version.source>1.7</java.version.source>
         <java.version.target>1.7</java.version.target>
         <junit.version>4.10</junit.version>
-        <maven.bundle.version>2.3.7</maven.bundle.version>
+        <maven.bundle.version>2.4.0</maven.bundle.version>
         <osgi.version>5.0.0</osgi.version>
         <jacoco.version>0.6.2.201302030002</jacoco.version>
         <slf4j.version>1.7.2</slf4j.version>
         <opendaylight.yang.version>0.5.9-SNAPSHOT</opendaylight.yang.version>
         <opendaylight.binding.version>0.6.0-SNAPSHOT</opendaylight.binding.version>
         <opendaylight.yangtools.version>0.1.1-SNAPSHOT</opendaylight.yangtools.version>
+        <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
     </properties>
 
     <dependencies>
                 <artifactId>config-persister-api</artifactId>
                 <version>${config.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>config-persister-api</artifactId>
+                <version>${config.version}</version>
+                <type>test-jar</type>
+            </dependency>
             <dependency>
                 <groupId>org.opendaylight.bgpcep</groupId>
                 <artifactId>mockito-configuration</artifactId>
                 <version>${config.version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>org.opendaylight.controller</groupId>
+                <artifactId>shutdown-api</artifactId>
+                <version>${config.version}</version>
+            </dependency>
+
             <!-- MD-SAL -->
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-plugin</artifactId>
             </plugin>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>build-helper-maven-plugin</artifactId>
-            </plugin>
+
+
         </plugins>
 
         <pluginManagement>
                                             org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
                                         </codeGeneratorClass>
                                         <outputBaseDir>
-                                            target/generated-sources/sal
+                                            ${salGeneratorPath}
                                         </outputBaseDir>
                                     </generator>
                                     <generator>
                         </dependency>
                     </dependencies>
                 </plugin>
+                <!-- tell eclipse about generated source folders -->
+                <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>${salGeneratorPath}</source>
+                                </sources>
+                            </configuration>
+                        </execution>
+                    </executions>
+                </plugin>
                 <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-jar-plugin</artifactId>
diff --git a/opendaylight/config/shutdown-api/pom.xml b/opendaylight/config/shutdown-api/pom.xml
new file mode 100644 (file)
index 0000000..0603b2d
--- /dev/null
@@ -0,0 +1,47 @@
+<?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">
+    <parent>
+        <artifactId>config-plugin-parent</artifactId>
+        <groupId>org.opendaylight.controller</groupId>
+        <version>0.2.3-SNAPSHOT</version>
+        <relativePath>../config-plugin-parent</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>bundle</packaging>
+    <artifactId>shutdown-api</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-api</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Export-Package>
+                            org.opendaylight.controller.config.shutdown,
+                            org.opendaylight.controller.config.yang.shutdown
+                        </Export-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/opendaylight/config/shutdown-api/src/main/java/org/opendaylight/controller/config/shutdown/ShutdownService.java b/opendaylight/config/shutdown-api/src/main/java/org/opendaylight/controller/config/shutdown/ShutdownService.java
new file mode 100644 (file)
index 0000000..1042417
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * 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.shutdown;
+
+import com.google.common.base.Optional;
+
+public interface ShutdownService {
+
+    /**
+     * Shut down the server.
+     *
+     * @param inputSecret must match configured secret of the implementation
+     * @param reason Optional string to be logged while shutting down
+     */
+    void shutdown(String inputSecret, Optional<String> reason);
+}
diff --git a/opendaylight/config/shutdown-api/src/main/yang/shutdown.yang b/opendaylight/config/shutdown-api/src/main/yang/shutdown.yang
new file mode 100644 (file)
index 0000000..eb09178
--- /dev/null
@@ -0,0 +1,29 @@
+module shutdown {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:shutdown";
+    prefix "shutdown";
+
+    import config { prefix config; revision-date 2013-04-05; }
+
+    description
+        "This module contains the base YANG definitions for
+         shutdown service.
+
+        Copyright (c)2013 Cisco Systems, Inc. All rights reserved.;
+
+        This program and the accompanying materials are made available
+        under the terms of the Eclipse Public License v1.0 which
+        accompanies this distribution, and is available at
+        http://www.eclipse.org/legal/epl-v10.html";
+
+    revision "2013-12-18" {
+        description
+            "Initial revision.";
+    }
+
+    identity shutdown {
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.config.shutdown.ShutdownService";
+    }
+
+}
diff --git a/opendaylight/config/shutdown-impl/pom.xml b/opendaylight/config/shutdown-impl/pom.xml
new file mode 100644 (file)
index 0000000..4fcb0c8
--- /dev/null
@@ -0,0 +1,64 @@
+<?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">
+    <parent>
+        <artifactId>config-plugin-parent</artifactId>
+        <groupId>org.opendaylight.controller</groupId>
+        <version>0.2.3-SNAPSHOT</version>
+        <relativePath>../config-plugin-parent</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>bundle</packaging>
+    <artifactId>shutdown-impl</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>shutdown-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-manager</artifactId>
+            <scope>test</scope>
+            <type>test-jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-manager</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-util</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.bgpcep</groupId>
+            <artifactId>mockito-configuration</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownModule.java b/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownModule.java
new file mode 100644 (file)
index 0000000..f6937f9
--- /dev/null
@@ -0,0 +1,91 @@
+/**
+ * Generated file
+
+ * Generated from: yang module name: shutdown-impl  yang module local name: shutdown
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Dec 18 14:02:06 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.shutdown.impl;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.osgi.framework.Bundle;
+
+public final class ShutdownModule extends AbstractShutdownModule {
+    private final Bundle systemBundle;
+    private final ShutdownModule nullableOldModule;
+
+    public ShutdownModule(ModuleIdentifier identifier, Bundle systemBundle) {
+        super(identifier, null);
+        singletonCheck(identifier);
+        this.systemBundle = systemBundle;
+        this.nullableOldModule = null;
+    }
+
+    public ShutdownModule(ModuleIdentifier identifier, ShutdownModule oldModule, java.lang.AutoCloseable oldInstance,
+                          Bundle systemBundle) {
+        super(identifier, null, oldModule, oldInstance);
+        singletonCheck(identifier);
+        this.systemBundle = systemBundle;
+        this.nullableOldModule = oldModule;
+    }
+
+    private static void singletonCheck(ModuleIdentifier identifier) {
+        if (AbstractShutdownModuleFactory.NAME.equals(identifier.getInstanceName()) == false) {
+            throw new IllegalArgumentException("Singleton enforcement failed. Expected instance name " + AbstractShutdownModuleFactory.NAME);
+        }
+    }
+
+    @Deprecated // needed for generated code
+    public ShutdownModule(ModuleIdentifier identifier, DependencyResolver dependencyResolver, ShutdownModule oldModule,
+                          AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+        throw new UnsupportedOperationException();
+    }
+
+    @Deprecated // needed for generated code
+    public ShutdownModule(ModuleIdentifier identifier, DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getSecret() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getOldSecret() {
+        throw new UnsupportedOperationException();
+    }
+
+    String getActualSecret() {
+        return super.getSecret();
+    }
+
+    String getActualOldSecret() {
+        return super.getOldSecret();
+    }
+
+    @Override
+    protected void customValidation() {
+        JmxAttributeValidationException.checkNotNull(super.getOldSecret(), oldSecretJmxAttribute);
+        JmxAttributeValidationException.checkNotNull(super.getSecret(), secretJmxAttribute);
+        if (nullableOldModule != null) {
+            // if nothing changed, remain valid
+            boolean sameAsOldModule = isSame(nullableOldModule);
+            if (sameAsOldModule == false) {
+                boolean valid = getActualOldSecret().equals(nullableOldModule.getActualSecret());
+                JmxAttributeValidationException.checkCondition(valid, "Invalid old secret", oldSecretJmxAttribute);
+            }
+        }
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        return new ShutdownServiceImpl(getActualSecret(), systemBundle, getRootRuntimeBeanRegistratorWrapper());
+    }
+}
diff --git a/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownModuleFactory.java b/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownModuleFactory.java
new file mode 100644 (file)
index 0000000..637395b
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ * Generated file
+
+ * Generated from: yang module name: shutdown-impl  yang module local name: shutdown
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Dec 18 14:02:06 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.shutdown.impl;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+public class ShutdownModuleFactory extends AbstractShutdownModuleFactory {
+
+    @Override
+    public org.opendaylight.controller.config.spi.Module createModule(String instanceName, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.api.DynamicMBeanWithInstance old, org.osgi.framework.BundleContext bundleContext) throws Exception {
+        org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModule oldModule = null;
+        try {
+            oldModule = (org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModule) old.getModule();
+        } catch(Exception e) {
+            return handleChangedClass(old);
+        }
+        org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModule module = instantiateModule(instanceName, dependencyResolver, oldModule, old.getInstance(), bundleContext);
+
+        module.setOldSecret(oldModule.getActualOldSecret());
+        module.setSecret(oldModule.getActualSecret());
+
+        return module;
+    }
+
+
+    public ShutdownModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+                                            ShutdownModule oldModule, AutoCloseable oldInstance,
+                                            BundleContext bundleContext) {
+        Bundle systemBundle = bundleContext.getBundle(0);
+        return new ShutdownModule(new ModuleIdentifier(NAME, instanceName), oldModule, oldInstance, systemBundle);
+    }
+
+
+    public ShutdownModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+                                            BundleContext bundleContext) {
+        Bundle systemBundle = bundleContext.getBundle(0);
+        return new ShutdownModule(new ModuleIdentifier(NAME, instanceName), systemBundle);
+    }
+}
diff --git a/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownServiceImpl.java b/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownServiceImpl.java
new file mode 100644 (file)
index 0000000..e5b95c8
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * 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.shutdown.impl;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.config.shutdown.ShutdownService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ShutdownServiceImpl implements ShutdownService, AutoCloseable {
+    private final ShutdownService impl;
+    private final ShutdownRuntimeRegistration registration;
+
+    public ShutdownServiceImpl(String secret, Bundle systemBundle,
+                               ShutdownRuntimeRegistrator rootRuntimeBeanRegistratorWrapper) {
+        if (secret == null) {
+            throw new IllegalArgumentException("Secret cannot be null");
+        }
+        impl = new Impl(secret, systemBundle);
+        registration = rootRuntimeBeanRegistratorWrapper.register(new MXBeanImpl(impl));
+    }
+
+    @Override
+    public void shutdown(String inputSecret, Optional<String> reason) {
+        impl.shutdown(inputSecret, reason);
+    }
+
+    @Override
+    public void close() {
+        registration.close();
+    }
+}
+
+class Impl implements ShutdownService {
+    private static final Logger logger = LoggerFactory.getLogger(Impl.class);
+    private final String secret;
+    private final Bundle systemBundle;
+
+    Impl(String secret, Bundle systemBundle) {
+        this.secret = secret;
+        this.systemBundle = systemBundle;
+    }
+
+    @Override
+    public void shutdown(String inputSecret, Optional<String> reason) {
+        logger.warn("Shutdown issued with secret {} and reason {}", inputSecret, reason);
+        try {
+            Thread.sleep(1000); // prevent brute force attack
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            logger.warn("Shutdown process interrupted", e);
+        }
+        if (this.secret.equals(inputSecret)) {
+            logger.info("Server is shutting down");
+
+            Thread stopSystemBundle = new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        // wait so that JMX response is received
+                        Thread.sleep(1000);
+                        systemBundle.stop();
+                    } catch (BundleException e) {
+                        logger.warn("Can not stop OSGi server", e);
+                    } catch (InterruptedException e) {
+                        logger.warn("Shutdown process interrupted", e);
+                    }
+                }
+            };
+            stopSystemBundle.start();
+
+        } else {
+            logger.warn("Unauthorized attempt to shut down server");
+            throw new IllegalArgumentException("Invalid secret");
+        }
+    }
+
+}
+
+class MXBeanImpl implements ShutdownRuntimeMXBean {
+    private final ShutdownService impl;
+
+    MXBeanImpl(ShutdownService impl) {
+        this.impl = impl;
+    }
+
+    @Override
+    public void shutdown(String inputSecret, String nullableReason) {
+        Optional<String> optionalReason;
+        if (nullableReason == null) {
+            optionalReason = Optional.absent();
+        } else {
+            optionalReason = Optional.of(nullableReason);
+        }
+        impl.shutdown(inputSecret, optionalReason);
+    }
+}
diff --git a/opendaylight/config/shutdown-impl/src/main/yang/shutdown-impl.yang b/opendaylight/config/shutdown-impl/src/main/yang/shutdown-impl.yang
new file mode 100644 (file)
index 0000000..78b44ab
--- /dev/null
@@ -0,0 +1,71 @@
+module shutdown-impl {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl";
+    prefix "shutdown-impl";
+
+    import shutdown { prefix shutdown; revision-date 2013-12-18; }
+    import config { prefix config; revision-date 2013-04-05; }
+    import rpc-context { prefix rpcx; revision-date 2013-06-17; }
+
+    organization "Cisco Systems, Inc.";
+
+    description
+        "This module contains the base YANG definitions for
+         shutdown implementation.
+
+        Copyright (c)2013 Cisco Systems, Inc. All rights reserved.;
+
+        This program and the accompanying materials are made available
+        under the terms of the Eclipse Public License v1.0 which
+        accompanies this distribution, and is available at
+        http://www.eclipse.org/legal/epl-v10.html";
+
+    revision "2013-12-18" {
+        description
+            "Initial revision.";
+    }
+
+    identity shutdown {
+        base config:module-type;
+        config:provided-service shutdown:shutdown;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case shutdown {
+            when "/config:modules/config:module/config:type = 'shutdown'";
+            leaf secret {
+                type string;
+                default "";
+            }
+            leaf old-secret {
+                type string;
+                default "";
+            }
+        }
+    }
+
+    augment "/config:modules/config:module/config:state" {
+        case shutdown {
+            when "/config:modules/config:module/config:type = 'shutdown'";
+            rpcx:rpc-context-instance "shutdown-rpc";
+        }
+    }
+
+    identity shutdown-rpc;
+
+    rpc shutdown {
+        input {
+            uses rpcx:rpc-context-ref {
+                refine context-instance {
+                    rpcx:rpc-context-instance shutdown-rpc;
+                }
+            }
+            leaf input-secret {
+                type string;
+            }
+            leaf reason {
+                type string;
+            }
+        }
+    }
+}
diff --git a/opendaylight/config/shutdown-impl/src/test/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownTest.java b/opendaylight/config/shutdown-impl/src/test/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownTest.java
new file mode 100644 (file)
index 0000000..86cd6fa
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * 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.shutdown.impl;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.ValidationException.ExceptionMessageWithStackTrace;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.ModuleFactoriesResolver;
+import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+import org.osgi.framework.Bundle;
+
+import javax.management.JMX;
+import javax.management.ObjectName;
+import java.util.Collections;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModuleFactory.NAME;
+
+public class ShutdownTest extends AbstractConfigTest {
+    private final ShutdownModuleFactory factory = new ShutdownModuleFactory();
+    @Mock
+    private Bundle mockedSysBundle;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        ModuleFactoriesResolver factoriesResolver = new HardcodedModuleFactoriesResolver(mockedContext, factory);
+        super.initConfigTransactionManagerImpl(factoriesResolver);
+        doReturn(mockedSysBundle).when(mockedContext).getBundle(0);
+        mockedContext.getBundle(0);
+        doNothing().when(mockedSysBundle).stop();
+    }
+
+    @Test
+    public void testSingleton_invalidName() throws Exception {
+        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+        try {
+            transaction.createModule(NAME, "foo");
+            fail();
+        } catch (IllegalArgumentException e) {
+            assertEquals("Singleton enforcement failed. Expected instance name shutdown", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testWithoutSecret() throws Exception {
+        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+        transaction.createModule(NAME, NAME);
+        transaction.commit();
+        // test JMX rpc
+        ObjectName runtimeON = ObjectNameUtil.createRuntimeBeanName(NAME, NAME, Collections.<String, String>emptyMap());
+        ShutdownRuntimeMXBean runtime = configRegistryClient.newMXBeanProxy(runtimeON, ShutdownRuntimeMXBean.class);
+        try {
+            runtime.shutdown("foo", null);
+            fail();
+        } catch (IllegalArgumentException e) {
+            assertEquals("Invalid secret", e.getMessage());
+        }
+        runtime.shutdown("", null);
+        assertStopped();
+    }
+
+
+    @Test
+    public void testWithSecret() throws Exception {
+        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+        ObjectName on = transaction.createModule(NAME, NAME);
+        ShutdownModuleMXBean proxy = transaction.newMXBeanProxy(on, ShutdownModuleMXBean.class);
+        String secret = "secret";
+        proxy.setSecret(secret);
+        transaction.commit();
+        shutdownViaRuntimeJMX(secret);
+
+        // test old secret
+        transaction = configRegistryClient.createTransaction();
+        on = transaction.lookupConfigBean(NAME, NAME);
+        proxy = transaction.newMXBeanProxy(on, ShutdownModuleMXBean.class);
+        try {
+            rethrowCause(proxy).getOldSecret();
+            fail();
+        } catch (UnsupportedOperationException e) {
+        }
+        try {
+            rethrowCause(proxy).getSecret();
+            fail();
+        } catch (UnsupportedOperationException e) {
+        }
+        // set secret to nothing
+        String newSecret = "newSecret";
+        proxy.setSecret(newSecret);
+        try {
+            transaction.commit();
+            fail("Old secret not provided - should fail validation");
+        } catch (ValidationException e) {
+            Map<String, Map<String, ExceptionMessageWithStackTrace>> failedValidations = e.getFailedValidations();
+            assertTrue(failedValidations.containsKey(NAME));
+            ExceptionMessageWithStackTrace exceptionMessageWithStackTrace = failedValidations.get(NAME).get(NAME);
+            assertNotNull(exceptionMessageWithStackTrace);
+            assertEquals("OldSecret Invalid old secret", exceptionMessageWithStackTrace.getMessage());
+
+        }
+        proxy.setOldSecret(secret);
+        transaction.commit();
+        shutdownViaRuntimeJMX(newSecret);
+    }
+
+    private void shutdownViaRuntimeJMX(String secret) throws Exception {
+        // test JMX rpc
+        ObjectName runtimeON = ObjectNameUtil.createRuntimeBeanName(NAME, NAME, Collections.<String, String>emptyMap());
+        ShutdownRuntimeMXBean runtime = JMX.newMXBeanProxy(platformMBeanServer, runtimeON, ShutdownRuntimeMXBean.class);
+        try {
+            runtime.shutdown("", null);
+            fail();
+        } catch (IllegalArgumentException e) {
+            assertEquals("Invalid secret", e.getMessage());
+        }
+        runtime.shutdown(secret, null);
+        assertStopped();
+    }
+
+
+    private void assertStopped() throws Exception {
+        Thread.sleep(2000); // happens on another thread
+        verify(mockedSysBundle).stop();
+        verifyNoMoreInteractions(mockedSysBundle);
+        reset(mockedSysBundle);
+        doNothing().when(mockedSysBundle).stop();
+    }
+}
index f108303165d0f6ce2de3dd3d36e58d145f250fac..0bdcbbcca413715de256fd7f965968d1e22b9d96 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
  * Generated file
 
index 14fcf41758f2e74f4503c58b4313056f73688adc..17d50562d38b1a71ec460f5ce2db17d7577b03c0 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
  * Generated file
 
index 92eaee5ef25e98e5e07b821a03f9cc718d1af240..6c365990784766410bc143ee0246bfe8bed8099f 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
  * Generated file
 
index e909998a7211a6b2a5af3549ddb33eaffe4dfe93..955d4f16e454b7c56bf94415fb1ae79ac59639a3 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
  * Generated file
 
index a761727e5c673028376b9a7df60a7e07e03e29ce..53320ae1472a709e4aab56624e9610d50f86d2f2 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
  * Generated file
 
index 5e70afb93e8977c5054b58e328f19257454d333d..ff81bc82ae78b9923390d0f9e382e0ae29064c00 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
  * Generated file
 
index de6e6a5ec8e36def81fd8078dbe20847154b277c..d06e6164b1b86cbd65a24ff814357a6b04f1a1e3 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
 * Generated file
 
index 1d3a37c50dd9ee50df23b18e06f71a91e13021e9..39e5f9a508f078985c9c2ce306884bff210cf5f0 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
 * Generated file
 
index 259d90817ea13eaeb83656d75ed8a67e98353189..94639d43c0248787c736a2d7df7738597a4ef975 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
 * Generated file
 
index 878adcfb2cad1af809032393504a1bd3c9448538..64b2a07fff4f0325ba4510a73f7416e43819b26a 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
 * Generated file
 
index 83c4cccfebb309c07af759213cd32a9aa843ed14..c6330e2e59bee1997268d81527c516525d702aa9 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
 * Generated file
 
index ea345baaeb7ef0bb8ef61114d2ed093d698b1356..69f5b1f9acd4ba9649c131787de324ad617171e5 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 /**
 * Generated file
 
index b2fc75d70016fca4ce13738e1b8d131f01cec64d..b9731cd46d1abc560009ffeeddbe0a3c306bf1b3 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.controller.config.threadpool.async;\r
 \r
 import static org.junit.Assert.assertThat;\r
index 4cd279f881864f858f2d5acbb909f74261b5d762..bc5e98bcb358ec419685823e0403fefe4f6f2e2d 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.config.threadpool.eventbus;
 
 import static org.junit.Assert.assertEquals;
index ee6bbc51bc49d1e1e761032f6adf3a14b3bbb4b4..01a89a987b9c19ea83a979812901140da11ed404 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.controller.config.threadpool.eventbus;\r
 \r
 import static org.mockito.Mockito.doNothing;\r
index 81455a9b21497c4cf1082cdf19542b5276facb92..8bfd049b4b2ca028400a78ad23e987e99400df14 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.controller.config.threadpool.fixed;\r
 \r
 import org.junit.Before;\r
index 00be5d8118983832c0b72543dbded3ac61f1435d..1fc0821405081a0c3a2d6766f91f6c2dfe4010d8 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.controller.config.threadpool.fixed;\r
 \r
 import static org.mockito.Mockito.doNothing;\r
index 5f1a3ee95723d737ce1ad2a7de2d1355fbf7cc45..43cb7e1bcbf3307259d6fd165105931f783a8c44 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.controller.config.threadpool.flexible;\r
 \r
 import org.junit.Before;\r
index 9e9565a4f965d835b2eec18dc4adca7c3d6ed3d0..7280b0410394b7ec11666cd94d30a7c6eb8559b0 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.controller.config.threadpool.naming;\r
 \r
 import static org.junit.Assert.assertEquals;\r
index 5c717ccd4c0ffca9c516e67daa33c25693934c31..f22da34d76f3e5ff39f603f69e672f51eda568f2 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.controller.config.threadpool.naming;\r
 \r
 import static org.mockito.Matchers.any;\r
index 1567896701f47e46b725fbc0af13d3c45388bc2c..6183cb56c172edb3b5c635e75d81e8bc6cdc0cec 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.controller.config.threadpool.scheduled;\r
 \r
 import org.junit.Before;\r
index d1464baa6e0ffb48d2aa7ebf84ac83b484846527..0fe5b0d1834cd78f2e17804fa1e759805d22ced8 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.controller.config.threadpool.scheduled;\r
 \r
 import com.google.common.util.concurrent.ListenableFutureTask;\r
index 10f19e8399c0fd01ab11b787fcb02951892a778f..7075865573bdb17a6cb2d717b8a03437c825fd69 100644 (file)
@@ -12,6 +12,16 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import org.apache.commons.io.FileUtils;
 import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.project.MavenProject;
@@ -22,6 +32,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry
 import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
 import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
@@ -29,17 +40,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.impl.StaticLoggerBinder;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
 /**
  * This class interfaces with yang-maven-plugin. Gets parsed yang modules in
  * {@link SchemaContext}, and parameters form the plugin configuration, and
@@ -70,7 +70,7 @@ public class JMXGenerator implements CodeGenerator {
 
     @Override
     public Collection<File> generateSources(SchemaContext context,
-            File outputBaseDir, Set<Module> yangModulesInCurrentMavenModule) {
+                                            File outputBaseDir, Set<Module> yangModulesInCurrentMavenModule) {
 
         Preconditions.checkArgument(context != null, "Null context received");
         Preconditions.checkArgument(outputBaseDir != null,
@@ -86,24 +86,25 @@ public class JMXGenerator implements CodeGenerator {
             outputBaseDir.mkdirs();
 
         GeneratedFilesTracker generatedFiles = new GeneratedFilesTracker();
+        // create SIE structure qNamesToSIEs
         Map<QName, ServiceInterfaceEntry> qNamesToSIEs = new HashMap<>();
 
-        // create SIE structure qNamesToSIEs
+
+        Map<IdentitySchemaNode, ServiceInterfaceEntry> knownSEITracker = new HashMap<>();
         for (Module module : context.getModules()) {
             String packageName = packageTranslator.getPackageName(module);
             Map<QName, ServiceInterfaceEntry> namesToSIEntries = ServiceInterfaceEntry
-                    .create(module, packageName);
+                    .create(module, packageName, knownSEITracker);
 
             for (Entry<QName, ServiceInterfaceEntry> sieEntry : namesToSIEntries
                     .entrySet()) {
-
                 // merge value into qNamesToSIEs
                 if (qNamesToSIEs.containsKey(sieEntry.getKey()) == false) {
                     qNamesToSIEs.put(sieEntry.getKey(), sieEntry.getValue());
                 } else {
                     throw new IllegalStateException(
-                            "Cannot add two SIE with same qname "
-                                    + sieEntry.getValue());
+                        "Cannot add two SIE  with same qname "
+                                + sieEntry.getValue());
                 }
             }
             if (yangModulesInCurrentMavenModule.contains(module)) {
index 869488e777350e08106d786e85fd648f5c1028a3..5bcc5402afae09edbbe53eb58c3d077fba5fc2ce 100644 (file)
@@ -7,11 +7,9 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static java.lang.String.format;
-import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName;
-
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -21,7 +19,6 @@ import java.util.Map.Entry;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute;
@@ -52,10 +49,10 @@ import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.UsesNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static java.lang.String.format;
+import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName;
 
 /**
  * Represents part of yang model that describes a module.
index f19a46d0f461e35a1ecf9dd97e05aa1500a821df..4831545b39f82b024f7a7ac21a3794029fb2a8b0 100644 (file)
@@ -163,41 +163,42 @@ public class RuntimeBeanEntry {
 
         for (RpcDefinition rpc : currentModule.getRpcs()) {
             ContainerSchemaNode input = rpc.getInput();
-            for (UsesNode uses : input.getUses()) {
-
-                if (uses.getGroupingPath().getPath().size() != 1)
-                    continue;
-
-                // check grouping path
-                QName qname = uses.getGroupingPath().getPath().get(0);
-                if (false == qname
-                        .equals(ConfigConstants.RPC_CONTEXT_REF_GROUPING_QNAME))
-                    continue;
-
-                for (SchemaNode refinedNode : uses.getRefines().values()) {
-
-                    for (UnknownSchemaNode unknownSchemaNode : refinedNode
-                            .getUnknownSchemaNodes()) {
-                        if (ConfigConstants.RPC_CONTEXT_INSTANCE_EXTENSION_QNAME
-                                .equals(unknownSchemaNode.getNodeType())) {
-                            String localIdentityName = unknownSchemaNode
-                                    .getNodeParameter();
-                            QName identityQName = new QName(
-                                    currentModule.getNamespace(),
-                                    currentModule.getRevision(),
-                                    localIdentityName);
-                            Set<RpcDefinition> rpcDefinitions = result
-                                    .get(identityQName);
-                            if (rpcDefinitions == null) {
-                                throw new IllegalArgumentException(
-                                        "Identity referenced by rpc not found. Identity:"
-                                                + localIdentityName + " , rpc "
-                                                + rpc);
+            if (input != null) {
+                for (UsesNode uses : input.getUses()) {
+
+                    if (uses.getGroupingPath().getPath().size() != 1)
+                        continue;
+
+                    // check grouping path
+                    QName qname = uses.getGroupingPath().getPath().get(0);
+                    if (false == qname
+                            .equals(ConfigConstants.RPC_CONTEXT_REF_GROUPING_QNAME))
+                        continue;
+
+                    for (SchemaNode refinedNode : uses.getRefines().values()) {
+
+                        for (UnknownSchemaNode unknownSchemaNode : refinedNode
+                                .getUnknownSchemaNodes()) {
+                            if (ConfigConstants.RPC_CONTEXT_INSTANCE_EXTENSION_QNAME
+                                    .equals(unknownSchemaNode.getNodeType())) {
+                                String localIdentityName = unknownSchemaNode
+                                        .getNodeParameter();
+                                QName identityQName = new QName(
+                                        currentModule.getNamespace(),
+                                        currentModule.getRevision(),
+                                        localIdentityName);
+                                Set<RpcDefinition> rpcDefinitions = result
+                                        .get(identityQName);
+                                if (rpcDefinitions == null) {
+                                    throw new IllegalArgumentException(
+                                            "Identity referenced by rpc not found. Identity:"
+                                                    + localIdentityName + " , rpc "
+                                                    + rpc);
+                                }
+                                rpcDefinitions.add(rpc);
                             }
-                            rpcDefinitions.add(rpc);
                         }
                     }
-
                 }
             }
         }
index aa2d6a5d7f044dde8d84b49fff2d8fa3ed28f383..ef40d9515b42c75ad3b6d6e56456ea83a1912688 100644 (file)
@@ -7,10 +7,7 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.lang.String.format;
-import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.SERVICE_TYPE_Q_NAME;
-
+import com.google.common.base.Optional;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -18,15 +15,15 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.String.format;
+import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.SERVICE_TYPE_Q_NAME;
 
 /**
  * Represents identity derived from {@link ConfigConstants#SERVICE_TYPE_Q_NAME}.
@@ -123,7 +120,7 @@ public class ServiceInterfaceEntry extends AbstractEntry {
      *         values
      */
     public static Map<QName, ServiceInterfaceEntry> create(Module currentModule,
-            String packageName) {
+            String packageName,Map<IdentitySchemaNode, ServiceInterfaceEntry> definedSEItracker) {
         logger.debug("Generating ServiceInterfaces from {} to package {}",
                 currentModule.getNamespace(), packageName);
 
@@ -152,7 +149,7 @@ public class ServiceInterfaceEntry extends AbstractEntry {
                     // this is a base type
                     created = new ServiceInterfaceEntry(identity, packageName, ModuleUtil.getQName(currentModule));
                 } else {
-                    ServiceInterfaceEntry foundBase = identitiesToSIs
+                    ServiceInterfaceEntry foundBase = definedSEItracker
                             .get(identity.getBaseIdentity());
                     // derived type, did we convert the parent?
                     if (foundBase != null) {
@@ -160,12 +157,15 @@ public class ServiceInterfaceEntry extends AbstractEntry {
                                 Optional.of(foundBase), identity, packageName, ModuleUtil.getQName(currentModule));
                     }
                 }
+
+
                 if (created != null) {
                     created.setYangModuleName(currentModule.getName());
                     // TODO how to get local name
                     created.setYangModuleLocalname(identity.getQName()
                             .getLocalName());
                     identitiesToSIs.put(identity, created);
+                    definedSEItracker.put(identity, created);
                     iterator.remove();
                 }
             }
index 38de6e15285377993f3d24b4a3da7977037ed737..b3e7b90c966d0f3e12e4c097c18c44d7ae1dbc14 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.config.yangjmxgenerator.attribute;
 
 import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
index e86c87616941d297cb3752a6f727203269a09b3d..9ea34ca2b8ed990c56c6c14988733e09d88e3995 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.config.yangjmxgenerator;
 
 import com.google.common.collect.Sets;
+import java.util.HashMap;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
@@ -22,6 +23,7 @@ import org.opendaylight.yangtools.sal.binding.model.api.Type;
 import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
 
 import javax.management.openmbean.ArrayType;
@@ -94,16 +96,18 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
 
     @Before
     public void setUp() {
+        Map<IdentitySchemaNode, ServiceInterfaceEntry> identitiesToSIs = new HashMap<>();
         modulesToSIEs = ServiceInterfaceEntry.create(threadsModule,
-                "packages.sis");
+                "packages.sis",identitiesToSIs);
     }
 
     @Test
     public void test_jmxImplModule() {
+        Map<IdentitySchemaNode, ServiceInterfaceEntry> identitiesToSIs = new HashMap<>();
         Map<QName, ServiceInterfaceEntry> modulesToSIEs = ServiceInterfaceEntry
-                .create(threadsModule, PACKAGE_NAME);
+                .create(threadsModule, PACKAGE_NAME,identitiesToSIs);
         modulesToSIEs.putAll(ServiceInterfaceEntry.create(jmxModule,
-                PACKAGE_NAME));
+                PACKAGE_NAME,identitiesToSIs));
         Map<String /* identity local name */, ModuleMXBeanEntry> namesToMBEs = ModuleMXBeanEntry
                 .create(jmxImplModule, modulesToSIEs, context, new TypeProviderWrapper(new TypeProviderImpl(context))
                         , PACKAGE_NAME);
index 97258fb697cbc25211a63645a8f454437b59f29c..b570302563b9d9c4e00a4171614beb28df578cd8 100644 (file)
@@ -7,12 +7,14 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator;
 
+import java.util.HashMap;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
 import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 
@@ -41,6 +43,7 @@ public class RuntimeBeanEntryTest extends AbstractYangTest {
     public static final String SLEEP_RPC_OUTPUT = "ThreadState";
     public static final String SLEEP_RPC_INPUT_NAME = "millis";
     public static final String SLEEP_RPC_INPUT_TYPE = "Long";
+    private static final Map<IdentitySchemaNode, ServiceInterfaceEntry> identitiesToSIs = new HashMap<>();
 
     @Test
     public void createRuntimeBean() {
@@ -61,7 +64,7 @@ public class RuntimeBeanEntryTest extends AbstractYangTest {
     public void runtimeBeanRPCTest() {
         // create service interfaces
         Map<QName, ServiceInterfaceEntry> modulesToSIEs = ServiceInterfaceEntry
-                .create(threadsModule, "packages.sis");
+                .create(threadsModule, "packages.sis",identitiesToSIs);
         assertNotNull(modulesToSIEs);
 
         // create MXBeans map
index 0da61b46c336043566d7b0b5c7b7da394771bde9..eed86951033bc5ec2aa5251e4f187ea0f0f3c1a9 100644 (file)
@@ -7,27 +7,26 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator;
 
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-
+import com.google.common.collect.Sets;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Arrays;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-
 import org.hamcrest.CoreMatchers;
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.common.QName;
-
-import com.google.common.collect.Sets;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
 
 public class ServiceInterfaceEntryTest extends AbstractYangTest {
     public static final String PACKAGE_NAME = "packages.sis";
@@ -38,6 +37,7 @@ public class ServiceInterfaceEntryTest extends AbstractYangTest {
 
     private static final URI THREADS_NAMESPACE;
     private static final Date THREADS_REVISION_DATE;
+
     static {
         try {
             THREADS_NAMESPACE = new URI(ConfigConstants.CONFIG_NAMESPACE
@@ -77,8 +77,9 @@ public class ServiceInterfaceEntryTest extends AbstractYangTest {
     @Test
     public void testCreateFromIdentities() {
         // each identity has to have a base that leads to service-type
+        Map<IdentitySchemaNode, ServiceInterfaceEntry> definedIdentities = new HashMap<>();
         Map<QName, ServiceInterfaceEntry> namesToSIEntries = ServiceInterfaceEntry
-                .create(threadsModule, PACKAGE_NAME);
+                .create(threadsModule, PACKAGE_NAME,definedIdentities);
         // expected eventbus, threadfactory, threadpool,
         // scheduled-threadpool,thread-rpc-context
         assertThat(namesToSIEntries.size(), is(expectedSIEFileNames.size()));
index 9356dd3752331f2f34fcc33b5df87151081a04b7..0d704a8f6aa49825da36d62b011d9294479fbb3d 100644 (file)
@@ -186,7 +186,15 @@ public class ExtenderYangTracker extends BundleTracker<Object> implements YangSt
                     yangStoreSnapshot.countModuleMXBeanEntries(), multimap.values().size());
             return yangStoreSnapshot;
         } catch (RuntimeException e) {
-            throw new YangStoreException("Unable to parse yang files from following URLs: " + multimap, e);
+            StringBuffer causeStr = new StringBuffer();
+            Throwable cause = e;
+            while (cause != null) {
+                causeStr.append(e.getMessage());
+                causeStr.append("\n");
+                cause = e.getCause();
+            }
+            throw new YangStoreException("Unable to parse yang files. \n" + causeStr.toString() +
+                    "URLs: " + multimap, e);
         }
     }
 
index 2be6c81ee75ae0438e4114711f590f4d670d0b9b..d54996dbb77fcd38799e9a705bcc26a77a28b763 100644 (file)
@@ -17,6 +17,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry
 import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
 import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
@@ -47,11 +48,12 @@ public class MbeParser {
 
         Map<QName, ServiceInterfaceEntry> qNamesToSIEs = new HashMap<>();
 
+        Map<IdentitySchemaNode, ServiceInterfaceEntry> knownSEITracker = new HashMap<>();
         // create SIE structure qNamesToSIEs
         for (Module module : resolveSchemaContext.getModules()) {
             String packageName = packageTranslator.getPackageName(module);
             Map<QName, ServiceInterfaceEntry> namesToSIEntries = ServiceInterfaceEntry
-                    .create(module, packageName);
+                    .create(module, packageName,knownSEITracker);
 
             for (Entry<QName, ServiceInterfaceEntry> sieEntry : namesToSIEntries
                     .entrySet()) {
@@ -4,8 +4,6 @@ import com.google.common.collect.Lists;
 import junit.framework.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.api.jmx.CommitStatus;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
@@ -15,8 +13,14 @@ import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.ObjectName;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 public class NetconfTestImplModuleTest  extends AbstractConfigTest {
 
     public static final String TESTING_DEP_PREFIX = "testing-dep";
@@ -32,17 +36,16 @@ public class NetconfTestImplModuleTest  extends AbstractConfigTest {
     }
 
     @Test
-    public void testDependencyList() throws InstanceAlreadyExistsException, ValidationException,
-            ConflictingVersionException {
+    public void testDependencyList() throws Exception {
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
 
         ObjectName on = createInstance(transaction, instanceName, 4);
         transaction.validateConfig();
-        CommitStatus status = transaction.commit();
+        CommitStatus status1 = transaction.commit();
 
         assertBeanCount(1, factory.getImplementationName());
         assertBeanCount(4 + 1, DepTestImplModuleFactory.NAME);
-        assertStatus(status, 1 + 4 + 1, 0, 0);
+        assertStatus(status1, 1 + 4 + 1, 0, 0);
 
         transaction = configRegistryClient.createTransaction();
 
@@ -56,6 +59,38 @@ public class NetconfTestImplModuleTest  extends AbstractConfigTest {
         assertTestingDeps(testingDeps, 4);
 
         transaction.abortConfig();
+
+        // check that reuse logic works - equals on list of dependencies.
+        transaction = configRegistryClient.createTransaction();
+        CommitStatus status2 = transaction.commit();
+        assertStatus(status2, 0, 0, 6);
+
+        // replace single dependency
+        transaction = configRegistryClient.createTransaction();
+        String instanceName1 = TESTING_DEP_PREFIX + 1;
+        transaction.destroyModule(DepTestImplModuleFactory.NAME, instanceName1);
+        transaction.createModule(DepTestImplModuleFactory.NAME, instanceName1);
+        CommitStatus status3 = transaction.commit();
+        assertStatus(status3, 1, 1, 4);
+
+    }
+
+    @Test
+    public void testNullCheckInListOfDependencies() throws Exception {
+        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+
+        ObjectName on = createInstance(transaction, instanceName, 4);
+        NetconfTestImplModuleMXBean proxy = transaction.newMXBeanProxy(on, NetconfTestImplModuleMXBean.class);
+        try{
+            proxy.setTestingDeps(null);
+            fail();
+        }catch(RuntimeException e) {
+            Throwable cause = e.getCause();
+            assertNotNull(cause);
+            assertTrue("Invalid type " + cause, cause instanceof IllegalArgumentException);
+            assertEquals("Null not supported", cause.getMessage());
+        }
+        proxy.setTestingDeps(Collections.<ObjectName>emptyList());
     }
 
     private void assertTestingDeps(List<ObjectName> testingDeps, int i) {
index d4ae1523756f0128775327ecc876a9b25bf233dc..282185bd7013a94d3d79b51434da27ad16dec2c2 100644 (file)
@@ -44,7 +44,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
   </dependencies>
 </project>
index 498b3d4e9335db0e8c7c0778f7672b1a7342ee00..db596bf346b07a4b3c5bfa47f8595bff6d7c5636 100644 (file)
@@ -52,7 +52,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
@@ -62,7 +62,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index e18fe8c1ed375ccc7ea666547914dda9c3969c4e..65d46c3e0a269bd1584efd67c2f77148bb8d6cd6 100644 (file)
@@ -35,7 +35,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 4471863c0d5c37ffeccea91c05cf939f3dc15049..ab0a32882e4b1376391033541d44b10ba7b90a5e 100644 (file)
@@ -45,7 +45,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 58b21eccb89c27efeefe37c3e8393222b4333887..a3cbe5160712dcb5bf6b259061b57bc28ac7163b 100644 (file)
@@ -54,7 +54,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
@@ -64,7 +64,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 5ba156ea7cb4690f2147915f1f29163d1b46fec4..718a3ff166e1a7ae72cae6175da0aaef12542e4c 100644 (file)
@@ -277,6 +277,11 @@ public abstract class AbstractScheme {
 
     public Status addNode (Node node, InetAddress controller) {
         if (node == null || controller == null) {
+            if (node == null) {
+                log.warn("addNode: node is null");
+            } else if (controller == null) {
+                log.error("Failed to add node {}. The controller address retrieved from clusterServices is null.", node);
+            }
             return new Status(StatusCode.BADREQUEST);
         }
         if (isLocal(node))  {
index f7e385c87842e6c68319c8cd2dc99a80a56c45f5..1ca905054b5f2e6b32793e84badbf7838100a461 100644 (file)
@@ -54,7 +54,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
   </dependencies>
 </project>
index 9740a9259833c0ef9d60ad821eaea1e0ee723aef..9d65ad343c4c540e2d93d750524becac00a3e9b8 100644 (file)
@@ -15,7 +15,9 @@ import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
@@ -308,9 +310,10 @@ public class ContainerFlowConfig implements Serializable {
     }
 
     /**
-     * Match Source IP Address.
+     * Match the set of these vlans with that of flowSpec's vlans.
      *
-     * @param flowSpec Flow Specification
+     * @param flowSpec
+     *            Flow Specification
      * @return true, if successful
      */
     private boolean matchDlVlan(ContainerFlowConfig flowSpec) {
@@ -320,7 +323,8 @@ public class ContainerFlowConfig implements Serializable {
         if (dlVlan == null || flowSpec.dlVlan == null) {
             return false;
         }
-        return dlVlan.equals(flowSpec.dlVlan);
+
+        return this.getVlanList().equals(flowSpec.getVlanList());
     }
 
     /**
@@ -404,18 +408,34 @@ public class ContainerFlowConfig implements Serializable {
     }
 
     /**
-     * Returns the vlan id number
+     * Returns the vlan id number for all vlans specified
      *
-     * @return the vlan id number
+     * @return the vlan id number for all vlans specified
      */
-    public Short getVlanId() {
-        Short vlan = 0;
+    public Set<Short> getVlanList() {
+        /*
+         * example: Vlan = "1,3,5-12"
+         * elemArray = ["1" "3" "5-12"]
+         * elem[2] = "5-12" --> limits = ["5" "12"]
+         * vlanList = [1 3 5 6 7 8 9 10 11 12]
+         */
+        Set<Short> vlanList = new HashSet<Short>();
         try {
-            vlan = Short.parseShort(dlVlan);
+            String[] elemArray = dlVlan.split(",");
+            for (String elem : elemArray) {
+                if (elem.contains("-")) {
+                    String[] limits = elem.split("-");
+                    for (short j = Short.valueOf(limits[0]); j <= Short.valueOf(limits[1]); j++) {
+                        vlanList.add(Short.valueOf(j));
+                    }
+                } else {
+                    vlanList.add(Short.valueOf(elem));
+                }
+            }
         } catch (NumberFormatException e) {
 
         }
-        return vlan;
+        return vlanList;
     }
 
     /**
@@ -617,13 +637,25 @@ public class ContainerFlowConfig implements Serializable {
         if (dlVlan != null) {
             short vlanId = 0;
             try {
-                vlanId = Short.parseShort(dlVlan);
+                String[] elemArray = dlVlan.split(",");
+                for (String elem : elemArray) {
+                    if (elem.contains("-")) {
+                        String[] limits = elem.split("-");
+                        if (Short.parseShort(limits[0]) < 0
+                                || Short.parseShort(limits[0]) >= Short.parseShort(limits[1])
+                                || Short.parseShort(limits[1]) > 0xfff) {
+                            return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
+                        }
+                    } else {
+                        vlanId = Short.parseShort(elem);
+                        if (vlanId < 0 || vlanId > 0xfff) {
+                            return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
+                        }
+                    }
+                }
             } catch (NumberFormatException e) {
                 return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
             }
-            if (vlanId < 0 || vlanId > 0xfff) {
-                return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
-            }
         }
         return new Status(StatusCode.SUCCESS);
     }
@@ -706,20 +738,46 @@ public class ContainerFlowConfig implements Serializable {
 
     /**
      * Returns the matches.
-     * If unidirectional flag is set, there will be only one match in the list
-     * If unidirectional flag is unset there will be two matches in the list,
+     * If unidirectional flag is set, there will be only one match per vlan in the list
+     * If unidirectional flag is unset there will be two matches per vlan in the list,
      * only if the specified flow has an intrinsic direction.
      * For Ex. if the cFlow only has the protocol field configured, no matter
-     * if unidirectional flag is set or not, only one match will be returned
+     * if unidirectional flag is set or not, only one match per vlan will be returned
      * The client just has to iterate over the returned list
      * @return the matches
      */
     public List<Match> getMatches() {
         List<Match> matches = new ArrayList<Match>();
-        Match match = new Match();
 
         if (this.dlVlan != null && !this.dlVlan.isEmpty()) {
-            match.setField(MatchType.DL_VLAN, this.getVlanId());
+            for(Short vlan:getVlanList()){
+                Match match = getMatch(vlan);
+                matches.add(match);
+            }
+        }
+        else{
+            Match match = getMatch(null);
+            matches.add(match);
+        }
+
+        if (!ContainerFlowConfig.unidirectional) {
+            List<Match> forwardMatches = new ArrayList<Match>(matches);
+            for (Match match : forwardMatches) {
+                Match reverse = match.reverse();
+                if (!match.equals(reverse)) {
+                    matches.add(reverse);
+                }
+            }
+        }
+
+        return matches;
+    }
+
+    private Match getMatch(Short vlan){
+        Match match = new Match();
+
+        if (vlan != null) {
+            match.setField(MatchType.DL_VLAN, vlan);
         }
         if (this.nwSrc != null && !this.nwSrc.trim().isEmpty()) {
             String parts[] = this.nwSrc.split("/");
@@ -756,15 +814,7 @@ public class ContainerFlowConfig implements Serializable {
         if (this.tpDst != null && !this.tpDst.trim().isEmpty()) {
             match.setField(MatchType.TP_DST, Integer.valueOf(tpDst).shortValue());
         }
-
-        matches.add(match);
-        if(!ContainerFlowConfig.unidirectional) {
-            Match reverse = match.reverse();
-            if (!match.equals(reverse)) {
-                matches.add(reverse);
-            }
-        }
-        return matches;
+        return match;
     }
 
     /*
index 18ed78c37bcb7cf348ede7e1e0641ee2a34a4c4c..bd12bfc87dda36258d60234ab52104b5e94fecec 100644 (file)
@@ -62,7 +62,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
@@ -87,7 +87,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 3b86a797ca22ae3841823043a118ac7e07e043a3..ee1ef12c11e0b565d60ddbc43053699011f9b0dd 100644 (file)
@@ -57,7 +57,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
@@ -67,7 +67,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked1.txt b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked1.txt
deleted file mode 100644 (file)
index aad7239..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-
-#24
-<rpc message-id="101" xm
-#28
-lns="urn:ietf:params:xml:ns:
-#2
-ne
-#33
-tconf:base:1.0">
-  <my-own-method
-#3
- xm
-#13
-lns="http://e
-#34
-xample.net/me/my-own/1.0">
-    <my
-#8
--first-p
-#21
-arameter>14</my-first
-#26
--parameter>
-    <another-p
-#23
-arameter>fred</another-
-#31
-parameter>
- </my-own-method>
- <
-#2
-/r
-#3
-pc>
-##
diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked2.txt b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked2.txt
deleted file mode 100644 (file)
index a36a85e..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-
-#22
-<rpc message-id="101" 
-#24
-xmlns="urn:ietf:params:x
-#15
-ml:ns:netconf:b
-#54
-ase:1.0">
-  <get-config>
-      <source>
-            <r
-#2
-un
-#9
-ning/>
-  
-#18
-  </source>    <fi
-#33
-lter type="subtree">
-      <top x
-#4
-mlns
-#31
-="http://example.com/schema/1.2
-#15
-/config">
-     
-#19
-   <users>
-        
-#8
-     <us
-#3
-er/
-#5
->
-   
-#77
-     </users>
-           </top>
-               </filter>
-                 </g
-#17
-et-config>
-</rpc>
-##
diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked3.txt b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked3.txt
deleted file mode 100644 (file)
index d9dc43d..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-
-#43
-<rpc message-id="101" xmlns="urn:ietf:param
-#14
-s:xml:ns:netco
-#14
-nf:base:1.0">
-
-#26
-<get-config>
-    <source>
-
-#35
-     <running/>
-         </source>
-
-#39
-    <filter type="subtree">
-          <
-#40
-top xmlns="http://example.com/schema/1.2
-#26
-/config">
-        <users>
-
-#36
-     <user>
-                 <name>f
-#56
-red</name>
-          </user>
-                  </users>
-
-#28
-      </top>
-          </fil
-#1
-t
-#28
-er>
-  </get-config>
-  </rpc>
-##
diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked4.txt b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked4.txt
deleted file mode 100644 (file)
index 0b8a102..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-
-#17
-<rpc message-id="
-#25
-101" xmlns="urn:ietf:para
-#19
-ms:xml:ns:netconf:b
-#3
-ase
-#19
-:1.0">
-  <get-confi
-#61
-g>
-    <source>
-          <running/>
-              </source>
-
-#43
-  <filter type="subtree">
-        <!-- requ
-#13
-est a text ve
-#22
-rsion of the configura
-#9
-tion -->
-
-#16
-   <config-text 
-#45
-xmlns="http://example.com/text/1.2/config"/>
-
-#22
-    </filter>
-      </
-#18
-get-config>
-</rpc>
-##
diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked5.txt b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/chunked5.txt
deleted file mode 100644 (file)
index f8f3c4d..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-
-#43
-<rpc message-id="101" xmlns="urn:ietf:param
-#41
-s:xml:ns:netconf:base:1.0">
-  <edit-confi
-#29
-g>
-    <target>
-          <ru
-#13
-nning/>
-    <
-#4
-/tar
-#18
-get>
-    <config>
-
-#41
-  <top xmlns="http://example.com/schema/1
-#32
-.2/config">
-        <interface>
-
-#29
-        <name>Ethernet0/0</na
-#30
-me>
-          <mtu>1500</mtu>
-
-#61
-</interface>
-      </top>
-          </config>
-            </e
-#9
-dit-confi
-#9
-g>
-</rpc>
-##
diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/databaseinteractions/jolokia_config_bean_response.txt b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/databaseinteractions/jolokia_config_bean_response.txt
deleted file mode 100644 (file)
index 2ae32ef..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-curl http://localhost:17777/jolokia/read/org.opendaylight.controller:instanceName=fixed1,type=ConfigBean,interfaceName=testing-threadpool | jsonpp
-{
-    "request": {
-        "mbean": "org.opendaylight.controller:instanceName=fixed1,interfaceName=testing-threadpool,type=ConfigBean",
-        "type": "read"
-    },
-    "status": 200,
-    "timestamp": 1362416252,
-    "value": {
-        "ExportedInterfaces": [
-            "testing-threadpool",
-            "modifiable-threadpool"
-        ],
-        "ImplementationName": "fixed",
-        "ThreadCount": 10,
-        "TriggerNewInstanceCreation": false
-    }
-}
\ No newline at end of file
diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/databaseinteractions/jolokia_lookupConfigBeans.txt b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/databaseinteractions/jolokia_lookupConfigBeans.txt
deleted file mode 100644 (file)
index 2ae705a..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-$ curl 'http://localhost:17777/jolokia/exec/org.opendaylight.controller:type=ConfigRegistry/lookupConfigBeans()' | jsonpp
-{
-    "request": {
-        "mbean": "org.opendaylight.controller:type=ConfigRegistry",
-        "operation": "lookupConfigBeans()",
-        "type": "exec"
-    },
-    "status": 200,
-    "timestamp": 1362417043,
-    "value": [
-        {
-            "objectName": "org.opendaylight.controller:instanceName=fixed1,interfaceName=modifiable-threadpool,type=ConfigBean"
-        },
-        {
-            "objectName": "org.opendaylight.controller:instanceName=fixed1,interfaceName=testing-threadpool,type=ConfigBean"
-        }
-    ]
-}
diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_commit.xml b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_commit.xml
deleted file mode 100644 (file)
index 6eca609..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<rpc message-id="104"
-     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <commit/>
-</rpc>
\ No newline at end of file
diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_lock_candidate.xml b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_lock_candidate.xml
deleted file mode 100644 (file)
index 6a9ed63..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<rpc message-id="102"
-     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <lock>
-        <target>
-            <candidate/>
-        </target>
-    </lock>
-</rpc>
\ No newline at end of file
diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_lock_running.xml b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_lock_running.xml
deleted file mode 100644 (file)
index 2d66c45..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<rpc message-id="101"
-     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <lock>
-        <target>
-            <running/>
-        </target>
-    </lock>
-</rpc>
\ No newline at end of file
diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_modify_candidate.xml b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_modify_candidate.xml
deleted file mode 100644 (file)
index ce67845..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<rpc message-id="103"
-     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <edit-config>
-        <target>
-            <candidate/>
-        </target>
-        <default-operation>none</default-operation>
-        <test-option>test-then-set</test-option>
-        <error-option>stop-on-error</error-option>
-        <nc:config
-                xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
-                xmlns="uri-for-my-data-model-namespace">
-            <some-existing-node>
-                <my-new-node nc:operation="create">
-                    <my-new-leaf>7</my-new-leaf>
-                </my-new-node>
-            </some-existing-node>
-        </nc:config>
-    </edit-config>
-</rpc>
\ No newline at end of file
diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_unlock_candidate.xml b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_unlock_candidate.xml
deleted file mode 100644 (file)
index dd6fe1b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<rpc message-id="105"
-     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <unlock>
-        <target>
-            <candidate/>
-        </target>
-    </unlock>
-</rpc>
\ No newline at end of file
diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_unlock_running.xml b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/client_unlock_running.xml
deleted file mode 100644 (file)
index f94af46..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<rpc message-id="106"
-     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <unlock>
-        <target>
-            <running/>
-        </target>
-    </unlock>
-</rpc>
\ No newline at end of file
diff --git a/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/server_error_missing_attribute.xml b/opendaylight/controller/netconf/netconf-impl/src/test/resources/org/opendaylight/netconf/impl/listener/databaseinteractions/notused/server_error_missing_attribute.xml
deleted file mode 100644 (file)
index c70184e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <rpc-error>
-        <error-type>rpc</error-type>
-        <error-tag>missing-attribute</error-tag>
-        <error-severity>error</error-severity>
-        <error-info>
-            <bad-attribute>message-id</bad-attribute>
-            <bad-element>rpc</bad-element>
-        </error-info>
-    </rpc-error>
-</rpc-reply>
index e3d1e5275df29f7efc3f27b9f77dedc09ec0ddc5..7ae309cce499dc138c5c8032b168b60b801a0eca 100644 (file)
@@ -51,7 +51,6 @@
 <unit id="org.eclipse.virgo.kernel.equinox.extensions" version="3.6.0.RELEASE"/>
 <unit id="org.eclipse.osgi.services" version="3.3.100.v20120522-1822"/>
 <unit id="org.eclipse.virgo.util.common" version="3.6.0.RELEASE"/>
-<unit id="com.sun.jersey.json" version="1.17.0"/>
 <unit id="org.eclipse.equinox.util" version="1.0.400.v20120522-2049"/>
 <unit id="org.springframework.core" version="3.1.3.RELEASE"/>
 <unit id="org.apache.commons.fileupload" version="1.2.2"/>
index b0f7ad89a4b81694c889c52e51f5cc00947c8c4f..5acdec834da3f56d66c9954e5bd4c47deb83fedf 100644 (file)
           <artifactId>forwardingrules-manager</artifactId>
           <version>${mdsal.version}</version>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller.md</groupId>
+          <artifactId>topology-lldp-discovery</artifactId>
+          <version>${mdsal.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller.md</groupId>
+          <artifactId>topology-manager</artifactId>
+          <version>${mdsal.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-topology</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+         <groupId>org.opendaylight.yangtools.model</groupId>
+         <artifactId>ietf-topology</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-util</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller.md</groupId>
           <artifactId>statistics-manager</artifactId>
           <artifactId>config-persister-directory-xml-adapter</artifactId>
           <version>${config.version}</version>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>config-persister-directory-autodetect-adapter</artifactId>
+          <version>${config.version}</version>
+        </dependency>
+
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>shutdown-api</artifactId>
+          <version>${config.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>shutdown-impl</artifactId>
+          <version>${config.version}</version>
+        </dependency>
 
        <!-- Netconf -->
         <dependency>
       <groupId>ch.qos.logback</groupId>
       <artifactId>logback-classic</artifactId>
     </dependency>
+
     <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-mapper-asl</artifactId>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-databind</artifactId>
     </dependency>
+
     <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-core-asl</artifactId>
+       <groupId>com.fasterxml.jackson.core</groupId>
+       <artifactId>jackson-annotations</artifactId>
     </dependency>
+
     <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-jaxrs</artifactId>
+       <groupId>com.fasterxml.jackson.core</groupId>
+       <artifactId>jackson-core</artifactId>
     </dependency>
+
     <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-xc</artifactId>
+      <groupId>com.fasterxml.jackson.jaxrs</groupId>
+      <artifactId>jackson-jaxrs-json-provider</artifactId>
     </dependency>
+
+      <dependency>
+         <groupId>com.fasterxml.jackson.jaxrs</groupId>
+         <artifactId>jackson-jaxrs-base</artifactId>
+      </dependency>
+
+    <dependency>
+      <groupId>com.fasterxml.jackson.module</groupId>
+      <artifactId>jackson-module-jaxb-annotations</artifactId>
+    </dependency>
+
     <dependency>
       <groupId>org.codehaus.jettison</groupId>
       <artifactId>jettison</artifactId>
       <groupId>com.sun.jersey</groupId>
       <artifactId>jersey-client</artifactId>
     </dependency>
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-json</artifactId>
-      <version>${jersey.version}</version>
-    </dependency>
+
     <dependency>
       <groupId>org.ow2.asm</groupId>
       <artifactId>asm-all</artifactId>
index 8fea1756148cee4774de9a3586c7ea1056821e81..6f8878bee950b87a3b234f00e19570a8b6256cfc 100644 (file)
@@ -24,7 +24,6 @@
         <exclude>ch.qos.logback:logback-core</exclude>
         <exclude>ch.qos.logback:logback-classic</exclude>
         <exclude>com.sun.jersey:jersey-core</exclude>
-        <exclude>com.sun.jersey:jersey-json</exclude>
         <exclude>com.sun.jersey:jersey-server</exclude>
         <exclude>org.opendaylight.controller:logging.bridge</exclude>
         <exclude>org.opendaylight.controller:sanitytest</exclude>
@@ -52,7 +51,6 @@
         <include>ch.qos.logback:logback-core</include>
         <include>ch.qos.logback:logback-classic</include>
         <include>com.sun.jersey:jersey-core</include>
-        <include>com.sun.jersey:jersey-json</include>
         <include>com.sun.jersey:jersey-server</include>
         <include>org.opendaylight.controller:logging.bridge</include>
       </includes>
index ba5d862c5789357a7d1eec08985d5569fa2ad457..be6fae759819e4d3226e96309e1e658db202480f 100644 (file)
@@ -10,7 +10,6 @@ osgi.bundles=\
     reference\:file\:../lib/logback-core-1.0.9.jar@1:start,\
     reference\:file\:../lib/logging.bridge-0.4.1-SNAPSHOT@1:start,\
     reference\:file\:../lib/jersey-core-1.17.jar@2:start,\
-    reference\:file\:../lib/jersey-json-1.17.jar@2:start,\
     reference\:file\:../lib/jersey-server-1.17.jar@2:start
 
 # Netconf startup configuration
@@ -22,10 +21,16 @@ netconf.tcp.client.port=8383
 
 netconf.ssh.address=0.0.0.0
 netconf.ssh.port=1830
+netconf.ssh.pk.path = ./configuration/RSA.pk
+
 
 netconf.config.persister.active=1,2
 # read startup configuration
-netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.config.persist.storage.directory.DirectoryStorageAdapter
+#netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.config.persist.storage.directory.DirectoryStorageAdapter
+#netconf.config.persister.1.properties.directoryStorage=configuration/initial/
+#netconf.config.persister.1.readonly=true
+
+netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.config.persist.storage.directory.autodetect.AutodetectDirectoryStorageAdapter
 netconf.config.persister.1.properties.directoryStorage=configuration/initial/
 netconf.config.persister.1.readonly=true
 
@@ -41,7 +46,6 @@ netconf.config.persister.2.storageAdapterClass=org.opendaylight.controller.confi
 netconf.config.persister.2.properties.fileStorage=configuration/current/controller.currentconfig.xml
 netconf.config.persister.2.properties.numberOfBackups=1
 
-
 yangstore.blacklist=.*controller.model.*
 
 # Set Default start level for framework
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.conf b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.conf
deleted file mode 100644 (file)
index c2f9bc3..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-//MODULES START
-       <module>
-               <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
-               <name>global-boss-group</name>
-       </module>
-       <module>
-               <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
-               <name>global-worker-group</name>
-       </module>
-       <module>
-               <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:timer">netty:netty-hashed-wheel-timer</type>
-               <name>global-timer</name>
-       </module>
-       <module>
-               <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor">netty:netty-global-event-executor</type>
-               <name>global-event-executor</name>
-       </module>
-//SERVICES START
-       <service>
-               <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-threadgroup</type>
-               <instance>
-                       <name>global-boss-group</name>
-                       <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-boss-group']</provider>
-               </instance>
-               <instance>
-                       <name>global-worker-group</name>
-                       <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-worker-group']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-event-executor</type>
-               <instance>
-                       <name>global-event-executor</name>
-                       <provider>/modules/module[type='netty-global-event-executor'][name='global-event-executor']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-timer</type>
-               <instance>
-                       <name>global-timer</name>
-                       <provider>/modules/module[type='netty-hashed-wheel-timer'][name='global-timer']</provider>
-               </instance>
-       </service>
-//CAPABILITIES START
-urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&revision=2013-11-19
-urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&revision=2013-11-12
-urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup?module=threadgroup&revision=2013-11-07
-urn:opendaylight:params:xml:ns:yang:controller:netty:timer?module=netty-timer&revision=2013-11-19
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml.conf b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml.conf
new file mode 100644 (file)
index 0000000..9ba5908
--- /dev/null
@@ -0,0 +1,60 @@
+<snapshot>
+    <required-capabilities>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&amp;revision=2013-11-19</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&amp;revision=2013-11-12</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup?module=threadgroup&amp;revision=2013-11-07</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:timer?module=netty-timer&amp;revision=2013-11-19</capability>
+    </required-capabilities>
+    <configuration>
+    
+        <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <module>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
+                    <name>global-boss-group</name>
+                </module>
+                <module>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
+                    <name>global-worker-group</name>
+                </module>
+                <module>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:timer">netty:netty-hashed-wheel-timer</type>
+                    <name>global-timer</name>
+                </module>
+                <module>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor">netty:netty-global-event-executor</type>
+                    <name>global-event-executor</name>
+                </module>
+            </modules>
+            
+            <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <service>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-threadgroup</type>
+                    <instance>
+                        <name>global-boss-group</name>
+                        <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-boss-group']</provider>
+                    </instance>
+                    <instance>
+                        <name>global-worker-group</name>
+                        <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-worker-group']</provider>
+                    </instance>
+                </service>
+                <service>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-event-executor</type>
+                    <instance>
+                        <name>global-event-executor</name>
+                        <provider>/modules/module[type='netty-global-event-executor'][name='global-event-executor']</provider>
+                    </instance>
+                </service>
+                <service>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-timer</type>
+                    <instance>
+                        <name>global-timer</name>
+                        <provider>/modules/module[type='netty-hashed-wheel-timer'][name='global-timer']</provider>
+                    </instance>
+                </service>
+            </services>
+        </data>
+
+    </configuration>
+</snapshot>
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.conf b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.conf
deleted file mode 100644 (file)
index edee185..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-//MODULES START
-       <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:cluster:store">prefix:dom-clustered-store-impl</type>
-        <name>cluster-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>
-            <!-- to switch to the clustered data store, comment out the hash-map-data-store <name> and uncomment the cluster-data-store one -->
-            <name>hash-map-data-store</name>
-            <!-- <name>cluster-data-store</name> -->
-               </data-store>
-       </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>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>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>dom-broker</name>
-               </dom-broker>
-               <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                       <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
-                       <name>runtime-mapping-singleton</name>
-               </mapping-service>
-       </module>
-//SERVICES START
-       <service>
-               <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
-               <instance>
-                       <name>yang-schema-service</name>
-                       <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
-               <instance>
-                       <name>binding-notification-broker</name>
-                       <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
-               <instance>
-                       <name>hash-map-data-store</name>
-                       <provider>/modules/module[type='hash-map-data-store'][name='hash-map-data-store']</provider>
-               </instance>
-               <instance>
-                       <name>cluster-data-store</name>
-                       <provider>/modules/module[type='dom-clustered-store-impl'][name='cluster-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>binding-osgi-broker</name>
-                       <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
-               <instance>
-                       <name>binding-rpc-broker</name>
-                       <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
-               <instance>
-                       <name>runtime-mapping-singleton</name>
-                       <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
-               </instance>
-       </service>
-       <service>
-       <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
-               <instance>
-                       <name>dom-broker</name>
-                       <provider>/modules/module[type='dom-broker-impl'][name='dom-broker']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
-               <instance>
-                       <name>binding-data-broker</name>
-                       <provider>/modules/module[type='binding-data-broker'][name='binding-data-broker']</provider>
-               </instance>
-       </service>
-//CAPABILITIES START
-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: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
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store?module=odl-sal-dom-clustered-store-cfg&revision=2013-10-28
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml.conf b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml.conf
new file mode 100644 (file)
index 0000000..20f5989
--- /dev/null
@@ -0,0 +1,153 @@
+<snapshot>
+
+    <configuration>
+    
+        <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:cluster:store">prefix:dom-clustered-store-impl</type>
+                    <name>cluster-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>
+                        <!-- to switch to the clustered data store, comment out the hash-map-data-store <name> and uncomment the cluster-data-store one -->
+                        <name>hash-map-data-store</name>
+                        <!-- <name>cluster-data-store</name> -->
+                    </data-store>
+                </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>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>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>dom-broker</name>
+                    </dom-broker>
+                    <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
+                        <name>runtime-mapping-singleton</name>
+                    </mapping-service>
+                </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>yang-schema-service</name>
+                                       <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
+                               </instance>
+                       </service>
+                       <service>
+                               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+                               <instance>
+                                       <name>binding-notification-broker</name>
+                                       <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
+                               </instance>
+                       </service>
+                       <service>
+                               <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
+                               <instance>
+                                       <name>hash-map-data-store</name>
+                                       <provider>/modules/module[type='hash-map-data-store'][name='hash-map-data-store']</provider>
+                               </instance>
+                               <instance>
+                                       <name>cluster-data-store</name>
+                                       <provider>/modules/module[type='dom-clustered-store-impl'][name='cluster-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>binding-osgi-broker</name>
+                                       <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+                               </instance>
+                       </service>
+                       <service>
+                               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+                               <instance>
+                                       <name>binding-rpc-broker</name>
+                                       <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+                               </instance>
+                       </service>
+                       <service>
+                               <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
+                               <instance>
+                                       <name>runtime-mapping-singleton</name>
+                                       <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
+                               </instance>
+                       </service>
+                       <service>
+                       <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+                               <instance>
+                                       <name>dom-broker</name>
+                                       <provider>/modules/module[type='dom-broker-impl'][name='dom-broker']</provider>
+                               </instance>
+                       </service>
+                       <service>
+                               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+                               <instance>
+                                       <name>binding-data-broker</name>
+                                       <provider>/modules/module[type='binding-data-broker'][name='binding-data-broker']</provider>
+                               </instance>
+                       </service>
+
+            </services>
+        </data>
+
+    </configuration>
+    
+    <required-capabilities>
+        <capability>urn:opendaylight:l2:types?module=opendaylight-l2-types&amp;revision=2013-08-27</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool?module=threadpool&amp;revision=2013-04-09</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config?module=config&amp;revision=2013-04-05</capability>
+        <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&amp;revision=2010-10-04</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&amp;revision=2013-11-12</capability>
+        <capability>urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&amp;revision=2013-06-17</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&amp;revision=2013-10-28</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&amp;revision=2010-09-24</capability>
+        <capability>urn:ietf:params:netconf:capability:rollback-on-error:1.0</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&amp;revision=2010-09-24</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?module=threadpool-impl&amp;revision=2013-04-05</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:yang:extension:yang-ext?module=yang-ext&amp;revision=2013-07-09</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:iana?module=iana&amp;revision=2013-08-16</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:ieee754?module=ieee754&amp;revision=2013-08-19</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store?module=odl-sal-dom-clustered-store-cfg&amp;revision=2013-10-28</capability>
+    </required-capabilities>
+</snapshot>
+
index 84d1c913c413ef5e1978aded60ff85c200437169..61d274d80c22daf91dd28fe6cf8b9c7138fb7c41 100644 (file)
@@ -41,7 +41,8 @@
   <logger name="org.opendaylight.controller" level="INFO"/>
 
   <!-- OSGi logging bridge -->
-  <logger name="org.opendaylight.controller.logging.bridge" level="WARN"/>
+  <logger name="org.opendaylight.controller.logging.bridge" level="INFO"/>
+  <logger name="org.opendaylight.controller.logging.bridge.internal" level="WARN"/>
 
   <!-- Netty -->
   <logger name="io.netty" level="WARN"/>
index f59d54ce2cbae48f270dad6e66bac3f04caa4373..1f3e8e20f3c9b596275868549ac1707f3a2e69d3 100755 (executable)
@@ -164,6 +164,8 @@ FWCLASSPATH=${FWCLASSPATH},file:${basedir}/lib/org.eclipse.virgo.kernel.equinox.
 CLASSPATH=${CLASSPATH}:${basedir}/lib/org.eclipse.equinox.launcher-1.3.0.v20120522-1813.jar
 FWCLASSPATH=${FWCLASSPATH},file:${basedir}/lib/org.eclipse.equinox.launcher-1.3.0.v20120522-1813.jar
 
+cd $basedir
+
 if [ "${stopdaemon}" -eq 1 ]; then
     if [ -e "${pidfile}" ]; then
         daemonpid=`cat "${pidfile}"`
index f160cddaade8ee635db3341d30abc85b97a837b9..a0b7367acde6a2ccaeadb6e13c2195583da9f5f8 100644 (file)
@@ -67,7 +67,7 @@
   <dependency>
    <groupId>org.opendaylight.controller</groupId>
    <artifactId>forwardingrulesmanager</artifactId>
-   <version>0.4.1-SNAPSHOT</version>
+   <version>0.5.0-SNAPSHOT</version>
   </dependency>
   <dependency>
    <groupId>org.opendaylight.controller</groupId>
@@ -86,7 +86,7 @@
   <dependency>
    <groupId>org.opendaylight.controller</groupId>
    <artifactId>sal</artifactId>
-   <version>0.5.1-SNAPSHOT</version>
+   <version>0.7.0-SNAPSHOT</version>
   </dependency>
  </dependencies>
 </project>
index 499b98c28ad1c04dd8512af4501b799e4a3e0124..afd3d0ba7ce74f83a710cbbefdcff345ecad8693 100644 (file)
@@ -78,7 +78,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 3ec9f8443a1264063ef79c4f192c0a9c9ea727ca..de6b8182b07c71c8975cd5fcfa49e3326197ef9e 100644 (file)
@@ -8,19 +8,6 @@
 
 package org.opendaylight.controller.forwardingrulesmanager;
 
-import java.io.Serializable;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-
 import org.opendaylight.controller.sal.action.Action;
 import org.opendaylight.controller.sal.action.ActionType;
 import org.opendaylight.controller.sal.action.Controller;
@@ -62,6 +49,18 @@ import org.opendaylight.controller.switchmanager.Switch;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 /**
  * Configuration Java Object which represents a flow configuration information
  * for Forwarding Rules Manager.
@@ -1044,6 +1043,7 @@ public class FlowConfig implements Serializable {
         }
 
         Flow flow = new Flow(match, getActionList());
+
         if (this.cookie != null) {
             flow.setId(Long.parseLong(cookie));
         }
@@ -1056,6 +1056,8 @@ public class FlowConfig implements Serializable {
         if (this.priority != null) {
             flow.setPriority(Integer.decode(this.priority).shortValue());
         }
+
+
         return flow;
     }
 
index 83106a391cb7bdc00ff0911fa703e7dee1c1c2f4..d9a0891c2ad812b855641c48155235633328ff51 100644 (file)
@@ -122,7 +122,7 @@ public class FlowEntry implements Cloneable, Serializable {
         }
 
         if (flow == null) {
-            return (other.flow == null) ? true : false;
+            return other.flow == null;
         } else if (other.flow == null) {
             return false;
         }
index 6b3f5347adb58e7bb31f28d4dae6de262a15db65..ef69b49ca91ff800ec1ee759f6d5c6f3fad7399d 100644 (file)
@@ -84,7 +84,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 3d6a0292ef67225079b11759a3560bdfddf85377..41075b9554339d7bd503ba9e1dd952bcfa080ac0 100644 (file)
@@ -2639,6 +2639,13 @@ public class ForwardingRulesManager implements
         }
     }
 
+    /**
+     * Function called by the dependency manager before Container is Stopped and Destroyed.
+     */
+    public void containerStop() {
+        uninstallAllFlowEntries(false);
+    }
+
     /**
      * Function called by the dependency manager before the services exported by
      * the component are unregistered, this will be followed by a "destroy ()"
@@ -2646,7 +2653,6 @@ public class ForwardingRulesManager implements
      */
     void stop() {
         stopping = true;
-        uninstallAllFlowEntries(false);
         // Shutdown executor
         this.executor.shutdownNow();
         // Now walk all the workMonitor and wake up the one sleeping because
@@ -2988,7 +2994,11 @@ public class ForwardingRulesManager implements
                 // staticFlowEntry should never be null.
                 // the null check is just an extra defensive check.
                 if(staticFlowEntry != null) {
-                    staticFlows.remove(staticFlowEntry.getKey());
+                    // Modify status and update cluster cache
+                    log.debug("Updating static flow configuration on async error event");
+                    String status = String.format("Cannot be installed on node. reason: %s", errorString);
+                    staticFlowEntry.getValue().setStatus(status);
+                    refreshClusterStaticFlowsStatus(node);
                 }
             }
         }
index ea66c34fa3f69dcb63800a0a5898a02720627103..bf2e360334b1221af3f8cc7eabde31084434e003 100644 (file)
   <dependency>
    <groupId>org.opendaylight.controller</groupId>
    <artifactId>clustering.services</artifactId>
-   <version>0.4.1-SNAPSHOT</version>
+   <version>0.5.0-SNAPSHOT</version>
   </dependency>
   <dependency>
    <groupId>org.opendaylight.controller</groupId>
    <artifactId>sal</artifactId>
-   <version>0.5.1-SNAPSHOT</version>
+   <version>0.7.0-SNAPSHOT</version>
   </dependency>
   <dependency>
    <groupId>junit</groupId>
index 258327cca7254472dcf8d8208b21a920a0f0ecc5..78c4ae4160f26c7e40f026353c6a5dcd614c98a7 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index d7c60e67a91dfa85213343e41e3f495bacf83e55..e222fcd7e42cdb23b5a0850f6b55fd6834deba8a 100644 (file)
@@ -25,7 +25,6 @@ public class HostTrackerTest extends TestCase {
 \r
         HostTracker hostTracker = null;\r
         hostTracker = new HostTracker();\r
-        Assert.assertFalse(hostTracker == null);\r
 \r
         InetAddress hostIP = InetAddress.getByName("192.168.0.8");\r
         IHostId id  = IPHostId.fromIP(hostIP);\r
@@ -44,7 +43,6 @@ public class HostTrackerTest extends TestCase {
     public void testHostTracker() throws UnknownHostException {\r
         HostTracker hostTracker = null;\r
         hostTracker = new HostTracker();\r
-        Assert.assertFalse(hostTracker == null);\r
 \r
         InetAddress hostIP_1 = InetAddress.getByName("192.168.0.8");\r
         IHostId id1 = IPHostId.fromIP(hostIP_1);\r
index d8b5a4843550f374be970e9e93fcaaaa39eb99e0..ba3da5f764a9c524cd47a83a577268941d77202b 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index 0405d45b6e1989cc186927a016794108c9ac86d2..c5caa7f317bfa5647ed0e6c30f772f461a440399 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 95f57ae31cc405ec83b69e59a2fc3310be24848e..b231faf15307b558cebc629524ee185c12c89a97 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
@@ -6,11 +5,13 @@
  * 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.logging.bridge.internal;
 
 import org.osgi.service.log.LogEntry;
+
+import java.lang.Thread.UncaughtExceptionHandler;
 import java.util.Enumeration;
+
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.BundleActivator;
@@ -21,7 +22,11 @@ import org.slf4j.ILoggerFactory;
 import org.osgi.service.log.LogReaderService;
 
 public class Activator implements BundleActivator {
+    private static final String UNCAUGHT_EXCEPTION_POLICY_PROP = "controller.uncaughtExceptionPolicy";
+    private static final UncaughtExceptionPolicy DEFAULT_UNCAUGHT_EXCEPTION_POLICY = UncaughtExceptionPolicy.IGNORE;
+
     private LogListenerImpl listener = null;
+    private ShutdownHandler shutdownHandler = null;
     private Logger log = null;
 
     @Override
@@ -62,16 +67,25 @@ public class Activator implements BundleActivator {
                  * handler will display the exceptions to OSGI console as well
                  * as log to file.
                  */
-                Thread.setDefaultUncaughtExceptionHandler(new org.opendaylight.
-                        controller.logging.bridge.internal.UncaughtExceptionHandler());
+                UncaughtExceptionHandler handler = DEFAULT_UNCAUGHT_EXCEPTION_POLICY;
+                final String policy = context.getProperty(UNCAUGHT_EXCEPTION_POLICY_PROP);
+                if (policy != null) {
+                    try {
+                        handler = UncaughtExceptionPolicy.valueOf(policy.toUpperCase());
+                    } catch (IllegalArgumentException ex) {
+                        log.warn("Invalid policy name \"{}\", defaulting to {}", policy, handler);
+                    }
+                }
+                log.info("Setting uncaught exception policy to {}", handler);
+                Thread.setDefaultUncaughtExceptionHandler(handler);
 
                 /*
                  * Install the Shutdown handler. This will intercept SIGTERM signal and
                  * close the system bundle. This allows for a graceful  closing of OSGI
                  * framework.
                  */
-
-                Runtime.getRuntime().addShutdownHook(new shutdownHandler(context));
+                shutdownHandler = new ShutdownHandler(context);
+                Runtime.getRuntime().addShutdownHook(shutdownHandler);
             } else {
                 this.log.error("Cannot register the LogListener because "
                         + "cannot retrieve LogReaderService");
@@ -90,14 +104,17 @@ public class Activator implements BundleActivator {
             LogReaderService reader = (LogReaderService) service;
             reader.removeLogListener(this.listener);
         }
-
+        if (this.shutdownHandler != null) {
+            Runtime.getRuntime().removeShutdownHook(this.shutdownHandler);
+        }
         this.listener = null;
         this.log = null;
+        this.shutdownHandler = null;
     }
 
-    private class shutdownHandler extends Thread {
+    private class ShutdownHandler extends Thread {
         BundleContext bundlecontext;
-        public shutdownHandler(BundleContext ctxt) {
+        public ShutdownHandler(BundleContext ctxt) {
                 this.bundlecontext = ctxt;
         }
 
diff --git a/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/UncaughtExceptionHandler.java b/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/UncaughtExceptionHandler.java
deleted file mode 100644 (file)
index 6fe9c44..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.opendaylight.controller.logging.bridge.internal;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-public class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
-        private static Logger log = LoggerFactory.getLogger(UncaughtExceptionHandler.class);
-
-        public void uncaughtException (Thread t, Throwable e) {
-                log.error("Uncaught ExceptionHandler:", e);
-        }
-}
diff --git a/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/UncaughtExceptionPolicy.java b/opendaylight/logging/bridge/src/main/java/org/opendaylight/controller/logging/bridge/internal/UncaughtExceptionPolicy.java
new file mode 100644 (file)
index 0000000..0545578
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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.logging.bridge.internal;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+enum UncaughtExceptionPolicy implements Thread.UncaughtExceptionHandler {
+    ABORT {
+        public static final int EXIT_CODE = 1;
+
+        @Override
+        public void uncaughtException(final Thread t, final Throwable e) {
+            log.error("Thread {} died because of an uncaught exception, forcing virtual machine shutdown", t, e);
+            System.exit(EXIT_CODE);
+        }
+    },
+    IGNORE {
+        @Override
+        public void uncaughtException(final Thread t, final Throwable e) {
+            log.error("Thread {} died because of an uncaught exception", t, e);
+        }
+    };
+
+    private static final Logger log = LoggerFactory.getLogger(UncaughtExceptionPolicy.class);
+}
index 9cbf35576f49ace3b4f6c26b8e7404f951f45c0a..62775c1eecf46115d6b741e93b36b2bbe835efe7 100644 (file)
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>0.7.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>clustering.services</artifactId>
-            <version>0.4.1-SNAPSHOT</version>
+            <version>0.5.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>junit</groupId>
index 176ab6cbe0138a5ae9cecdf4877bb5a4ebeaa5d1..129e6ff5fcf449122e578bcd8d0c1218a58a7a91 100644 (file)
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>0.7.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>clustering.services</artifactId>
-            <version>0.4.1-SNAPSHOT</version>
+            <version>0.5.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal.implementation</artifactId>
-            <version>0.4.0-SNAPSHOT</version>
+            <version>0.4.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>containermanager</artifactId>
-            <version>0.5.0-SNAPSHOT</version>
+            <version>0.5.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>containermanager.it.implementation</artifactId>
-            <version>0.5.0-SNAPSHOT</version>
+            <version>0.5.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>clustering.stub</artifactId>
-            <version>0.4.0-SNAPSHOT</version>
+            <version>0.4.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
index 3c8bf979614082dcc257e0e0ff82e8c44190c9ec..fd31e358594a62a9a248a4833dbfcb5c735be9d7 100644 (file)
@@ -77,7 +77,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index d9fb18f84de5d6b0c3cc1c25e9c5be475ab40a42..1b510d0e0b0c082bc090631e3973dfc895900859 100644 (file)
@@ -51,7 +51,7 @@
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>switchmanager</artifactId>
-            <version>0.6.1-SNAPSHOT</version>
+            <version>0.7.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
@@ -98,7 +98,7 @@
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>forwardingrulesmanager</artifactId>
-            <version>0.4.1-SNAPSHOT</version>
+            <version>0.5.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
index 430b5957efc1e3d4d9f707963871897b68341f54..5d0e7e6fe7ae2599edf54cc112a4b710d8754322 100644 (file)
@@ -225,7 +225,7 @@ class CompatibleSwitchManager extends ConfigurableSwitchManager implements ISwit
         val ret = new HashSet<NodeConnector>();
         for (nc : data.nodeConnector) {
             val flowConn = nc.getAugmentation(FlowCapableNodeConnector);
-            if (flowConn != null && flowConn.state == PortState.Live) {
+            if (flowConn != null && flowConn.state != null && !flowConn.state.linkDown) {
                 ret.add(new NodeConnector(MD_SAL_TYPE, nc.key, node));
             }
         }
@@ -286,4 +286,7 @@ class CompatibleSwitchManager extends ConfigurableSwitchManager implements ISwit
         throw new UnsupportedOperationException("TODO: auto-generated method stub")
     }
 
+    override getConfiguredNotConnectedSwitches() {
+        return null;
     }
+}
index 151fdbfaaa19ffcc229338080aa65768e59d3235..37d866dca5f5c4cc5bdbc473005e62343259e0c3 100644 (file)
@@ -25,7 +25,7 @@
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>0.7.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller.model</groupId>
index 15a9a689b3da5975dc6a6a0f1597cb3990e6a1ea..74193ea128c0525de4f9c4b7e2d1245e4fb020c2 100644 (file)
       <artifactId>model-flow-statistics</artifactId>
       <version>1.0-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller.model</groupId>
+      <artifactId>model-topology</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</groupId>
+        <artifactId>clustering.services</artifactId>
+        <version>0.5.0-SNAPSHOT</version>
+    </dependency>
   </dependencies>
   <packaging>bundle</packaging>
 
index a03128995f1567b6153081ed9de3b8d729a01e02..4587cc59edc9dfd587daaa68d7d2b40be023166a 100644 (file)
@@ -1,37 +1,50 @@
 package org.opendaylight.controller.sal.compatibility
 
-import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
-import org.opendaylight.controller.sal.core.Node
-import org.opendaylight.controller.sal.core.NodeConnector
-import static org.opendaylight.controller.sal.compatibility.NodeMapping.*
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
-import org.apache.felix.dm.Component
 import java.util.Arrays
-import org.opendaylight.yangtools.yang.binding.NotificationListener
 import java.util.Dictionary
 import java.util.Hashtable
-import org.opendaylight.controller.sal.utils.GlobalConstants
+import org.apache.felix.dm.Component
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker
-import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService
-import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
-import org.opendaylight.controller.sal.reader.IPluginInReadService
-import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService
-import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer
 import org.opendaylight.controller.sal.binding.api.NotificationService
 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.compatibility.topology.TopologyAdapter
+import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase
+import org.opendaylight.controller.sal.core.Node
+import org.opendaylight.controller.sal.core.NodeConnector
+import org.opendaylight.controller.sal.discovery.IDiscoveryService
+import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService
+import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService
+import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
 import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService
-import org.osgi.framework.BundleContext
+import org.opendaylight.controller.sal.reader.IPluginInReadService
 import org.opendaylight.controller.sal.reader.IPluginOutReadService
-import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
-import org.opendaylight.controller.sal.discovery.IDiscoveryService
+import org.opendaylight.controller.sal.topology.IPluginInTopologyService
 import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+import org.opendaylight.controller.sal.utils.GlobalConstants
+import org.opendaylight.controller.sal.utils.INodeConnectorFactory
+import org.opendaylight.controller.sal.utils.INodeFactory
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices
+import org.opendaylight.controller.sal.packet.IPluginInDataPacketService
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
+import org.osgi.framework.BundleContext
 
-class ComponentActivator extends ComponentActivatorAbstractBase implements BindingAwareConsumer {
+import static org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import org.opendaylight.controller.sal.compatibility.topology.TopologyProvider
+import org.opendaylight.controller.sal.compatibility.adsal.DataPacketServiceAdapter
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
+
+class ComponentActivator extends ComponentActivatorAbstractBase {
 
     private BundleContext context;
 
@@ -45,11 +58,25 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
     DataPacketAdapter dataPacket = new DataPacketAdapter;
 
     @Property
-    org.opendaylight.controller.sal.utils.INodeFactory nodeFactory = new MDSalNodeFactory
+    INodeFactory nodeFactory = new MDSalNodeFactory
+
+    @Property
+    INodeConnectorFactory nodeConnectorFactory = new MDSalNodeConnectorFactory
+    
+    @Property
+    TopologyAdapter topology = new TopologyAdapter
+    
+    @Property
+    TopologyProvider tpProvider = new TopologyProvider()
+
+    @Property
+    DataPacketServiceAdapter dataPacketService = new DataPacketServiceAdapter()
+
+
 
     override protected init() {
-        Node.NodeIDType.registerIDType(MD_SAL_TYPE, NodeKey);
-        NodeConnector.NodeConnectorIDType.registerIDType(MD_SAL_TYPE, NodeConnectorKey, MD_SAL_TYPE);
+        Node.NodeIDType.registerIDType(MD_SAL_TYPE, String);
+        NodeConnector.NodeConnectorIDType.registerIDType(MD_SAL_TYPE, String, MD_SAL_TYPE);
     }
 
     override start(BundleContext context) {
@@ -58,38 +85,32 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
     }
 
     def setBroker(BindingAwareBroker broker) {
-        broker.registerConsumer(this, context)
+        broker.registerProvider(new SalCompatibilityProvider(this), context)
     }
 
-    override onSessionInitialized(ConsumerContext session) {
-        val subscribe = session.getSALService(NotificationService)
-
-        // Registration of Flow Service
-        flow.delegate = session.getRpcService(SalFlowService)
-        subscribe.registerNotificationListener(flow);
-
-        // Data Packet Service
-        subscribe.registerNotificationListener(inventory);
-
-        // Inventory Service
-        inventory.dataService = session.getSALService(DataBrokerService);
-        inventory.flowStatisticsService = session.getRpcService(OpendaylightFlowStatisticsService);
-        inventory.topologyDiscovery = session.getRpcService(FlowTopologyDiscoveryService);
-
-        subscribe.registerNotificationListener(dataPacket)
-
-    }
 
     override protected getGlobalImplementations() {
-        return Arrays.asList(this, flow, inventory, dataPacket, nodeFactory)
+        return Arrays.asList(this, flow, inventory, dataPacket, nodeFactory, nodeConnectorFactory,topology,tpProvider)
     }
 
     override protected configureGlobalInstance(Component c, Object imp) {
         configure(imp, c);
     }
 
+    override protected getImplementations() {
+        return Arrays.asList(dataPacketService)
+    }
+
+    override protected configureInstance(Component c, Object imp, String containerName) {
+        instanceConfigure(imp, c, containerName);
+    }
+
     private def dispatch configure(MDSalNodeFactory imp, Component it) {
-        setInterface(org.opendaylight.controller.sal.utils.INodeFactory.name, properties);
+        setInterface(INodeFactory.name, properties);
+    }
+
+    private def dispatch configure(MDSalNodeConnectorFactory imp, Component it) {
+        setInterface(INodeConnectorFactory.name, properties);
     }
 
     private def dispatch configure(ComponentActivator imp, Component it) {
@@ -116,31 +137,59 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
             .setService(IPluginOutFlowProgrammerService) //
             .setCallbacks("setFlowProgrammerPublisher", "setFlowProgrammerPublisher") //
             .setRequired(false))
+
+        add(
+            createServiceDependency() //
+            .setService(IClusterGlobalServices) //
+            .setCallbacks("setClusterGlobalServices", "unsetClusterGlobalServices") //
+            .setRequired(false))
+
     }
 
+    private def dispatch instanceConfigure(DataPacketServiceAdapter imp, Component it, String containerName) {
+        setInterface(IPluginInDataPacketService.name, properties)
+    }
+
+    private def dispatch instanceConfigure(ComponentActivator imp, Component it, String containerName) {
+    }
+
+
     private def dispatch configure(InventoryAndReadAdapter imp, Component it) {
         setInterface(Arrays.asList(IPluginInInventoryService.name, IPluginInReadService.name), properties)
         add(
             createServiceDependency() //
             .setService(IPluginOutReadService) //
-            .setCallbacks("setReadPublisher", "setReadPublisher") //
+            .setCallbacks("setReadPublisher", "unsetReadPublisher") //
             .setRequired(false))
         add(
             createServiceDependency() //
             .setService(IPluginOutInventoryService) //
-            .setCallbacks("setInventoryPublisher", "setInventoryPublisher") //
+            .setCallbacks("setInventoryPublisher", "unsetInventoryPublisher") //
+            .setRequired(false))
+        add(
+            createServiceDependency() //
+            .setService(IDiscoveryService) //
+            .setCallbacks("setDiscoveryPublisher", "setDiscoveryPublisher") //
             .setRequired(false))
+
+        
+    }
+    
+    private def dispatch configure (TopologyAdapter imp, Component it) {
+        setInterface(Arrays.asList(IPluginInTopologyService.name), properties)
         add(
             createServiceDependency() //
             .setService(IPluginOutTopologyService) //
             .setCallbacks("setTopologyPublisher", "setTopologyPublisher") //
             .setRequired(false))
+    }
+    
+    private def dispatch configure (TopologyProvider imp, Component it) {
         add(
             createServiceDependency() //
-            .setService(IDiscoveryService) //
-            .setCallbacks("setDiscoveryPublisher", "setDiscoveryPublisher") //
+            .setService(IPluginOutTopologyService) //
+            .setCallbacks("setTopologyPublisher", "setTopologyPublisher") //
             .setRequired(false))
-        
     }
 
     private def Dictionary<String, Object> properties() {
@@ -150,3 +199,54 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
         return props;
     }
 }
+package class SalCompatibilityProvider implements BindingAwareProvider {
+    
+    private val ComponentActivator activator;
+    
+    new(ComponentActivator cmpAct) {
+        activator = cmpAct;
+    }
+    
+    override getFunctionality() {
+        // Noop
+    }
+    
+    override getImplementations() {
+        // Noop
+    }
+    
+    
+    override onSessionInitialized(ConsumerContext session) {
+        // Noop
+    }
+    
+    
+    override onSessionInitiated(ProviderContext session) {
+        val it = activator
+                val subscribe = session.getSALService(NotificationService)
+
+        // Registration of Flow Service
+        flow.delegate = session.getRpcService(SalFlowService)
+        flow.dataBrokerService = session.getSALService(DataBrokerService);
+        subscribe.registerNotificationListener(flow);
+
+        // Data Packet Service
+        subscribe.registerNotificationListener(inventory);
+        dataPacketService.delegate = session.getRpcService(PacketProcessingService)
+
+        // Inventory Service
+        inventory.dataService = session.getSALService(DataBrokerService);
+        inventory.flowStatisticsService = session.getRpcService(OpendaylightFlowStatisticsService);
+        inventory.flowTableStatisticsService = session.getRpcService(OpendaylightFlowTableStatisticsService);
+        inventory.nodeConnectorStatisticsService = session.getRpcService(OpendaylightPortStatisticsService);
+        inventory.topologyDiscovery = session.getRpcService(FlowTopologyDiscoveryService);
+        inventory.dataProviderService = session.getSALService(DataProviderService)
+        topology.dataService = session.getSALService(DataProviderService)
+        tpProvider.dataService = session.getSALService(DataProviderService)
+
+
+        tpProvider.start();
+
+        subscribe.registerNotificationListener(dataPacket)
+    }
+}
index 2eae511e02975e6aa23f9d2a09091fa186ab3764..35c641c45aae4e3d0b9f18233abd96228e8ca8fd 100644 (file)
@@ -1,12 +1,21 @@
 package org.opendaylight.controller.sal.compatibility
 
+import java.util.Map
+import java.util.UUID
 import java.util.concurrent.ExecutionException
+import java.util.concurrent.ConcurrentHashMap
+import java.util.concurrent.Future
+import java.util.EnumSet
 import org.opendaylight.controller.sal.core.Node
 import org.opendaylight.controller.sal.flowprogrammer.Flow
 import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService
 import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService
 import org.opendaylight.controller.sal.utils.Status
 import org.opendaylight.controller.sal.utils.StatusCode
+import org.opendaylight.controller.clustering.services.CacheExistException
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices
+import org.opendaylight.controller.clustering.services.IClusterServices
+
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved
@@ -18,7 +27,19 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Node
 import org.opendaylight.yangtools.yang.common.RpcResult
 import org.slf4j.LoggerFactory
 
-import static org.opendaylight.controller.sal.compatibility.MDFlowMapping.*
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
+
+
+import static extension org.opendaylight.controller.sal.compatibility.MDFlowMapping.*
 
 import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
 import static extension org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils.*
@@ -26,67 +47,55 @@ import static extension org.opendaylight.controller.sal.compatibility.ToSalConve
 class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowListener {
 
     private static val LOG = LoggerFactory.getLogger(FlowProgrammerAdapter);
+    private static val CACHE_NAME = "flowprogrammeradapter.flowtoid";
 
     @Property
     private SalFlowService delegate;
+
+    @Property
+    private DataBrokerService dataBrokerService;
     
     @Property
     private IPluginOutFlowProgrammerService flowProgrammerPublisher;
 
+    @Property
+    private IClusterGlobalServices clusterGlobalServices;
+
+
+    @Property
+    private Map<Flow, UUID> flowToFlowId = new ConcurrentHashMap<Flow, UUID>();
+
+
     override addFlow(Node node, Flow flow) {
-        val input = addFlowInput(node, flow);
-        val future = delegate.addFlow(input);
-        try {
-            val result = future.get();
-            return toStatus(result); // how get status from result? conversion?
-        } catch (Exception e) {
-            return processException(e);
-        }
+        return toFutureStatus(internalAddFlowAsync(node,flow,0));
     }
 
     override modifyFlow(Node node, Flow oldFlow, Flow newFlow) {
-        val input = updateFlowInput(node, oldFlow, newFlow);
-        val future = delegate.updateFlow(input);
-        try {
-            val result = future.get();
-            return toStatus(result);
-        } catch (Exception e) {
-            return processException(e);
-        }
+        return toFutureStatus(internalModifyFlowAsync(node, oldFlow,newFlow,0));
     }
 
     override removeFlow(Node node, Flow flow) {
-        val input = removeFlowInput(node, flow);
-        val future = delegate.removeFlow(input);
-
-        try {
-            val result = future.get();
-            return toStatus(result);
-        } catch (Exception e) {
-            return processException(e);
-        }
+        return toFutureStatus(internalRemoveFlowAsync(node, flow,0));
     }
 
     override addFlowAsync(Node node, Flow flow, long rid) {
-        val input = addFlowInput(node, flow);
-        delegate.addFlow(input);
-        return new Status(StatusCode.SUCCESS);
+        internalAddFlowAsync(node, flow, rid);
+        return toStatus(true);
     }
 
     override modifyFlowAsync(Node node, Flow oldFlow, Flow newFlow, long rid) {
-        val input = updateFlowInput(node, oldFlow, newFlow);
-        delegate.updateFlow(input);
-        return new Status(StatusCode.SUCCESS);
+        internalModifyFlowAsync(node, oldFlow, newFlow, rid);
+        return toStatus(true);
     }
 
     override removeFlowAsync(Node node, Flow flow, long rid) {
-        val input = removeFlowInput(node, flow);
-        delegate.removeFlow(input);
-        return new Status(StatusCode.SUCCESS);
+        internalRemoveFlowAsync(node, flow, rid);
+        return toStatus(true);
     }
 
     override removeAllFlows(Node node) {
-        throw new UnsupportedOperationException("Not present in MD-SAL");
+        // I know this looks like a copout... but its exactly what the legacy OFplugin did
+        return new Status(StatusCode.SUCCESS);
     }
 
     override syncSendBarrierMessage(Node node) {
@@ -101,13 +110,17 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi
         return null;
     }
 
-    public static def toStatus(RpcResult<?> result) {
-        if (result.isSuccessful()) {
+    private static def toStatus(boolean successful) {
+        if (successful) {
             return new Status(StatusCode.SUCCESS);
         } else {
             return new Status(StatusCode.INTERNALERROR);
         }
     }
+
+    public static def toStatus(RpcResult<?> result) {
+        return toStatus(result.isSuccessful());
+    }
     
     private static dispatch def Status processException(InterruptedException e) {
         LOG.error("Interruption occured during processing flow",e);
@@ -147,4 +160,90 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi
                 NodeExperimenterErrorNotification notification) {
         // NOOP : Not supported by AD SAL
     }
+
+    private def Future<RpcResult<TransactionStatus>> writeFlowAsync(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow flow, NodeKey nodeKey){
+        val modification = this._dataBrokerService.beginTransaction();
+        val flowPath = InstanceIdentifier.builder(Nodes)
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, nodeKey)
+                .augmentation(FlowCapableNode)
+                .child(Table, new TableKey(flow.getTableId()))
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow, new FlowKey(flow.id))
+                .build;
+        modification.putConfigurationData(flowPath, flow);
+        return modification.commit();
+    }
+
+    private def Future<RpcResult<TransactionStatus>> internalAddFlowAsync(Node node, Flow flow, long rid){
+        var flowId = getCache().get(flow);
+        if(flowId != null) {
+            removeFlow(node, flow);
+            return internalAddFlowAsync(node, flow, rid);
+        }
+
+        flowId = UUID.randomUUID();
+        getCache().put(flow, flowId);
+
+        return writeFlowAsync(flow.toMDFlow(flowId.toString()), new NodeKey(new NodeId(node.getNodeIDString())));
+    }
+
+    private def Future<RpcResult<TransactionStatus>> internalModifyFlowAsync(Node node, Flow oldFlow, Flow newFlow, long rid) {
+        val flowId = getCache().remove(oldFlow);
+        if(flowId == null){
+            throw new IllegalArgumentException("oldFlow is unknown");
+        }
+
+        getCache().put(newFlow, flowId);
+        return writeFlowAsync(newFlow.toMDFlow(flowId.toString()), new NodeKey(new NodeId(node.getNodeIDString())));
+    }
+
+
+    private def Future<RpcResult<TransactionStatus>> internalRemoveFlowAsync(Node node, Flow adflow, long rid){
+        val flowId = getCache().remove(adflow);
+        if(flowId == null){
+            throw new IllegalArgumentException("adflow is unknown");
+        }
+        val flow = adflow.toMDFlow(flowId.toString());
+        val modification = this._dataBrokerService.beginTransaction();
+        val flowPath = InstanceIdentifier.builder(Nodes)
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, new NodeKey(new NodeId(node.getNodeIDString())))
+                .augmentation(FlowCapableNode)
+                .child(Table, new TableKey(flow.getTableId()))
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow, new FlowKey(flow.id))
+                .build;
+        modification.removeConfigurationData(flowPath);
+        return modification.commit();
+    }
+
+    private def toFutureStatus(Future<RpcResult<TransactionStatus>> future){
+        try {
+            val result = future.get();
+            return toStatus(result);
+        } catch (InterruptedException e) {
+            return processException(e);
+        } catch (ExecutionException e) {
+            return processException(e);
+        } catch (Exception e){
+            processException(e);
+        }
+        return toStatus(false);
+    }
+
+    private def Map<Flow, UUID> getCache(){
+        if(clusterGlobalServices == null){
+            return new ConcurrentHashMap<Flow, UUID>();
+        }
+
+        var cache = clusterGlobalServices.getCache(CACHE_NAME);
+
+        if(cache == null) {
+            try {
+                cache = clusterGlobalServices.createCache(CACHE_NAME, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+            } catch (CacheExistException e) {
+                cache = clusterGlobalServices.getCache(CACHE_NAME);
+            }
+        }
+        return cache as Map<Flow, UUID>;
+
+    }
+
 }
index ad6009c827a365ff40ebdce31cb1c87e92efb7f8..eba4aa901bdc1d2496a485c9676024bb01002f3b 100644 (file)
@@ -1,5 +1,9 @@
 package org.opendaylight.controller.sal.compatibility;
 
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.CRUDP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP;
 import static org.opendaylight.controller.sal.match.MatchType.DL_DST;
 import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
 import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE;
@@ -8,11 +12,7 @@ import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 
-
 import org.opendaylight.controller.sal.core.NodeConnector;
-
-
-
 import org.opendaylight.controller.sal.match.Match;
 import org.opendaylight.controller.sal.match.MatchField;
 import org.opendaylight.controller.sal.match.MatchType;
@@ -22,14 +22,12 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
@@ -53,9 +51,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
+
 import com.google.common.net.InetAddresses;
-import static org.opendaylight.controller.sal.compatibility.NodeMapping.*;
-import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.*;
 
 public class FromSalConversionsUtils {
 
@@ -63,19 +60,7 @@ public class FromSalConversionsUtils {
 
     }
 
-    public static GetNodeConnectorStatisticsInput nodeConnectorStatistics(
-            NodeConnector connector) {
-        GetNodeConnectorStatisticsInputBuilder target = new GetNodeConnectorStatisticsInputBuilder();
-
-        NodeRef nodeRef = toNodeRef(connector.getNode());
-        target.setNode(nodeRef);
-
-        NodeConnectorRef nodeConnectorRef = toNodeConnectorRef(connector);
-        target.setNodeConnector(nodeConnectorRef);
-
-        return target.build();
-    }
-
+    @SuppressWarnings("unused")
     private static Address addressFromAction(InetAddress inetAddress) {
         String strInetAddresss = InetAddresses.toAddrString(inetAddress);
         if (inetAddress instanceof Inet4Address) {
@@ -100,6 +85,7 @@ public class FromSalConversionsUtils {
             targetBuilder.setVlanMatch(vlanMatch(sourceMatch));
             targetBuilder.setLayer3Match(layer3Match(sourceMatch));
             targetBuilder.setLayer4Match(layer4Match(sourceMatch));
+            targetBuilder.setInPort(inPortMatch(sourceMatch));
 
             return targetBuilder.build();
         }
@@ -107,6 +93,14 @@ public class FromSalConversionsUtils {
 
     }
 
+    private static NodeConnectorId inPortMatch(Match sourceMatch) {
+        MatchField inPort = sourceMatch.getField(MatchType.IN_PORT);
+        if(inPort != null && inPort.getValue() != null && (inPort.getValue() instanceof NodeConnector)) {
+            return new NodeConnectorId(((NodeConnector) inPort.getValue()).getNodeConnectorIdAsString());
+        }
+        return null;
+    }
+
     private static Layer4Match layer4Match(final Match sourceMatch) {
         MatchField nwProto = sourceMatch.getField(MatchType.NW_PROTO);
         Short nwProtocolSource = null;
@@ -138,8 +132,10 @@ public class FromSalConversionsUtils {
             sctpMatchBuilder.setSctpDestinationPort(new PortNumber(
                     destinationPort));
         }
-
-        return sctpMatchBuilder.build();
+        if(sourcePort != null || destinationPort != null) {
+            return sctpMatchBuilder.build();
+        }
+        return null;
     }
 
     private static Layer4Match Layer4MatchAsUdp(final Match sourceMatch) {
@@ -157,8 +153,10 @@ public class FromSalConversionsUtils {
             udpMatchBuilder.setUdpDestinationPort(new PortNumber(
                     destinationPort));
         }
-
-        return udpMatchBuilder.build();
+        if(sourcePort != null || destinationPort != null) {
+            return udpMatchBuilder.build();
+        }
+        return null;
     }
 
     private static Layer4Match Layer4MatchAsTcp(final Match sourceMatch) {
@@ -175,8 +173,10 @@ public class FromSalConversionsUtils {
             tcpMatchBuilder.setTcpDestinationPort(new PortNumber(
                     destinationPort));
         }
-
-        return tcpMatchBuilder.build();
+        if(sourcePort != null || destinationPort != null) {
+            return tcpMatchBuilder.build();
+        }
+        return null;
     }
 
     private static Integer transportPort(final Match sourceMatch,
@@ -196,7 +196,7 @@ public class FromSalConversionsUtils {
         MatchField vlan = sourceMatch.getField(MatchType.DL_VLAN);
         if (vlan != null && vlan.getValue() != null) {
             VlanIdBuilder vlanIDBuilder = new VlanIdBuilder();
-            vlanIDBuilder.setVlanId(new VlanId((int) (NetUtils
+            vlanIDBuilder.setVlanId(new VlanId((NetUtils
                     .getUnsignedShort((short) vlan.getValue()))));
             vlanMatchBuild.setVlanId(vlanIDBuilder.build());
         }
@@ -206,8 +206,10 @@ public class FromSalConversionsUtils {
             vlanMatchBuild.setVlanPcp(new VlanPcp((short) ((byte) vlanPriority
                     .getValue())));
         }
-
-        return vlanMatchBuild.build();
+        if((vlan != null && vlan.getValue() != null) || (vlanPriority != null && vlanPriority.getValue() != null)) {
+            return vlanMatchBuild.build();
+        }
+        return null;
     }
 
     private static IpMatch ipMatch(final Match sourceMatch) {
@@ -225,21 +227,24 @@ public class FromSalConversionsUtils {
             targetIpMatchBuild.setIpProtocol((short) ((byte) protocol
                     .getValue()));
         }
-
-        return targetIpMatchBuild.build();
-
+        if((networkTos != null && networkTos.getValue() != null) || (protocol != null && protocol.getValue() != null)) {
+            return targetIpMatchBuild.build();
+        }
+        return null;
     }
 
     private static EthernetMatch ethernetMatch(final Match sourceMatch) {
         final EthernetMatchBuilder targetEthMatchBuild = new EthernetMatchBuilder();
-
-        EthernetSourceBuilder ethSourBuild = new EthernetSourceBuilder()
-                .setAddress(ethernetSourceAddress(sourceMatch));
-        targetEthMatchBuild.setEthernetSource(ethSourBuild.build());
-
-        EthernetDestinationBuilder ethDestBuild = new EthernetDestinationBuilder()
-                .setAddress(ethernetDestAddress(sourceMatch));
-        targetEthMatchBuild.setEthernetDestination(ethDestBuild.build());
+        if(sourceMatch.getField(DL_SRC) != null && sourceMatch.getField(DL_SRC).getValue() != null) {
+            EthernetSourceBuilder ethSourBuild = new EthernetSourceBuilder()
+                    .setAddress(ethernetSourceAddress(sourceMatch));
+            targetEthMatchBuild.setEthernetSource(ethSourBuild.build());
+        }
+        if(sourceMatch.getField(DL_DST) != null && sourceMatch.getField(DL_DST).getValue() != null) {
+            EthernetDestinationBuilder ethDestBuild = new EthernetDestinationBuilder()
+                    .setAddress(ethernetDestAddress(sourceMatch));
+            targetEthMatchBuild.setEthernetDestination(ethDestBuild.build());
+        }
 
         final MatchField dataLinkType = sourceMatch.getField(MatchType.DL_TYPE);
         if (dataLinkType != null && dataLinkType.getValue() != null) {
@@ -249,7 +254,12 @@ public class FromSalConversionsUtils {
                     .setType(etherType);
             targetEthMatchBuild.setEthernetType(ethType.build());
         }
-        return targetEthMatchBuild.build();
+        if((sourceMatch.getField(DL_SRC) != null && sourceMatch.getField(DL_SRC).getValue() != null) || 
+                (sourceMatch.getField(DL_DST) != null && sourceMatch.getField(DL_DST).getValue() != null)|| 
+                dataLinkType != null ) {
+            return targetEthMatchBuild.build();            
+        } 
+        return null;
     }
 
     private static MacAddress ethernetSourceAddress(final Match sourceMatch) {
@@ -270,12 +280,12 @@ public class FromSalConversionsUtils {
 
         InetAddress inetDestAddress = null;
         MatchField netDest = sourceMatch.getField(MatchType.NW_DST);
-        if (netSource != null && netSource.getValue() != null) {
+        if (netDest != null && netDest.getValue() != null) {
             inetDestAddress = (InetAddress) (netDest.getValue());
         }
 
         if ((inetSourceAddress instanceof Inet4Address)
-                && (inetDestAddress instanceof Inet4Address)) {
+                || (inetDestAddress instanceof Inet4Address)) {
             MatchField dataLinkType = sourceMatch.getField(DL_TYPE);
             Short dLType = null;
             if (dataLinkType != null && dataLinkType.getValue() != null) {
@@ -290,7 +300,7 @@ public class FromSalConversionsUtils {
                         (Inet4Address) inetDestAddress);
             }
         } else if ((inetSourceAddress instanceof Inet6Address)
-                && (inetDestAddress instanceof Inet6Address)) {
+                || (inetDestAddress instanceof Inet6Address)) {
             return setLayer3MatchAsIpv6((Inet6Address) inetSourceAddress,
                     (Inet6Address) inetDestAddress);
         }
@@ -344,15 +354,18 @@ public class FromSalConversionsUtils {
     private static Layer3Match setLayer3MatchAsIpv4(
             final Inet4Address inetSourceAddress,
             final Inet4Address inetDestAddress) {
-        String inetSrcAddressString = InetAddresses
-                .toAddrString(inetSourceAddress);
-        String inetDstAddressString = InetAddresses
-                .toAddrString(inetDestAddress);
-
         Ipv4MatchBuilder layer4MatchBuild = new Ipv4MatchBuilder();
-        layer4MatchBuild.setIpv4Source(new Ipv4Prefix(inetSrcAddressString));
-        layer4MatchBuild
-                .setIpv4Destination(new Ipv4Prefix(inetDstAddressString));
+        if(inetSourceAddress != null) {
+            String inetSrcAddressString = InetAddresses
+                    .toAddrString(inetSourceAddress);
+            layer4MatchBuild.setIpv4Source(new Ipv4Prefix(inetSrcAddressString));
+        }
+        if(inetDestAddress != null) {
+            String inetDstAddressString = InetAddresses
+                    .toAddrString(inetDestAddress);
+            layer4MatchBuild
+            .setIpv4Destination(new Ipv4Prefix(inetDstAddressString));
+        }       
         return layer4MatchBuild.build();
 
     }
@@ -360,16 +373,90 @@ public class FromSalConversionsUtils {
     private static Layer3Match setLayer3MatchAsIpv6(
             final Inet6Address inetSourceAddress,
             final Inet6Address inetDestAddress) {
-        String inetSrcAddressString = InetAddresses
-                .toAddrString(inetSourceAddress);
-        String inetDstAddressString = InetAddresses
-                .toAddrString(inetDestAddress);
         Ipv6MatchBuilder layer6MatchBuild = new Ipv6MatchBuilder();
-
-        layer6MatchBuild.setIpv6Source(new Ipv6Prefix(inetSrcAddressString));
-        layer6MatchBuild
-                .setIpv6Destination(new Ipv6Prefix(inetDstAddressString));
+        if(inetSourceAddress != null) {
+            String inetSrcAddressString = InetAddresses
+                    .toAddrString(inetSourceAddress);
+            layer6MatchBuild.setIpv6Source(new Ipv6Prefix(inetSrcAddressString));
+        }
+        if(inetDestAddress != null) {
+            String inetDstAddressString = InetAddresses
+                    .toAddrString(inetDestAddress);    
+            layer6MatchBuild
+                    .setIpv6Destination(new Ipv6Prefix(inetDstAddressString));
+        }
         return layer6MatchBuild.build();
     }
+    
+    public static boolean flowEquals(Flow statsFlow, Flow storedFlow) {
+        if (statsFlow.getClass() != storedFlow.getClass()) {
+            return false;
+        }
+        if (statsFlow.getBufferId()== null) {
+            if (storedFlow.getBufferId() != null) {
+                return false;
+            }
+        } else if(!statsFlow.getBufferId().equals(storedFlow.getBufferId())) {
+            return false;
+        }
+        if (statsFlow.getContainerName()== null) {
+            if (storedFlow.getContainerName()!= null) {
+                return false;
+            }
+        } else if(!statsFlow.getContainerName().equals(storedFlow.getContainerName())) {
+            return false;
+        }
+        if (statsFlow.getCookie()== null) {
+            if (storedFlow.getCookie()!= null) {
+                return false;
+            }
+        } else if(!statsFlow.getCookie().equals(storedFlow.getCookie())) {
+            return false;
+        }
+        if (statsFlow.getMatch()== null) {
+            if (storedFlow.getMatch() != null) {
+                return false;
+            }
+        } else if(!statsFlow.getMatch().equals(storedFlow.getMatch())) {
+            return false;
+        }
+        if (statsFlow.getCookie()== null) {
+            if (storedFlow.getCookie()!= null) {
+                return false;
+            }
+        } else if(!statsFlow.getCookie().equals(storedFlow.getCookie())) {
+            return false;
+        }
+        if (statsFlow.getHardTimeout() == null) {
+            if (storedFlow.getHardTimeout() != null) {
+                return false;
+            }
+        } else if(!statsFlow.getHardTimeout().equals(storedFlow.getHardTimeout() )) {
+            return false;
+        }
+        if (statsFlow.getIdleTimeout()== null) {
+            if (storedFlow.getIdleTimeout() != null) {
+                return false;
+            }
+        } else if(!statsFlow.getIdleTimeout().equals(storedFlow.getIdleTimeout())) {
+            return false;
+        }
+        if (statsFlow.getPriority() == null) {
+            if (storedFlow.getPriority() != null) {
+                return false;
+            }
+        } else if(!statsFlow.getPriority().equals(storedFlow.getPriority())) {
+            return false;
+        }
+        if (statsFlow.getTableId() == null) {
+            if (storedFlow.getTableId() != null) {
+                return false;
+            }
+        } else if(!statsFlow.getTableId().equals(storedFlow.getTableId())) {
+            return false;
+        }
+        return true;
+    }
+
 
 }
index 609ace469556e1101389bd17677796b159dde8a6..21af047c3d79a5cb2d6c2508e05f9121b119be71 100644 (file)
 package org.opendaylight.controller.sal.compatibility
 
-import org.opendaylight.controller.sal.reader.IPluginInReadService
-import org.opendaylight.controller.sal.core.NodeConnector
+import java.util.ArrayList
+import java.util.Collections
+import java.util.List
+import java.util.Set
+import java.util.concurrent.CopyOnWriteArrayList;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.core.Edge
 import org.opendaylight.controller.sal.core.Node
-import org.opendaylight.controller.sal.flowprogrammer.Flow
 import org.opendaylight.controller.sal.core.NodeTable
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
-
-import static extension org.opendaylight.controller.sal.common.util.Arguments.*
-import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
-import static org.opendaylight.controller.sal.compatibility.MDFlowMapping.*
+import org.opendaylight.controller.sal.core.UpdateType
+import org.opendaylight.controller.sal.flowprogrammer.Flow
+import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
+import org.opendaylight.controller.sal.reader.FlowOnNode
+import org.opendaylight.controller.sal.reader.IPluginInReadService
+import org.opendaylight.controller.sal.reader.IPluginOutReadService
+import org.opendaylight.controller.sal.reader.NodeConnectorStatistics
+import org.opendaylight.controller.sal.reader.NodeDescription
+import org.opendaylight.controller.sal.reader.NodeTableStatistics
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
-import org.opendaylight.controller.sal.reader.NodeConnectorStatistics
-import org.opendaylight.controller.sal.reader.FlowOnNode
-import org.opendaylight.controller.sal.reader.NodeDescription
-import org.slf4j.LoggerFactory
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsInputBuilder
-import java.util.ArrayList
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllNodeConnectorStatisticsInputBuilder
-import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
-import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
-import java.util.Collections
-import org.opendaylight.controller.sal.core.UpdateType
+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.NodeRemoved
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatistics
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
 import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
-import org.opendaylight.controller.sal.topology.IPluginInTopologyService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryListener
-import org.opendaylight.controller.sal.core.Edge
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link
-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.controller.sal.topology.TopoEdgeUpdate
-import org.opendaylight.controller.sal.discovery.IDiscoveryService
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.slf4j.LoggerFactory
 
-class InventoryAndReadAdapter implements IPluginInTopologyService, IPluginInReadService, IPluginInInventoryService, OpendaylightInventoryListener, FlowTopologyDiscoveryListener {
+import static extension org.opendaylight.controller.sal.common.util.Arguments.*
+import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import java.util.concurrent.ConcurrentHashMap
+import java.util.Map
+
+class InventoryAndReadAdapter implements IPluginInReadService,
+                                                                                        IPluginInInventoryService,
+                                                                                        OpendaylightInventoryListener,
+                                                                                        OpendaylightFlowStatisticsListener,
+                                                                                        OpendaylightFlowTableStatisticsListener,
+                                                                                        OpendaylightPortStatisticsListener {
 
     private static val LOG = LoggerFactory.getLogger(InventoryAndReadAdapter);
 
+       private static val OPENFLOWV10_TABLE_ID = new Integer(0).shortValue;
     @Property
     DataBrokerService dataService;
 
     @Property
-    OpendaylightFlowStatisticsService flowStatisticsService;
+    DataProviderService dataProviderService;
 
     @Property
-    IPluginOutInventoryService inventoryPublisher;
+    OpendaylightFlowStatisticsService flowStatisticsService;
 
     @Property
-    IPluginOutTopologyService topologyPublisher;
+    OpendaylightPortStatisticsService nodeConnectorStatisticsService;
     
     @Property
-    IDiscoveryService discoveryPublisher;
+    OpendaylightFlowTableStatisticsService flowTableStatisticsService;
 
     @Property
     FlowTopologyDiscoveryService topologyDiscovery;
+    
+    @Property
+    List<IPluginOutReadService> statisticsPublisher = new CopyOnWriteArrayList<IPluginOutReadService>();
+
+    @Property
+    List<IPluginOutInventoryService> inventoryPublisher = new CopyOnWriteArrayList<IPluginOutInventoryService>();
+
+       def setInventoryPublisher(IPluginOutInventoryService listener){
+        inventoryPublisher.add(listener);
+       }
+
+       def unsetInventoryPublisher(IPluginOutInventoryService listener){
+        inventoryPublisher.remove(listener);
+       }
 
-    override getTransmitRate(NodeConnector connector) {
+    def setReadPublisher(IPluginOutReadService listener) {
+       statisticsPublisher.add(listener);
+    }
+    
+    def unsetReadPublisher (IPluginOutReadService listener) {
+       if( listener != null)
+               statisticsPublisher.remove(listener);
+    }
+
+    protected def startChange() {
+        return dataProviderService.beginTransaction;
+    }
+
+    override getTransmitRate(org.opendaylight.controller.sal.core.NodeConnector connector) {
         val nodeConnector = readFlowCapableNodeConnector(connector.toNodeConnectorRef);
         return nodeConnector.currentSpeed
     }
 
     override readAllFlow(Node node, boolean cached) {
-        val input = new GetAllFlowStatisticsInputBuilder;
-        input.setNode(node.toNodeRef);
-        val result = flowStatisticsService.getAllFlowStatistics(input.build)
 
-        val statistics = result.get.result;
         val output = new ArrayList<FlowOnNode>();
-        for (stat : statistics.flowStatistics) {
-            // FIXME: Create FlowOnNode
-        }
+               val tableRef = InstanceIdentifier.builder(Nodes)
+                                                                               .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+                                                       .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
+               
+               val it = this.startChange();
+               
+               val table= it.readConfigurationData(tableRef) as Table;
+               
+               if(table != null){
+                       LOG.info("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
+                       
+                       for(flow : table.flow){
+                               
+                               val adsalFlow = ToSalConversionsUtils.toFlow(flow);
+                               val statsFromDataStore = flow.getAugmentation(FlowStatisticsData);
+                               
+                               if(statsFromDataStore != null){
+                                       val it = new FlowOnNode(adsalFlow);
+                                       byteCount =  statsFromDataStore.flowStatistics.byteCount.value.longValue;
+                                       packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
+                                       durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
+                                       durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
+                                       
+                                       output.add(it);
+                               }
+                       }
+               }
+        
+        //TODO (main): Shell we send request to the switch? It will make async request to the switch.
+        // Once plugin receive response, it will let adaptor know through onFlowStatisticsUpdate()
+        // If we assume that md-sal statistics manager will always be running, then its not required
+        // But if not, then sending request will collect the latest data for adaptor atleast.
+        val input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
+        input.setNode(node.toNodeRef);
+        flowStatisticsService.getAllFlowsStatisticsFromAllFlowTables(input.build)
+        
         return output;
     }
 
     override readAllNodeConnector(Node node, boolean cached) {
-        val input = new GetAllNodeConnectorStatisticsInputBuilder();
+       
+       val ret = new ArrayList<NodeConnectorStatistics>();
+               val nodeRef = InstanceIdentifier.builder(Nodes)
+                                                                       .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+                                                                       .toInstance();
+               
+               val provider = this.startChange();
+               
+               val dsNode= provider.readConfigurationData(nodeRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+               
+               if(dsNode != null){
+                       
+                       for (dsNodeConnector : dsNode.nodeConnector){
+                               val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
+                                                                       .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+                                                                       .child(NodeConnector, dsNodeConnector.key)
+                                                                       .toInstance();
+                               
+                               val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
+                               
+                               if(nodeConnectorFromDS != null){
+                                       val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
+                                       
+                                       ret.add(toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,dsNode.id,dsNodeConnector.id));
+                               }
+                       }
+               }
+
+               //TODO: Refer TODO (main)
+        val input = new GetAllNodeConnectorsStatisticsInputBuilder();
         input.setNode(node.toNodeRef);
-        val result = flowStatisticsService.getAllNodeConnectorStatistics(input.build());
-        val statistics = result.get.result.nodeConnectorStatistics;
-        val ret = new ArrayList<NodeConnectorStatistics>();
-        for (stat : statistics) {
-            ret.add(stat.toNodeConnectorStatistics())
-        }
+        nodeConnectorStatisticsService.getAllNodeConnectorsStatistics(input.build());
         return ret;
     }
 
     override readAllNodeTable(Node node, boolean cached) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+       val ret = new ArrayList<NodeTableStatistics>();
+       
+               val dsFlowCapableNode= readFlowCapableNode(node.toNodeRef)
+               
+               if(dsFlowCapableNode != null){
+                       
+                       for (table : dsFlowCapableNode.table){
+                               
+                               val tableStats = table.getAugmentation(FlowTableStatisticsData);
+                               
+                               if(tableStats != null){
+                                       ret.add(toNodeTableStatistics(tableStats.flowTableStatistics,table.id,node));
+                               }
+                       }
+               }
+
+               //TODO: Refer TODO (main)
+        val input = new GetFlowTablesStatisticsInputBuilder();
+        input.setNode(node.toNodeRef);
+        flowTableStatisticsService.getFlowTablesStatistics(input.build);
+        return ret;
     }
 
     override readDescription(Node node, boolean cached) {
-        val capableNode = readFlowCapableNode(node.toNodeRef)
-
-        val it = new NodeDescription()
-        manufacturer = capableNode.manufacturer
-        serialNumber = capableNode.serialNumber
-        software = capableNode.software
-        description = capableNode.description
-
-        return it;
+        return toNodeDescription(node.toNodeRef);
+       }
+
+    override readFlow(Node node, Flow targetFlow, boolean cached) {
+               var FlowOnNode ret= null;
+               
+               val tableRef = InstanceIdentifier.builder(Nodes)
+                                                                               .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+                                                       .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
+               
+               val it = this.startChange();
+               
+               val table= it.readConfigurationData(tableRef) as Table;
+               
+               if(table != null){
+                       LOG.info("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
+                       
+                       for(mdsalFlow : table.flow){
+                               if(FromSalConversionsUtils.flowEquals(mdsalFlow, MDFlowMapping.toMDSalflow(targetFlow))){
+                                       val statsFromDataStore = mdsalFlow.getAugmentation(FlowStatisticsData);
+                                       
+                                       if(statsFromDataStore != null){
+                                               LOG.debug("Found matching flow in the data store flow table ");
+                                               val it = new FlowOnNode(targetFlow);
+                                               byteCount =  statsFromDataStore.flowStatistics.byteCount.value.longValue;
+                                               packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
+                                               durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
+                                               durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
+                                               
+                                               ret = it;
+                                       }
+                               }                       
+                       }
+               }
+        
+        //TODO: Refer TODO (main)
+        val input = new GetFlowStatisticsFromFlowTableInputBuilder;
+        input.setNode(node.toNodeRef);
+        input.fieldsFrom(MDFlowMapping.toMDSalflow(targetFlow));
+        flowStatisticsService.getFlowStatisticsFromFlowTable(input.build)
+        
+        return ret;
+       
     }
 
-    override readFlow(Node node, Flow flow, boolean cached) {
-        val input = flowStatisticsInput(node, flow);
-        val output = flowStatisticsService.getFlowStatistics(input);
-
-        try {
-            val statistics = output.get().getResult();
-            if (statistics != null) {
-                val it = new FlowOnNode(flow);
-                byteCount = statistics.byteCount.value.longValue
-                durationNanoseconds = statistics.duration.getNanosecond().getValue().intValue();
-                durationSeconds = statistics.duration.getSecond().getValue().intValue();
-                packetCount = statistics.getPacketCount().getValue().longValue();
-                return it;
-            }
-        } catch (Exception e) {
-            LOG.error("Read flow not processed", e);
-        }
-        return null;
+    override readNodeConnector(org.opendaylight.controller.sal.core.NodeConnector connector, boolean cached) {
+       var NodeConnectorStatistics  nodeConnectorStatistics = null;
+       
+               val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
+                                                                       .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(connector.node))
+                                                                       .child(NodeConnector, InventoryMapping.toNodeConnectorKey(connector))
+                                                                       .toInstance();
+               val provider = this.startChange();
+                               
+               val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
+                               
+               if(nodeConnectorFromDS != null){
+                       val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
+                       if(nodeConnectorStatsFromDs != null) {
+                               nodeConnectorStatistics = toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,
+                                                                                                                                               InventoryMapping.toNodeKey(connector.node).id,
+                                                                                                                                               InventoryMapping.toNodeConnectorKey(connector).id);
+                       }
+               }
+
+               //TODO: Refer TODO (main)
+        val input = new GetNodeConnectorStatisticsInputBuilder();
+        input.setNode(connector.node.toNodeRef);
+        input.setNodeConnectorId(InventoryMapping.toNodeConnectorKey(connector).id);
+        nodeConnectorStatisticsService.getNodeConnectorStatistics(input.build());
+        return nodeConnectorStatistics;
     }
 
-    override readNodeConnector(NodeConnector connector, boolean cached) {
-
-        val getNodeConnectorStatisticsInput = FromSalConversionsUtils.nodeConnectorStatistics(connector);
-        val future = flowStatisticsService.getNodeConnectorStatistics(getNodeConnectorStatisticsInput);
-        try {
-            val rpcResult = future.get();
-            val output = rpcResult.getResult();
-
-            if (output != null) {
-                return output.toNodeConnectorStatistics;
-            }
-        } catch (Exception e) {
-            LOG.error("Read node connector not processed", e);
-        }
-
-        return null;
+    override readNodeTable(NodeTable nodeTable, boolean cached) {
+       var NodeTableStatistics nodeStats = null
+       
+       val tableRef = InstanceIdentifier.builder(Nodes)
+                                                                               .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(nodeTable.node))
+                                                       .augmentation(FlowCapableNode).child(Table, new TableKey(nodeTable.ID as Short)).toInstance();
+               
+               val it = this.startChange();
+               
+               val table= it.readConfigurationData(tableRef) as Table;
+               
+               if(table != null){
+                       val tableStats = table.getAugmentation(FlowTableStatisticsData);
+                               
+                       if(tableStats != null){
+                               nodeStats =  toNodeTableStatistics(tableStats.flowTableStatistics,table.id,nodeTable.node);
+                       }
+               }
+
+               //TODO: Refer TODO (main)
+        val input = new GetFlowTablesStatisticsInputBuilder();
+        input.setNode(nodeTable.node.toNodeRef);
+        flowTableStatisticsService.getFlowTablesStatistics(input.build);
+        
+        return nodeStats;
     }
 
     override onNodeConnectorRemoved(NodeConnectorRemoved update) {
@@ -158,54 +339,97 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, IPluginInRead
 
     override onNodeRemoved(NodeRemoved notification) {
         val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
-        val org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value  as org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>;
 
-        inventoryPublisher.updateNode(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
+        publishNodeUpdate(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
     }
 
     override onNodeConnectorUpdated(NodeConnectorUpdated update) {
-        val properties = new java.util.HashSet<org.opendaylight.controller.sal.core.Property>();
-
-
-        val org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> identifier = update.nodeConnectorRef.value as org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>;
         var updateType = UpdateType.CHANGED;
-        if ( this._dataService.readOperationalData(identifier) == null ){
+        if ( this._dataService.readOperationalData(update.nodeConnectorRef.value as InstanceIdentifier<? extends DataObject>) == null ){
             updateType = UpdateType.ADDED;
         }
 
         var nodeConnector = update.nodeConnectorRef.toADNodeConnector
 
-
-        properties.add(new org.opendaylight.controller.sal.core.Name(nodeConnector.ID.toString()));
-
-        inventoryPublisher.updateNodeConnector(nodeConnector , updateType , properties);
+        publishNodeConnectorUpdate(nodeConnector , updateType , update.toADNodeConnectorProperties);
     }
 
     override onNodeUpdated(NodeUpdated notification) {
-        val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
-        val org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value  as org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>;
+        val InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value  as InstanceIdentifier<? extends DataObject>;
 
         var updateType = UpdateType.CHANGED;
         if ( this._dataService.readOperationalData(identifier) == null ){
             updateType = UpdateType.ADDED;
         }
-        inventoryPublisher.updateNode(notification.nodeRef.toADNode, updateType, properties);
+        publishNodeUpdate(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
+        
+               //Notify the listeners of IPluginOutReadService
+        
+        for (statsPublisher : statisticsPublisher){
+                       val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
+                       statsPublisher.descriptionStatisticsUpdated(nodeRef.toADNode,toNodeDescription(notification.nodeRef));
+               }
     }
 
     override getNodeProps() {
-
-        // FIXME: Read from MD-SAL inventory service
-        return null;
+        val props = new ConcurrentHashMap<Node, Map<String, org.opendaylight.controller.sal.core.Property>>()
+        
+        val nodes = readAllMDNodes()
+        for (node : nodes.node ) {
+            val fcn = node.getAugmentation(FlowCapableNode)
+            if(fcn != null) {
+                val perNodeProps = fcn.toADNodeProperties(node.id)
+                val perNodePropMap = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
+                if(perNodeProps != null ) {
+                    for(perNodeProp : perNodeProps) {
+                        perNodePropMap.put(perNodeProp.name,perNodeProp)
+                    }
+                }
+                props.put(new Node(MD_SAL_TYPE, node.id.toADNodeId),perNodePropMap)
+            }
+        }
+        return props;
     }
-
-    override getNodeConnectorProps(Boolean refresh) {
-
-        // FIXME: Read from MD-SAL Invcentory Service
-        return null;
+    
+    private def readAllMDNodes() {
+        val nodesRef = InstanceIdentifier.builder(Nodes)
+            .toInstance
+        val reader = TypeSafeDataReader.forReader(dataService)
+        return reader.readOperationalData(nodesRef)
+    }
+    
+    private def readAllMDNodeConnectors(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node) {
+        val nodeRef = InstanceIdentifier.builder(Nodes)
+            .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(node.id))
+            .toInstance
+        val reader = TypeSafeDataReader.forReader(dataService)
+        return reader.readOperationalData(nodeRef).nodeConnector
     }
 
-    override readNodeTable(NodeTable table, boolean cached) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+    override getNodeConnectorProps(Boolean refresh) {
+        // Note, because the MD-SAL has a unified data store, we can ignore the Boolean refresh, as we have no secondary 
+        // data store to refresh from
+        val props = new ConcurrentHashMap<org.opendaylight.controller.sal.core.NodeConnector, Map<String, org.opendaylight.controller.sal.core.Property>>()
+        val nodes = readAllMDNodes()
+        for (node : nodes.node) {
+            val ncs = node.readAllMDNodeConnectors
+            if(ncs != null) {
+                for( nc : ncs ) {
+                    val fcnc = nc.getAugmentation(FlowCapableNodeConnector)
+                    if(fcnc != null) {
+                        val ncps = fcnc.toADNodeConnectorProperties
+                        val ncpsm = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
+                        if(ncps != null) {
+                            for(p : ncps) {
+                                ncpsm.put(p.name,p)
+                            }
+                        }  
+                        props.put(nc.id.toADNodeConnector(node.id),ncpsm)
+                    }
+                }
+            }
+        }
+        return props
     }
 
     private def FlowCapableNode readFlowCapableNode(NodeRef ref) {
@@ -218,57 +442,159 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, IPluginInRead
     private def FlowCapableNodeConnector readFlowCapableNodeConnector(NodeConnectorRef ref) {
         val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
         val node = dataObject.checkInstanceOf(
-            org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector);
+            NodeConnector);
         return node.getAugmentation(FlowCapableNodeConnector);
     }
 
-    private static def toNodeConnectorStatistics(
-        org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics output) {
-        val it = new NodeConnectorStatistics
-
-        collisionCount = output.getCollisionCount().longValue();
-        receiveCRCErrorCount = output.getReceiveCrcError().longValue();
-        receiveFrameErrorCount = output.getReceiveFrameError().longValue();
-        receiveOverRunErrorCount = output.getReceiveOverRunError().longValue();
+    private def toNodeConnectorStatistics(
+        org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics nodeConnectorStatistics, NodeId nodeId, NodeConnectorId nodeConnectorId) {
+               
+                       val it = new NodeConnectorStatistics();
+                       
+                       receivePacketCount = nodeConnectorStatistics.packets.received.longValue;
+                       transmitPacketCount = nodeConnectorStatistics.packets.transmitted.longValue;
+                       
+                       receiveByteCount = nodeConnectorStatistics.bytes.received.longValue;
+                       transmitByteCount = nodeConnectorStatistics.bytes.transmitted.longValue;
+                       
+                       receiveDropCount = nodeConnectorStatistics.receiveDrops.longValue;
+                       transmitDropCount = nodeConnectorStatistics.transmitDrops.longValue;
+                       
+                       receiveErrorCount = nodeConnectorStatistics.receiveErrors.longValue;
+                       transmitErrorCount = nodeConnectorStatistics.transmitErrors.longValue;
+                       
+                       receiveFrameErrorCount = nodeConnectorStatistics.receiveFrameError.longValue;
+                       receiveOverRunErrorCount = nodeConnectorStatistics.receiveOverRunError.longValue;
+                       receiveCRCErrorCount = nodeConnectorStatistics.receiveCrcError.longValue;
+                       collisionCount = nodeConnectorStatistics.collisionCount.longValue;
+                       
+                       val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
+                                                               .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(nodeId))
+                                                               .child(NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance;
+                       
+                       nodeConnector = NodeMapping.toADNodeConnector(new NodeConnectorRef(nodeConnectorRef));
+                       
+                       return it;
+    }
 
-        receiveDropCount = output.getReceiveDrops().longValue();
-        receiveErrorCount = output.getReceiveErrors().longValue();
-        receivePacketCount = output.getPackets().getReceived().longValue();
-        receiveByteCount = output.getBytes().getReceived().longValue();
+       private def toNodeTableStatistics(
+               FlowTableStatistics tableStats,
+               Short tableId,Node node){
+               var it = new NodeTableStatistics();
+               
+               activeCount = tableStats.activeFlows.value.intValue;
+               lookupCount = tableStats.packetsLookedUp.value.intValue;
+               matchedCount = tableStats.packetsMatched.value.intValue;
+               name = tableId.toString;
+               nodeTable = new NodeTable(NodeMapping.MD_SAL_TYPE,tableId,node);
+               return it;
+       }
+       
+       private def toNodeDescription(NodeRef nodeRef){
+               val capableNode = readFlowCapableNode(nodeRef);
 
-        transmitDropCount = output.getTransmitDrops().longValue();
-        transmitErrorCount = output.getTransmitErrors().longValue();
-        transmitPacketCount = output.getPackets().getTransmitted().longValue();
-        transmitByteCount = output.getBytes().getTransmitted().longValue();
+        val it = new NodeDescription()
+        manufacturer = capableNode.manufacturer
+        serialNumber = capableNode.serialNumber
+        software = capableNode.software
+        description = capableNode.description
+        
         return it;
-    }
-
-    override sollicitRefresh() {
-        topologyDiscovery.solicitRefresh
-    }
-    
-    override onLinkDiscovered(LinkDiscovered notification) {
-        val update = new TopoEdgeUpdate(notification.toADEdge,Collections.emptySet(),UpdateType.ADDED);
-        discoveryPublisher.notifyEdge(notification.toADEdge,UpdateType.ADDED,Collections.emptySet());
-        topologyPublisher.edgeUpdate(Collections.singletonList(update))
-    }
-    
-    override onLinkOverutilized(LinkOverutilized notification) {
-        topologyPublisher.edgeOverUtilized(notification.toADEdge)
-    }
-    
-    override onLinkRemoved(LinkRemoved notification) {
-        val update = new TopoEdgeUpdate(notification.toADEdge,Collections.emptySet(),UpdateType.REMOVED);
-        topologyPublisher.edgeUpdate(Collections.singletonList(update))
-    }
-    
-    override onLinkUtilizationNormal(LinkUtilizationNormal notification) {
-        topologyPublisher.edgeUtilBackToNormal(notification.toADEdge)
-    }
+       }
     
     
     def Edge toADEdge(Link link) {
         new Edge(link.source.toADNodeConnector,link.destination.toADNodeConnector)
     }
-
+       
+       /*
+        * OpendaylightFlowStatisticsListener interface implementation
+        */
+       override onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
+        //Ignoring this notification as there does not seem to be a way to bubble this up to AD-SAL
+       }
+       
+       override onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) {
+               
+               val adsalFlowsStatistics = new ArrayList<FlowOnNode>();
+               
+               for(flowStats : notification.flowAndStatisticsMapList){
+                       if(flowStats.tableId == 0)
+                               adsalFlowsStatistics.add(toFlowOnNode(flowStats));
+               }
+               
+               for (statsPublisher : statisticsPublisher){
+                       val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
+                       statsPublisher.nodeFlowStatisticsUpdated(nodeRef.toADNode,adsalFlowsStatistics);
+               }
+               
+       }
+       /*
+        * OpendaylightFlowTableStatisticsListener interface implementation
+        */     
+       override onFlowTableStatisticsUpdate(FlowTableStatisticsUpdate notification) {
+               var adsalFlowTableStatistics = new ArrayList<NodeTableStatistics>();
+               
+               for(stats : notification.flowTableAndStatisticsMap){
+                       if (stats.tableId.value == 0){
+                               val it = new NodeTableStatistics();
+                               activeCount = stats.activeFlows.value.intValue;
+                               lookupCount = stats.packetsLookedUp.value.longValue;
+                               matchedCount = stats.packetsMatched.value.longValue;
+                               
+                               adsalFlowTableStatistics.add(it);
+                       }
+               }
+               for (statsPublisher : statisticsPublisher){
+                       val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
+                       statsPublisher.nodeTableStatisticsUpdated(nodeRef.toADNode,adsalFlowTableStatistics);
+               }
+       }
+       
+       /*
+        * OpendaylightPortStatisticsUpdate interface implementation
+        */
+       override onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
+               
+               val adsalPortStatistics  = new ArrayList<NodeConnectorStatistics>();
+               
+               for(nodeConnectorStatistics : notification.nodeConnectorStatisticsAndPortNumberMap){
+                       adsalPortStatistics.add(toNodeConnectorStatistics(nodeConnectorStatistics,notification.id,nodeConnectorStatistics.nodeConnectorId));
+               }
+               
+               for (statsPublisher : statisticsPublisher){
+                       val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
+                       statsPublisher.nodeConnectorStatisticsUpdated(nodeRef.toADNode,adsalPortStatistics);
+               }
+               
+       }
+       
+       private static def toFlowOnNode (FlowAndStatisticsMapList flowAndStatsMap){
+               
+               val it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap));
+               
+               byteCount = flowAndStatsMap.byteCount.value.longValue;
+               packetCount = flowAndStatsMap.packetCount.value.longValue;
+               durationSeconds = flowAndStatsMap.duration.second.value.intValue;
+               durationNanoseconds = flowAndStatsMap.duration.nanosecond.value.intValue;
+               
+               return it;
+       }
+
+       override  getConfiguredNotConnectedNodes() {
+        return Collections.emptySet();
+       }
+
+
+       private def publishNodeUpdate(Node node, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
+           for( publisher : inventoryPublisher){
+               publisher.updateNode(node, updateType, properties);
+           }
+       }
+
+       private def publishNodeConnectorUpdate(org.opendaylight.controller.sal.core.NodeConnector nodeConnector, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
+           for( publisher : inventoryPublisher){
+               publisher.updateNodeConnector(nodeConnector, updateType, properties);
+           }
+       }
 }
index 6cf728cde967d2ca1ed250dc93198a061a226795..5a91e919dd0e2667dafaad0a6a166a730df94ae2 100644 (file)
@@ -5,7 +5,6 @@ import java.math.BigInteger
 import java.net.Inet4Address
 import java.net.Inet6Address
 import java.util.ArrayList
-import java.util.List
 import org.opendaylight.controller.sal.action.Controller
 import org.opendaylight.controller.sal.action.Drop
 import org.opendaylight.controller.sal.action.Flood
@@ -40,7 +39,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddF
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsInputBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder
@@ -67,7 +65,6 @@ 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.hw.path.action._case.HwPathActionBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.loopback.action._case.LoopbackActionBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.dst.action._case.SetDlDstActionBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.src.action._case.SetDlSrcActionBuilder
@@ -106,6 +103,9 @@ 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.SwPathActionCaseBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId
 
 public class MDFlowMapping {
 
@@ -130,34 +130,52 @@ public class MDFlowMapping {
         }
         instructions = targetActions.toApplyInstruction();
         match = sourceFlow.match.toMatch();
+        tableId = new Integer(0).shortValue
         return it.build();
 
     }
     
+    public static def toMDFlow(Flow sourceFlow, String flowId) {
+       if (sourceFlow == null)
+            throw new IllegalArgumentException();
+       val it = new FlowBuilder();
+       hardTimeout = sourceFlow.hardTimeout as int
+       idleTimeout = sourceFlow.idleTimeout as int
+       cookie = BigInteger.valueOf(sourceFlow.id)
+       priority = sourceFlow.priority as int
+       id = new FlowId(flowId)
+    
+       val sourceActions = sourceFlow.actions;
+       val targetActions = new ArrayList<Action>();
+       for (sourceAction : sourceActions) {
+           targetActions.add(sourceAction.toAction());
+       }
+       instructions = targetActions.toApplyInstruction();
+       match = sourceFlow.match.toMatch();
+       tableId = new Integer(0).shortValue
+       return it.build();
+    }
+    
     public static def Instructions toApplyInstruction(ArrayList<Action> actions) {
         val it = new InstructionsBuilder;
         val applyActions = new InstructionBuilder;
         applyActions.instruction = new ApplyActionsCaseBuilder().setApplyActions(new ApplyActionsBuilder().setAction(actions).build()).build()
+        applyActions.setOrder(new Integer(0))
         instruction = Collections.<Instruction>singletonList(applyActions.build)
         return it.build;
     }
 
-    public static def flowStatisticsInput(Node sourceNode, Flow sourceFlow) {
-        val source = flowAdded(sourceFlow);
-        val it = new GetFlowStatisticsInputBuilder(source as org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow);
-        node = sourceNode.toNodeRef();
-        return it.build();
-    }
-
     public static def removeFlowInput(Node sourceNode, Flow sourceFlow) {
         val source = flowAdded(sourceFlow);
         val it = new RemoveFlowInputBuilder(source as org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow);
+        node = sourceNode.toNodeRef()
         return it.build();
     }
 
     public static def addFlowInput(Node sourceNode, Flow sourceFlow) {
         val source = flowAdded(sourceFlow);
         val it = new AddFlowInputBuilder(source as org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow);
+        it.setNode(sourceNode.toNodeRef)
         return it.build();
     }
 
@@ -355,7 +373,7 @@ public class MDFlowMapping {
     }
 
     public static def Uri toUri(NodeConnector connector) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        return new NodeConnectorId(connector.ID as String);
     }
 
     public static def MacAddress toMacAddress(byte[] bytes) {
@@ -367,4 +385,25 @@ public class MDFlowMapping {
         }
         return new MacAddress(sb.toString());
     }
+       
+       public static def toMDSalflow(Flow sourceFlow) {
+        if (sourceFlow == null)
+            throw new IllegalArgumentException();
+        val it = new FlowBuilder();
+
+        hardTimeout = sourceFlow.hardTimeout as int
+        idleTimeout = sourceFlow.idleTimeout as int
+        cookie = BigInteger.valueOf(sourceFlow.id)
+        priority = sourceFlow.priority as int
+
+        val sourceActions = sourceFlow.actions;
+        val targetActions = new ArrayList<Action>();
+        for (sourceAction : sourceActions) {
+            targetActions.add(sourceAction.toAction());
+        }
+        instructions = targetActions.toApplyInstruction();
+        match = sourceFlow.match.toMatch();
+        return it.build();
+       }
+       
 }
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDSalNodeConnectorFactory.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDSalNodeConnectorFactory.java
new file mode 100644 (file)
index 0000000..5b4b16a
--- /dev/null
@@ -0,0 +1,23 @@
+package org.opendaylight.controller.sal.compatibility;
+
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.utils.INodeConnectorFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MDSalNodeConnectorFactory implements INodeConnectorFactory{
+    private Logger logger = LoggerFactory.getLogger(MDSalNodeConnectorFactory.class);
+
+    @Override
+    public NodeConnector fromStringNoNode(String type, String id, Node node) {
+        try {
+            return new NodeConnector(type, id, node);
+        } catch (ConstructionException e) {
+            logger.error("Could not construct NodeConnector", e);
+        }
+        return null;
+
+    }
+}
index 0c1ee781ac000df073825c8701dbfef44bfaaada..e36ebd7245aa0d31d8393b17ca5e2b1ee78c62e7 100644 (file)
@@ -3,8 +3,6 @@ package org.opendaylight.controller.sal.compatibility;
 import org.opendaylight.controller.sal.core.ConstructionException;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.utils.INodeFactory;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -15,7 +13,7 @@ public class MDSalNodeFactory implements INodeFactory{
     public Node fromString(String type, String id) {
 
         try {
-            return new Node(type, new NodeKey(new NodeId(id)));
+            return new Node(type, id);
         } catch (ConstructionException e) {
             logger.error("Could not construct Node", e);
         }
index 4c9a9e6658145c481c153e9747434ef65b395443..4378e7dffece701592936ce85dba77884c6ce8d8 100644 (file)
@@ -7,13 +7,48 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableIt
 
 import static com.google.common.base.Preconditions.*;
 import static extension org.opendaylight.controller.sal.common.util.Arguments.*;
+import static extension org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils.*;
 
 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.opendaylight.inventory.rev130819.NodeConnectorId
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
 import org.opendaylight.controller.sal.core.ConstructionException
 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.NodeId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures
+import org.opendaylight.controller.sal.core.Bandwidth
+import org.opendaylight.controller.sal.core.AdvertisedBandwidth
+import org.opendaylight.controller.sal.core.SupportedBandwidth
+import org.opendaylight.controller.sal.core.PeerBandwidth
+import org.opendaylight.controller.sal.core.Name
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig
+import org.opendaylight.controller.sal.core.Config
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.flow.capable.port.State
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
+import java.util.HashSet
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated
+import org.opendaylight.controller.sal.core.Tables
+import java.util.List
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FeatureCapability
+import org.opendaylight.controller.sal.core.Buffers
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityFlowStats
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityTableStats
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityIpReasm
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityPortStats
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityStp
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityQueueStats
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityArpMatchIp
+import org.opendaylight.controller.sal.core.Capabilities
+import org.opendaylight.controller.sal.core.MacAddress
+import java.util.Date
+import org.opendaylight.controller.sal.core.TimeStamp
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNodeConnector
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNode
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
 
 public class NodeMapping {
 
@@ -27,29 +62,80 @@ public class NodeMapping {
     }
 
     public static def toADNode(InstanceIdentifier<?> node) throws ConstructionException {
+        return node.toNodeId.toADNode
+    }
+
+    public static def toADNode(NodeId id) {
+        return new Node(MD_SAL_TYPE, id.toADNodeId);
+    }
+
+    public static def toNodeId(InstanceIdentifier<?> node) {
         checkNotNull(node);
         checkNotNull(node.getPath());
         checkArgument(node.getPath().size() >= 2);
         val arg = node.getPath().get(1);
         val item = arg.checkInstanceOf(IdentifiableItem);
         val nodeKey = item.getKey().checkInstanceOf(NodeKey);
-        return new Node(MD_SAL_TYPE, nodeKey);
+        return nodeKey.id
+    }
+
+    public static def toADNodeId(NodeId nodeId) {
+        checkNotNull(nodeId);
+        return nodeId.value
     }
 
     public static def toADNodeConnector(NodeConnectorRef source) throws ConstructionException {
         checkNotNull(source);
         val InstanceIdentifier<?> path = checkNotNull(source.getValue());
-        val node = path.toADNode();
         checkArgument(path.path.size() >= 3);
         val arg = path.getPath().get(2);
         val item = arg.checkInstanceOf(IdentifiableItem);
         val connectorKey = item.getKey().checkInstanceOf(NodeConnectorKey);
-        return new NodeConnector(MD_SAL_TYPE, connectorKey, node);
+        return connectorKey.id.toADNodeConnector(path.toNodeId)
+    }
+    
+    public static def toADNodeConnector(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId ncid,
+        org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId nid) {
+            return new NodeConnector(ncid.toNodeConnectorType(nid),
+            ncid.toADNodeConnectorId(nid), nid.toADNode);
+     }
+
+    public static def toNodeConnectorType(NodeConnectorId ncId, NodeId nodeId) {
+        if (ncId.equals(nodeId.toLocalNodeConnectorId)) {
+            return NodeConnector.NodeConnectorIDType.SWSTACK
+        } else if (ncId.equals(nodeId.toNormalNodeConnectorId)) {
+            return NodeConnector.NodeConnectorIDType.HWPATH
+        } else if (ncId.equals(nodeId.toControllerNodeConnectorId)) {
+            return NodeConnector.NodeConnectorIDType.CONTROLLER
+        }
+        return MD_SAL_TYPE
+    }
+
+    public static def toADNodeConnectorId(NodeConnectorId nodeConnectorId, NodeId nodeId) {
+        if (nodeConnectorId.equals(nodeId.toLocalNodeConnectorId) ||
+            nodeConnectorId.equals(nodeId.toNormalNodeConnectorId) ||
+            nodeConnectorId.equals(nodeId.toControllerNodeConnectorId)) {
+            return NodeConnector.SPECIALNODECONNECTORID
+        }
+        return nodeConnectorId.value
+    }
+
+    public static def toControllerNodeConnectorId(NodeId node) {
+        return new NodeConnectorId(node.value + ":" + 4294967293L)
+    }
+
+    public static def toLocalNodeConnectorId(NodeId node) {
+        return new NodeConnectorId(node.value + ":" + 4294967294L)
+    }
+
+    public static def toNormalNodeConnectorId(NodeId node) {
+        return new NodeConnectorId(node.value + ":" + 4294967290L)
     }
 
     public static def toNodeRef(Node node) {
         checkArgument(MD_SAL_TYPE.equals(node.getType()));
-        val nodeKey = node.ID.checkInstanceOf(NodeKey);
+        var nodeId = node.ID.checkInstanceOf(String)
+        val nodeKey = new NodeKey(new NodeId(nodeId));
         val nodePath = InstanceIdentifier.builder().node(Nodes).child(NODE_CLASS, nodeKey).toInstance();
         return new NodeRef(nodePath);
     }
@@ -57,7 +143,19 @@ public class NodeMapping {
     public static def toNodeConnectorRef(NodeConnector nodeConnector) {
         val node = nodeConnector.node.toNodeRef();
         val nodePath = node.getValue() as InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node>
-        val connectorKey = nodeConnector.ID.checkInstanceOf(NodeConnectorKey);
+        var NodeConnectorId nodeConnectorId
+        if (nodeConnector.ID.equals(NodeConnector.SPECIALNODECONNECTORID)) {
+            if (nodeConnector.type.equals(NodeConnector.NodeConnectorIDType.SWSTACK)) {
+                nodeConnectorId = nodePath.toNodeId.toLocalNodeConnectorId
+            } else if (nodeConnector.type.equals(NodeConnector.NodeConnectorIDType.HWPATH)) {
+                nodeConnectorId = nodePath.toNodeId.toNormalNodeConnectorId
+            } else if (nodeConnector.type.equals(NodeConnector.NodeConnectorIDType.CONTROLLER)) {
+                nodeConnectorId = nodePath.toNodeId.toControllerNodeConnectorId
+            }
+        } else {
+            nodeConnectorId = new NodeConnectorId(nodeConnector.ID.checkInstanceOf(String))
+        }
+        val connectorKey = new NodeConnectorKey(nodeConnectorId);
         val path = InstanceIdentifier.builder(nodePath).child(NODECONNECTOR_CLASS, connectorKey).toInstance();
         return new NodeConnectorRef(path);
     }
@@ -66,4 +164,194 @@ public class NodeMapping {
         return toADNode(node.getValue());
     }
 
+    public static def toADNodeConnectorProperties(NodeConnectorUpdated nc) {
+        val fcncu = nc.getAugmentation(FlowCapableNodeConnectorUpdated)
+        if (fcncu != null) {
+            return fcncu.toADNodeConnectorProperties
+        }
+        return new HashSet<org.opendaylight.controller.sal.core.Property>();
+    }
+
+    public static def toADNodeConnectorProperties(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector nc) {
+        val fcnc = nc.getAugmentation(FlowCapableNodeConnector)
+        if (fcnc != null) {
+            return fcnc.toADNodeConnectorProperties
+        }
+        return new HashSet<org.opendaylight.controller.sal.core.Property>();
+    }
+
+    public static def toADNodeConnectorProperties(FlowNodeConnector fcncu) {
+        val props = new HashSet<org.opendaylight.controller.sal.core.Property>();
+        if (fcncu != null) {
+            if (fcncu.currentFeature != null && fcncu.currentFeature.toAdBandwidth != null) {
+                props.add(fcncu.currentFeature.toAdBandwidth)
+            }
+            if (fcncu.advertisedFeatures != null && fcncu.advertisedFeatures.toAdAdvertizedBandwidth != null) {
+                props.add(fcncu.advertisedFeatures.toAdAdvertizedBandwidth)
+            }
+            if (fcncu.supported != null && fcncu.supported.toAdSupportedBandwidth != null) {
+                props.add(fcncu.supported.toAdSupportedBandwidth)
+            }
+            if (fcncu.peerFeatures != null && fcncu.peerFeatures.toAdPeerBandwidth != null) {
+                props.add(fcncu.peerFeatures.toAdPeerBandwidth)
+            }
+            if (fcncu.name != null && fcncu.name.toAdName != null) {
+                props.add(fcncu.name.toAdName)
+            }
+            if (fcncu.configuration != null && fcncu.configuration.toAdConfig != null) {
+                props.add(fcncu.configuration.toAdConfig)
+            }
+            if (fcncu.state != null && fcncu.state.toAdState != null) {
+                props.add(fcncu.state.toAdState)
+            }
+        }
+        return props
+    }
+
+    public static def toAdName(String name) {
+        return new Name(name)
+    }
+
+    public static def toAdConfig(PortConfig pc) {
+        var Config config;
+        if (pc.PORTDOWN) {
+            config = new Config(Config.ADMIN_DOWN)
+        } else {
+            config = new Config(Config.ADMIN_UP)
+        }
+        return config
+    }
+
+    public static def toAdState(State s) {
+        var org.opendaylight.controller.sal.core.State state
+        if (s.linkDown) {
+            state = new org.opendaylight.controller.sal.core.State(org.opendaylight.controller.sal.core.State.EDGE_DOWN)
+        } else {
+            state = new org.opendaylight.controller.sal.core.State(org.opendaylight.controller.sal.core.State.EDGE_UP)
+        }
+        return state
+    }
+
+    public static def toAdBandwidth(PortFeatures pf) {
+        var Bandwidth bw = null
+        if (pf.is_10mbHd || pf.is_10mbFd) {
+            bw = new Bandwidth(Bandwidth.BW10Mbps)
+        } else if (pf.is_100mbHd || pf.is_100mbFd) {
+            bw = new Bandwidth(Bandwidth.BW100Mbps)
+        } else if (pf.is_1gbHd || pf.is_1gbFd) {
+            bw = new Bandwidth(Bandwidth.BW1Gbps)
+        } else if (pf.is_1gbFd) {
+            bw = new Bandwidth(Bandwidth.BW10Gbps)
+        } else if (pf.is_10gbFd) {
+            bw = new Bandwidth(Bandwidth.BW10Gbps)
+        } else if (pf.is_40gbFd) {
+            bw = new Bandwidth(Bandwidth.BW40Gbps)
+        } else if (pf.is_100gbFd) {
+            bw = new Bandwidth(Bandwidth.BW100Gbps)
+        } else if (pf.is_1tbFd) {
+            bw = new Bandwidth(Bandwidth.BW1Tbps)
+        }
+        return bw;
+    }
+
+    public static def toAdAdvertizedBandwidth(PortFeatures pf) {
+        var AdvertisedBandwidth abw
+        val bw = pf.toAdBandwidth
+        if (bw != null) {
+            abw = new AdvertisedBandwidth(bw.value)
+        }
+        return abw
+    }
+
+    public static def toAdSupportedBandwidth(PortFeatures pf) {
+        var SupportedBandwidth sbw
+        val bw = pf.toAdBandwidth
+        if (bw != null) {
+            sbw = new SupportedBandwidth(bw.value)
+        }
+        return sbw
+    }
+
+    public static def toAdPeerBandwidth(PortFeatures pf) {
+        var PeerBandwidth pbw
+        val bw = pf.toAdBandwidth
+        if (bw != null) {
+            pbw = new PeerBandwidth(bw.value)
+        }
+        return pbw
+    }
+
+    public static def toADNodeProperties(NodeUpdated nu) {
+        val fcnu = nu.getAugmentation(FlowCapableNodeUpdated)
+        if (fcnu != null) {
+            return fcnu.toADNodeProperties(nu.id)
+        }
+        return new HashSet<org.opendaylight.controller.sal.core.Property>();
+
+    }
+
+    public static def toADNodeProperties(FlowNode fcnu, NodeId id) {
+        val props = new HashSet<org.opendaylight.controller.sal.core.Property>();
+        if (fcnu != null) {
+            props.add(toADTimestamp)
+
+            // props.add(fcnu.supportedActions.toADActions) - TODO
+            if (id != null) {
+                props.add(id.toADMacAddress)
+            }
+            if (fcnu.switchFeatures != null) {
+                if (fcnu.switchFeatures.maxTables != null) {
+                    props.add(fcnu.switchFeatures.maxTables.toADTables)
+                }
+                if (fcnu.switchFeatures.capabilities != null) {
+                    props.add(fcnu.switchFeatures.capabilities.toADCapabiliities)
+                }
+                if (fcnu.switchFeatures.maxBuffers != null) {
+                    props.add(fcnu.switchFeatures.maxBuffers.toADBuffers)
+                }
+            }
+        }
+        return props;
+    }
+
+    public static def toADTimestamp() {
+        val date = new Date();
+        val timestamp = new TimeStamp(date.time, "connectedSince")
+        return timestamp;
+    }
+
+    public static def toADMacAddress(NodeId id) {
+        return new MacAddress(Long.parseLong(id.value.replaceAll("openflow:", "")).longValue.bytesFromDpid)
+    }
+
+    public static def toADTables(Short tables) {
+        return new Tables(tables.byteValue)
+    }
+
+    public static def toADCapabiliities(List<Class<? extends FeatureCapability>> capabilities) {
+        var int b
+        for (capability : capabilities) {
+            if (capability.equals(FlowFeatureCapabilityFlowStats)) {
+                b = Capabilities.CapabilitiesType.FLOW_STATS_CAPABILITY.value.bitwiseOr(b)
+            } else if (capability.equals(FlowFeatureCapabilityTableStats)) {
+                b = Capabilities.CapabilitiesType.TABLE_STATS_CAPABILITY.value.bitwiseOr(b)
+            } else if (capability.equals(FlowFeatureCapabilityPortStats)) {
+                b = Capabilities.CapabilitiesType.PORT_STATS_CAPABILITY.value.bitwiseOr(b)
+            } else if (capability.equals(FlowFeatureCapabilityStp)) {
+                b = Capabilities.CapabilitiesType.STP_CAPABILITY.value.bitwiseOr(b)
+            } else if (capability.equals(FlowFeatureCapabilityIpReasm)) {
+                b = Capabilities.CapabilitiesType.IP_REASSEM_CAPABILITY.value.bitwiseOr(b)
+            } else if (capability.equals(FlowFeatureCapabilityQueueStats)) {
+                b = Capabilities.CapabilitiesType.QUEUE_STATS_CAPABILITY.value.bitwiseOr(b)
+            } else if (capability.equals(FlowFeatureCapabilityArpMatchIp)) {
+                b = Capabilities.CapabilitiesType.ARP_MATCH_IP_CAPABILITY.value.bitwiseOr(b)
+            }
+        }
+        return new Capabilities(b)
+    }
+
+    public static def toADBuffers(Long buffers) {
+        return new Buffers(buffers.intValue)
+    }
+
 }
index a8349be1b410f2abcd3714de6ba141e8257c02d0..46fd62f3f2790dbd7223b9cba53af42284c57ef1 100644 (file)
@@ -1,6 +1,25 @@
 package org.opendaylight.controller.sal.compatibility;
 
-import com.google.common.net.InetAddresses;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.CRUDP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP;
+import static org.opendaylight.controller.sal.match.MatchType.DL_DST;
+import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
+import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE;
+import static org.opendaylight.controller.sal.match.MatchType.DL_VLAN;
+import static org.opendaylight.controller.sal.match.MatchType.DL_VLAN_PR;
+import static org.opendaylight.controller.sal.match.MatchType.NW_DST;
+import static org.opendaylight.controller.sal.match.MatchType.NW_PROTO;
+import static org.opendaylight.controller.sal.match.MatchType.NW_SRC;
+import static org.opendaylight.controller.sal.match.MatchType.NW_TOS;
+import static org.opendaylight.controller.sal.match.MatchType.TP_DST;
+import static org.opendaylight.controller.sal.match.MatchType.TP_SRC;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 import org.opendaylight.controller.sal.action.Controller;
 import org.opendaylight.controller.sal.action.Drop;
@@ -24,6 +43,7 @@ import org.opendaylight.controller.sal.action.SetVlanCfi;
 import org.opendaylight.controller.sal.action.SetVlanId;
 import org.opendaylight.controller.sal.action.SetVlanPcp;
 import org.opendaylight.controller.sal.action.SwPath;
+import org.opendaylight.controller.sal.core.Capabilities;
 import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.flowprogrammer.Flow;
 import org.opendaylight.controller.sal.match.Match;
@@ -33,7 +53,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.ActionList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.ControllerActionCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCase;
@@ -67,6 +86,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FeatureCapability;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
@@ -88,26 +108,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanId;
 
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP;
-import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.CRUDP;
-import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP;
-import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP;
-import static org.opendaylight.controller.sal.match.MatchType.DL_DST;
-import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
-import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE;
-import static org.opendaylight.controller.sal.match.MatchType.DL_VLAN;
-import static org.opendaylight.controller.sal.match.MatchType.DL_VLAN_PR;
-import static org.opendaylight.controller.sal.match.MatchType.NW_DST;
-import static org.opendaylight.controller.sal.match.MatchType.NW_PROTO;
-import static org.opendaylight.controller.sal.match.MatchType.NW_SRC;
-import static org.opendaylight.controller.sal.match.MatchType.NW_TOS;
-import static org.opendaylight.controller.sal.match.MatchType.TP_DST;
-import static org.opendaylight.controller.sal.match.MatchType.TP_SRC;
+import com.google.common.net.InetAddresses;
 
 public class ToSalConversionsUtils {
 
@@ -484,11 +485,11 @@ public class ToSalConversionsUtils {
     private static void fillFromArp(Match target, ArpMatch source) {
         Ipv4Prefix sourceAddress = source.getArpSourceTransportAddress();
         if (sourceAddress != null) {
-            target.setField(NW_SRC, (InetAddress) inetAddressFrom(sourceAddress), null);
+            target.setField(NW_SRC, inetAddressFrom(sourceAddress), null);
         }
         Ipv4Prefix destAddress = source.getArpTargetTransportAddress();
         if (destAddress != null) {
-            target.setField(NW_DST, (InetAddress) inetAddressFrom(destAddress), null);
+            target.setField(NW_DST, inetAddressFrom(destAddress), null);
         }
         ArpSourceHardwareAddress sourceHwAddress = source.getArpSourceHardwareAddress();
         if (sourceHwAddress != null) {
@@ -506,22 +507,22 @@ public class ToSalConversionsUtils {
     private static void fillFromIpv6(Match target, Ipv6Match source) {
         Ipv6Prefix sourceAddress = source.getIpv6Source();
         if (sourceAddress != null) {
-            target.setField(NW_SRC, (InetAddress) inetAddressFrom(sourceAddress), null);
+            target.setField(NW_SRC, inetAddressFrom(sourceAddress), null);
         }
         Ipv6Prefix destAddress = source.getIpv6Destination();
         if (destAddress != null) {
-            target.setField(NW_DST, (InetAddress) inetAddressFrom(destAddress), null);
+            target.setField(NW_DST, inetAddressFrom(destAddress), null);
         }
     }
 
     private static void fillFromIpv4(Match target, Ipv4Match source) {
         Ipv4Prefix sourceAddress = source.getIpv4Source();
         if (sourceAddress != null) {
-            target.setField(NW_SRC, (InetAddress) inetAddressFrom(sourceAddress), null);
+            target.setField(NW_SRC, inetAddressFrom(sourceAddress), null);
         }
         Ipv4Prefix destAddress = source.getIpv4Destination();
         if (destAddress != null) {
-            target.setField(NW_DST, (InetAddress) inetAddressFrom(destAddress), null);
+            target.setField(NW_DST, inetAddressFrom(destAddress), null);
         }
     }
 
@@ -564,7 +565,7 @@ public class ToSalConversionsUtils {
         }
     }
 
-    private static byte[] bytesFrom(MacAddress address) {
+    public static byte[] bytesFrom(MacAddress address) {
         String[] mac = address.getValue().split(":");
         byte[] macAddress = new byte[6]; // mac.length == 6 bytes
         for (int i = 0; i < mac.length; i++) {
@@ -572,4 +573,15 @@ public class ToSalConversionsUtils {
         }
         return macAddress;
     }
+    
+    public static byte[] bytesFromDpid(long dpid) {
+        byte[] mac = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+        for (short i = 0; i < 6; i++) {
+            mac[5 - i] = (byte) dpid;
+            dpid >>= 8;
+        }
+
+        return mac;
+    }
 }
index aa67600124e8ebc229b46c3d391f09011b604ce7..edd3a27255d48dc27f3e67ff808a6ca7c8ce440b 100644 (file)
@@ -3,7 +3,6 @@ package org.opendaylight.controller.sal.compatibility.adsal;
 import org.opendaylight.controller.sal.compatibility.NodeMapping;
 import org.opendaylight.controller.sal.packet.IPluginInDataPacketService;
 import org.opendaylight.controller.sal.packet.RawPacket;
-import org.opendaylight.controller.sal.packet.RawPacket;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
@@ -22,8 +21,12 @@ public class DataPacketServiceAdapter implements IPluginInDataPacketService {
     private TransmitPacketInput toTransmitPacketInput(RawPacket rawPacket) {
         TransmitPacketInputBuilder builderTPIB = new TransmitPacketInputBuilder();
 
-        NodeConnectorRef egress = NodeMapping.toNodeConnectorRef(rawPacket.getOutgoingNodeConnector());
-        NodeConnectorRef ingress = NodeMapping.toNodeConnectorRef(rawPacket.getIncomingNodeConnector());
+        builderTPIB.setNode(NodeMapping.toNodeRef(rawPacket.getOutgoingNodeConnector().getNode()));
+
+        NodeConnectorRef egress = rawPacket.getOutgoingNodeConnector() == null ? null :
+                NodeMapping.toNodeConnectorRef(rawPacket.getOutgoingNodeConnector());
+        NodeConnectorRef ingress = rawPacket.getIncomingNodeConnector() == null ? null :
+                NodeMapping.toNodeConnectorRef(rawPacket.getIncomingNodeConnector());
         byte[] payload = rawPacket.getPacketData();
 
         builderTPIB.setEgress(egress);
@@ -33,4 +36,14 @@ public class DataPacketServiceAdapter implements IPluginInDataPacketService {
         return builderTPIB.build();
     }
 
+    public PacketProcessingService getDelegate() {
+        return delegate;
+    }
+
+    public void setDelegate(PacketProcessingService delegate) {
+        this.delegate = delegate;
+    }
+
+
+
 }
index 09585d6273a0c2cecd32e90d4f442313bf685946..149544b6c4e76509af96635ccc7fd21423dc9935 100644 (file)
@@ -8,6 +8,8 @@ import java.util.concurrent.Future;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.common.util.Futures;
 import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.compatibility.FromSalConversionsUtils;
+import org.opendaylight.controller.sal.compatibility.InventoryMapping;
 import org.opendaylight.controller.sal.compatibility.NodeMapping;
 import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils;
 import org.opendaylight.controller.sal.core.ConstructionException;
@@ -19,87 +21,78 @@ import org.opendaylight.controller.sal.reader.IReadServiceListener;
 import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
 import org.opendaylight.controller.sal.reader.NodeDescription;
 import org.opendaylight.controller.sal.reader.NodeTableStatistics;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter32;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter64;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllNodeConnectorStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllNodeConnectorStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllNodeConnectorStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowTableStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowTableStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowTableStatisticsOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.NodeConnectorStatisticsUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.flow.statistics.output.FlowStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.flow.statistics.output.FlowStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.node.connector.statistics.output.NodeConnectorStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.statistics.Duration;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.statistics.DurationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.Bytes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.Packets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService, IReadServiceListener {
+public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService, IReadServiceListener{
 
     private static final Logger LOG = LoggerFactory.getLogger(FlowStatisticsAdapter.class);
     private IReadService readDelegate;
     private NotificationProviderService notifier;
 
     @Override
-    public Future<RpcResult<GetAllFlowStatisticsOutput>> getAllFlowStatistics(GetAllFlowStatisticsInput input) {
-        GetAllFlowStatisticsOutput rpcResultType = null;
-        boolean rpcResultBool = false;
-
-        try {
-            Node adNode = NodeMapping.toADNode(input.getNode());
-            List<FlowOnNode> flowsOnNode = readDelegate.readAllFlows(adNode);
-            List<FlowStatistics> flowsStatistics = toOdFlowsStatistics(flowsOnNode);
-            GetAllFlowStatisticsOutputBuilder builder = new GetAllFlowStatisticsOutputBuilder();
-            rpcResultType = builder.setFlowStatistics(flowsStatistics).build();
-            rpcResultBool = true;
-        } catch (ConstructionException e) {
-            LOG.error(e.getMessage());
-        }
+    public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> getAggregateFlowStatisticsFromFlowTableForAllFlows(
+            GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput input) {
+        //TODO: No supported API exist in AD-SAL, it can either be implemented by fetching all the stats of the flows and 
+        // generating aggregate flow statistics out of those individual flow stats.
+        return null;
+    }
 
-        return Futures.immediateFuture(Rpcs.getRpcResult(rpcResultBool, rpcResultType, null));
+    @Override
+    public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> getAggregateFlowStatisticsFromFlowTableForGivenMatch(
+            GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
+        //TODO: No supported API exist in AD-SAL, it can either be implemented by fetching all the stats of the flows and 
+        // generating aggregate flow statistics out of those individual flow stats.
+        return null;
     }
 
     @Override
-    public Future<RpcResult<GetAllNodeConnectorStatisticsOutput>> getAllNodeConnectorStatistics(
-            GetAllNodeConnectorStatisticsInput input) {
-        GetAllNodeConnectorStatisticsOutput rpcResultType = null;
+    public Future<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> getAllFlowStatisticsFromFlowTable(
+            GetAllFlowStatisticsFromFlowTableInput input) {
+        GetAllFlowStatisticsFromFlowTableOutput rpcResultType = null;
         boolean rpcResultBool = false;
 
         try {
             Node adNode = NodeMapping.toADNode(input.getNode());
-            List<NodeConnectorStatistics> nodesConnectorStatistics = readDelegate.readNodeConnectors(adNode);
-            List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.node.connector.statistics.output.NodeConnectorStatistics> odNodesConnectorStatistics;
-            odNodesConnectorStatistics = toOdNodesConnectorStatistics(nodesConnectorStatistics);
-            GetAllNodeConnectorStatisticsOutputBuilder builder = new GetAllNodeConnectorStatisticsOutputBuilder();
-            rpcResultType = builder.setNodeConnectorStatistics(odNodesConnectorStatistics).build();
+            List<FlowOnNode> flowsOnNode = readDelegate.readAllFlows(adNode);
+            List<FlowAndStatisticsMapList> flowsStatistics = toOdFlowsStatistics(flowsOnNode);
+            GetAllFlowStatisticsFromFlowTableOutputBuilder builder = new GetAllFlowStatisticsFromFlowTableOutputBuilder();
+            builder.setTransactionId(new TransactionId(new BigInteger("0")));
+            rpcResultType = builder.setFlowAndStatisticsMapList(flowsStatistics).build();
+            
             rpcResultBool = true;
         } catch (ConstructionException e) {
             LOG.error(e.getMessage());
@@ -108,17 +101,24 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
         return Futures.immediateFuture(Rpcs.getRpcResult(rpcResultBool, rpcResultType, null));
     }
 
+    /**
+     * Essentially this API will return the same result as getAllFlowStatisticsFromFlowTable
+     */
     @Override
-    public Future<RpcResult<GetFlowStatisticsOutput>> getFlowStatistics(GetFlowStatisticsInput input) {
-        GetFlowStatisticsOutput rpcResultType = null;
+    public Future<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> getAllFlowsStatisticsFromAllFlowTables(
+            GetAllFlowsStatisticsFromAllFlowTablesInput input) {
+        
+        GetAllFlowsStatisticsFromAllFlowTablesOutput rpcResultType = null;
         boolean rpcResultBool = false;
 
         try {
-            Node node = NodeMapping.toADNode(input.getNode());
-            Flow flow = ToSalConversionsUtils.toFlow(input);
-            FlowOnNode readFlow = readDelegate.readFlow(node, flow);
-            FlowStatistics flowOnNodeToFlowStatistics = toOdFlowStatistics(readFlow);
-            rpcResultType = new GetFlowStatisticsOutputBuilder(flowOnNodeToFlowStatistics).build();
+            Node adNode = NodeMapping.toADNode(input.getNode());
+            List<FlowOnNode> flowsOnNode = readDelegate.readAllFlows(adNode);
+            List<FlowAndStatisticsMapList> flowsStatistics = toOdFlowsStatistics(flowsOnNode);
+            GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder builder = new GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder();
+            builder.setTransactionId(new TransactionId(new BigInteger("0")));
+            rpcResultType = builder.setFlowAndStatisticsMapList(flowsStatistics).build();
+            
             rpcResultBool = true;
         } catch (ConstructionException e) {
             LOG.error(e.getMessage());
@@ -128,38 +128,18 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
     }
 
     @Override
-    public Future<RpcResult<GetFlowTableStatisticsOutput>> getFlowTableStatistics(GetFlowTableStatisticsInput input) {
-        GetFlowTableStatisticsOutput rpcResultType = null;
+    public Future<RpcResult<GetFlowStatisticsFromFlowTableOutput>> getFlowStatisticsFromFlowTable(
+            GetFlowStatisticsFromFlowTableInput input) {
+        GetFlowStatisticsFromFlowTableOutput rpcResultType = null;
         boolean rpcResultBool = false;
 
         try {
             Node node = NodeMapping.toADNode(input.getNode());
-            List<NodeTableStatistics> nodesTable = readDelegate.readNodeTable(node);
-            NodeTableStatistics nodeTable = null;
-            if (!nodesTable.isEmpty()) {
-                nodeTable = nodesTable.get(0);
-                rpcResultType = toOdTableStatistics(nodeTable);
-                rpcResultBool = true;
-            }
-        } catch (ConstructionException e) {
-            LOG.error(e.getMessage());
-        }
-
-        return Futures.immediateFuture(Rpcs.getRpcResult(rpcResultBool, rpcResultType, null));
-    }
-
-    @Override
-    public Future<RpcResult<GetNodeConnectorStatisticsOutput>> getNodeConnectorStatistics(
-            GetNodeConnectorStatisticsInput input) {
-        GetNodeConnectorStatisticsOutput rpcResultType = null;
-        boolean rpcResultBool = false;
-
-        NodeConnectorRef nodeConnector = input.getNodeConnector();
-        try {
-            NodeConnectorStatistics nodeConnectorStats = readDelegate.readNodeConnector(NodeMapping
-                    .toADNodeConnector(nodeConnector));
-            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.node.connector.statistics.output.NodeConnectorStatistics odNodeConnectorStatistics = toOdNodeConnectorStatistics(nodeConnectorStats);
-            rpcResultType = new GetNodeConnectorStatisticsOutputBuilder(odNodeConnectorStatistics).build();
+            Flow flow = ToSalConversionsUtils.toFlow(input);
+            FlowOnNode readFlow = readDelegate.readFlow(node, flow);
+            List<FlowAndStatisticsMapList> flowOnNodeToFlowStatistics = new ArrayList<FlowAndStatisticsMapList>();
+            flowOnNodeToFlowStatistics.add(toOdFlowStatistics(readFlow));
+            rpcResultType = new GetFlowStatisticsFromFlowTableOutputBuilder().setFlowAndStatisticsMapList(flowOnNodeToFlowStatistics).build();
             rpcResultBool = true;
         } catch (ConstructionException e) {
             LOG.error(e.getMessage());
@@ -169,59 +149,74 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
     }
 
     @Override
-    public void descriptionStatisticsUpdated(Node node, NodeDescription nodeDescription) {
-
-        // TODO which *StatisticsUpdated interface should be used?
-
+    public void nodeFlowStatisticsUpdated(Node node, List<FlowOnNode> flowStatsList) {
+        List<FlowAndStatisticsMapList> flowStatistics = toOdFlowsStatistics(flowStatsList);
+        FlowsStatisticsUpdateBuilder flowsStatisticsUpdateBuilder = new FlowsStatisticsUpdateBuilder();
+        flowsStatisticsUpdateBuilder.setFlowAndStatisticsMapList(flowStatistics);
+        flowsStatisticsUpdateBuilder.setMoreReplies(false);
+        flowsStatisticsUpdateBuilder.setTransactionId(null);
+        flowsStatisticsUpdateBuilder.setId(InventoryMapping.toNodeKey(node).getId());
+        notifier.publish(flowsStatisticsUpdateBuilder.build());
     }
 
     @Override
     public void nodeConnectorStatisticsUpdated(Node node, List<NodeConnectorStatistics> ncStatsList) {
-        for (NodeConnectorStatistics ndConStats : ncStatsList) {
-            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.node.connector.statistics.output.NodeConnectorStatistics odNodeConnectorStatistics;
-            odNodeConnectorStatistics = toOdNodeConnectorStatistics(ndConStats);
-            NodeConnectorStatisticsUpdatedBuilder statisticsBuilder = new NodeConnectorStatisticsUpdatedBuilder(
-                    odNodeConnectorStatistics);
-            notifier.publish(statisticsBuilder.build());
-        }
-    }
-
-    @Override
-    public void nodeFlowStatisticsUpdated(Node node, List<FlowOnNode> flowStatsList) {
-        for (FlowOnNode flowOnNode : flowStatsList) {
-            FlowStatistics flowStatistics = toOdFlowStatistics(flowOnNode);
-            FlowStatisticsUpdatedBuilder statisticsBuilder = new FlowStatisticsUpdatedBuilder(flowStatistics);
-            notifier.publish(statisticsBuilder.build());
-        }
+        NodeConnectorStatisticsUpdateBuilder nodeConnectorStatisticsUpdateBuilder = new NodeConnectorStatisticsUpdateBuilder();
+        List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorStatistics = toOdNodeConnectorStatistics(ncStatsList);
+        
+        nodeConnectorStatisticsUpdateBuilder.setNodeConnectorStatisticsAndPortNumberMap(nodeConnectorStatistics);
+        nodeConnectorStatisticsUpdateBuilder.setMoreReplies(false);
+        nodeConnectorStatisticsUpdateBuilder.setTransactionId(null);
+        nodeConnectorStatisticsUpdateBuilder.setId(InventoryMapping.toNodeKey(node).getId());
+        notifier.publish(nodeConnectorStatisticsUpdateBuilder.build());
     }
 
     @Override
     public void nodeTableStatisticsUpdated(Node node, List<NodeTableStatistics> tableStatsList) {
-        // TODO : Not implemented by AD-SAL.
+        
+        FlowTableStatisticsUpdateBuilder flowTableStatisticsUpdateBuilder = new FlowTableStatisticsUpdateBuilder();  
+        
+        List<FlowTableAndStatisticsMap>  flowTableStatistics = toOdFlowTableStatistics(tableStatsList);
+        flowTableStatisticsUpdateBuilder.setFlowTableAndStatisticsMap(flowTableStatistics);
+        flowTableStatisticsUpdateBuilder.setMoreReplies(false);
+        flowTableStatisticsUpdateBuilder.setTransactionId(null);
+        flowTableStatisticsUpdateBuilder.setId(InventoryMapping.toNodeKey(node).getId());
+        notifier.publish(flowTableStatisticsUpdateBuilder.build());
+}
+
+        @Override
+    public void descriptionStatisticsUpdated(Node node, NodeDescription nodeDescription) {
+            // TODO which *StatisticsUpdated interface should be used?
+        
     }
 
-    private List<FlowStatistics> toOdFlowsStatistics(List<FlowOnNode> flowsOnNode) {
-        List<FlowStatistics> flowsStatistics = new ArrayList<>();
+    private List<FlowAndStatisticsMapList> toOdFlowsStatistics(List<FlowOnNode> flowsOnNode) {
+        List<FlowAndStatisticsMapList> flowsStatistics = new ArrayList<>();
         for (FlowOnNode flowOnNode : flowsOnNode) {
             flowsStatistics.add(toOdFlowStatistics(flowOnNode));
         }
         return flowsStatistics;
     }
 
-    private FlowStatistics toOdFlowStatistics(FlowOnNode flowOnNode) {
-        FlowStatisticsBuilder builder = new FlowStatisticsBuilder();
+    private FlowAndStatisticsMapList toOdFlowStatistics(FlowOnNode flowOnNode) {
+        FlowAndStatisticsMapListBuilder builder = new FlowAndStatisticsMapListBuilder();
 
         builder.setByteCount(toCounter64(flowOnNode.getByteCount()));
         builder.setPacketCount(toCounter64(flowOnNode.getPacketCount()));
         builder.setDuration(extractDuration(flowOnNode));
-
+        builder.setMatch(FromSalConversionsUtils.toMatch(flowOnNode.getFlow().getMatch()));
+        builder.setPriority((int)flowOnNode.getFlow().getPriority());
+        builder.setHardTimeout((int)flowOnNode.getFlow().getHardTimeout());
+        builder.setIdleTimeout((int)flowOnNode.getFlow().getIdleTimeout());
+        //TODO: actions to instruction conversion
+        builder.setInstructions(null);
         return builder.build();
     }
 
-    private Duration extractDuration(FlowOnNode flowOnNode) {
+    private org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.Duration extractDuration(FlowOnNode flowOnNode) {
         DurationBuilder builder = new DurationBuilder();
-        builder.setNanosecond(toCounter64(flowOnNode.getDurationNanoseconds()));
-        builder.setSecond(toCounter64(flowOnNode.getDurationSeconds()));
+        builder.setNanosecond(new Counter32((long)flowOnNode.getDurationNanoseconds()));
+        builder.setSecond(new Counter32((long)flowOnNode.getDurationSeconds()));
         return builder.build();
     }
 
@@ -231,38 +226,43 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
         return new Counter64(byteCountBigInt);
     }
 
-    private Counter64 toCounter64(int num) {
-        String byteCountStr = String.valueOf(num);
-        BigInteger byteCountBigInt = new BigInteger(byteCountStr);
-        return new Counter64(byteCountBigInt);
-    }
-
-    private List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.node.connector.statistics.output.NodeConnectorStatistics> toOdNodesConnectorStatistics(
-            List<NodeConnectorStatistics> nodesConnectorStatistics) {
-        List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.node.connector.statistics.output.NodeConnectorStatistics> odNodesConnectorStatistics = new ArrayList<>();
-        for (NodeConnectorStatistics nodeConnectorStatistics : nodesConnectorStatistics) {
-            odNodesConnectorStatistics.add(toOdNodeConnectorStatistics(nodeConnectorStatistics));
+    private List<FlowTableAndStatisticsMap> toOdFlowTableStatistics(List<NodeTableStatistics> tableStatsList) {
+        
+        List<FlowTableAndStatisticsMap> flowTableStatsMap = new ArrayList<FlowTableAndStatisticsMap>();
+        for (NodeTableStatistics nodeTableStatistics : tableStatsList) {
+            FlowTableAndStatisticsMapBuilder flowTableAndStatisticsMapBuilder = new FlowTableAndStatisticsMapBuilder();
+            flowTableAndStatisticsMapBuilder.setActiveFlows(new Counter32((long) nodeTableStatistics.getActiveCount()));
+            flowTableAndStatisticsMapBuilder.setPacketsLookedUp(toCounter64(nodeTableStatistics.getLookupCount()));
+            flowTableAndStatisticsMapBuilder.setPacketsMatched(toCounter64(nodeTableStatistics.getMatchedCount()));
+            flowTableAndStatisticsMapBuilder.setActiveFlows(new Counter32((long) nodeTableStatistics.getActiveCount()));
+            flowTableAndStatisticsMapBuilder.setTableId(new TableId((short)nodeTableStatistics.getNodeTable().getID()));
+            flowTableStatsMap.add(flowTableAndStatisticsMapBuilder.build());
         }
-        return odNodesConnectorStatistics;
+        
+        return flowTableStatsMap;
     }
 
-    private org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.all.node.connector.statistics.output.NodeConnectorStatistics toOdNodeConnectorStatistics(
-            NodeConnectorStatistics ndConStats) {
-        NodeConnectorStatisticsBuilder builder = new NodeConnectorStatisticsBuilder();
-
-        builder.setBytes(extractBytes(ndConStats));
-        builder.setCollisionCount(toBI(ndConStats.getCollisionCount()));
-        builder.setDuration(null);
-        builder.setPackets(extractPackets(ndConStats));
-        builder.setReceiveCrcError(toBI(ndConStats.getReceiveCRCErrorCount()));
-        builder.setReceiveDrops(toBI(ndConStats.getReceiveDropCount()));
-        builder.setReceiveErrors(toBI(ndConStats.getReceiveErrorCount()));
-        builder.setReceiveFrameError(toBI(ndConStats.getReceiveFrameErrorCount()));
-        builder.setReceiveOverRunError(toBI(ndConStats.getReceiveOverRunErrorCount()));
-        builder.setTransmitDrops(toBI(ndConStats.getTransmitDropCount()));
-        builder.setTransmitErrors(toBI(ndConStats.getTransmitErrorCount()));
-
-        return builder.build();
+    private List<NodeConnectorStatisticsAndPortNumberMap> toOdNodeConnectorStatistics(
+            List<NodeConnectorStatistics> ncStatsList) {
+        List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorStatisticsList = new ArrayList<NodeConnectorStatisticsAndPortNumberMap>();
+        for(NodeConnectorStatistics ofNodeConnectorStatistics : ncStatsList){
+            NodeConnectorStatisticsAndPortNumberMapBuilder nodeConnectorStatisticsAndPortNumberMapBuilder = new NodeConnectorStatisticsAndPortNumberMapBuilder();
+            
+            nodeConnectorStatisticsAndPortNumberMapBuilder.setBytes(extractBytes(ofNodeConnectorStatistics));
+            nodeConnectorStatisticsAndPortNumberMapBuilder.setCollisionCount(toBI(ofNodeConnectorStatistics.getCollisionCount()));
+            nodeConnectorStatisticsAndPortNumberMapBuilder.setDuration(null);
+            nodeConnectorStatisticsAndPortNumberMapBuilder.setPackets(extractPackets(ofNodeConnectorStatistics));
+            nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveCrcError(toBI(ofNodeConnectorStatistics.getReceiveCRCErrorCount()));
+            nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveDrops(toBI(ofNodeConnectorStatistics.getReceiveDropCount()));
+            nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveErrors(toBI(ofNodeConnectorStatistics.getReceiveErrorCount()));
+            nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveFrameError(toBI(ofNodeConnectorStatistics.getReceiveFrameErrorCount()));
+            nodeConnectorStatisticsAndPortNumberMapBuilder.setReceiveOverRunError(toBI(ofNodeConnectorStatistics.getReceiveOverRunErrorCount()));
+            nodeConnectorStatisticsAndPortNumberMapBuilder.setTransmitDrops(toBI(ofNodeConnectorStatistics.getTransmitDropCount()));
+            nodeConnectorStatisticsAndPortNumberMapBuilder.setTransmitErrors(toBI(ofNodeConnectorStatistics.getTransmitErrorCount()));
+            nodeConnectorStatisticsList.add(nodeConnectorStatisticsAndPortNumberMapBuilder.build());
+        }
+        
+        return nodeConnectorStatisticsList;
     }
 
     private BigInteger toBI(long num) {
@@ -292,49 +292,4 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
         return builder.build();
     }
 
-    private GetFlowTableStatisticsOutput toOdTableStatistics(NodeTableStatistics nodeTable) {
-        GetFlowTableStatisticsOutputBuilder builder = new GetFlowTableStatisticsOutputBuilder();
-
-        builder.setActive(toCounter64(nodeTable.getActiveCount()));
-        builder.setLookup(toCounter64(nodeTable.getLookupCount()));
-        builder.setMatched(toCounter64(nodeTable.getMatchedCount()));
-
-        return builder.build();
-    }
-
-    @Override
-    public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> getAggregateFlowStatisticsFromFlowTableForAllFlows(
-            GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput input) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> getAggregateFlowStatisticsFromFlowTableForGivenMatch(
-            GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Future<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> getAllFlowStatisticsFromFlowTable(
-            GetAllFlowStatisticsFromFlowTableInput input) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Future<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> getAllFlowsStatisticsFromAllFlowTables(
-            GetAllFlowsStatisticsFromAllFlowTablesInput input) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Future<RpcResult<GetFlowStatisticsFromFlowTableOutput>> getFlowStatisticsFromFlowTable(
-            GetFlowStatisticsFromFlowTableInput input) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
 }
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend
new file mode 100644 (file)
index 0000000..bd2590f
--- /dev/null
@@ -0,0 +1,30 @@
+package org.opendaylight.controller.sal.compatibility.topology
+
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.topology.IPluginInTopologyService
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+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.TopologyId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+
+import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.*
+
+class TopologyAdapter implements IPluginInTopologyService {
+    
+    @Property
+    DataProviderService dataService;
+    
+    @Property
+    IPluginOutTopologyService topologyPublisher;
+    
+    override sollicitRefresh() {
+        val path = InstanceIdentifier.builder(NetworkTopology).child(Topology,new TopologyKey(new TopologyId("flow:1"))).toInstance;
+        val reader = TypeSafeDataReader.forReader(dataService)
+        val topology = reader.readOperationalData(path)
+        topologyPublisher.edgeUpdate(topology.toADEdgeUpdates(reader))
+    }
+    
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend
new file mode 100644 (file)
index 0000000..7d05ce6
--- /dev/null
@@ -0,0 +1,62 @@
+package org.opendaylight.controller.sal.compatibility.topology
+
+import com.google.common.collect.FluentIterable
+import java.util.concurrent.CopyOnWriteArrayList
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+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.api.data.DataProviderService
+import org.opendaylight.controller.sal.core.UpdateType
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
+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.TopologyId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+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.network.topology.topology.Link
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.*
+import org.slf4j.LoggerFactory
+
+class TopologyCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+    static val LOG = LoggerFactory.getLogger(TopologyCommitHandler);
+    @Property
+    IPluginOutTopologyService topologyPublisher;
+    
+    @Property
+    DataProviderService dataService;
+    
+    new(DataProviderService dataService) {
+        _topologyPublisher = topologyPublisher
+        _dataService = dataService
+    }
+    
+    override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+        val msg = new CopyOnWriteArrayList<TopoEdgeUpdate>()
+        try {
+            val reader = TypeSafeDataReader.forReader(dataService)
+            val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, new TopologyKey(new TopologyId("flow:1"))).toInstance
+            val topology = reader.readOperationalData(topologyPath)
+            val adds = FluentIterable.from(modification.createdOperationalData.entrySet)
+                .filter[value instanceof Link]
+                .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED,reader)]
+                .toList
+            val updates = FluentIterable.from(modification.updatedOperationalData.entrySet)
+                .filter[!modification.createdOperationalData.containsKey(key) && (value instanceof Link)]
+                .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED,reader)] // Evidently the ADSAL does not expect edge 'CHANGED"
+                .toList
+            val removes = FluentIterable.from(modification.removedOperationalData)
+                .transform[reader.readOperationalData(it as InstanceIdentifier<DataObject>)]
+                .filter[it instanceof Link]
+                .transform[(it as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.REMOVED,reader)]
+                .toList
+            msg.addAll(adds)
+            msg.addAll(updates)
+            msg.addAll(removes)
+         } catch (Exception e) {
+            LOG.error("Exception caught",e)
+         }
+        return new TopologyTransaction(modification,topologyPublisher,dataService,msg)
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend
new file mode 100644 (file)
index 0000000..62983cc
--- /dev/null
@@ -0,0 +1,71 @@
+package org.opendaylight.controller.sal.compatibility.topology
+
+import com.google.common.collect.FluentIterable
+import java.util.Collections
+import java.util.List
+import java.util.concurrent.CopyOnWriteArrayList
+import org.opendaylight.controller.sal.core.ConstructionException
+import org.opendaylight.controller.sal.core.Edge
+import org.opendaylight.controller.sal.core.Node
+import org.opendaylight.controller.sal.core.NodeConnector
+import org.opendaylight.controller.sal.core.UpdateType
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
+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.TpId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
+
+import static com.google.common.base.Preconditions.*
+import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
+
+class TopologyMapping {
+    
+    private new() {
+        throw new UnsupportedOperationException("Utility class. Instantiation is not allowed.");
+    }
+    
+    public static def toADEdgeUpdates(Topology topology,TypeSafeDataReader reader) {
+        val List<TopoEdgeUpdate> result = new CopyOnWriteArrayList<TopoEdgeUpdate>()
+        return FluentIterable.from(topology.link).transform[toAdEdge(topology).toTopoEdgeUpdate(reader)].copyInto(result)
+    }
+    
+    public static def toAdEdge(Link link,Topology topology) {
+        val adSrc = link.source.sourceTp.toADNodeConnector(link.source.sourceNode)
+        val adDst = link.destination.destTp.toADNodeConnector(link.destination.destNode)
+        return new Edge(adSrc,adDst); 
+    }
+    
+    public static def toTopoEdgeUpdate(Edge e,TypeSafeDataReader reader) {
+        return toTopoEdgeUpdate(e,UpdateType.ADDED,reader)
+    }
+    
+    public static def toTopoEdgeUpdate(Edge e,UpdateType type,TypeSafeDataReader reader) {
+        return new TopoEdgeUpdate(e,e.toAdEdgeProperties(reader),type)
+    }
+    
+    public static def toAdEdgeProperties(Edge e,TypeSafeDataReader reader) {
+        val nc = reader.readOperationalData(e.tailNodeConnector.toNodeConnectorRef.value as InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector>)
+        return nc.toADNodeConnectorProperties     
+    }
+    
+    public static def toADNodeId(NodeId nodeId) {
+        checkNotNull(nodeId);
+        return nodeId.value
+    }
+    public static def toADNodeConnector(TpId source,NodeId nodeId) throws ConstructionException {
+        checkNotNull(source);
+        return new NodeConnector(MD_SAL_TYPE,source.toADNodeConnectorId,nodeId.toADNode)
+    }
+    
+    public static def toADNodeConnectorId(TpId nodeConnectorId) {
+        return nodeConnectorId.value
+    }
+    
+    public static def toADNode(NodeId nodeId) {
+        checkNotNull(nodeId);
+        return new Node(MD_SAL_TYPE,nodeId.toADNodeId);       
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend
new file mode 100644 (file)
index 0000000..1fde282
--- /dev/null
@@ -0,0 +1,48 @@
+package org.opendaylight.controller.sal.compatibility.topology
+
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+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.TopologyId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
+import org.slf4j.LoggerFactory
+
+class TopologyProvider implements AutoCloseable{
+    static val LOG = LoggerFactory.getLogger(TopologyProvider);
+    TopologyCommitHandler commitHandler
+    
+    @Property
+    IPluginOutTopologyService topologyPublisher;
+    
+    @Property
+    DataProviderService dataService;
+    
+    Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
+    
+    def void start() {
+        commitHandler = new TopologyCommitHandler(dataService)
+        commitHandler.setTopologyPublisher(topologyPublisher)
+        val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(NetworkTopology)
+            .child(Topology,new TopologyKey(new TopologyId("flow:1")))
+            .child(Link)
+            .toInstance();
+        commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
+        LOG.info("TopologyProvider started")
+    }
+    
+    override close() throws Exception {
+        commitHandlerRegistration.close
+    }
+    
+    def setTopologyPublisher(IPluginOutTopologyService topologyPublisher) {
+        _topologyPublisher = topologyPublisher;
+        commitHandler.setTopologyPublisher(topologyPublisher);
+    }
+    
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend
new file mode 100644 (file)
index 0000000..33927ff
--- /dev/null
@@ -0,0 +1,66 @@
+package org.opendaylight.controller.sal.compatibility.topology
+
+import java.util.Collections
+import java.util.List
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
+import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.common.RpcResult
+import org.slf4j.LoggerFactory
+
+class TopologyTransaction implements DataCommitTransaction<InstanceIdentifier<?extends DataObject>, DataObject> {
+    static val LOG = LoggerFactory.getLogger(TopologyTransaction);
+    @Property
+    val DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
+    
+    @Property
+    IPluginOutTopologyService topologyPublisher;
+    
+    @Property
+    DataProviderService dataService;
+    @Property
+    List<TopoEdgeUpdate> edgeUpdates;
+    
+    new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,IPluginOutTopologyService topologyPublisher,
+        DataProviderService dataService,List<TopoEdgeUpdate> edgeUpdates) {
+        _modification = modification;
+        _topologyPublisher = topologyPublisher
+        _dataService = dataService
+        _edgeUpdates = edgeUpdates
+    }
+    override finish() throws IllegalStateException {
+        
+        if(topologyPublisher != null && _edgeUpdates != null && !edgeUpdates.empty) {
+            topologyPublisher.edgeUpdate(edgeUpdates)
+        }
+         
+         return new RpcResultTo()
+    }
+    
+    override getModification() {
+        return _modification;
+    }
+    
+    override rollback() throws IllegalStateException {
+        // NOOP
+    }
+}
+class RpcResultTo implements RpcResult<Void> {
+    
+    override getErrors() {
+        return Collections.emptySet
+    }
+    
+    override getResult() {
+        return null;
+    }
+    
+    override isSuccessful() {
+        return true;
+    }
+    
+}
\ No newline at end of file
index 5203d3c1a8165932e78fbe4fbe0f739b45926f0d..dc2a7ee6f99647106818d9672bca999f87e372c6 100644 (file)
@@ -15,14 +15,17 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N
 import org.opendaylight.yangtools.yang.binding.DataObject
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
 
 class FlowTransaction extends AbstractTransaction {
     
     @Property
-    val SalFlowService salFlowService;
+    val SalFlowService salFlowService;   
+    
     
     new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalFlowService salFlowService) {
-        super(modification)
+        super(modification)        
         _salFlowService = salFlowService;
     }
     
@@ -32,8 +35,10 @@ class FlowTransaction extends AbstractTransaction {
             val tableInstanceId = instanceId.firstIdentifierOf(Table);
             val nodeInstanceId = instanceId.firstIdentifierOf(Node);
             val builder = new RemoveFlowInputBuilder(flow);
+            builder.setFlowRef(new FlowRef(instanceId));            
             builder.setNode(new NodeRef(nodeInstanceId));
             builder.setFlowTable(new FlowTableRef(tableInstanceId));
+            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
             _salFlowService.removeFlow(builder.build());            
         }
     }
@@ -45,8 +50,10 @@ class FlowTransaction extends AbstractTransaction {
             val nodeInstanceId = instanceId.firstIdentifierOf(Node);
             val builder = new UpdateFlowInputBuilder();
             builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setFlowRef(new FlowRef(instanceId));
             val ufb = new UpdatedFlowBuilder(updatedFlow);
             builder.setUpdatedFlow((ufb.build()));
+            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
             val ofb = new OriginalFlowBuilder(originalFlow);
             builder.setOriginalFlow(ofb.build());      
             _salFlowService.updateFlow(builder.build());
@@ -61,6 +68,8 @@ class FlowTransaction extends AbstractTransaction {
             val nodeInstanceId = instanceId.firstIdentifierOf(Node);
             val builder = new AddFlowInputBuilder(flow);
             builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
+            builder.setFlowRef(new FlowRef(instanceId));
             builder.setFlowTable(new FlowTableRef(tableInstanceId));
             _salFlowService.addFlow(builder.build());            
         }
index 54382ea0560b561018005f9f86542c91dbd153be..f79c9b61a62ec4d467a3289740d3cbbd5132847a 100644 (file)
@@ -2,34 +2,27 @@ package org.opendaylight.controller.frm.group
 
 import org.opendaylight.controller.frm.AbstractTransaction
 import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
 import org.opendaylight.yangtools.yang.binding.DataObject
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
 
 class GroupTransaction extends AbstractTransaction {
     
     @Property
     val SalGroupService groupService;
-    
+        
     new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalGroupService groupService) {
-        super(modification)
+        super(modification)        
         _groupService = groupService;
     }
     
@@ -39,6 +32,8 @@ class GroupTransaction extends AbstractTransaction {
             val nodeInstanceId = instanceId.firstIdentifierOf(Node);
             val builder = new RemoveGroupInputBuilder(group);
             builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
+            builder.setGroupRef(new GroupRef(instanceId));
             _groupService.removeGroup(builder.build());            
         }
     }
@@ -50,8 +45,10 @@ class GroupTransaction extends AbstractTransaction {
             val nodeInstanceId = instanceId.firstIdentifierOf(Node);
             val builder = new UpdateGroupInputBuilder();
             builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setGroupRef(new GroupRef(instanceId));
             val ufb = new UpdatedGroupBuilder(updatedGroup);
             builder.setUpdatedGroup((ufb.build()));
+            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
             val ofb = new OriginalGroupBuilder(originalGroup);
             builder.setOriginalGroup(ofb.build());      
             _groupService.updateGroup(builder.build());
@@ -65,6 +62,8 @@ class GroupTransaction extends AbstractTransaction {
             val nodeInstanceId = instanceId.firstIdentifierOf(Node);
             val builder = new AddGroupInputBuilder(group);
             builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setGroupRef(new GroupRef(instanceId));
+            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
             _groupService.addGroup(builder.build());            
         }
     }
index 3ed1f4073565ec64cac14d265a8c9a307181fa47..594a16c34ec813c94ba8ecfb14ed84f6d3e6ce8a 100644 (file)
@@ -13,14 +13,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.met
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter
 import org.opendaylight.yangtools.yang.binding.DataObject
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
 
 class MeterTransaction extends AbstractTransaction {
     
     @Property
     val SalMeterService salMeterService;
-    
+        
     new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalMeterService salMeterService) {
-        super(modification)
+        super(modification)    
         _salMeterService = salMeterService;
     }
     
@@ -30,6 +32,8 @@ class MeterTransaction extends AbstractTransaction {
             val nodeInstanceId = instanceId.firstIdentifierOf(Node);
             val builder = new RemoveMeterInputBuilder(meter);
             builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setMeterRef(new MeterRef(instanceId));
+            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
             _salMeterService.removeMeter(builder.build());            
         }
     }
@@ -41,8 +45,10 @@ class MeterTransaction extends AbstractTransaction {
             val nodeInstanceId = instanceId.firstIdentifierOf(Node);
             val builder = new UpdateMeterInputBuilder();
             builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setMeterRef(new MeterRef(instanceId));
             val ufb = new UpdatedMeterBuilder(updatedMeter);
             builder.setUpdatedMeter((ufb.build()));
+            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
             val ofb = new OriginalMeterBuilder(originalMeter);
             builder.setOriginalMeter(ofb.build());      
             _salMeterService.updateMeter(builder.build());
@@ -56,6 +62,8 @@ class MeterTransaction extends AbstractTransaction {
             val nodeInstanceId = instanceId.firstIdentifierOf(Node);
             val builder = new AddMeterInputBuilder(meter);
             builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setMeterRef(new MeterRef(instanceId));
+            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
             _salMeterService.addMeter(builder.build());            
         }
     }
index 2b023a72e1c0442cb8f932c0d1472381cb3740ea..1a66b3ba16316b4c5a1c92485e909cf061c3d398 100644 (file)
@@ -76,7 +76,7 @@ class NodeChangeCommiter implements OpendaylightInventoryListener {
 
         // Check path
         val it = manager.startChange()
-        removeRuntimeData(ref.value as InstanceIdentifier<? extends DataObject>);
+        removeOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
         commit()
     }
 
@@ -93,7 +93,7 @@ class NodeChangeCommiter implements OpendaylightInventoryListener {
             data.addAugmentation(FlowCapableNodeConnector, augment)
         }
 
-        putRuntimeData(ref.value as InstanceIdentifier<NodeConnector>, data.build());
+        putOperationalData(ref.value as InstanceIdentifier<NodeConnector>, data.build());
         commit()
     }
 
@@ -101,7 +101,7 @@ class NodeChangeCommiter implements OpendaylightInventoryListener {
         val ref = node.nodeRef;
         val it = manager.startChange()
 
-        removeRuntimeData(ref.value as InstanceIdentifier<? extends DataObject>);
+        removeOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
         commit()
     }
 
@@ -117,7 +117,7 @@ class NodeChangeCommiter implements OpendaylightInventoryListener {
             data.addAugmentation(FlowCapableNode, augment)
         }
 
-        putRuntimeData(ref.value as InstanceIdentifier<Node>, data.build())
+        putOperationalData(ref.value as InstanceIdentifier<Node>, data.build())
         commit()
     }
 }
index 13ffa3f91002121c17dc71abb1d748ffe90f906f..5e69548d9a8cbcf70bee61561b6235bae60aae0d 100644 (file)
         <dependency>
             <groupId>org.opendaylight.yangtools.model</groupId>
             <artifactId>opendaylight-l2-types</artifactId>
-            <version>2013.08.27.0</version>
+            <version>2013.08.27.1</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>model-inventory</artifactId>
+            <version>${project.version}</version>
         </dependency>
     </dependencies>
     <packaging>bundle</packaging>
index 8c874e2fe80a60f345f67fe091cde4a883fcc631..4442fbb3358001297434fee652faad30bb5712c4 100644 (file)
@@ -84,6 +84,10 @@ module opendaylight-group-types {
        description "Check chaining for loops and delete";
     }
     
+    typedef group-ref {
+        type instance-identifier;
+    }
+    
     grouping group {
         
         leaf group-type {
@@ -102,10 +106,6 @@ module opendaylight-group-types {
             type string; 
         }
         
-        leaf install {
-            type boolean; 
-        } 
-        
         leaf barrier {
             type boolean; 
         }       
index 1ed1b6827bdc6ace925576b207b7d818d27ac8b5..31736d2737dbcd7358ef264587de0910153afb63 100644 (file)
@@ -5,6 +5,7 @@ module opendaylight-match-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-l2-types {prefix l2t;revision-date "2013-08-27";}
+    import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
 
     revision "2013-10-26" {
         description "Initial revision of macth types";
@@ -270,11 +271,11 @@ module opendaylight-match-types {
     
     grouping match {
         leaf in-port {
-            type uint32;
+            type inv:node-connector-id;
         }
         
         leaf in-phy-port {
-            type uint32;
+            type inv:node-connector-id;
         }
         
         container "metadata" {
index b380af22129c44f068bb02d50aa57283e8bfbac0..d84b2f08511f466848886cb75aa4f418341d5563 100644 (file)
@@ -112,6 +112,10 @@ module opendaylight-meter-types {
         }
     }
     
+    typedef meter-ref {
+        type instance-identifier;
+    }
+    
     grouping meter {
         
         leaf flags {
@@ -120,11 +124,12 @@ module opendaylight-meter-types {
         
         leaf meter-id {
             type meter-id;
-        }
+        }       
         
-        leaf install {
+        leaf barrier {
             type boolean; 
         }
+        
         leaf meter-name {
             type string;
         }
index 43754a1dfdad4e7d8354d43005ed52661e47c202..3cc490f01774ae710aa94c93f4b8223099b989f2 100644 (file)
@@ -49,9 +49,7 @@ module opendaylight-action-types {
                     }
                     
                     leaf max-length {
-                        type uint16 {
-                            range "0..65294";
-                        }
+                        type uint16;
                     }
                 }
             }
@@ -59,9 +57,7 @@ module opendaylight-action-types {
             case controller-action-case {
                 container controller-action {
                  leaf max-length {
-                     type uint16 {
-                         range "0..65294";
-                     }
+                     type uint16;
                  }
              }
             }
index 2bcd40522330901eaaf08824d68680cfdb48d381..a0beb2a84c936f51b83c20bd469b235563857949 100644 (file)
@@ -12,6 +12,10 @@ module opendaylight-flow-types {
         description "Initial revision of flow service";
     }
     
+    typedef flow-ref {
+        type instance-identifier;
+    }
+    
     typedef output-port-values {
         type enumeration {
             enum MAX {
index bc05894da82637cfae12f61257fc79bdd2609500..2554fffadb7a047d0e8bb525688a20ba1423ba13 100644 (file)
@@ -27,11 +27,15 @@ module opendaylight-port-types {
         }
     }
     
-    typedef port-state {
-        type enumeration {
-            enum link-down;
-            enum blocked;
-            enum live;
+    grouping port-state {
+        leaf link-down {
+            type boolean;
+        }
+        leaf blocked {
+            type boolean;
+        }   
+        leaf live {
+            type boolean;
         }
     }
     
@@ -103,9 +107,9 @@ module opendaylight-port-types {
             description "Human readable name of the port";                    
         }
         
-        leaf state {
-            type port-state;
-            description "Bit map of OFPPS-* flags";            
+        container state {
+            uses port-state;
+            description "Description of state of port";            
         }
         
         leaf current-feature {
index 1a0c37055b782bf38d55c381566a46f6723ddbba..db2c62d9af24e8199988113d80439a3d7c6f252c 100644 (file)
@@ -29,7 +29,7 @@
         <dependency>
             <groupId>org.opendaylight.yangtools.model</groupId>
             <artifactId>opendaylight-l2-types</artifactId>
-            <version>2013.08.27.0</version>
+            <version>2013.08.27.1</version>
         </dependency>
     </dependencies>
     <packaging>bundle</packaging>
index 6b8df6a4c8cd3ca42bdffa48160aad3c3b24dc78..c2e48b3df59d13134c73747b3d5b637fb6eb0ccc 100644 (file)
@@ -29,7 +29,7 @@
         <dependency>
             <groupId>org.opendaylight.yangtools.model</groupId>
             <artifactId>opendaylight-l2-types</artifactId>
-            <version>2013.08.27.0</version>
+            <version>2013.08.27.1</version>
         </dependency>
     </dependencies>
     <packaging>bundle</packaging>
index 483c0c9e126995c60c1a6bd343e796ae4b74084b..1c675f015dfd4a4964214bb289c4b765a05b1846 100644 (file)
@@ -3,6 +3,7 @@ module flow-capable-transaction {
     prefix type;
 
     import opendaylight-inventory {prefix inv; revision-date "2013-08-19";}
+    import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
     import yang-ext {prefix ext; revision-date "2013-07-09";}
     
     revision "2013-11-03" {
@@ -12,6 +13,12 @@ module flow-capable-transaction {
     typedef transaction-id {
        type uint64;
     }
+    // This refers to MD-SAL transaction reference.
+    grouping transaction-metadata {
+        leaf transaction-uri {
+            type inet:uri;
+        }
+    }
     
     grouping transaction-aware {
         leaf transaction-id {
index e55c50fb29612f2511adef62063a25b0468575cd..0f5cc71e8bc7052b1743d7e13d85ea3914e08bfd 100644 (file)
@@ -92,7 +92,7 @@ module flow-node-inventory {
     }
 
     typedef flow-id {
-        type uint32; // Note: This doesn't really belong here, and not sure if unint32 is right
+        type inet:uri;
     }
 
     grouping tables {
index 089469f045c6ae30caf8f800bc61796d140bbf89..5c68a137c3d71f8c23da9cd8da3f64d6552e2b56 100644 (file)
@@ -51,8 +51,11 @@ module sal-flow {
 
     rpc add-flow {
         input {
-            uses node-flow;
-            uses tr:transaction-aware;
+            uses tr:transaction-metadata;
+            leaf flow-ref {
+                type types:flow-ref;
+            }
+            uses node-flow;            
         }
         output {
             uses tr:transaction-aware;
@@ -61,8 +64,11 @@ module sal-flow {
 
     rpc remove-flow {
         input {
-            uses node-flow;
-            uses tr:transaction-aware;
+            uses tr:transaction-metadata;
+            leaf flow-ref {
+                type types:flow-ref;
+            }
+            uses node-flow;            
         }
         output {
             uses tr:transaction-aware;
@@ -71,8 +77,11 @@ module sal-flow {
 
     rpc update-flow {
         input {
-            uses flow-update;
-            uses tr:transaction-aware;
+            uses tr:transaction-metadata;
+            leaf flow-ref {
+                type types:flow-ref;
+            }
+            uses flow-update;           
         }
         output {
             uses tr:transaction-aware;
@@ -80,16 +89,28 @@ module sal-flow {
     }
 
     notification flow-added {
+        uses tr:transaction-metadata;
+        leaf flow-ref {
+            type types:flow-ref;
+        }
         uses node-flow;
         uses tr:transaction-aware;
     }
 
     notification flow-updated {
+        uses tr:transaction-metadata;
+        leaf flow-ref {
+            type types:flow-ref;
+        }
         uses node-flow;
-        uses tr:transaction-aware;
+        uses tr:transaction-aware;        
     }
 
     notification flow-removed {
+        uses tr:transaction-metadata;
+        leaf flow-ref {
+            type types:flow-ref;
+        }
         uses node-flow;
         uses tr:transaction-aware;
     }
@@ -101,6 +122,7 @@ module sal-flow {
     notification node-error-notification {
         uses error:error-message;
         uses tr:transaction-aware;
+        uses tr:transaction-metadata;
     }
     
     notification node-experimenter-error-notification {
index bbe4740e711b66850970b395ccce04f1d2e2c6f7..7eeb0ac0f3767eb0d40e211d0b9c88d188cb8517 100644 (file)
@@ -31,8 +31,11 @@ module sal-group {
 
     rpc add-group {
         input {
-            uses node-group;
-            uses tr:transaction-aware;
+            uses tr:transaction-metadata;
+            leaf group-ref {
+                type group-type:group-ref;
+            }
+            uses node-group;            
         }
         output {
             uses tr:transaction-aware;
@@ -41,8 +44,11 @@ module sal-group {
 
     rpc remove-group {
         input {
-            uses node-group;
-            uses tr:transaction-aware;
+            uses tr:transaction-metadata;
+            leaf group-ref {
+                type group-type:group-ref;
+            }
+            uses node-group;            
         }
         output {
             uses tr:transaction-aware;
@@ -51,8 +57,11 @@ module sal-group {
 
     rpc update-group {
         input {
-            uses group-update;
-            uses tr:transaction-aware;
+            uses tr:transaction-metadata;
+            leaf group-ref {
+                type group-type:group-ref;
+            }
+            uses group-update;            
         }
         output {
             uses tr:transaction-aware;
@@ -60,16 +69,28 @@ module sal-group {
     } 
 
     notification group-added {
+        uses tr:transaction-metadata;
+        leaf group-ref {
+            type group-type:group-ref;
+        }
         uses node-group;
         uses tr:transaction-aware;
     }
 
     notification group-updated {
+        uses tr:transaction-metadata;
+        leaf group-ref {
+            type group-type:group-ref;
+        }
         uses node-group;
         uses tr:transaction-aware;
     }
 
     notification group-removed {
+        uses tr:transaction-metadata;
+        leaf group-ref {
+            type group-type:group-ref;
+        }
         uses node-group;
         uses tr:transaction-aware;
     }    
index 65b22b29ddbf5d6562c48238049978a0ada0f832..ecdef41951aa63482b11c122c51f08d602cb8f26 100644 (file)
@@ -31,8 +31,11 @@ module sal-meter {
 
     rpc add-meter {
         input {
-            uses node-meter;
-            uses tr:transaction-aware;            
+            uses tr:transaction-metadata;            
+            leaf meter-ref {
+                type meter-type:meter-ref;
+            }
+            uses node-meter;            
         }
         output {
             uses tr:transaction-aware;
@@ -41,8 +44,12 @@ module sal-meter {
 
     rpc remove-meter {
         input {
-            uses node-meter;
-            uses tr:transaction-aware;            
+            uses tr:transaction-metadata;            
+            leaf meter-ref {
+                type meter-type:meter-ref;
+            }
+            
+            uses node-meter;                       
         }
         output {
             uses tr:transaction-aware;
@@ -51,8 +58,12 @@ module sal-meter {
 
     rpc update-meter {
         input {
-            uses meter-update;
-            uses tr:transaction-aware;            
+            uses tr:transaction-metadata;            
+            leaf meter-ref {
+                type meter-type:meter-ref;
+            }
+            
+            uses meter-update;                       
         }
         output {
             uses tr:transaction-aware;
@@ -60,16 +71,28 @@ module sal-meter {
     }
         
     notification meter-added {
+        uses tr:transaction-metadata;
+        leaf meter-ref {
+            type meter-type:meter-ref;
+        }
         uses node-meter;
         uses tr:transaction-aware;
     }
 
     notification meter-updated {
+        uses tr:transaction-metadata;
+        leaf meter-ref {
+            type meter-type:meter-ref;
+        }
         uses node-meter;
         uses tr:transaction-aware;
     }
 
     notification meter-removed {
+        uses tr:transaction-metadata;
+        leaf meter-ref {
+            type meter-type:meter-ref;
+        }
         uses node-meter;
         uses tr:transaction-aware;
     }
index bfdf5049c3d8b585be5a94c949c4718945440c8d..00ecdbacf08d5a8a87a0db80427b5a4c52ec0ff6 100644 (file)
@@ -6,6 +6,8 @@ module packet-processing {
     import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
     import ietf-yang-types {prefix yang;revision-date "2010-09-24";} 
     import opendaylight-l2-types {prefix types;revision-date "2013-08-27";}
+    import opendaylight-match-types {prefix match-type;revision-date "2013-10-26";}
+    import opendaylight-table-types {prefix table-type;revision-date "2013-10-26";}
     
     revision "2013-07-09" {
         description "";
@@ -34,11 +36,44 @@ module packet-processing {
        }
     }
 
+    identity packet-in-reason {
+       description "Base identity for all the available packet in reason"; 
+    }
+    
+    identity no-match {
+       base packet-in-reason;
+       description "No matching flow in the classifier";
+    }
+    
+    identity send-to-controller {
+       base packet-in-reason;
+       description "Explicit instruction to send packet to controller";
+    }
+    
+    identity invalid-ttl {
+       base packet-in-reason;
+       description "Packet with invalid TTL";
+    }
 
     notification packet-received {
        leaf cookie {
                 type cookie;
         }
+        
+        leaf table-id {
+               type table-type:table-id;
+        }
+        
+        leaf packet-in-reason {
+               type identityref {
+                       base packet-in-reason;
+               }
+               }
+        
+        container match {
+                       uses match-type:match;
+        }
+        
         uses raw-packet;
     }
 
@@ -56,4 +91,4 @@ module packet-processing {
                uses raw-packet;
        }
     }
-}
\ No newline at end of file
+}
index 476c817c9084812ad78f5cb6993ed047a631e379..e95fe24f28a9e8e6cf9e32af8a2f823fc001a20f 100644 (file)
@@ -29,7 +29,7 @@
         <dependency>
             <groupId>org.opendaylight.yangtools.model</groupId>
             <artifactId>opendaylight-l2-types</artifactId>
-            <version>2013.08.27-SNAPSHOT</version>
+            <version>2013.08.27.1-SNAPSHOT</version>
         </dependency>
     </dependencies>
     <packaging>bundle</packaging>
index 3bd37bcf3387ae4500f45d372f6a6454c949526f..2b1d99302629fa842ee04ed2ddb208392851e9aa 100644 (file)
@@ -11,6 +11,7 @@ module opendaylight-flow-statistics {
     import flow-node-inventory {prefix flow-node;revision-date "2013-08-19";}
     import flow-capable-transaction {prefix tr;}
     import sal-flow {prefix flow;}
+    import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
     
 
     revision "2013-08-19" {
@@ -33,7 +34,7 @@ module opendaylight-flow-statistics {
        
        typedef flow-id {
                description "flow id";
-               type yang:counter32;
+               type inet:uri;
        }
        
        grouping flow-and-statistics-map-list {
@@ -115,7 +116,7 @@ module opendaylight-flow-statistics {
         }
        }    
        
-    // RPC calls to fetch flow statistics
+    // RPC calls to fetch aggregate flow statistics
     rpc get-aggregate-flow-statistics-from-flow-table-for-all-flows {
        description "Fetch aggregate statistics for all the flows present in the specific flow table of the switch"; 
         input {
@@ -150,76 +151,4 @@ module opendaylight-flow-statistics {
                uses stat-types:aggregate-flow-statistics;
                uses tr:transaction-aware;
     }
-       
-       //Keeping flow statistics RPC call for backward compatibility for sal-compatibility layer --START
-       rpc get-flow-statistics {
-        input {
-            uses inv:node-context-ref;
-            uses flow-types:flow;
-        }
-        output {
-            uses flow-types:flow-statistics;
-        }
-    }
-
-    rpc get-all-flow-statistics {
-        input {
-            uses inv:node-context-ref;
-        }
-        output {
-            list flow-statistics {
-                uses flow-types:flow-statistics;
-            }
-        }
-    }
-
-    notification flow-statistics-updated {
-        uses flow-types:flow-statistics;
-    }
-       
-       //Keeping flow statistics RPC call for backward compatibility for sal-compatibility layer --END
-       
-       //RPC call to fetch node connector statistics
-    rpc get-node-connector-statistics {
-        input {
-            uses inv:node-context-ref;
-            leaf node-connector {
-                type inv:node-connector-ref;
-            }
-        }
-        output {
-            uses stat-types:node-connector-statistics;
-        }
-    }
-
-    rpc get-all-node-connector-statistics {
-        input {
-            uses inv:node-context-ref;
-        }
-        output {
-            list node-connector-statistics {
-                uses stat-types:node-connector-statistics;
-            }
-        }
-    }
-
-    rpc get-flow-table-statistics {
-        input {
-            uses inv:node-context-ref;
-        }
-        output {
-            uses flow-types:flow-table-statistics;
-        }
-    }
-
-    notification flow-table-statistics-updated {
-        leaf flow-table {
-            type flow:flow-table-ref;
-        }
-        uses flow-types:flow-table-statistics;
-    }
-
-    notification node-connector-statistics-updated {
-        uses stat-types:node-connector-statistics;
-    }
 }
index 5640858d516c341c9dd167fe43fe321a00fc3220..834e0a78358fa9cc55a5b419abc04f2e4fdeba87 100644 (file)
@@ -6,6 +6,7 @@ module opendaylight-group-statistics {
     import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
     import opendaylight-group-types {prefix group-types;revision-date "2013-10-18";}
     import flow-capable-transaction {prefix tr;}
+    import flow-node-inventory {prefix fni;}
     
     contact
         "Anilkumar Vishnoi
@@ -22,7 +23,7 @@ module opendaylight-group-statistics {
         }
        }    
     
-    augment "/inv:nodes/inv:node/group-types:group" {
+    augment "/inv:nodes/inv:node/fni:group" {
         ext:augment-identifier "node-group-statistics";
         uses group-statistics;
     }
index 0cb6a60cfe0e5dd23d918be3879859c848ab55dc..787a4e6aa0ef2fe3b26931877aa56a608450eda8 100644 (file)
@@ -30,19 +30,19 @@ module opendaylight-port-statistics {
        }    
        
     // RPC calls
-    rpc get-all-ports-statistics {
-       description "Get statistics for all the ports from the node";
+    rpc get-all-node-connectors-statistics {
+       description "Get statistics for all node connectors from the node";
         input {
             uses inv:node-context-ref;
         }
         output {
-            uses stat-types:node-connector-statistics;
+                       uses node-connector-statistics-and-port-number-map;
             uses tr:transaction-aware;
         }
     }
     
-    rpc get-port-statistics {
-       description "Get statistics for given port from the node";
+    rpc get-node-connector-statistics {
+       description "Get statistics for given node connector from the node";
        input {
                uses inv:node-context-ref;
                leaf node-connector-id {
@@ -55,9 +55,9 @@ module opendaylight-port-statistics {
        }
     }
     
-    //Notification for port statistics update
+    //Notification for node connector statistics update
        grouping node-connector-statistics-and-port-number-map {
-               description "List of flow and statistics map";
+               description "List of map - node connectors and their statistics";
                list node-connector-statistics-and-port-number-map {
                        key "node-connector-id";
                        leaf node-connector-id {
@@ -67,7 +67,7 @@ module opendaylight-port-statistics {
                }
        }
 
-       notification port-statistics-update {
+       notification node-connector-statistics-update {
         leaf moreReplies {
             type boolean;
         }
diff --git a/opendaylight/md-sal/model/model-inventory/src/main/yang/netconf-node-inventory.yang b/opendaylight/md-sal/model/model-inventory/src/main/yang/netconf-node-inventory.yang
new file mode 100644 (file)
index 0000000..b5cde6e
--- /dev/null
@@ -0,0 +1,27 @@
+module netconf-node-inventory {
+    namespace "urn:opendaylight:netconf-node-inventory";
+    prefix "netinv";
+    
+    import opendaylight-inventory { prefix inv; revision-date "2013-08-19";}
+    import yang-ext {prefix ext; revision-date "2013-07-09";}
+    
+    revision "2014-01-08" {
+        description "Initial revision of Inventory model";
+    }
+    
+    grouping netconf-node-fields {
+        leaf-list initial-capability {
+            type string;
+        }
+        
+        leaf-list current-capability {
+            type string;
+        }
+    }
+    
+    augment /inv:nodes/inv:node {
+        ext:augment-identifier "netconf-node";
+        
+        uses netconf-node-fields;
+    }
+}
\ No newline at end of file
index c91b9dd53ab701f185516f33db4b52b0e5990e1f..e2ce7a9735fb2b2cbe13c8aa492332d49f2a19b0 100644 (file)
     <packaging>bundle</packaging>
     
     <dependencies>
-    <dependency>
-        <groupId>org.opendaylight.controller.model</groupId>
-        <artifactId>model-inventory</artifactId>
-        <version>1.0-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-        <groupId>org.opendaylight.yangtools.model</groupId>
-        <artifactId>ietf-topology</artifactId>
-        <version>2013.07.12.2-SNAPSHOT</version>
-    </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-inventory</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools.model</groupId>
+            <artifactId>ietf-topology</artifactId>
+            <version>2013.10.21.0-SNAPSHOT</version>
+        </dependency>
     </dependencies>
 </project>
index 33c03ba059722a1a2162c7f3b3559a24c6267b49..87de0f5ae191e51b205668e72b8b08def97c1e7b 100644 (file)
@@ -8,7 +8,7 @@ module opendaylight-topology-inventory {
     import ietf-inet-types { prefix "inet"; }
     import opendaylight-inventory {prefix "inv";}
     import opendaylight-topology {prefix "odt";}
-    import network-topology {prefix "topo";}
+    import network-topology {prefix "topo"; revision-date "2013-07-12"; }
 
     organization "TBD";
 
@@ -21,14 +21,16 @@ module opendaylight-topology-inventory {
 
     augment "/topo:network-topology/topo:topology/topo:node" {
         ext:augment-identifier "inventory-node";
-        uses inv:node-context-ref;
+        leaf inventory-node-ref {
+            type inv:node-ref;
+        }
     }
 
     augment "/topo:network-topology/topo:topology/topo:node/topo:termination-point" {
         ext:augment-identifier "inventory-node-connector";
-        leaf node-connector {
+        leaf inventory-node-connector-ref {
             ext:context-reference "inv:node-connector-context";
             type inv:node-connector-ref;
         }
     }
-}
\ No newline at end of file
+}
index 038a1b7c67b4bf70a8ab403935858d19ae926ee0..6bbfd4b4794ff110b408b80732afa6eeb84fb56e 100644 (file)
@@ -7,7 +7,7 @@ module opendaylight-topology {
     import yang-ext { prefix "ext"; }
     import ietf-inet-types { prefix "inet"; }
     import opendaylight-inventory {prefix "inv";}
-    import network-topology {prefix "topo";}
+    import network-topology {prefix "topo"; revision-date "2013-07-12"; }
 
     organization "TBD";
 
index 2fecb327ca748f6f686adabc9f7e9b77afd296b3..1a10bf6fdd2cb191d3fb556c776e5c5b8c68432a 100644 (file)
@@ -6,7 +6,7 @@ module opendaylight-topology-view  {
 
     import yang-ext { prefix "ext"; }
     import ietf-inet-types { prefix "inet"; }
-    import network-topology {prefix "topo";}
+    import network-topology {prefix "topo"; revision-date "2013-07-12"; }
     import opendaylight-topology {prefix "odl";}
 
     organization "TBD";
@@ -45,4 +45,4 @@ module opendaylight-topology-view  {
         ext:augment-identifier "aggregated-node";
         uses aggregate-node;
     }
-}
\ No newline at end of file
+}
index c5f1dddc344b0e239595d7ae55ac6aa3dbd1bf99..571e9d8df2a66f2ea7e48b7aebc03c7e4a338320 100644 (file)
@@ -19,7 +19,7 @@
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <bundle.plugin.version>2.3.7</bundle.plugin.version>
+        <bundle.plugin.version>2.4.0</bundle.plugin.version>
     </properties>
 
     <modules>
@@ -40,7 +40,7 @@
                 <configuration>
                     <instructions>
                         <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
-                        <Import-Package>*,org.opendaylight.yangtools.yang.binding.annotations</Import-Package>
+                        <Import-Package>org.opendaylight.yangtools.yang.binding.annotations, *</Import-Package>
                     </instructions>
                 </configuration>
             </plugin>
                                     <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
                                     <outputBaseDir>target/site/models</outputBaseDir>
                                 </generator>
+                                <generator>
+                                    <codeGeneratorClass>org.opendaylight.yangtools.yang.wadl.generator.maven.WadlGenerator</codeGeneratorClass>
+                                    <outputBaseDir>target/site/models</outputBaseDir>
+                                </generator>
                             </codeGenerators>
                             <inspectDependencies>true</inspectDependencies>
                         </configuration>
index 0d6523bc0bbb38dd059e9c978be147cab7a4b7e8..efc84237b5ba202b0806bfa2e34db3a94e0d7a20 100644 (file)
@@ -50,7 +50,9 @@
 
         <module>inventory-manager</module>
         <module>statistics-manager</module>
+        <module>topology-manager</module>
         <module>forwardingrules-manager</module>
+        <module>topology-lldp-discovery</module>
 
         <!-- Compability Packages -->
         <module>compatibility</module>
index a788baf4c0642a1ebb26b390ba415a338a45a033..dedd318a0cf4b1e2cce4396d5b1874cc63548a74 100644 (file)
@@ -86,7 +86,7 @@
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>clustering.services</artifactId>
-            <version>0.4.1-SNAPSHOT</version>
+            <version>0.5.0-SNAPSHOT</version>
         </dependency>
 
 
index 35b2a4b25064d86794938e59bfcacf5b47548d72..1fd4b762c173089c720ddf3842ccc202faf5c91c 100644 (file)
@@ -25,7 +25,7 @@
             </Export-Package>
             <Import-Package>
               com.sun.jersey.spi.container.servlet,
-              org.codehaus.jackson.annotate,
+              com.fasterxml.jackson.annotation,
               javax.ws.rs,
               javax.ws.rs.core,
               javax.xml.bind,
index e20640d4202d0bc3441d713bb3caee9a5e14e9eb..72c6b1d75d99fec54f2914b2cc201e9a527910ed 100644 (file)
@@ -7,7 +7,7 @@ import org.opendaylight.yangtools.yang.binding.RpcService;
  * version of RpcServices
  * 
  */
-public interface RpcConsumerRegistry {
+public interface RpcConsumerRegistry extends BindingAwareService {
     /**
      * Returns a session specific instance (implementation) of requested
      * YANG module implentation / service provided by consumer.
index 972e64faf6caa16db8c994db7c39c5682eed1539..cc764888cca932b89dacfe8210c6671147bc5f9d 100644 (file)
@@ -1,18 +1,22 @@
 package org.opendaylight.controller.sal.binding.api;
 
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 
 /**
- * Interface defining provider's access to the Rpc Registry
- * which could be used to register their implementations of service to the MD-SAL.
+ * Interface defining provider's access to the Rpc Registry which could be used
+ * to register their implementations of service to the MD-SAL.
  * 
  * @author ttkacik
- *
+ * 
  */
-public interface RpcProviderRegistry extends RpcConsumerRegistry {
+public interface RpcProviderRegistry extends //
+        RpcConsumerRegistry, //
+        RouteChangePublisher<RpcContextIdentifier, InstanceIdentifier<?>> {
     /**
      * Registers an global RpcService implementation.
      * 
@@ -25,12 +29,16 @@ public interface RpcProviderRegistry extends RpcConsumerRegistry {
 
     /**
      * 
-     * Register an Routed RpcService where routing is determined on annotated (in YANG model)
-     * context-reference and value of annotated leaf.
+     * Register an Routed RpcService where routing is determined on annotated
+     * (in YANG model) context-reference and value of annotated leaf.
      * 
-     * @param type Type of RpcService, use generated interface class, not your implementation clas
-     * @param implementation Implementation of RpcService
-     * @return Registration object for routed Rpc which could be used to close an 
+     * @param type
+     *            Type of RpcService, use generated interface class, not your
+     *            implementation clas
+     * @param implementation
+     *            Implementation of RpcService
+     * @return Registration object for routed Rpc which could be used to close
+     *         an
      * 
      * @throws IllegalStateException
      */
index d91a216baa0f66bf4d5b7c8de94460844a321f06..194c431ec0aad22a2391f20d4949f414b53bc41b 100644 (file)
@@ -1,18 +1,36 @@
 package org.opendaylight.controller.sal.binding.api.mount;
 
+import java.util.EventListener;
+
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * Provider MountProviderService, this version allows access to MD-SAL
- * services specific for this mountpoint and registration / provision of
- * interfaces for mount point.
+ * Provider MountProviderService, this version allows access to MD-SAL services
+ * specific for this mountpoint and registration / provision of interfaces for
+ * mount point.
  * 
  * @author ttkacik
  * 
  */
-public interface MountProviderService extends MountInstance {
+public interface MountProviderService extends MountService {
+    
+    @Override
+    public MountProviderInstance getMountPoint(InstanceIdentifier<?> path);
 
     MountProviderInstance createMountPoint(InstanceIdentifier<?> path);
+
+    MountProviderInstance createOrGetMountPoint(InstanceIdentifier<?> path);
+
+    ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener);
+
+    public interface MountProvisionListener extends EventListener {
+
+        void onMountPointCreated(InstanceIdentifier<?> path);
+
+        void onMountPointRemoved(InstanceIdentifier<?> path);
+
+    }
 }
similarity index 98%
rename from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRouter.java
rename to opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRouter.java
index 621d048dfd771694d5b479588980140e9e873066..31fed62d876ef5b8e25512023393204bf1856d02 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.controller.sal.binding.spi;
+package org.opendaylight.controller.sal.binding.api.rpc;
 
 import java.util.Set;
 
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.controller.sal.binding.spi;
+package org.opendaylight.controller.sal.binding.api.rpc;
 
 import java.util.Map;
 
index 1b0f78384f1a6c166b46fed6f4f89152e276c77c..29357c04328a056c107af1671b35228970060979 100644 (file)
             <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.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
index c46b0dd6b4c529d00e0fae55f862f6a0229e701b..cd45f2c8b2bf8439f19bccbd4125e3eb3d253309 100644 (file)
@@ -1,48 +1,85 @@
 /**\r
-* Generated file\r
+ * Generated file\r
 \r
-* Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: binding-broker-impl\r
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator\r
-* Generated at: Wed Nov 20 17:33:01 CET 2013\r
-*\r
-* Do not modify this file unless it is present under src/main directory\r
-*/\r
+ * Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: binding-broker-impl\r
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator\r
+ * Generated at: Wed Nov 20 17:33:01 CET 2013\r
+ *\r
+ * Do not modify this file unless it is present under src/main directory\r
+ */\r
 package org.opendaylight.controller.config.yang.md.sal.binding.impl;\r
 \r
-import org.opendaylight.controller.sal.binding.impl.BindingAwareBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;\r
+import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;\r
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;\r
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardingUtils;\r
 import org.osgi.framework.BundleContext;\r
 \r
-import com.google.common.base.Preconditions;\r
+import com.google.common.util.concurrent.MoreExecutors;\r
 \r
 /**\r
 *\r
 */\r
-public final class BindingBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule {\r
+public final class BindingBrokerImplModule extends\r
+        org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule {\r
 \r
     private BundleContext bundleContext;\r
 \r
-    public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {\r
+    public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,\r
+            org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {\r
         super(identifier, dependencyResolver);\r
     }\r
 \r
-    public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, BindingBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {\r
+    public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,\r
+            org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,\r
+            BindingBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {\r
         super(identifier, dependencyResolver, oldModule, oldInstance);\r
     }\r
 \r
     @Override\r
-    public void validate(){\r
+    public void validate() {\r
         super.validate();\r
     }\r
 \r
     @Override\r
     public java.lang.AutoCloseable createInstance() {\r
-        BindingAwareBrokerImpl broker = new BindingAwareBrokerImpl(getIdentifier().getInstanceName(),getBundleContext());\r
-        broker.setDataBroker(getDataBrokerDependency());\r
-        broker.setNotifyBroker(getNotificationServiceDependency());\r
+\r
+        RootBindingAwareBroker broker;\r
+        if (DomForwardingUtils.isDomForwardedBroker(getDataBrokerDependency())) {\r
+            broker = createForwardedBroker();\r
+        } else {\r
+            broker = createStandaloneBroker();\r
+        }\r
         broker.start();\r
         return broker;\r
     }\r
 \r
+    private RootBindingAwareBroker createStandaloneBroker() {\r
+        RootBindingAwareBroker broker = new RootBindingAwareBroker(getIdentifier().getInstanceName());\r
+\r
+        broker.setDataBroker(getDataBrokerDependency());\r
+        broker.setNotificationBroker(getNotificationServiceDependency());\r
+        broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier()));\r
+        return broker;\r
+    }\r
+\r
+    private RootBindingAwareBroker createForwardedBroker() {\r
+        DomForwardedBindingBrokerImpl broker = new DomForwardedBindingBrokerImpl(getIdentifier().getInstanceName());\r
+\r
+        broker.setDataBroker(getDataBrokerDependency());\r
+        broker.setNotificationBroker(getNotificationServiceDependency());\r
+        broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier()));\r
+\r
+        broker.getMountManager().setDataCommitExecutor(SingletonHolder.getDefaultCommitExecutor());\r
+        broker.getMountManager().setNotificationExecutor(SingletonHolder.getDefaultNotificationExecutor());\r
+\r
+\r
+        DomForwardingUtils.reuseForwardingFrom(broker, broker.getDataBroker());\r
+        broker.startForwarding();\r
+        return broker;\r
+    }\r
+\r
     public BundleContext getBundleContext() {\r
         return bundleContext;\r
     }\r
index 01dc6b8c0cd6162be049fe44d6806524da820f7a..185b37bab53a2789763979525f9455e73aaee8d3 100644 (file)
@@ -13,12 +13,16 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;\r
 import java.util.concurrent.ScheduledExecutorService;\r
 \r
-import org.opendaylight.controller.config.yang.md.sal.binding.statistics.DataBrokerRuntimeMXBeanImpl;\r
 import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter;\r
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;\r
 import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.impl.RootDataBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;\r
 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;\r
 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;\r
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedDataBrokerImpl;\r
 import org.opendaylight.controller.sal.core.api.Broker;\r
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;\r
 import org.opendaylight.controller.sal.core.api.data.DataProviderService;\r
 import org.opendaylight.yangtools.yang.binding.DataObject;\r
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
@@ -52,25 +56,38 @@ public final class DataBrokerImplModule extends
 \r
     @Override\r
     public java.lang.AutoCloseable createInstance() {\r
-        DataBrokerRuntimeMXBeanImpl dataBindingBroker = new DataBrokerRuntimeMXBeanImpl();\r
+        RootDataBrokerImpl dataBindingBroker;\r
         \r
-        // FIXME: obtain via dependency management\r
-        ExecutorService executor = Executors.newCachedThreadPool();\r
-        ExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);\r
-        dataBindingBroker.setExecutor(listeningExecutor);\r
-\r
-        Broker domBroker = getDomBrokerDependency();\r
-        BindingIndependentMappingService mappingService = getMappingServiceDependency();\r
         \r
-        if (domBroker != null && mappingService != null) {\r
-            BindingIndependentConnector runtimeMapping = new BindingIndependentConnector();\r
-            runtimeMapping.setMappingService(mappingService);\r
-            runtimeMapping.setBaDataService(dataBindingBroker);\r
-            domBroker.registerProvider(runtimeMapping, getBundleContext());\r
+        ExecutorService listeningExecutor = SingletonHolder.getDefaultCommitExecutor();\r
+        \r
+        if (getDomBrokerDependency() != null && getMappingServiceDependency() != null) {\r
+            \r
+            dataBindingBroker = createDomConnectedBroker(listeningExecutor);\r
+        } else {\r
+            dataBindingBroker = createStandAloneBroker(listeningExecutor);\r
         }\r
-        getRootRuntimeBeanRegistratorWrapper().register(dataBindingBroker);\r
+        dataBindingBroker.registerRuntimeBean(getRootRuntimeBeanRegistratorWrapper());\r
+\r
         return dataBindingBroker;\r
     }\r
+    private RootDataBrokerImpl createStandAloneBroker(ExecutorService listeningExecutor) {\r
+        RootDataBrokerImpl broker = new RootDataBrokerImpl();\r
+        broker.setExecutor(listeningExecutor);\r
+        return broker;\r
+    }\r
+\r
+    private RootDataBrokerImpl createDomConnectedBroker(ExecutorService listeningExecutor) {\r
+        DomForwardedDataBrokerImpl forwardedBroker = new DomForwardedDataBrokerImpl();\r
+        forwardedBroker.setExecutor(listeningExecutor);\r
+        BindingIndependentConnector connector = BindingDomConnectorDeployer.createConnector(getMappingServiceDependency());\r
+        getDomBrokerDependency().registerProvider(forwardedBroker, getBundleContext());\r
+        ProviderSession domContext = forwardedBroker.getDomProviderContext();\r
+        forwardedBroker.setConnector(connector);\r
+        forwardedBroker.setDomProviderContext(domContext);\r
+        forwardedBroker.startForwarding();\r
+        return forwardedBroker;\r
+    }\r
 \r
     public BundleContext getBundleContext() {\r
         return bundleContext;\r
index e4f74deb4b3487e31f080186315bc14dc4f9d9d5..644860595e0de2f7b4974616ac341ccc363dc453 100644 (file)
@@ -13,6 +13,7 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
 import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl;
 
 import com.google.common.util.concurrent.ListeningExecutorService;
@@ -43,8 +44,7 @@ public final class NotificationBrokerImplModule extends
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        ExecutorService executor = Executors.newFixedThreadPool(5);
-        ListeningExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);
+        ListeningExecutorService listeningExecutor = SingletonHolder.getDefaultNotificationExecutor();
         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/statistics/DataBrokerRuntimeMXBeanImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/statistics/DataBrokerRuntimeMXBeanImpl.java
deleted file mode 100644 (file)
index 5da084e..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.opendaylight.controller.config.yang.md.sal.binding.statistics;\r
-\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.Data;\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeMXBean;\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.Transactions;\r
-import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;\r
-\r
-public class DataBrokerRuntimeMXBeanImpl extends DataBrokerImpl implements DataBrokerImplRuntimeMXBean {\r
-    \r
-    private final Transactions transactions = new Transactions();\r
-    private final Data data = new Data();\r
-    \r
-    public Transactions getTransactions() {\r
-        transactions.setCreated(getCreatedTransactionsCount().get());\r
-        transactions.setSubmitted(getSubmittedTransactionsCount().get());\r
-        transactions.setSuccessful(getFinishedTransactionsCount().get());\r
-        transactions.setFailed(getFailedTransactionsCount().get());\r
-        return transactions;\r
-    }\r
-\r
-    @Override\r
-    public Data getData() {\r
-        transactions.setCreated(getCreatedTransactionsCount().get());\r
-        transactions.setSubmitted(getSubmittedTransactionsCount().get());\r
-        transactions.setSuccessful(getFinishedTransactionsCount().get());\r
-        transactions.setFailed(getFailedTransactionsCount().get());\r
-        data.setTransactions(transactions);\r
-        return data;\r
-    }\r
-}\r
index 7789a06fe8c734f61215805d3e5b18bd558c4916..8aff12b44a5f1b5c58dfd816f457a918b497925d 100644 (file)
@@ -7,8 +7,8 @@
  */
 package org.opendaylight.controller.sal.binding.codegen;
 
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
 import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext;
index 8b2db8b13cd09b175fc1269ebec693717b70aab5..d976a0cec9ac7e828b9877001d0847e4cc29dab9 100644 (file)
@@ -3,7 +3,8 @@ package org.opendaylight.controller.sal.binding.codegen.impl;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable;
 import org.opendaylight.yangtools.yang.binding.BaseIdentity;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
@@ -13,7 +14,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.HashMap;
 
-import org.opendaylight.controller.sal.binding.spi.RpcRoutingTable;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.RpcImplementation;
 import org.opendaylight.controller.md.sal.common.api.routing.MutableRoutingTable;
@@ -147,7 +147,6 @@ public class RpcRouterCodegenInstance<T extends RpcService> implements //
         @Override
         public void unregisterPath(Class<? extends BaseIdentity> context, InstanceIdentifier<?> path) {
             routingTables.get(context).removeRoute(path, getInstance());
-
         }
 
         @Override
index 808358fb3503c1ea38bca66951137c1353c7b64d..76318ae843ff2e7f0689aea0527250ab288756d5 100644 (file)
@@ -1,6 +1,6 @@
 package org.opendaylight.controller.sal.binding.codegen.impl;
 
-import org.opendaylight.controller.sal.binding.spi.RpcRoutingTable;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable;
 import org.opendaylight.yangtools.yang.binding.BaseIdentity;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
index 266293fb6dc7f66fff5727fce78798046ced2561..446a9caf8e7fd48f415926f457c6e68abcf73745 100644 (file)
@@ -1,14 +1,49 @@
 package org.opendaylight.controller.sal.binding.codegen.impl;
 
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+
 import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator;
 import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
 
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
 import javassist.ClassPool;
 
 public class SingletonHolder {
 
-    public static final ClassPool CLASS_POOL = new ClassPool(); 
-    public static final org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator RPC_GENERATOR_IMPL = new org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator(CLASS_POOL);
+    public static final ClassPool CLASS_POOL = new ClassPool();
+    public static final org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator RPC_GENERATOR_IMPL = new org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator(
+            CLASS_POOL);
     public static final RuntimeCodeGenerator RPC_GENERATOR = RPC_GENERATOR_IMPL;
     public static final NotificationInvokerFactory INVOKER_FACTORY = RPC_GENERATOR_IMPL.getInvokerFactory();
+    private static ListeningExecutorService NOTIFICATION_EXECUTOR = null;
+    private static ListeningExecutorService COMMIT_EXECUTOR = null;
+
+    public static synchronized final ListeningExecutorService getDefaultNotificationExecutor() {
+        if (NOTIFICATION_EXECUTOR == null) {
+            NOTIFICATION_EXECUTOR = createNamedExecutor("md-sal-binding-notification-%d");
+        }
+        return NOTIFICATION_EXECUTOR;
+    }
+
+    public static synchronized final ListeningExecutorService getDefaultCommitExecutor() {
+        if (COMMIT_EXECUTOR == null) {
+            COMMIT_EXECUTOR = createNamedExecutor("md-sal-binding-commit-%d");
+        }
+
+        return COMMIT_EXECUTOR;
+    }
+
+    private static ListeningExecutorService createNamedExecutor(String format) {
+        ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat(format).build();
+        ExecutorService executor = Executors.newCachedThreadPool(factory);
+        return MoreExecutors.listeningDecorator(executor);
+
+    }
+
 }
index cdddec76d41f1e643f2f23591c3f678cd26c6eba..970e077c03be4800e25bdf9ee3c3e5ecf0b562ed 100644 (file)
@@ -1,6 +1,7 @@
 package org.opendaylight.controller.sal.binding.dom.serializer.api;
 
 import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.Node;
 
@@ -12,4 +13,6 @@ public interface AugmentationCodec<A extends Augmentation<?>> extends DomCodec<A
     
     @Override
     public ValueWithQName<A> deserialize(Node<?> input);
+
+    public QName getAugmentationQName();
 }
index b9a4fe87ac80518d054372b5d1056227ea683efb..4565b545baa4aaacc6926e5b43320263297548c3 100644 (file)
@@ -10,6 +10,7 @@ import java.util.List;
 
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.controller.sal.binding.dom.serializer.api.IdentifierCodec;
+import org.opendaylight.yangtools.yang.binding.DataObject;
 
 
 public interface CodecRegistry {
@@ -36,4 +37,6 @@ public interface CodecRegistry {
     void bindingClassEncountered(Class<?> cls);
 
     void putPathToClass(List<QName> names, Class<?> cls);
+
+    public abstract QName getQNameForAugmentation(Class<?> cls);
 }
index 150d0f199f83f5615a9a5a8b7bda07347e6be309..f84503bea4d6e720fe3f16578a01e23116b2e72b 100644 (file)
@@ -26,13 +26,13 @@ import org.opendaylight.yangtools.yang.binding.Augmentable
 import com.google.common.collect.ImmutableList
 import org.opendaylight.yangtools.yang.binding.Augmentation
 import java.util.concurrent.ConcurrentHashMap
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections
 
 class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
     
     private static val LOG = LoggerFactory.getLogger(InstanceIdentifierCodecImpl);
     val CodecRegistry codecRegistry;
     
-    val Map<Class<?>,QName> classToQName = new WeakHashMap;
     val Map<Class<?>, Map<List<QName>, Class<?>>> classToPreviousAugment = new WeakHashMap;
     
     public new(CodecRegistry registry) {
@@ -106,7 +106,7 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
                 
                 previousAugmentation = null;
             } else {
-                previousQName = resolveQname(baArg.type);
+                previousQName = codecRegistry.getQNameForAugmentation(baArg.type as Class);
                 previousAugmentation = baArg.type;
             }
         }
@@ -122,7 +122,7 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
     
     private def dispatch PathArgument serializePathArgument(Item argument, QName previousQname) {
         val type = argument.type;
-        val qname = resolveQname(type);
+        val qname = BindingReflections.findQName(type);
         if(previousQname == null) {
             return new NodeIdentifier(qname);
         }
@@ -134,7 +134,7 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
         val Map<QName,Object> predicates = new HashMap();
         val type = argument.type;
         val keyCodec = codecRegistry.getIdentifierCodecForIdentifiable(type);
-        val qname = resolveQname(type);
+        val qname = BindingReflections.findQName(type);
         val combinedInput =  new ValueWithQName(previousQname,argument.key)
         val compositeOutput = keyCodec.serialize(combinedInput as ValueWithQName);
         for(outputValue :compositeOutput.value) {
@@ -145,15 +145,4 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
         }
         return new NodeIdentifierWithPredicates(QName.create(previousQname,qname.localName),predicates);
     }
-    
-    def resolveQname(Class<?> class1) {
-        val qname = classToQName.get(class1);
-        if(qname !== null) {
-            return qname;
-        }
-        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 cabb1bc4e2c5359582bc95e1e30514f557801b64..89d9b49081bc5dbe032fa47572062a5570d3279f 100644 (file)
@@ -44,6 +44,7 @@ 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.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.Node;
@@ -153,6 +154,12 @@ public class LazyGeneratedCodecRegistry implements //
         }
         return codec;
     }
+    
+    @Override
+    public QName getQNameForAugmentation(Class<?> cls) {
+        checkArgument(Augmentation.class.isAssignableFrom(cls));
+        return getCodecForAugmentation((Class<? extends Augmentation>)cls).getAugmentationQName();
+    }
 
     private static Class<? extends Augmentable<?>> getAugmentableArgumentFrom(
             final Class<? extends Augmentation<?>> augmentation) {
@@ -909,9 +916,11 @@ public class LazyGeneratedCodecRegistry implements //
             Delegator<BindingCodec> {
 
         private BindingCodec delegate;
+        private QName augmentationQName;
 
         public AugmentationCodecWrapper(BindingCodec<Map<QName, Object>, Object> rawCodec) {
             this.delegate = rawCodec;
+            this.augmentationQName = BindingReflections.findQName(rawCodec.getClass());
         }
 
         @Override
@@ -936,6 +945,11 @@ public class LazyGeneratedCodecRegistry implements //
             Object rawCodecValue = getDelegate().deserialize((Map<QName, Object>) input);
             return new ValueWithQName<T>(input.getNodeType(), (T) rawCodecValue);
         }
+        
+        @Override
+        public QName getAugmentationQName() {
+            return augmentationQName;
+        }
     }
 
     private class IdentityCompositeCodec implements IdentitityCodec {
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend
deleted file mode 100644 (file)
index b4bf3f5..0000000
+++ /dev/null
@@ -1,76 +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.binding.impl
-
-import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider
-import org.osgi.framework.BundleContext
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener
-import org.opendaylight.controller.sal.binding.spi.RpcContextIdentifier
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.slf4j.LoggerFactory
-
-class BindingAwareBrokerImpl extends RpcProviderRegistryImpl implements BindingAwareBroker, AutoCloseable {
-    private static val log = LoggerFactory.getLogger(BindingAwareBrokerImpl)
-
-    private InstanceIdentifier<? extends DataObject> root = InstanceIdentifier.builder().toInstance();
-
-    @Property
-    private var NotificationProviderService notifyBroker
-
-    @Property
-    private var DataProviderService dataBroker
-
-    @Property
-    var BundleContext brokerBundleContext
-
-    public new(String name,BundleContext bundleContext) {
-        super(name);
-        _brokerBundleContext = bundleContext;
-    }
-
-    def start() {
-        log.info("Starting MD-SAL: Binding Aware Broker");
-    }
-
-
-
-    override registerConsumer(BindingAwareConsumer consumer, BundleContext bundleCtx) {
-        val ctx = consumer.createContext(bundleCtx)
-        consumer.onSessionInitialized(ctx)
-        return ctx
-    }
-
-    override registerProvider(BindingAwareProvider provider, BundleContext bundleCtx) {
-        val ctx = provider.createContext(bundleCtx)
-        provider.onSessionInitialized(ctx)
-        provider.onSessionInitiated(ctx as ProviderContext)
-        return ctx
-    }
-
-    private def createContext(BindingAwareConsumer consumer, BundleContext consumerCtx) {
-        new OsgiConsumerContext(consumerCtx, this)
-    }
-
-    private def createContext(BindingAwareProvider provider, BundleContext providerCtx) {
-        new OsgiProviderContext(providerCtx, this)
-    }
-
-    override <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> registerRouteChangeListener(L listener) {
-        super.<L>registerRouteChangeListener(listener)
-    }
-    
-    override close() throws Exception {
-        
-    }
-}
\ No newline at end of file
index 5db522f56c34b6c6816b067d96441034a01dfed1..0069de98026dfa2f710e77fc3b60b3a026e6f37d 100644 (file)
@@ -3,7 +3,7 @@ package org.opendaylight.controller.sal.binding.impl;
 import java.util.Set;
 import java.util.concurrent.Future;\r
 import java.util.concurrent.atomic.AtomicLong;\r
-
+\r
 import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker;\r
 import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;\r
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;\r
@@ -11,12 +11,13 @@ import org.opendaylight.controller.sal.binding.impl.util.BindingAwareDataReaderR
 import org.opendaylight.controller.sal.common.DataStoreIdentifier;\r
 import org.opendaylight.yangtools.yang.binding.DataObject;\r
 import org.opendaylight.yangtools.yang.binding.DataRoot;\r
+import org.opendaylight.yangtools.yang.binding.Identifiable;\r
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
 import org.opendaylight.yangtools.yang.common.RpcResult;\r
 \r
 \r
-public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> implements\r
-        DataProviderService, AutoCloseable {\r
+public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> //\r
+       implements DataProviderService, AutoCloseable {\r
 \r
     private final AtomicLong nextTransaction = new AtomicLong();\r
     private final AtomicLong createdTransactionsCount = new AtomicLong();\r
@@ -114,7 +115,6 @@ public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? exte
                 return true;
             }
         }
-
         return false;
     }\r
 }
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/MountPointManagerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/MountPointManagerImpl.java
new file mode 100644 (file)
index 0000000..f8059fe
--- /dev/null
@@ -0,0 +1,120 @@
+package org.opendaylight.controller.sal.binding.impl;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.md.sal.binding.util.AbstractBindingSalProviderInstance;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+public class MountPointManagerImpl implements MountProviderService {
+
+    public final Logger LOG = LoggerFactory.getLogger(MountPointManagerImpl.class);
+
+    private final ConcurrentMap<InstanceIdentifier<?>, BindingMountPointImpl> mountPoints;
+    private final ListenerRegistry<MountProvisionListener> listeners = ListenerRegistry.create();
+    
+    private ListeningExecutorService notificationExecutor;
+    private ListeningExecutorService dataCommitExecutor;
+
+    public MountPointManagerImpl() {
+        mountPoints = new ConcurrentHashMap<>();
+    }
+
+    public ListeningExecutorService getNotificationExecutor() {
+        return notificationExecutor;
+    }
+
+    public void setNotificationExecutor(ListeningExecutorService notificationExecutor) {
+        this.notificationExecutor = notificationExecutor;
+    }
+
+    public ListeningExecutorService getDataCommitExecutor() {
+        return dataCommitExecutor;
+    }
+
+    public void setDataCommitExecutor(ListeningExecutorService dataCommitExecutor) {
+        this.dataCommitExecutor = dataCommitExecutor;
+    }
+
+    @Override
+    public synchronized BindingMountPointImpl createMountPoint(InstanceIdentifier<?> path) {
+        BindingMountPointImpl potential = mountPoints.get(path);
+        if (potential != null) {
+            throw new IllegalStateException("Mount point already exists.");
+        }
+        return createOrGetMountPointImpl(path);
+    }
+
+    @Override
+    public BindingMountPointImpl createOrGetMountPoint(InstanceIdentifier<?> path) {
+        BindingMountPointImpl potential = getMountPoint(path);
+        if (potential != null) {
+            return potential;
+        }
+        return createOrGetMountPointImpl(path);
+    }
+
+    @Override
+    public BindingMountPointImpl getMountPoint(InstanceIdentifier<?> path) {
+        return mountPoints.get(path);
+    }
+
+    private synchronized BindingMountPointImpl createOrGetMountPointImpl(InstanceIdentifier<?> path) {
+        BindingMountPointImpl potential = getMountPoint(path);
+        if (potential != null) {
+            return potential;
+        }
+        RpcProviderRegistryImpl rpcRegistry = new RpcProviderRegistryImpl("mount");
+        NotificationBrokerImpl notificationBroker = new NotificationBrokerImpl();
+        notificationBroker.setExecutor(getNotificationExecutor());
+        DataBrokerImpl dataBroker = new DataBrokerImpl();
+        dataBroker.setExecutor(getDataCommitExecutor());
+        BindingMountPointImpl mountInstance = new BindingMountPointImpl(path, rpcRegistry, notificationBroker,
+                dataBroker);
+        mountPoints.putIfAbsent(path, mountInstance);
+        notifyMountPointCreated(path);
+        return mountInstance;
+    }
+
+    private void notifyMountPointCreated(InstanceIdentifier<?> path) {
+        for (ListenerRegistration<MountProvisionListener> listener : listeners) {
+            try {
+                listener.getInstance().onMountPointCreated(path);
+            } catch (Exception e) {
+                LOG.error("Unhandled exception during invoking listener.", e);
+            }
+        }
+    }
+
+    @Override
+    public ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener) {
+        return listeners.register(listener);
+    }
+
+    public class BindingMountPointImpl extends
+            AbstractBindingSalProviderInstance<DataBrokerImpl, NotificationBrokerImpl, RpcProviderRegistryImpl>
+    implements MountProviderInstance {
+
+        private InstanceIdentifier<?> identifier;
+
+        public BindingMountPointImpl(org.opendaylight.yangtools.yang.binding.InstanceIdentifier<?> identifier,
+                RpcProviderRegistryImpl rpcRegistry, NotificationBrokerImpl notificationBroker,
+                DataBrokerImpl dataBroker) {
+            super(rpcRegistry, notificationBroker, dataBroker);
+            this.identifier = identifier;
+        }
+        
+        @Override
+        public InstanceIdentifier<?> getIdentifier() {
+            return this.identifier;
+        }
+    }
+}
index b10c06f0c53e359ec2cabe3028b7243339c6f53b..b4fd6b67712d6054b2f74737d89f3ea091aa9345 100644 (file)
@@ -20,8 +20,9 @@ import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
 import org.opendaylight.yangtools.concepts.ListenerRegistration\r
 import org.opendaylight.yangtools.concepts.Registration\r
 import org.opendaylight.yangtools.yang.binding.Notification\r
-import org.slf4j.LoggerFactory\rimport org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder
-
+import org.slf4j.LoggerFactory\r
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder\r
+\r
 class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable {\r
 \r
     val Multimap<Class<? extends Notification>, NotificationListener<?>> listeners;\r
@@ -174,14 +175,24 @@ class NotifyTask implements Callable<Object> {
 \r
     private static val log = LoggerFactory.getLogger(NotifyTask);\r
 \r
+    @SuppressWarnings("rawtypes")\r
     val NotificationListener listener;\r
     val Notification notification;\r
 \r
     override call() {\r
+        //Only logging the complete notification in debug mode\r
         try {\r
-            log.info("Delivering notification {} to {}",notification,listener);\r
+            if(log.isDebugEnabled){\r
+                log.debug("Delivering notification {} to {}",notification,listener);\r
+            } else {\r
+                log.info("Delivering notification {} to {}",notification.class.name,listener);\r
+            }\r
             listener.onNotification(notification);\r
-            log.info("Notification delivered {} to {}",notification,listener);\r
+            if(log.isDebugEnabled){\r
+                log.debug("Notification delivered {} to {}",notification,listener);\r
+            } else {\r
+                log.info("Notification delivered {} to {}",notification.class.name,listener);\r
+            }\r
         } catch (Exception e) {\r
             log.error("Unhandled exception thrown by listener: {}", listener, e);\r
         }\r
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend
deleted file mode 100644 (file)
index 644c50b..0000000
+++ /dev/null
@@ -1,60 +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.binding.impl;
-
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
-import org.opendaylight.controller.sal.binding.api.BindingAwareService;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.slf4j.LoggerFactory
-import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.*
-
-class OsgiConsumerContext implements ConsumerContext {
-
-    static val log = LoggerFactory.getLogger(OsgiConsumerContext)
-    protected val BundleContext bundleContext;
-    protected val BindingAwareBrokerImpl broker;
-
-    new(BundleContext ctx, BindingAwareBrokerImpl broker) {
-        this.bundleContext = ctx;
-        this.broker = broker;
-    }
-
-    override def <T extends BindingAwareService> getSALService(Class<T> service) {
-
-        // SAL Services are global
-        var ref = bundleContext.getServiceReference(service);
-        return bundleContext.getService(ref) as T;
-    }
-
-    override def <T extends RpcService> T getRpcService(Class<T> module) {
-        try {
-
-            val services = bundleContext.getServiceReferences(module, getProxyFilter());
-
-            // Proxy service found / using first implementation
-            // FIXME: Add advanced logic to retrieve service with right set of models
-            if (false == services.empty) {
-                val ref = services.iterator().next() as ServiceReference<T>;
-                return bundleContext.getService(ref) as T;
-            } else {
-                return broker.getRpcService(module);
-            }
-        } catch (InvalidSyntaxException e) {
-            log.error("Created filter was invalid:", e.message, e)
-        }
-        return null;
-
-    }
-
-    private def getProxyFilter() {
-        return '''(«SAL_SERVICE_TYPE»=«SAL_SERVICE_TYPE_CONSUMER_PROXY»)'''
-    }
-}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiProviderContext.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiProviderContext.xtend
deleted file mode 100644 (file)
index d1ec351..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.impl;
-
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.osgi.framework.BundleContext;
-
-import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.*;
-import static extension org.opendaylight.controller.sal.binding.impl.osgi.PropertiesUtils.*;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality
-import static com.google.common.base.Preconditions.*
-
-class OsgiProviderContext extends OsgiConsumerContext implements ProviderContext {
-
-    @Property
-    val Map<Class<? extends RpcService>, RpcRegistration<? extends RpcService>> registeredServices
-
-    new(BundleContext ctx, BindingAwareBrokerImpl broker) {
-        super(ctx, broker);
-        _registeredServices = new HashMap();
-    }
-
-    override <T extends RpcService> addRpcImplementation(Class<T> type, T implementation) {
-        val salReg = broker.addRpcImplementation(type, implementation)
-        registeredServices.put(type, salReg)
-        return salReg;
-    }
-
-    override <T extends RpcService> addRoutedRpcImplementation(Class<T> type, T implementation) throws IllegalStateException {
-        val salReg = broker.addRoutedRpcImplementation(type, implementation)
-        registeredServices.put(type, salReg)
-        return salReg;
-    }
-
-    override registerFunctionality(ProviderFunctionality functionality) {
-        // NOOP for now
-    }
-
-    override unregisterFunctionality(ProviderFunctionality functionality) {
-        // NOOP for now
-    }
-}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootBindingAwareBroker.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootBindingAwareBroker.java
new file mode 100644 (file)
index 0000000..35c2bee
--- /dev/null
@@ -0,0 +1,174 @@
+package org.opendaylight.controller.sal.binding.impl;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import org.opendaylight.controller.md.sal.binding.util.AbstractBindingSalProviderInstance;
+import org.opendaylight.controller.md.sal.binding.util.BindingContextUtils;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareService;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.NotificationService;
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
+import org.opendaylight.controller.sal.binding.api.mount.MountService;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Mutable;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableClassToInstanceMap;
+
+public class RootBindingAwareBroker implements //
+        Mutable, //
+        Identifiable<String>, //
+        BindingAwareBroker, AutoCloseable,
+        RpcProviderRegistry {
+
+    private final static Logger LOG = LoggerFactory.getLogger(RootBindingAwareBroker.class);
+
+    RootSalInstance controllerRoot;
+
+    private final String identifier;
+
+    private RpcProviderRegistry rpcBroker;
+
+    private NotificationProviderService notificationBroker;
+
+    private DataProviderService dataBroker;
+
+    private MountPointManagerImpl mountManager;
+
+    public MountPointManagerImpl getMountManager() {
+        return mountManager;
+    }
+
+    public void setMountManager(MountPointManagerImpl mountManager) {
+        this.mountManager = mountManager;
+    }
+
+    private ImmutableClassToInstanceMap<BindingAwareService> supportedConsumerServices;
+
+    private ImmutableClassToInstanceMap<BindingAwareService> supportedProviderServices;
+
+    public RootBindingAwareBroker(String instanceName) {
+        this.identifier = instanceName;
+        mountManager = new MountPointManagerImpl();
+    }
+
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    public RootSalInstance getRoot() {
+        return controllerRoot;
+    }
+
+    public DataProviderService getDataBroker() {
+        return this.dataBroker;
+    }
+
+    public NotificationProviderService getNotificationBroker() {
+        return this.notificationBroker;
+    }
+
+    public RpcProviderRegistry getRpcProviderRegistry() {
+        return this.rpcBroker;
+    }
+
+    public RpcProviderRegistry getRpcBroker() {
+        return rpcBroker;
+    }
+
+    public void setRpcBroker(RpcProviderRegistry rpcBroker) {
+        this.rpcBroker = rpcBroker;
+    }
+
+    public void setNotificationBroker(NotificationProviderService notificationBroker) {
+        this.notificationBroker = notificationBroker;
+    }
+
+    public void setDataBroker(DataProviderService dataBroker) {
+        this.dataBroker = dataBroker;
+    }
+
+    public void start() {
+        checkState(controllerRoot == null, "Binding Aware Broker was already started.");
+        LOG.info("Starting Binding Aware Broker: {}", identifier);
+
+        controllerRoot = new RootSalInstance(getRpcProviderRegistry(), getNotificationBroker(), getDataBroker());
+        
+
+        supportedConsumerServices = ImmutableClassToInstanceMap.<BindingAwareService> builder()
+                .put(NotificationService.class, getRoot()) //
+                .put(DataBrokerService.class, getRoot()) //
+                .put(RpcConsumerRegistry.class, getRoot()) //
+                .put(MountService.class, mountManager).build();
+
+        supportedProviderServices = ImmutableClassToInstanceMap.<BindingAwareService> builder()
+                .putAll(supportedConsumerServices)
+                .put(NotificationProviderService.class, getRoot()) //
+                .put(DataProviderService.class, getRoot()) //
+                .put(RpcProviderRegistry.class, getRoot()) //
+                .put(MountProviderService.class, mountManager).build();
+    }
+
+    @Override
+    public ConsumerContext registerConsumer(BindingAwareConsumer consumer, BundleContext ctx) {
+        checkState(supportedConsumerServices != null, "Broker is not initialized.");
+        return BindingContextUtils.createConsumerContextAndInitialize(consumer, supportedConsumerServices);
+    }
+
+    @Override
+    public ProviderContext registerProvider(BindingAwareProvider provider, BundleContext ctx) {
+        checkState(supportedProviderServices != null, "Broker is not initialized.");
+        return BindingContextUtils.createProviderContextAndInitialize(provider, supportedProviderServices);
+    }
+
+    @Override
+    public void close() throws Exception {
+        // FIXME: Close all sessions
+    }
+    
+    @Override
+    public <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type, T implementation)
+            throws IllegalStateException {
+        return getRoot().addRoutedRpcImplementation(type, implementation);
+    }
+    
+    @Override
+    public <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
+            throws IllegalStateException {
+        return getRoot().addRpcImplementation(type, implementation);
+    }
+    
+    @Override
+    public <T extends RpcService> T getRpcService(Class<T> module) {
+        return getRoot().getRpcService(module);
+    }
+    @Override
+    public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
+            L arg0) {
+        return getRoot().registerRouteChangeListener(arg0);
+    }
+    
+
+    public class RootSalInstance extends
+            AbstractBindingSalProviderInstance<DataProviderService, NotificationProviderService, RpcProviderRegistry> {
+
+        public RootSalInstance(RpcProviderRegistry rpcRegistry, NotificationProviderService notificationBroker,
+                DataProviderService dataBroker) {
+            super(rpcRegistry, notificationBroker, dataBroker);
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootDataBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootDataBrokerImpl.java
new file mode 100644 (file)
index 0000000..1b6c56d
--- /dev/null
@@ -0,0 +1,43 @@
+package org.opendaylight.controller.sal.binding.impl;\r
+\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.Data;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeMXBean;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeRegistration;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeRegistrator;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.Transactions;\r
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;\r
+\r
+public class RootDataBrokerImpl extends DataBrokerImpl implements DataBrokerImplRuntimeMXBean {\r
+\r
+    private final Transactions transactions = new Transactions();\r
+    private final Data data = new Data();\r
+    private BindingIndependentConnector bindingIndependentConnector;\r
+    private DataBrokerImplRuntimeRegistration runtimeBeanRegistration;\r
+\r
+    public BindingIndependentConnector getBindingIndependentConnector() {\r
+        return bindingIndependentConnector;\r
+    }\r
+\r
+    public Transactions getTransactions() {\r
+        transactions.setCreated(getCreatedTransactionsCount().get());\r
+        transactions.setSubmitted(getSubmittedTransactionsCount().get());\r
+        transactions.setSuccessful(getFinishedTransactionsCount().get());\r
+        transactions.setFailed(getFailedTransactionsCount().get());\r
+        return transactions;\r
+    }\r
+\r
+    @Override\r
+    public Data getData() {\r
+        data.setTransactions(getTransactions());\r
+        return data;\r
+    }\r
+\r
+    public void setBindingIndependentConnector(BindingIndependentConnector runtimeMapping) {\r
+        this.bindingIndependentConnector = runtimeMapping;\r
+    }\r
+\r
+    public void registerRuntimeBean(DataBrokerImplRuntimeRegistrator rootRegistrator) {\r
+        runtimeBeanRegistration = rootRegistrator.register(this);\r
+    }\r
+\r
+}\r
index 6a17007d22779c81dd9a55d592fc80da73323f6f..8773476caee9ee4fd01f7b75b3b128bb331e3edd 100644 (file)
@@ -15,11 +15,11 @@ import org.opendaylight.controller.md.sal.common.impl.routing.RoutingUtils;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
 import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator;
 import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper;
 import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
-import org.opendaylight.controller.sal.binding.spi.RpcContextIdentifier;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
 import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java
new file mode 100644 (file)
index 0000000..f200b4d
--- /dev/null
@@ -0,0 +1,103 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+
+public class BindingDomConnectorDeployer {
+
+    private static BindingIndependentMappingService mappingService;
+
+    public static BindingIndependentConnector tryToDeployConnector(RootBindingAwareBroker baBroker,
+            ProviderSession domSession) {
+        checkNotNull(baBroker);
+        checkNotNull(domSession);
+        BindingIndependentConnector connector = createConnector(mappingService);
+        return connector;
+    }
+
+    public static BindingIndependentConnector createConnector(BindingIndependentMappingService mappingService) {
+        BindingIndependentConnector connector = new BindingIndependentConnector();
+        connector.setMappingService(mappingService);
+        return connector;
+    }
+
+    public static BindingIndependentConnector createConnector(BindingIndependentConnector source) {
+        BindingIndependentConnector connector = new BindingIndependentConnector();
+        connector.setMappingService(source.getMappingService());
+        return connector;
+    }
+    
+    public static void startDataForwarding(BindingIndependentConnector connector, DataProviderService baService,
+            ProviderSession domContext) {
+        startDataForwarding(connector, baService,
+                domContext.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
+    }
+
+    public static void startRpcForwarding(BindingIndependentConnector connector,
+            RpcProviderRegistry rpcProviderRegistry, ProviderSession domProviderContext) {
+        startRpcForwarding(connector, rpcProviderRegistry, domProviderContext.getService(RpcProvisionRegistry.class));
+
+    }
+    
+    public static void startNotificationForwarding(BindingIndependentConnector connector, NotificationProviderService provider,ProviderSession domProviderContext) {
+        startNotificationForwarding(connector, provider, domProviderContext.getService(NotificationPublishService.class));
+    }
+
+    public static void startRpcForwarding(BindingIndependentConnector connector, RpcProviderRegistry baService,
+            RpcProvisionRegistry domService) {
+        if (connector.isRpcForwarding()) {
+            return;
+        }
+
+        connector.setDomRpcRegistry(domService);
+        connector.setBindingRpcRegistry(baService);
+        connector.startRpcForwarding();
+    }
+
+    public static void startDataForwarding(BindingIndependentConnector connector, DataProviderService baService,
+            org.opendaylight.controller.sal.core.api.data.DataProviderService domService) {
+        if (connector.isDataForwarding()) {
+            return;
+        }
+
+        connector.setBindingDataService(baService);
+        connector.setDomDataService(domService);
+        connector.startDataForwarding();
+    }
+    
+    public static void startNotificationForwarding(BindingIndependentConnector connector, NotificationProviderService baService, NotificationPublishService domService) {
+        if(connector.isNotificationForwarding()) {
+            return;
+        }
+        
+        // FIXME
+    }
+
+    //
+    // public static BindingIndependentMappingService getGlobalMappingService()
+    // {
+    // return mappingService;
+    // }
+    //
+    // protected static BindingIndependentMappingService
+    // setGlobalMappingService(BindingIndependentMappingService service) {
+    // mappingService= service;
+    // return mappingService;
+    // }
+    //
+    // public static BindingIndependentConnector
+    // tryToDeployConnector(MountProviderInstance baMount,MountProvisionInstance
+    // domMount) {
+    //
+    //
+    // return null;
+    // }
+
+}
index daa3914cf73fd717c63cb2c3e251dc175ffe1191..75b0138e7cd75657adba42182d0dc7e0cf9c270c 100644 (file)
@@ -1,12 +1,9 @@
 package org.opendaylight.controller.sal.binding.impl.connect.dom;
 
 import java.lang.ref.WeakReference;
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -18,21 +15,23 @@ import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
-
 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.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.md.sal.common.api.data.DataReader;
 import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
 import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
 import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
-import org.opendaylight.controller.sal.binding.spi.RpcContextIdentifier;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.controller.sal.common.util.CommitHandlerTransactions;
 import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
@@ -49,7 +48,6 @@ import org.opendaylight.yangtools.yang.binding.BindingMapping;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.RpcInput;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -65,7 +63,6 @@ import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableSet;
 
 import static com.google.common.base.Preconditions.*;
-import static org.opendaylight.yangtools.concepts.util.ClassLoaderUtils.*;
 
 public class BindingIndependentConnector implements //
         RuntimeDataProvider, //
@@ -96,7 +93,7 @@ public class BindingIndependentConnector implements //
     private Registration<DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode>> biCommitHandlerRegistration;
 
     private RpcProvisionRegistry biRpcRegistry;
-    private RpcProviderRegistryImpl baRpcRegistry;
+    private RpcProviderRegistry baRpcRegistry;
 
     private ListenerRegistration<DomToBindingRpcForwardingManager> domToBindingRpcManager;
     // private ListenerRegistration<BindingToDomRpcForwardingManager>
@@ -111,36 +108,44 @@ public class BindingIndependentConnector implements //
 
     };
 
+    private Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> baDataReaderRegistration;
+
+    private boolean rpcForwarding = false;
+
+    private boolean dataForwarding = false;
+
+    private boolean notificationForwarding = false;
+
     @Override
     public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
         try {
             org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
-
             CompositeNode result = biDataService.readOperationalData(biPath);
-            Class<? extends DataObject> targetType = path.getTargetType();
-
-            if (Augmentation.class.isAssignableFrom(targetType)) {
-                path = mappingService.fromDataDom(biPath);
-                Class<? extends Augmentation<?>> augmentType = (Class<? extends Augmentation<?>>) targetType;
-                DataObject parentTo = mappingService.dataObjectFromDataDom(path, result);
-                if (parentTo instanceof Augmentable<?>) {
-                    return (DataObject) ((Augmentable) parentTo).getAugmentation(augmentType);
-                }
-
-            }
-            return mappingService.dataObjectFromDataDom(path, result);
-
+            return potentialAugmentationRead(path,biPath,result);
         } catch (DeserializationException e) {
             throw new IllegalStateException(e);
         }
     }
 
+    private DataObject potentialAugmentationRead(InstanceIdentifier<? extends DataObject> path, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, CompositeNode result) throws DeserializationException {
+        Class<? extends DataObject> targetType = path.getTargetType();
+        if (Augmentation.class.isAssignableFrom(targetType)) {
+            path = mappingService.fromDataDom(biPath);
+            Class<? extends Augmentation<?>> augmentType = (Class<? extends Augmentation<?>>) targetType;
+            DataObject parentTo = mappingService.dataObjectFromDataDom(path, result);
+            if (parentTo instanceof Augmentable<?>) {
+                return (DataObject) ((Augmentable) parentTo).getAugmentation(augmentType);
+            }
+        }
+        return mappingService.dataObjectFromDataDom(path, result);
+    }
+
     @Override
     public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
         try {
             org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
             CompositeNode result = biDataService.readConfigurationData(biPath);
-            return mappingService.dataObjectFromDataDom(path, result);
+            return potentialAugmentationRead(path,biPath,result);
         } catch (DeserializationException e) {
             throw new IllegalStateException(e);
         }
@@ -222,7 +227,7 @@ public class BindingIndependentConnector implements //
         return biDataService;
     }
 
-    public void setBiDataService(org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
+    protected void setDomDataService(org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
         this.biDataService = biDataService;
     }
 
@@ -230,7 +235,7 @@ public class BindingIndependentConnector implements //
         return baDataService;
     }
 
-    public void setBaDataService(DataProviderService baDataService) {
+    protected void setBindingDataService(DataProviderService baDataService) {
         this.baDataService = baDataService;
     }
 
@@ -238,23 +243,33 @@ public class BindingIndependentConnector implements //
         return baRpcRegistry;
     }
 
-    public void setRpcRegistry(RpcProviderRegistryImpl rpcRegistry) {
+    protected void setBindingRpcRegistry(RpcProviderRegistry rpcRegistry) {
         this.baRpcRegistry = rpcRegistry;
     }
 
-    public void start() {
-        baDataService.registerDataReader(ROOT, this);
+    public void startDataForwarding() {
+        checkState(!dataForwarding, "Connector is already forwarding data.");
+        baDataReaderRegistration = baDataService.registerDataReader(ROOT, this);
         baCommitHandlerRegistration = baDataService.registerCommitHandler(ROOT, bindingToDomCommitHandler);
         biCommitHandlerRegistration = biDataService.registerCommitHandler(ROOT_BI, domToBindingCommitHandler);
         baDataService.registerCommitHandlerListener(domToBindingCommitHandler);
-
-        if (baRpcRegistry != null && biRpcRegistry != null) {
+        dataForwarding = true;
+    }
+    
+    public void startRpcForwarding() {
+        if (baRpcRegistry != null && biRpcRegistry != null && baRpcRegistry instanceof RouteChangePublisher<?, ?>) {
+            checkState(!rpcForwarding,"Connector is already forwarding RPCs");
             domToBindingRpcManager = baRpcRegistry.registerRouteChangeListener(new DomToBindingRpcForwardingManager());
-
+            rpcForwarding = true;
         }
     }
+    
+    public void startNotificationForwarding() {
+        checkState(!notificationForwarding, "Connector is already forwarding notifications.");
+        notificationForwarding = true;
+    }
 
-    public void setMappingService(BindingIndependentMappingService mappingService) {
+    protected void setMappingService(BindingIndependentMappingService mappingService) {
         this.mappingService = mappingService;
     }
 
@@ -265,8 +280,9 @@ public class BindingIndependentConnector implements //
 
     @Override
     public void onSessionInitiated(ProviderSession session) {
-        setBiDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
-        start();
+        setDomDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
+        setDomRpcRegistry(session.getService(RpcProvisionRegistry.class));
+        
     }
 
     public <T extends RpcService> void onRpcRouterCreated(Class<T> serviceType, RpcRouter<T> router) {
@@ -381,7 +397,7 @@ public class BindingIndependentConnector implements //
              */
             if (bindingOpenedTransactions.containsKey(bindingTransaction.getIdentifier())) {
 
-                return CommitHandlersTransactions.allwaysSuccessfulTransaction(bindingTransaction);
+                return CommitHandlerTransactions.allwaysSuccessfulTransaction(bindingTransaction);
             }
             DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction);
             BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction);
@@ -420,7 +436,7 @@ public class BindingIndependentConnector implements //
              * duplicating data.
              */
             if (domOpenedTransactions.containsKey(identifier)) {
-                return CommitHandlersTransactions.allwaysSuccessfulTransaction(domTransaction);
+                return CommitHandlerTransactions.allwaysSuccessfulTransaction(domTransaction);
             }
 
             org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction baTransaction = createDomToBindingTransaction(domTransaction);
@@ -597,6 +613,7 @@ public class BindingIndependentConnector implements //
         @SuppressWarnings("rawtypes")
         private WeakReference<Class> outputClass;
 
+        @SuppressWarnings({ "rawtypes", "unchecked" })
         public DefaultInvocationStrategy(Method targetMethod, Class<?> outputClass,
                 Class<? extends DataContainer> inputClass) {
             super(targetMethod);
@@ -624,10 +641,27 @@ public class BindingIndependentConnector implements //
         }
 
         public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
+            @SuppressWarnings("unchecked")
             Future<RpcResult<Void>> result = (Future<RpcResult<Void>>) targetMethod.invoke(rpcService);
             RpcResult<Void> bindingResult = result.get();
             return Rpcs.getRpcResult(bindingResult.isSuccessful(), bindingResult.getErrors());
         }
+    }
+
+    public boolean isRpcForwarding() {
+        return rpcForwarding;
+    }
+
+    public boolean isDataForwarding() {
+        return dataForwarding;
+    }
+
+    public boolean isNotificationForwarding() {
+        // TODO Auto-generated method stub
+        return notificationForwarding;
+    }
 
+    public BindingIndependentMappingService getMappingService() {
+        return mappingService;
     }
 }
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java
new file mode 100644 (file)
index 0000000..630b5fa
--- /dev/null
@@ -0,0 +1,128 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class BindingIndependentMountPointForwarder {
+
+    private MountProvisionService domMountService;
+    private MountProviderService baMountService;
+    private BindingIndependentMappingService mappingService;
+    
+    private final DomMountPointForwardingManager domForwardingManager = new DomMountPointForwardingManager();
+    private final BindingMountPointForwardingManager bindingForwardingManager = new BindingMountPointForwardingManager();
+
+    private ConcurrentMap<InstanceIdentifier<?>, BindingIndependentConnector> connectors;
+    private ConcurrentMap<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded;
+    private ListenerRegistration<MountProvisionListener> domListenerRegistration;
+    private ListenerRegistration<org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener> baListenerRegistration;
+
+    public MountProvisionService getDomMountService() {
+        return domMountService;
+    }
+
+    public void setDomMountService(MountProvisionService domMountService) {
+        this.domMountService = domMountService;
+    }
+
+    public void start() {
+        if(domMountService != null && baMountService != null) {
+            domListenerRegistration = domMountService.registerProvisionListener(domForwardingManager);
+            baListenerRegistration = baMountService.registerProvisionListener(bindingForwardingManager);
+        }
+    }
+
+    private void tryToDeployConnector(InstanceIdentifier<?> baPath,
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier previous = forwarded.putIfAbsent(baPath, biPath);
+        if(previous != null) {
+            return;
+        }
+        MountProviderInstance baMountPoint = baMountService.getMountPoint(baPath);
+        MountProvisionInstance domMountPoint = domMountService.getMountPoint(biPath);
+        BindingIndependentConnector connector = createForwarder(baPath, baMountPoint, domMountPoint);
+        connectors.put(baPath, connector);
+        connector.startDataForwarding();
+        connector.startRpcForwarding();
+        connector.startNotificationForwarding();
+    }
+
+    private BindingIndependentConnector createForwarder(InstanceIdentifier<?> path, MountProviderInstance baMountPoint,
+            MountProvisionInstance domMountPoint) {
+        BindingIndependentConnector connector = new BindingIndependentConnector();
+        
+        connector.setBindingDataService(baMountPoint);
+        connector.setBindingRpcRegistry(baMountPoint);
+        //connector.setBindingNotificationBroker(baMountPoint);
+        
+        connector.setDomDataService(domMountPoint);
+        connector.setDomRpcRegistry(domMountPoint);
+        //connector.setDomNotificationBroker(domMountPoint);
+        return connector;
+    }
+
+    public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) {
+        InstanceIdentifier<?> baPath;
+        try {
+            baPath = mappingService.fromDataDom(domPath);
+            BindingIndependentConnector potentialConnector = connectors.get(baPath);
+            if(potentialConnector != null) {
+                return;
+            }
+            tryToDeployConnector(baPath,domPath);
+        } catch (DeserializationException e) {
+            
+        }
+    }
+
+    public synchronized void tryToDeployBindingForwarder(InstanceIdentifier<?> baPath) {
+        BindingIndependentConnector potentialConnector =connectors.get(baPath);
+        if(potentialConnector != null) {
+            return;
+        }
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(baPath);
+        tryToDeployConnector(baPath, domPath);
+    }
+
+    public synchronized void undeployBindingForwarder(InstanceIdentifier<?> baPath) {
+        // FIXME: Implement closeMountPoint
+    }
+
+    public synchronized void undeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
+        // FIXME: Implement closeMountPoint
+    }
+
+    private class DomMountPointForwardingManager implements MountProvisionListener {
+
+        @Override
+        public void onMountPointCreated(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
+            tryToDeployDomForwarder(path);
+        }
+
+        @Override
+        public void onMountPointRemoved(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
+            undeployDomForwarder(path);
+        }
+    }
+
+    private class BindingMountPointForwardingManager implements
+            org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener {
+
+        @Override
+        public void onMountPointCreated(InstanceIdentifier<?> path) {
+            tryToDeployBindingForwarder(path);
+        }
+
+        @Override
+        public void onMountPointRemoved(InstanceIdentifier<?> path) {
+            undeployBindingForwarder(path);
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java
deleted file mode 100644 (file)
index d22da30..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-package org.opendaylight.controller.sal.binding.impl.connect.dom;
-
-public class BindingIndependentRpcConnector {
-
-}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java
new file mode 100644 (file)
index 0000000..c715c67
--- /dev/null
@@ -0,0 +1,166 @@
+package org.opendaylight.controller.sal.binding.impl.forward;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.DeserializationException;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class DomForwardedBindingBrokerImpl extends RootBindingAwareBroker implements DomForwardedBroker {
+
+    private ProviderSession domProviderContext;
+    private BindingIndependentConnector connector;
+    
+    private MountProvisionService domMountService;
+
+    private final DomMountPointForwardingManager domForwardingManager = new DomMountPointForwardingManager();
+    private final BindingMountPointForwardingManager bindingForwardingManager = new BindingMountPointForwardingManager();
+
+    private ConcurrentMap<InstanceIdentifier<?>, BindingIndependentConnector> connectors = new ConcurrentHashMap<>();
+    private ConcurrentMap<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded = new ConcurrentHashMap<>();
+    private ListenerRegistration<MountProvisionListener> domListenerRegistration;
+    private ListenerRegistration<org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener> baListenerRegistration;
+
+
+    public DomForwardedBindingBrokerImpl(String instanceName) {
+        super(instanceName);
+    }
+
+    @Override
+    public BindingIndependentConnector getConnector() {
+        return connector;
+    }
+
+    @Override
+    public ProviderSession getDomProviderContext() {
+        return domProviderContext;
+    }
+
+    @Override
+    public void setConnector(BindingIndependentConnector connector) {
+        this.connector = connector;
+    }
+
+    @Override
+    public void setDomProviderContext(ProviderSession domProviderContext) {
+        this.domProviderContext = domProviderContext;
+    }
+
+    @Override
+    public void startForwarding() {
+        BindingDomConnectorDeployer.startDataForwarding(getConnector(), getDataBroker(), getDomProviderContext());
+        BindingDomConnectorDeployer.startRpcForwarding(getConnector(), getRpcProviderRegistry(),
+                getDomProviderContext());
+        BindingDomConnectorDeployer.startNotificationForwarding(getConnector(), getNotificationBroker(),
+                getDomProviderContext());
+        startMountpointForwarding();
+    }
+
+    private void startMountpointForwarding() {
+        domMountService = getDomProviderContext().getService(MountProvisionService.class);
+        if (domMountService != null && getMountManager() != null) {
+            domListenerRegistration = domMountService.registerProvisionListener(domForwardingManager);
+            baListenerRegistration = getMountManager().registerProvisionListener(bindingForwardingManager);
+        }
+    }
+
+    public MountProvisionService getDomMountService() {
+        return domMountService;
+    }
+
+    public void setDomMountService(MountProvisionService domMountService) {
+        this.domMountService = domMountService;
+    }
+
+    private void tryToDeployConnector(InstanceIdentifier<?> baPath,
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier previous = forwarded.putIfAbsent(baPath, biPath);
+        if (previous != null) {
+            return;
+        }
+        MountProviderInstance baMountPoint = getMountManager().createOrGetMountPoint(baPath);
+        MountProvisionInstance domMountPoint = domMountService.createOrGetMountPoint(biPath);
+        BindingIndependentConnector connector = createForwarder(baPath, baMountPoint, domMountPoint);
+        connectors.put(baPath, connector);
+    }
+
+    private BindingIndependentConnector createForwarder(InstanceIdentifier<?> path, MountProviderInstance baMountPoint,
+            MountProvisionInstance domMountPoint) {
+        BindingIndependentConnector mountConnector = BindingDomConnectorDeployer.createConnector(getConnector());
+
+        BindingDomConnectorDeployer.startDataForwarding(mountConnector, baMountPoint, domMountPoint);
+        BindingDomConnectorDeployer.startRpcForwarding(mountConnector, baMountPoint, domMountPoint);
+        BindingDomConnectorDeployer.startNotificationForwarding(mountConnector, baMountPoint, domMountPoint);
+        // connector.setDomNotificationBroker(domMountPoint);
+        return connector;
+    }
+
+    public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) {
+        InstanceIdentifier<?> baPath;
+        try {
+            baPath = connector.getMappingService().fromDataDom(domPath);
+            BindingIndependentConnector potentialConnector = connectors.get(baPath);
+            if (potentialConnector != null) {
+                return;
+            }
+            tryToDeployConnector(baPath, domPath);
+        } catch (DeserializationException e) {
+
+        }
+    }
+
+    public synchronized void tryToDeployBindingForwarder(InstanceIdentifier<?> baPath) {
+        BindingIndependentConnector potentialConnector = connectors.get(baPath);
+        if (potentialConnector != null) {
+            return;
+        }
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = connector.getMappingService().toDataDom(baPath);
+        tryToDeployConnector(baPath, domPath);
+    }
+
+    public synchronized void undeployBindingForwarder(InstanceIdentifier<?> baPath) {
+        // FIXME: Implement closeMountPoint
+    }
+
+    public synchronized void undeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
+        // FIXME: Implement closeMountPoint
+    }
+
+    private class DomMountPointForwardingManager implements MountProvisionListener {
+
+        @Override
+        public void onMountPointCreated(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
+            tryToDeployDomForwarder(path);
+        }
+
+        @Override
+        public void onMountPointRemoved(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
+            undeployDomForwarder(path);
+        }
+    }
+
+    private class BindingMountPointForwardingManager implements
+            org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener {
+
+        @Override
+        public void onMountPointCreated(InstanceIdentifier<?> path) {
+            tryToDeployBindingForwarder(path);
+        }
+
+        @Override
+        public void onMountPointRemoved(InstanceIdentifier<?> path) {
+            undeployBindingForwarder(path);
+        }
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBroker.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBroker.java
new file mode 100644 (file)
index 0000000..c7dbcd4
--- /dev/null
@@ -0,0 +1,17 @@
+package org.opendaylight.controller.sal.binding.impl.forward;
+
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+
+interface DomForwardedBroker {
+
+    public BindingIndependentConnector getConnector();
+    
+    public void setConnector(BindingIndependentConnector connector);
+    
+    public void setDomProviderContext(ProviderSession domProviderContext);
+
+    public ProviderSession getDomProviderContext();
+
+    void startForwarding();
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedDataBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedDataBrokerImpl.java
new file mode 100644 (file)
index 0000000..f90a4ac
--- /dev/null
@@ -0,0 +1,49 @@
+package org.opendaylight.controller.sal.binding.impl.forward;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.opendaylight.controller.sal.binding.impl.RootDataBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
+import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+
+public class DomForwardedDataBrokerImpl extends RootDataBrokerImpl implements Provider, DomForwardedBroker {
+
+    private BindingIndependentConnector connector;
+    private ProviderSession domProviderContext;
+
+    public void setConnector(BindingIndependentConnector connector) {
+        this.connector = connector;
+    }
+
+    @Override
+    public void onSessionInitiated(ProviderSession session) {
+        this.setDomProviderContext(session);
+    }
+
+    @Override
+    public Collection<ProviderFunctionality> getProviderFunctionality() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public BindingIndependentConnector getConnector() {
+        return connector;
+    }
+
+    @Override
+    public ProviderSession getDomProviderContext() {
+        return domProviderContext;
+    }
+
+    public void setDomProviderContext(ProviderSession domProviderContext) {
+        this.domProviderContext = domProviderContext;
+    }
+
+    @Override
+    public void startForwarding() {
+        BindingDomConnectorDeployer.startDataForwarding(getConnector(), this, getDomProviderContext());
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardingUtils.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardingUtils.java
new file mode 100644 (file)
index 0000000..581b217
--- /dev/null
@@ -0,0 +1,25 @@
+package org.opendaylight.controller.sal.binding.impl.forward;
+
+import com.google.common.base.Preconditions;
+
+public class DomForwardingUtils {
+
+    public static boolean isDomForwardedBroker(Object obj) {
+        return obj instanceof DomForwardedBroker;
+    }
+
+    public static void reuseForwardingFrom(Object target,Object source) {
+        Preconditions.checkArgument(isDomForwardedBroker(source));
+        Preconditions.checkArgument(isDomForwardedBroker(target));
+        DomForwardedBroker forwardedSource = (DomForwardedBroker) source;
+        DomForwardedBroker forwardedTarget = (DomForwardedBroker) target;
+        reuseForwardingFrom(forwardedTarget, forwardedSource);
+        
+    }
+
+    private static void reuseForwardingFrom(DomForwardedBroker target, DomForwardedBroker source) {
+        target.setConnector(source.getConnector());
+        target.setDomProviderContext(source.getDomProviderContext());
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/Constants.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/Constants.xtend
deleted file mode 100644 (file)
index 9fb2140..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.impl.osgi
-
-class Constants {
-
-    private new() {
-    }
-
-    public static val SAL_SERVICE_TYPE = "salServiceType"
-    public static val SAL_SERVICE_TYPE_CONSUMER_PROXY = "consumerProxy"
-    public static val SAL_SERVICE_TYPE_PROVIDER = "provider"
-    public static val SAL_SERVICE_TYPE_CONNECTOR = "connector"
-}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/PropertiesUtils.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/PropertiesUtils.xtend
deleted file mode 100644 (file)
index d04ca7f..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.impl.osgi
-
-import java.util.Hashtable
-import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.*
-
-class PropertiesUtils {
-
-    private new() {
-    }
-
-    static def setSalServiceType(Hashtable<String, String> properties, String value) {
-        properties.put(SAL_SERVICE_TYPE, value)
-        return properties
-    }
-
-    static def getSalServiceType(Hashtable<String, String> properties) {
-        return properties.get(SAL_SERVICE_TYPE)
-    }
-
-    static def newProperties() {
-        new Hashtable<String, String>()
-    }
-
-}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/package-info.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/package-info.java
deleted file mode 100644 (file)
index d788ccf..0000000
+++ /dev/null
@@ -1,8 +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.binding.impl.osgi;
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RoutingContext.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RoutingContext.java
deleted file mode 100644 (file)
index 49e056b..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-package org.opendaylight.controller.sal.binding.spi;
-
-public class RoutingContext {
-
-}
index b040aa025e2bd05450f5458922df34f85c46fa30..b0d1629a73f645333fb3aacfc3d33aae4fa562a2 100644 (file)
@@ -85,10 +85,10 @@ module opendaylight-sal-binding-broker-impl {
                         config:required-identity sal:binding-notification-service;
                     }
                 }
-            } 
+            }
         }
     }
-    
+
     augment "/config:modules/config:module/config:configuration" {
         case binding-data-broker {
             when "/config:modules/config:module/config:type = 'binding-data-broker'";
@@ -100,6 +100,7 @@ module opendaylight-sal-binding-broker-impl {
                     }
                 }
             }
+
             container mapping-service {
                 uses config:service-ref {
                     refine type {
index 6f0db4cd8d3635d0cd43bea0e943dd7d5555fdd2..20181a62c8a8b38abc3add11873ed3452350cf89 100644 (file)
@@ -16,11 +16,11 @@ import org.junit.Test;
 import static org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper.*;
 
 import org.opendaylight.controller.sal.binding.api.NotificationListener;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable;
 import org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator;
 import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
 import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
-import org.opendaylight.controller.sal.binding.spi.RpcRoutingTable;
 import org.opendaylight.controller.sal.binding.test.mock.BarListener;
 import org.opendaylight.controller.sal.binding.test.mock.BarUpdate;
 import org.opendaylight.controller.sal.binding.test.mock.CompositeListener;
index d4d27a14eceb68c3df38c8b826ae23845fb76e69..c03d851f5c9ef740a14a9097feceaf8909833184 100644 (file)
@@ -4,26 +4,44 @@ import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.Future;
 
 import javassist.ClassPool;
 
+import org.eclipse.xtext.xbase.lib.Pure;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
 import org.opendaylight.controller.sal.binding.dom.serializer.impl.RuntimeGeneratedMappingServiceImpl;
-import org.opendaylight.controller.sal.binding.impl.BindingAwareBrokerImpl;
 import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
 import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl;
 import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.controller.sal.core.api.BrokerService;
 import org.opendaylight.controller.sal.core.api.RpcImplementation;
 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
 import org.opendaylight.controller.sal.core.api.data.DataStore;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
 import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
+import org.opendaylight.controller.sal.dom.broker.MountPointManagerImpl;
 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.RpcRouterImpl;
 import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
@@ -33,26 +51,26 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Predicate;
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.ImmutableClassToInstanceMap;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 
 import static com.google.common.base.Preconditions.*;
 
 public class BindingTestContext implements AutoCloseable {
-    
-    
+
     public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier TREE_ROOT = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
             .builder().toInstance();
 
     private static final Logger LOG = LoggerFactory.getLogger(BindingTestContext.class);
-    
+
     private RuntimeGeneratedMappingServiceImpl mappingServiceImpl;
-    
-    
-    private BindingAwareBrokerImpl baBrokerImpl;
+
+    private DomForwardedBindingBrokerImpl baBrokerImpl;
     private DataBrokerImpl baDataImpl;
     private NotificationBrokerImpl baNotifyImpl;
-    private BindingIndependentConnector baConnectDataServiceImpl;
+    private BindingIndependentConnector baConnectImpl;
 
     private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
     private BrokerImpl biBrokerImpl;
@@ -61,15 +79,15 @@ public class BindingTestContext implements AutoCloseable {
     private DataStoreStatsWrapper dataStoreStats;
     private DataStore dataStore;
 
-    
     private boolean dataStoreStatisticsEnabled = false;
-    
+
     private final ListeningExecutorService executor;
     private final ClassPool classPool;
 
     private final boolean startWithSchema;
 
-    
+    private MountPointManagerImpl biMountImpl;
+
     protected BindingTestContext(ListeningExecutorService executor, ClassPool classPool, boolean startWithSchema) {
         this.executor = executor;
         this.classPool = classPool;
@@ -82,74 +100,133 @@ public class BindingTestContext implements AutoCloseable {
         rawDataStore = new HashMapDataStore();
         schemaAwareDataStore = new SchemaAwareDataStoreAdapter();
         schemaAwareDataStore.changeDelegate(rawDataStore);
-        if(dataStoreStatisticsEnabled) {
-        dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore);
-        dataStore = dataStoreStats;
+        if (dataStoreStatisticsEnabled) {
+            dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore);
+            dataStore = dataStoreStats;
         } else {
             dataStore = schemaAwareDataStore;
         }
-        
+
         biDataImpl.registerConfigurationReader(TREE_ROOT, dataStore);
         biDataImpl.registerOperationalReader(TREE_ROOT, dataStore);
         biDataImpl.registerCommitHandler(TREE_ROOT, dataStore);
     }
-    
+
     public void startDomDataBroker() {
-        checkState(executor != null,"Executor needs to be set");
+        checkState(executor != null, "Executor needs to be set");
         biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl();
         biDataImpl.setExecutor(executor);
     }
-    
+
     public void startBindingDataBroker() {
-        checkState(executor != null,"Executor needs to be set");
+        checkState(executor != null, "Executor needs to be set");
         baDataImpl = new DataBrokerImpl();
         baDataImpl.setExecutor(executor);
     }
-    
+
     public void startBindingBroker() {
-        checkState(executor != null,"Executor needs to be set");
-        checkState(baDataImpl != null,"Binding Data Broker must be started");
+        checkState(executor != null, "Executor needs to be set");
+        checkState(baDataImpl != null, "Binding Data Broker must be started");
         checkState(baNotifyImpl != null, "Notification Service must be started");
-        baBrokerImpl = new BindingAwareBrokerImpl("test",null);
-        
+        baBrokerImpl = new DomForwardedBindingBrokerImpl("test");
+
+        baBrokerImpl.getMountManager().setDataCommitExecutor(executor);
+        baBrokerImpl.getMountManager().setNotificationExecutor(executor);
+        baBrokerImpl.setRpcBroker(new RpcProviderRegistryImpl("test"));
         baBrokerImpl.setDataBroker(baDataImpl);
-        baBrokerImpl.setNotifyBroker(baNotifyImpl);
-        
+        baBrokerImpl.setNotificationBroker(baNotifyImpl);
         baBrokerImpl.start();
     }
-    
-    public void startBindingToDomDataConnector() {
-        checkState(baDataImpl != null,"Binding Data Broker needs to be started");
-        checkState(biDataImpl != null,"DOM Data Broker needs to be started.");
-        checkState(mappingServiceImpl != null,"DOM Mapping Service needs to be started.");
-        baConnectDataServiceImpl = new BindingIndependentConnector();
-        baConnectDataServiceImpl.setRpcRegistry(baBrokerImpl);
-        baConnectDataServiceImpl.setDomRpcRegistry(getDomRpcRegistry());
-        baConnectDataServiceImpl.setBaDataService(baDataImpl);
-        baConnectDataServiceImpl.setBiDataService(biDataImpl);
-        baConnectDataServiceImpl.setMappingService(mappingServiceImpl);
-        baConnectDataServiceImpl.start();
+
+    public void startForwarding() {
+        checkState(baDataImpl != null, "Binding Data Broker needs to be started");
+        checkState(biDataImpl != null, "DOM Data Broker needs to be started.");
+        checkState(mappingServiceImpl != null, "DOM Mapping Service needs to be started.");
+
+        baConnectImpl = BindingDomConnectorDeployer.createConnector(getBindingToDomMappingService());
+        baConnectImpl.setDomRpcRegistry(getDomRpcRegistry());
+        baBrokerImpl.setConnector(baConnectImpl);
+        baBrokerImpl.setDomProviderContext(createMockContext());
+        baBrokerImpl.startForwarding();
     }
-    
+
+    private ProviderSession createMockContext() {
+        // TODO Auto-generated method stub
+        final ClassToInstanceMap<BrokerService> domBrokerServices = ImmutableClassToInstanceMap
+                .<BrokerService> builder()
+                //
+                .put(org.opendaylight.controller.sal.core.api.data.DataProviderService.class, biDataImpl) //
+                .put(RpcProvisionRegistry.class, biBrokerImpl.getRouter()) //
+                .put(MountProvisionService.class, biMountImpl) //
+                .build();
+
+        return new ProviderSession() {
+
+            @Override
+            public Future<RpcResult<CompositeNode>> rpc(QName rpc, CompositeNode input) {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public <T extends BrokerService> T getService(Class<T> service) {
+                return domBrokerServices.getInstance(service);
+            }
+
+            @Override
+            public boolean isClosed() {
+                return false;
+            }
+
+            @Override
+            public Set<QName> getSupportedRpcs() {
+                return null;
+            }
+
+            @Override
+            public void close() {
+            }
+
+            @Override
+            public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(
+                    RpcRegistrationListener listener) {
+                return null;
+            }
+
+            @Override
+            public RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
+                    throws IllegalArgumentException {
+                return null;
+            }
+
+            @Override
+            public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+                return null;
+            }
+
+            @Override
+            public RoutedRpcRegistration addMountedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+                return null;
+            }
+        };
+    }
+
     public void startBindingToDomMappingService() {
-        checkState(classPool != null,"ClassPool needs to be present");
+        checkState(classPool != null, "ClassPool needs to be present");
         mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl();
         mappingServiceImpl.setPool(classPool);
         mappingServiceImpl.start(null);
     }
-    
-    
+
     public void updateYangSchema(String[] files) {
         SchemaContext context = getContext(files);
-        if(schemaAwareDataStore != null) {
+        if (schemaAwareDataStore != null) {
             schemaAwareDataStore.onGlobalContextUpdated(context);
         }
-        if(mappingServiceImpl != null) {
+        if (mappingServiceImpl != null) {
             mappingServiceImpl.onGlobalContextUpdated(context);
         }
     }
-    
-    
+
     public static String[] getAllYangFilesOnClasspath() {
         Predicate<String> predicate = new Predicate<String>() {
             @Override
@@ -161,7 +238,7 @@ public class BindingTestContext implements AutoCloseable {
         Set<String> result = reflection.getResources(predicate);
         return (String[]) result.toArray(new String[result.size()]);
     }
-    
+
     private static SchemaContext getContext(String[] yangFiles) {
         ClassLoader loader = BindingTestContext.class.getClassLoader();
         List<InputStream> streams = new ArrayList<>();
@@ -173,7 +250,7 @@ public class BindingTestContext implements AutoCloseable {
         Set<Module> modules = parser.parseYangModelsFromStreams(streams);
         return parser.resolveSchemaContext(modules);
     }
-    
+
     public void start() {
         startBindingDataBroker();
         startBindingNotificationBroker();
@@ -181,13 +258,19 @@ public class BindingTestContext implements AutoCloseable {
         startDomDataBroker();
         startDomDataStore();
         startDomBroker();
+        startDomMountPoint();
         startBindingToDomMappingService();
-        startBindingToDomDataConnector();
-        if(startWithSchema) {
+        startForwarding();
+        if (startWithSchema) {
             loadYangSchemaFromClasspath();
         }
     }
 
+    private void startDomMountPoint() {
+        biMountImpl = new MountPointManagerImpl();
+        biMountImpl.setDataBroker(getDomDataBroker());
+    }
+
     private void startDomBroker() {
         checkState(executor != null);
         biBrokerImpl = new BrokerImpl();
@@ -198,7 +281,7 @@ public class BindingTestContext implements AutoCloseable {
     public void startBindingNotificationBroker() {
         checkState(executor != null);
         baNotifyImpl = new NotificationBrokerImpl(executor);
-        
+
     }
 
     public void loadYangSchemaFromClasspath() {
@@ -223,10 +306,10 @@ public class BindingTestContext implements AutoCloseable {
     }
 
     public void logDataStoreStatistics() {
-        if(dataStoreStats == null) {
+        if (dataStoreStats == null) {
             return;
         }
-        
+
         LOG.info("BIDataStore Statistics: Configuration Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
                 dataStoreStats.getConfigurationReadCount(), dataStoreStats.getConfigurationReadTotalTime(),
                 dataStoreStats.getConfigurationReadAverageTime());
@@ -241,22 +324,30 @@ public class BindingTestContext implements AutoCloseable {
     }
 
     public RpcProviderRegistry getBindingRpcRegistry() {
-        return baBrokerImpl;
+        return baBrokerImpl.getRoot();
     }
 
     public RpcProvisionRegistry getDomRpcRegistry() {
-        if(biBrokerImpl == null) {
+        if (biBrokerImpl == null) {
             return null;
         }
         return biBrokerImpl.getRouter();
     }
-    
+
     public RpcImplementation getDomRpcInvoker() {
         return biBrokerImpl.getRouter();
     }
-    
+
     @Override
     public void close() throws Exception {
-        
+
+    }
+
+    public MountProviderService getBindingMountProviderService() {
+        return baBrokerImpl.getMountManager();
+    }
+
+    public MountProvisionService getDomMountProviderService() {
+        return biMountImpl;
     }
 }
index 1304f0d52a8fb5da53fc8aa6130badd8666917f1..e31ae6b8c718be73af48eeef26c3cb8517b38b9d 100644 (file)
@@ -1,35 +1,10 @@
 package org.opendaylight.controller.sal.binding.test.bugfix;
 
-import java.util.ArrayList;
-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 com.google.common.collect.ImmutableSet;
 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.controller.sal.binding.test.AbstractDataServiceTest;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.mpls.action._case.PopMplsActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
@@ -48,16 +23,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.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.flow.types.rev131026.instruction.list.InstructionKey;
-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.nodes.Node;
 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;
@@ -65,21 +37,21 @@ 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;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 
 public class FlagsSerializationTest 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 FLOW_ID = "1234";
     private static final short TABLE_ID = (short)0;
     private static final String NODE_ID = "node:1";
 
index 96d0361b1dd5194e9665ab89a80c774e64d5cb4a..d9b16af469727f80e66d608dfb576a936ddfa8c9 100644 (file)
@@ -12,6 +12,8 @@ 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.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SupportedActions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SupportedActionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.supported.actions.ActionType;
@@ -130,8 +132,60 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data
         assertBindingIndependentVersion(NODE_INSTANCE_ID_BI);
         testNodeRemove();
     }
+    
+    @Test
+    public void putNodeWithAugmentation() throws Exception {
+        
+        NodeBuilder nodeBuilder = new NodeBuilder();
+        nodeBuilder.setId(new NodeId(NODE_ID));
+        nodeBuilder.setKey(NODE_KEY);
+        FlowCapableNodeBuilder fnub = new FlowCapableNodeBuilder();
+        fnub.setHardware("Hardware Foo");
+        fnub.setManufacturer("Manufacturer Foo");
+        fnub.setSerialNumber("Serial Foo");
+        fnub.setDescription("Description Foo");
+        fnub.setSoftware("JUnit emulated");
+        FlowCapableNode fnu = fnub.build();
+        
+        nodeBuilder.addAugmentation(FlowCapableNode.class, fnu);
+        DataModificationTransaction baseTransaction = baDataService.beginTransaction();
+        baseTransaction.putOperationalData(NODE_INSTANCE_ID_BA, nodeBuilder.build());
+        RpcResult<TransactionStatus> result = baseTransaction.commit().get();
+        assertEquals(TransactionStatus.COMMITED, result.getResult());
+        
+        FlowCapableNode readedAugmentation = (FlowCapableNode) baDataService.readOperationalData(InstanceIdentifier.builder(NODE_INSTANCE_ID_BA).augmentation(FlowCapableNode.class).toInstance());
+        assertNotNull(readedAugmentation);
+        assertEquals(fnu.getHardware(), readedAugmentation.getHardware());
+        
+        testPutNodeConnectorWithAugmentation();
+        testNodeRemove();
+    }
 
     
+    private void testPutNodeConnectorWithAugmentation() throws Exception {
+        NodeConnectorKey ncKey = new NodeConnectorKey(new NodeConnectorId("test:0:0"));
+        InstanceIdentifier<NodeConnector> ncPath = InstanceIdentifier.builder(NODE_INSTANCE_ID_BA)
+        .child(NodeConnector.class, ncKey).toInstance();
+        InstanceIdentifier<FlowCapableNodeConnector> ncAugmentPath = InstanceIdentifier.builder(ncPath)
+        .augmentation(FlowCapableNodeConnector.class).toInstance();
+        
+        NodeConnectorBuilder nc = new NodeConnectorBuilder();
+        nc.setKey(ncKey);
+        
+        FlowCapableNodeConnectorBuilder fncb = new FlowCapableNodeConnectorBuilder();
+        fncb.setName("Baz");
+        nc.addAugmentation(FlowCapableNodeConnector.class, fncb.build());
+        
+        DataModificationTransaction baseTransaction = baDataService.beginTransaction();
+        baseTransaction.putOperationalData(ncPath, nc.build());
+        RpcResult<TransactionStatus> result = baseTransaction.commit().get();
+        assertEquals(TransactionStatus.COMMITED, result.getResult());
+        
+        FlowCapableNodeConnector readedAugmentation = (FlowCapableNodeConnector) baDataService.readOperationalData(ncAugmentPath);
+        assertNotNull(readedAugmentation);
+        assertEquals(fncb.getName(), readedAugmentation.getName());
+    }
+
     private void testNodeRemove() throws Exception {
         DataModificationTransaction transaction = baDataService.beginTransaction();
         transaction.removeOperationalData(NODE_INSTANCE_ID_BA);
index ea36f81b0b940d069cc4898e5b2fcad6f2bde5de..0258c3e439acde92a132406f82861e23314147df 100644 (file)
@@ -1,29 +1,18 @@
 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 com.google.common.collect.ImmutableMap;
 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.common.util.CommitHandlerTransactions;
 import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpVersion;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.mpls.action._case.PopMplsActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpVersion;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 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.action.types.rev131112.action.list.ActionKey;
@@ -44,14 +33,10 @@ 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.IpMatchBuilder;
-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.Ipv4Match;
 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.vlan.match.fields.VlanIdBuilder;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -59,7 +44,14 @@ 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;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 
 public class ChangeOriginatedInDomBrokerTest extends AbstractDataServiceTest {
 
@@ -69,7 +61,7 @@ public class ChangeOriginatedInDomBrokerTest extends AbstractDataServiceTest {
     private static final QName TABLE_ID_QNAME = QName.create(Table.QNAME, "id");
 
     private static final String NODE_ID = "node:1";
-    private static final FlowId FLOW_ID = new FlowId(1234L);
+    private static final FlowId FLOW_ID = new FlowId("1234");
     private static final Short TABLE_ID = Short.valueOf((short) 0);
 
     private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID));
@@ -144,7 +136,7 @@ public class ChangeOriginatedInDomBrokerTest extends AbstractDataServiceTest {
             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);
+                return CommitHandlerTransactions.allwaysSuccessfulTransaction(modification);
             }
 
         };
diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java
new file mode 100644 (file)
index 0000000..a99d80f
--- /dev/null
@@ -0,0 +1,154 @@
+package org.opendaylight.controller.sal.binding.test.connect.dom;
+
+import static junit.framework.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+
+import java.math.BigInteger;
+import java.util.Collections;
+import java.util.Map;
+
+import javax.management.Notification;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
+import org.opendaylight.controller.sal.binding.test.util.BindingBrokerTestFactory;
+import org.opendaylight.controller.sal.binding.test.util.BindingTestContext;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
+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.NodeKey;
+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.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.MoreExecutors;
+
+public class CrossBrokerMountPointTest {
+
+    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 QName TABLE_ID_QNAME = QName.create(Table.QNAME, "id");
+
+    private static final String NODE_ID = "node:1";
+
+    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 GroupKey GROUP_KEY = new GroupKey(new GroupId(0L));
+
+    private static final InstanceIdentifier<GroupStatistics> GROUP_STATISTICS_ID_BA = InstanceIdentifier
+            .builder(NODE_INSTANCE_ID_BA).augmentation(FlowCapableNode.class) //
+            .child(Group.class, GROUP_KEY) //
+            .augmentation(NodeGroupStatistics.class) //
+            .child(GroupStatistics.class) //
+            .toInstance();
+
+    private static final QName AUGMENTED_GROUP_STATISTICS = QName.create(NodeGroupStatistics.QNAME,
+            GroupStatistics.QNAME.getLocalName());
+
+    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 org.opendaylight.yangtools.yang.data.api.InstanceIdentifier GROUP_STATISTICS_ID_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+            //
+            .builder(NODE_INSTANCE_ID_BI)
+            .nodeWithKey(QName.create(FlowCapableNode.QNAME, "group"), QName.create(FlowCapableNode.QNAME, "group-id"),
+                    0L).node(AUGMENTED_GROUP_STATISTICS).toInstance();
+
+    private static final NodeRef NODE_REF = new NodeRef(NODE_INSTANCE_ID_BA);
+
+    private BindingTestContext testContext;
+    private MountProviderService bindingMountPointService;
+    private MountProvisionService domMountPointService;
+
+    @Before
+    public void setup() {
+        BindingBrokerTestFactory testFactory = new BindingBrokerTestFactory();
+        testFactory.setExecutor(MoreExecutors.sameThreadExecutor());
+        testFactory.setStartWithParsedSchema(true);
+        testContext = testFactory.getTestContext();
+
+        testContext.start();
+        bindingMountPointService = testContext.getBindingMountProviderService();
+        domMountPointService = testContext.getDomMountProviderService();
+
+        // biRpcInvoker = testContext.getDomRpcInvoker();
+        assertNotNull(bindingMountPointService);
+        assertNotNull(domMountPointService);
+
+        // flowService = MessageCapturingFlowService.create(baRpcRegistry);
+    }
+
+    @Test
+    public void testMountPoint() {
+
+        testContext.getBindingDataBroker().readOperationalData(NODE_INSTANCE_ID_BA);
+
+        MountProvisionInstance domMountPoint = domMountPointService.createMountPoint(NODE_INSTANCE_ID_BI);
+        assertNotNull(domMountPoint);
+        MountProviderInstance bindingMountPoint = bindingMountPointService.getMountPoint(NODE_INSTANCE_ID_BA);
+        assertNotNull(bindingMountPoint);
+
+        final BigInteger packetCount = BigInteger.valueOf(500L);
+        
+        
+        DataReader<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> simpleReader = new DataReader<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode>() {
+
+            @Override
+            public CompositeNode readConfigurationData(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier arg0) {
+                return null;
+            }
+
+            
+            @Override
+            public CompositeNode readOperationalData(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier arg0) {
+                if (arg0.equals(GROUP_STATISTICS_ID_BI)) {
+                    ImmutableCompositeNode data = ImmutableCompositeNode
+                            .builder()
+                            .setQName(AUGMENTED_GROUP_STATISTICS)
+                            .addLeaf(QName.create(AUGMENTED_GROUP_STATISTICS, "packet-count"), packetCount) //
+                            .toInstance();
+
+                    return data;
+                }
+                return null;
+            }
+
+        };
+        domMountPoint.registerOperationalReader(NODE_INSTANCE_ID_BI, simpleReader);
+        
+        GroupStatistics data = (GroupStatistics) bindingMountPoint.readOperationalData(GROUP_STATISTICS_ID_BA);
+        assertNotNull(data);
+        assertEquals(packetCount,data.getPacketCount().getValue());
+    }
+}
index 112b57cd33fc2fbb43c08059a5274f9647574084..c943226ccac994284cef91da558f3fce973ea11f 100644 (file)
@@ -87,6 +87,7 @@ public class TestHelper {
                 mavenBundle(CONTROLLER, "sal-binding-api").versionAsInProject(), // //
                 mavenBundle(CONTROLLER, "sal-binding-config").versionAsInProject(), //
                 mavenBundle(CONTROLLER, "sal-binding-broker-impl").versionAsInProject(), // //
+                mavenBundle(CONTROLLER, "sal-binding-util").versionAsInProject(), //
                 mavenBundle("org.javassist", "javassist").versionAsInProject(), // //
                 mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), // //
 
index 6fec18033f8feeed2df5dd7f040d2ddf622d63ad..2f86ee4cc2e9e34c4db55b803b565f090c7962b5 100644 (file)
@@ -5,13 +5,16 @@ import static org.junit.Assert.assertNotNull;
 
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality;
 import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.NotificationService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded;
@@ -24,6 +27,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalF
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.binding.RpcService;
 
 public class NoficationTest extends AbstractTest {
 
@@ -95,16 +99,36 @@ public class NoficationTest extends AbstractTest {
          * The registration of the Consumer 2. SalFlowListener is registered
          * registered as notification listener.
          */
-        BindingAwareConsumer consumer2 = new BindingAwareConsumer() {
+        BindingAwareProvider provider = new BindingAwareProvider() {
+            
             @Override
-            public void onSessionInitialized(ConsumerContext session) {
+            public void onSessionInitiated(ProviderContext session) {
                 listener2Reg = session.getSALService(NotificationProviderService.class).registerNotificationListener(
                         listener2);
             }
+            
+            @Override
+            public void onSessionInitialized(ConsumerContext session) {
+                // TODO Auto-generated method stub
+                
+            }
+            
+            @Override
+            public Collection<? extends RpcService> getImplementations() {
+                // TODO Auto-generated method stub
+                return null;
+            }
+            
+            @Override
+            public Collection<? extends ProviderFunctionality> getFunctionality() {
+                // TODO Auto-generated method stub
+                return null;
+            }
+            
         };
 
         // registerConsumer method calls onSessionInitialized method above
-        broker.registerConsumer(consumer2, getBundleContext());
+        broker.registerProvider(provider, getBundleContext());
 
         /**
          * 3 notifications are published
index 26041ea85ec61d1f7bece2d274627fea3bd63e33..67c10f4a048405b64ca6ca58b1f7a22cdc8d9d53 100644 (file)
             <artifactId>sal-binding-api</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.dependencymanager</artifactId>
-            <version>3.1.0</version>
-        </dependency>
     </dependencies>
 </project>
diff --git a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalConsumerInstance.java b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalConsumerInstance.java
new file mode 100644 (file)
index 0000000..ff6f618
--- /dev/null
@@ -0,0 +1,178 @@
+package org.opendaylight.controller.md.sal.binding.util;
+
+import java.util.concurrent.Future;
+import java.util.zip.Checksum;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.NotificationListener;
+import org.opendaylight.controller.sal.binding.api.NotificationService;
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.mount.MountInstance;
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.DataRoot;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import com.google.common.base.Preconditions;
+
+public abstract class AbstractBindingSalConsumerInstance<D extends DataBrokerService, N extends NotificationService, R extends RpcConsumerRegistry> //
+        implements //
+        RpcConsumerRegistry, //
+        NotificationService, //
+        DataBrokerService {
+
+    private final R rpcRegistry;
+    private final N notificationBroker;
+    private final D dataBroker;
+
+    protected final R getRpcRegistry() {
+        return rpcRegistry;
+    }
+
+    protected final N getNotificationBroker() {
+        return notificationBroker;
+    }
+
+    protected final D getDataBroker() {
+        return dataBroker;
+    }
+    
+    protected final R getRpcRegistryChecked() {
+        Preconditions.checkState(rpcRegistry != null,"Rpc Registry is not available.");
+        return rpcRegistry;
+    }
+
+    protected final N getNotificationBrokerChecked() {
+        Preconditions.checkState(notificationBroker != null,"Notification Broker is not available.");
+        return notificationBroker;
+    }
+
+    protected final D getDataBrokerChecked() {
+        Preconditions.checkState(dataBroker != null, "Data Broker is not available");
+        return dataBroker;
+    }
+    
+
+    protected AbstractBindingSalConsumerInstance(R rpcRegistry, N notificationBroker, D dataBroker) {
+        this.rpcRegistry = rpcRegistry;
+        this.notificationBroker = notificationBroker;
+        this.dataBroker = dataBroker;
+    }
+
+    public <T extends RpcService> T getRpcService(Class<T> module) {
+        return getRpcRegistryChecked().getRpcService(module);
+    }
+
+    @Deprecated
+    public <T extends Notification> void addNotificationListener(Class<T> notificationType,
+            NotificationListener<T> listener) {
+        getNotificationBrokerChecked().addNotificationListener(notificationType, listener);
+    }
+
+    @Deprecated
+    public void addNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
+        getNotificationBrokerChecked().addNotificationListener(listener);
+    }
+
+    @Deprecated
+    public void removeNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
+        getNotificationBrokerChecked().removeNotificationListener(listener);
+    }
+
+    @Deprecated
+    public <T extends Notification> void removeNotificationListener(Class<T> notificationType,
+            NotificationListener<T> listener) {
+        getNotificationBrokerChecked().removeNotificationListener(notificationType, listener);
+    }
+
+    public <T extends Notification> Registration<NotificationListener<T>> registerNotificationListener(
+            Class<T> notificationType, NotificationListener<T> listener) {
+        return getNotificationBrokerChecked().registerNotificationListener(notificationType, listener);
+    }
+
+    public Registration<org.opendaylight.yangtools.yang.binding.NotificationListener> registerNotificationListener(
+            org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
+        return getNotificationBrokerChecked().registerNotificationListener(listener);
+    }
+
+    @Deprecated
+    public <T extends DataRoot> T getData(DataStoreIdentifier store, Class<T> rootType) {
+        return getDataBrokerChecked().getData(store, rootType);
+    }
+
+    @Deprecated
+    public <T extends DataRoot> T getData(DataStoreIdentifier store, T filter) {
+        return getDataBrokerChecked().getData(store, filter);
+    }
+
+    @Deprecated
+    public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, Class<T> rootType) {
+        return getDataBrokerChecked().getCandidateData(store, rootType);
+    }
+
+    @Deprecated
+    public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, T filter) {
+        return getDataBrokerChecked().getCandidateData(store, filter);
+    }
+
+    @Deprecated
+    public RpcResult<DataRoot> editCandidateData(DataStoreIdentifier store, DataRoot changeSet) {
+        return getDataBrokerChecked().editCandidateData(store, changeSet);
+    }
+
+    @Deprecated
+    public Future<RpcResult<Void>> commit(DataStoreIdentifier store) {
+        return getDataBrokerChecked().commit(store);
+    }
+
+    @Deprecated
+    public DataObject getData(InstanceIdentifier<? extends DataObject> data) {
+        return getDataBrokerChecked().getData(data);
+    }
+
+    @Deprecated
+    public DataObject getConfigurationData(InstanceIdentifier<?> data) {
+        return getDataBrokerChecked().getConfigurationData(data);
+    }
+
+    public DataModificationTransaction beginTransaction() {
+        return getDataBrokerChecked().beginTransaction();
+    }
+
+    @Deprecated
+    public void registerChangeListener(InstanceIdentifier<? extends DataObject> path, DataChangeListener changeListener) {
+        getDataBrokerChecked().registerChangeListener(path, changeListener);
+    }
+
+    @Deprecated
+    public void unregisterChangeListener(InstanceIdentifier<? extends DataObject> path,
+            DataChangeListener changeListener) {
+        getDataBrokerChecked().unregisterChangeListener(path, changeListener);
+    }
+
+    @Deprecated
+    public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+        return getDataBrokerChecked().readConfigurationData(path);
+    }
+
+    public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+        return getDataBrokerChecked().readOperationalData(path);
+    }
+
+    @Deprecated
+    public ListenerRegistration<DataChangeListener> registerDataChangeListener(
+            InstanceIdentifier<? extends DataObject> path, DataChangeListener listener) {
+        return getDataBrokerChecked().registerDataChangeListener(path, listener);
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java
new file mode 100644 (file)
index 0000000..278e90e
--- /dev/null
@@ -0,0 +1,95 @@
+package org.opendaylight.controller.md.sal.binding.util;
+
+import java.util.concurrent.ExecutorService;
+
+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.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+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.Notification;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+public abstract class AbstractBindingSalProviderInstance<D extends DataProviderService, N extends NotificationProviderService, R extends RpcProviderRegistry> //
+        extends AbstractBindingSalConsumerInstance<D, N, R> //
+        implements //
+        DataProviderService, //
+        RpcProviderRegistry, //
+        NotificationProviderService {
+
+    public AbstractBindingSalProviderInstance(R rpcRegistry, N notificationBroker,
+            D dataBroker) {
+        super(rpcRegistry, notificationBroker, dataBroker);
+    }
+
+    @Override
+    public Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> registerDataReader(
+            InstanceIdentifier<? extends DataObject> path,
+            DataReader<InstanceIdentifier<? extends DataObject>, DataObject> reader) {
+        return getDataBrokerChecked().registerDataReader(path, reader);
+    }
+
+    @Override
+    public Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> registerCommitHandler(
+            InstanceIdentifier<? extends DataObject> path,
+            DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> commitHandler) {
+        return getDataBrokerChecked().registerCommitHandler(path, commitHandler);
+    }
+
+    @Override
+    public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject>>> registerCommitHandlerListener(
+            RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject>> commitHandlerListener) {
+        return getDataBrokerChecked().registerCommitHandlerListener(commitHandlerListener);
+    }
+
+    @Override
+    public <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
+            throws IllegalStateException {
+        return getRpcRegistryChecked().addRpcImplementation(type, implementation);
+    }
+
+    @Override
+    public <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type, T implementation)
+            throws IllegalStateException {
+        return getRpcRegistryChecked().addRoutedRpcImplementation(type, implementation);
+    }
+
+    @Override
+    @Deprecated
+    public void notify(Notification notification) {
+        getNotificationBrokerChecked().notify(notification);
+    }
+
+    @Override
+    @Deprecated
+    public void notify(Notification notification, ExecutorService service) {
+        getNotificationBrokerChecked().notify(notification, service);
+    }
+
+    @Override
+    public void publish(Notification notification) {
+        getNotificationBrokerChecked().publish(notification);
+    }
+
+    @Override
+    public void publish(Notification notification, ExecutorService service) {
+        getNotificationBrokerChecked().publish(notification, service);
+    }
+
+    @Override
+    public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
+            L listener) {
+        return getRpcRegistryChecked().registerRouteChangeListener(listener);
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/BindingContextUtils.java b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/BindingContextUtils.java
new file mode 100644 (file)
index 0000000..6f2186b
--- /dev/null
@@ -0,0 +1,143 @@
+package org.opendaylight.controller.md.sal.binding.util;
+
+import java.awt.image.SinglePixelPackedSampleModel;
+
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
+import org.opendaylight.controller.sal.binding.api.BindingAwareService;
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+import static com.google.common.base.Preconditions.*;
+
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.MutableClassToInstanceMap;
+
+public class BindingContextUtils {
+
+    public static ConsumerContext createConsumerContext(BindingAwareConsumer consumer,
+            ClassToInstanceMap<BindingAwareService> serviceProvider) {
+        checkNotNull(consumer,"Consumer should not be null");
+        checkNotNull(serviceProvider,"Service map should not be null");
+        return new SingleConsumerContextImpl(serviceProvider);
+    }
+    
+    public static ProviderContext createProviderContext(BindingAwareProvider provider,
+            ClassToInstanceMap<BindingAwareService> serviceProvider) {
+        checkNotNull(provider,"Provider should not be null");
+        checkNotNull(serviceProvider,"Service map should not be null");
+        return new SingleProviderContextImpl(serviceProvider);
+    }
+
+    public static ConsumerContext createConsumerContextAndInitialize(BindingAwareConsumer consumer,
+            ClassToInstanceMap<BindingAwareService> serviceProvider) {
+        ConsumerContext context = createConsumerContext(consumer, serviceProvider);
+        consumer.onSessionInitialized(context);
+        return context;
+    }
+    
+    public static ProviderContext createProviderContextAndInitialize(BindingAwareProvider provider,
+            ClassToInstanceMap<BindingAwareService> serviceProvider) {
+        ProviderContext context = createProviderContext(provider, serviceProvider);
+        provider.onSessionInitiated(context);
+        return context;
+    }
+
+    public static <T extends BindingAwareService> T createContextProxyOrReturnService(Class<T> service, T instance) {
+        // FIXME: Create Proxy
+        return instance;
+    }
+    
+    private static class SingleConsumerContextImpl implements ConsumerContext, AutoCloseable {
+        
+        private ClassToInstanceMap<BindingAwareService> alreadyRetrievedServices;
+        private ClassToInstanceMap<BindingAwareService> serviceProvider;
+
+        public SingleConsumerContextImpl(ClassToInstanceMap<BindingAwareService> serviceProvider) {
+            this.alreadyRetrievedServices = MutableClassToInstanceMap.create();
+            this.serviceProvider = serviceProvider;
+        }
+
+        @Override
+        public final <T extends RpcService> T getRpcService(Class<T> module) {
+            return getSALService(RpcConsumerRegistry.class).getRpcService(module);
+        }
+        
+        @Override
+        public final <T extends BindingAwareService> T getSALService(Class<T> service) {
+            checkNotNull(service,"Service class should not be null.");
+            T potential = alreadyRetrievedServices.getInstance(service);
+            if(potential != null) {
+                return potential;
+            }
+            return tryToRetrieveSalService(service);
+        }
+        
+        private synchronized <T extends BindingAwareService> T tryToRetrieveSalService(Class<T> service) {
+            final T potential = alreadyRetrievedServices.getInstance(service);
+            if(potential != null) {
+                return potential;
+            }
+            final T requested = serviceProvider.getInstance(service);
+            if(requested == null) {
+                throw new IllegalArgumentException("Requested service "+service.getName() +" is not available.");
+            }
+            final T retrieved = BindingContextUtils.createContextProxyOrReturnService(service,requested);
+            alreadyRetrievedServices.put(service, retrieved);
+            return retrieved;
+        }
+        
+        @Override
+        public final void close() throws Exception {
+            alreadyRetrievedServices = null;
+            serviceProvider = null;
+        }
+    }
+    
+    private static class SingleProviderContextImpl extends SingleConsumerContextImpl implements ProviderContext {
+
+        public SingleProviderContextImpl(ClassToInstanceMap<BindingAwareService> serviceProvider) {
+            super(serviceProvider);
+        }
+        
+        @Override
+        public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
+                L listener) {
+            return getSALService(RpcProviderRegistry.class).registerRouteChangeListener(listener);
+        }
+        
+        @Override
+        public <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type,
+                T implementation) throws IllegalStateException {
+            return getSALService(RpcProviderRegistry.class).addRoutedRpcImplementation(type, implementation);
+        }
+        
+        @Override
+        public <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
+                throws IllegalStateException {
+            return getSALService(RpcProviderRegistry.class).addRpcImplementation(type, implementation);
+        }
+        
+        @Deprecated
+        @Override
+        public void registerFunctionality(ProviderFunctionality functionality) {
+            // NOOP
+        }
+        
+        @Deprecated
+        @Override
+        public void unregisterFunctionality(ProviderFunctionality functionality) {
+            // NOOP
+        }
+    }
+}
index 738a14a9bd408ddeed36aa161824ceb2f39e91e4..17de595a8b79752400ee5ba36c442d3412f8f5d6 100644 (file)
@@ -6,33 +6,27 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public final class TypeSafeDataReader {
 
-    
-    private final DataReader<InstanceIdentifier<?>,DataObject> delegate;
-    
-    
-    
+    private final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate;
+
     public DataReader<InstanceIdentifier<?>, DataObject> getDelegate() {
         return delegate;
     }
 
-
-    public TypeSafeDataReader(DataReader<InstanceIdentifier<?>, DataObject> delegate) {
+    public TypeSafeDataReader(DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
         this.delegate = delegate;
     }
 
-
     @SuppressWarnings("unchecked")
     public <D extends DataObject> D readConfigurationData(InstanceIdentifier<D> path) {
         return (D) delegate.readConfigurationData(path);
     }
-    
-    
+
     @SuppressWarnings("unchecked")
-    public <D extends DataObject> D  readOperationalData(InstanceIdentifier<D> path) {
+    public <D extends DataObject> D readOperationalData(InstanceIdentifier<D> path) {
         return (D) delegate.readOperationalData(path);
     }
-    
-    public static TypeSafeDataReader forReader(DataReader<InstanceIdentifier<?>, DataObject> delegate) {
+
+    public static TypeSafeDataReader forReader(DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
         return new TypeSafeDataReader(delegate);
     }
 }
index ff15e72ba6fc3d1106a46bfadd08dfcd2e67bd60..adbe3d2a4997e183d6ce73d2420fe67b50db8dab 100644 (file)
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-common-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    
   </dependencies>
 
   <packaging>bundle</packaging>
index 2d10fba8a5fd77c18b872991669d576f9aae7a7e..902665d1a6fa137d41d7f1bc89cf8116fbb52ee1 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.sal.common.util;
 
 public class Arguments {
@@ -1,15 +1,14 @@
-package org.opendaylight.controller.sal.binding.impl.connect.dom;
+package org.opendaylight.controller.sal.common.util;
 
 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 {
+public class CommitHandlerTransactions {
 
     private static class AllwaysSuccessfulTransaction<P extends Path<P>,D> implements DataCommitTransaction<P, D> {
         
@@ -33,7 +32,6 @@ public class CommitHandlersTransactions {
         }
     }
     
-    
     public static final <P extends Path<P>,D> AllwaysSuccessfulTransaction<P, D> allwaysSuccessfulTransaction(DataModification<P, D> modification)  {
         return new AllwaysSuccessfulTransaction<>(modification);
     }
index d9cf5cc477aa2a81cd33796dd6b5f90b488fb1b9..42b00ba03d113dbcf0eb67958f068d5370491792 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.sal.common.util;
 
 import java.util.concurrent.ExecutionException;
index c326bab7a4677bf5db471f940ad2a35768b11dc0..951d5b142e76561485c5cd7f52e12fb84a462cce 100644 (file)
@@ -4,7 +4,7 @@ import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
 import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
 import org.opendaylight.yangtools.yang.common.QName;
 
-public interface RpcProvisionRegistry {
+public interface RpcProvisionRegistry extends BrokerService {
 
     /**
      * Registers an implementation of the rpc.
index 1596165601a0155dfda3cb8c1160c8c4baf41e1e..18c854646cca6aa08596a84ddaeba77959129219 100644 (file)
@@ -6,7 +6,6 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-
 package org.opendaylight.controller.sal.core.api.mount;
 
 import java.util.concurrent.Future;
@@ -16,8 +15,13 @@ import org.opendaylight.controller.sal.core.api.notify.NotificationService;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-public interface MountInstance extends NotificationService, DataBrokerService {
+public interface MountInstance extends //
+        NotificationService, //
+        DataBrokerService {
 
     Future<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input);
+
+    SchemaContext getSchemaContext();
 }
index 92542bc3455e497a6082fe64cf6607a290b30723..e5fc4b7aa4a1338c666034db88be0113302cff67 100644 (file)
@@ -3,6 +3,8 @@ package org.opendaylight.controller.sal.core.api.mount;
 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
 import org.opendaylight.controller.sal.core.api.data.DataProviderService;
 import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+import com.google.common.base.Optional;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public interface MountProvisionInstance extends //
         MountInstance,//
@@ -10,4 +12,6 @@ public interface MountProvisionInstance extends //
         RpcProvisionRegistry,//
         DataProviderService {
 
+    void setSchemaContext(SchemaContext optional);
+
 }
index fade7d341b2bf7d69ee0ad41ad0d4f4e64042acf..c1f873c3af4694395d8cd8a141c06814ecc11bbf 100644 (file)
@@ -1,5 +1,8 @@
 package org.opendaylight.controller.sal.core.api.mount;
 
+import java.util.EventListener;
+
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 
 public interface MountProvisionService extends MountService {
@@ -10,4 +13,14 @@ public interface MountProvisionService extends MountService {
     MountProvisionInstance createMountPoint(InstanceIdentifier path);
     
     MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path);
+    
+    ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener);
+    
+    public  interface MountProvisionListener extends EventListener {
+        
+        void onMountPointCreated(InstanceIdentifier path);
+        
+        void onMountPointRemoved(InstanceIdentifier path);
+        
+    }
 }
index 4740b0d5697c916c747079819700d2f732550b1f..10e7946a7b5d3038d87d52beb0c3efda8b5975dc 100644 (file)
             <artifactId>sal-common-impl</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>sal-common-impl</artifactId>
-            <version>1.0-SNAPSHOT</version>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-core-spi</artifactId>
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/$ModuleInfo.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/$ModuleInfo.java
new file mode 100644 (file)
index 0000000..3cc5a61
--- /dev/null
@@ -0,0 +1,6 @@
+package org.opendaylight.controller.sal.dom.broker;
+
+public class $ModuleInfo {
+
+    
+}
index 56eae97848b71c9556c0eb3108c6d7f92e38b200..8f62be97d801f7a557026a1aacd054bdaf5f6936 100644 (file)
@@ -13,6 +13,8 @@ import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 
+import com.google.common.util.concurrent.MoreExecutors;
+
 public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier, CompositeNode, DataChangeListener> implements
         DataProviderService, AutoCloseable {
 
@@ -21,6 +23,7 @@ public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier, Compo
     
     public DataBrokerImpl() {
         setDataReadRouter(new DataReaderRouter());
+        setExecutor(MoreExecutors.sameThreadExecutor());
     }
     
     public AtomicLong getCreatedTransactionsCount() {
index 7509a38a1429308029f25bcc85d90a32b6ed8f2d..b4fccff3b0fe745ae71088942ed05e92429f5e0e 100644 (file)
@@ -31,21 +31,24 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public class MountPointImpl implements MountProvisionInstance {
 
     private final RpcRouter rpcs;
-    private final DataReaderRouter dataReader;
+    private final DataBrokerImpl dataReader;
     private final NotificationRouter notificationRouter;
     private final DataReader<InstanceIdentifier,CompositeNode> readWrapper;
     
     
     private final InstanceIdentifier mountPath;
 
+    private SchemaContext schemaContext;
+
     public MountPointImpl(InstanceIdentifier path) {
         this.mountPath = path;
         rpcs = new RpcRouterImpl("");
-        dataReader = new DataReaderRouter();
+        dataReader = new DataBrokerImpl();
         notificationRouter = new NotificationRouterImpl();
         readWrapper = new ReadWrapper();
     }
@@ -121,15 +124,13 @@ public class MountPointImpl implements MountProvisionInstance {
 
     @Override
     public DataModificationTransaction beginTransaction() {
-        // TODO Auto-generated method stub
-        return null;
+        return dataReader.beginTransaction();
     }
 
     @Override
     public ListenerRegistration<DataChangeListener> registerDataChangeListener(InstanceIdentifier path,
             DataChangeListener listener) {
-        // TODO Auto-generated method stub
-        return null;
+        return dataReader.registerDataChangeListener(path, listener);
     }
 
     @Override
@@ -140,8 +141,7 @@ public class MountPointImpl implements MountProvisionInstance {
     @Override
     public Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> registerCommitHandler(
             InstanceIdentifier path, DataCommitHandler<InstanceIdentifier, CompositeNode> commitHandler) {
-        // TODO Auto-generated method stub
-        return null;
+        return dataReader.registerCommitHandler(path, commitHandler);
     }
     
     @Override
@@ -163,6 +163,14 @@ public class MountPointImpl implements MountProvisionInstance {
         // NOOP
     }
     
+    public SchemaContext getSchemaContext() {
+        return schemaContext;
+    }
+
+    public void setSchemaContext(SchemaContext schemaContext) {
+        this.schemaContext = schemaContext;
+    }
+
     class ReadWrapper implements DataReader<InstanceIdentifier, CompositeNode> {
         
         
@@ -197,7 +205,6 @@ public class MountPointImpl implements MountProvisionInstance {
     @Override
     public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>>> registerCommitHandlerListener(
             RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>> commitHandlerListener) {
-        // TODO Auto-generated method stub
-        return null;
+        return dataReader.registerCommitHandlerListener(commitHandlerListener);
     }
 }
index 19634d79c2203fafe5aaa0156c41bf45a62f905f..5d441bddbd0f23e263c452695da13afe9ecacc3e 100644 (file)
@@ -7,12 +7,16 @@ import java.util.concurrent.ConcurrentMap
 import java.util.concurrent.ConcurrentHashMap
 import static com.google.common.base.Preconditions.*;
 import org.opendaylight.controller.sal.core.api.data.DataProviderService
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry
 
 class MountPointManagerImpl implements MountProvisionService {
     
     @Property
     DataProviderService dataBroker;
     
+    val ListenerRegistry<MountProvisionListener> listeners = ListenerRegistry.create()
+    
     ConcurrentMap<InstanceIdentifier,MountPointImpl> mounts = new ConcurrentHashMap();
     
     override createMountPoint(InstanceIdentifier path) {
@@ -20,15 +24,26 @@ class MountPointManagerImpl implements MountProvisionService {
         val mount = new MountPointImpl(path);
         registerMountPoint(mount);
         mounts.put(path,mount);
+        notifyMountCreated(path);
         return mount;
     }
     
+    def notifyMountCreated(InstanceIdentifier identifier) {
+        for(listener : listeners) {
+            listener.instance.onMountPointCreated(identifier);
+        }
+    }
+    
     def registerMountPoint(MountPointImpl impl) {
         dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper);
         dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper);
         
     }
     
+    override registerProvisionListener(MountProvisionListener listener) {
+        listeners.register(listener)
+    }
+    
     
     override createOrGetMountPoint(InstanceIdentifier path) {
         val mount = mounts.get(path);
index 0d18cb323a8dace4eda4ab023de87fa433d638ed..0021dd8f0f3a707a282ccd1831dc332e1dfadd73 100644 (file)
@@ -3,6 +3,7 @@ package org.opendaylight.controller.sal.dom.broker.osgi;
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.osgi.framework.ServiceReference;
 
@@ -24,4 +25,9 @@ public class MountProviderServiceProxy extends AbstractBrokerServiceProxy<MountP
     public MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path) {
         return getDelegate().createOrGetMountPoint(path);
     }
+    
+    @Override
+    public ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener) {
+        return getDelegate().registerProvisionListener(listener);
+    }
 }
index 3ff1d1d6cbafa87a7479945965542eaf8235368e..3b31380afbb5333165062949eafd13378bbbd410 100644 (file)
@@ -121,7 +121,6 @@ public class YangSchemaUtils {
             // TODO Auto-generated constructor stub
         }
 
-        @Override
         public YangNode getParent() {
             // TODO Auto-generated method stub
             return null;
index fe613565a6232b608ab91ed33e014b327c4a4e2a..67e2934a0ea1b604d2737d122bf723714045722c 100644 (file)
             <scope>test</scope>
             <version>${netconf.version}</version>
         </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>yang-test</artifactId>
-            <scope>test</scope>
-            <version>${netconf.version}</version>
-        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>config-manager</artifactId>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-broker-impl</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+           <groupId>org.opendaylight.controller</groupId>
+           <artifactId>sal-binding-broker-impl</artifactId>
+           <version>1.0-SNAPSHOT</version>
+           <type>test-jar</type>
+           <scope>test</scope>
+        </dependency>
+        <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>ietf-netconf-monitoring</artifactId>
+        <version>0.2.3-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools.model</groupId>
             <artifactId>ietf-inet-types</artifactId>
index 55a1fbfe486a03f033ba961586675cb21beea2d6..2403027e01bcd97c626ad129e09a2d954f2e7a51 100644 (file)
@@ -12,8 +12,12 @@ package org.opendaylight.controller.config.yang.md.sal.connector.netconf;
 import io.netty.channel.EventLoopGroup;
 import io.netty.util.concurrent.GlobalEventExecutor;
 
+import java.io.File;
+import java.io.InputStream;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 import javax.net.ssl.SSLContext;
 
@@ -24,6 +28,10 @@ import org.opendaylight.controller.netconf.util.handler.ssh.authentication.Login
 import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
 import org.opendaylight.protocol.framework.ReconnectStrategy;
 import org.opendaylight.protocol.framework.TimedReconnectStrategy;
+import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider;
+import org.opendaylight.yangtools.yang.model.util.repo.FilesystemSchemaCachingProvider;
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders;
 import org.osgi.framework.BundleContext;
 
 import static com.google.common.base.Preconditions.*;
@@ -37,6 +45,8 @@ import com.google.common.net.InetAddresses;
 public final class NetconfConnectorModule extends org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModule
 {
 
+    private static ExecutorService GLOBAL_PROCESSING_EXECUTOR = null;
+    private static AbstractCachingSchemaSourceProvider<String, InputStream> GLOBAL_NETCONF_SOURCE_PROVIDER = null;
     private BundleContext bundleContext;
 
     public NetconfConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -74,31 +84,57 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
         } else {
             addressValue = getAddress().getIpv6Address().getValue();
         }
-        
         */
         ReconnectStrategy strategy = new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, attemptMsTimeout, 1000, 1.0, null,
                 Long.valueOf(connectionAttempts), null);
         
-        
-        device.setStrategy(strategy);
+        device.setReconnectStrategy(strategy);
         
         InetAddress addr = InetAddresses.forString(addressValue);
         InetSocketAddress socketAddress = new InetSocketAddress(addr , getPort().intValue());
+
+        
+        device.setProcessingExecutor(getGlobalProcessingExecutor());
+        
         device.setSocketAddress(socketAddress);
+        device.setEventExecutor(getEventExecutorDependency());
+        device.setDispatcher(createDispatcher());
+        device.setSchemaSourceProvider(getGlobalNetconfSchemaProvider(bundleContext));
         
+        getDomRegistryDependency().registerProvider(device, bundleContext);
+        device.start();
+        return device;
+    }
+
+    private ExecutorService getGlobalProcessingExecutor() {
+        if(GLOBAL_PROCESSING_EXECUTOR == null) {
+            
+            GLOBAL_PROCESSING_EXECUTOR = Executors.newCachedThreadPool();
+            
+        }
+        return GLOBAL_PROCESSING_EXECUTOR;
+    }
+
+    private synchronized AbstractCachingSchemaSourceProvider<String, InputStream> getGlobalNetconfSchemaProvider(BundleContext bundleContext) {
+        if(GLOBAL_NETCONF_SOURCE_PROVIDER == null) {
+            String storageFile = "cache/schema";
+//            File directory = bundleContext.getDataFile(storageFile);
+            File directory = new File("cache/schema");
+            SchemaSourceProvider<String> defaultProvider = SchemaSourceProviders.noopProvider();
+            GLOBAL_NETCONF_SOURCE_PROVIDER = FilesystemSchemaCachingProvider.createFromStringSourceProvider(defaultProvider, directory);
+        }
+        return GLOBAL_NETCONF_SOURCE_PROVIDER;
+    }
+
+    private NetconfClientDispatcher createDispatcher() {
         EventLoopGroup bossGroup = getBossThreadGroupDependency();
         EventLoopGroup workerGroup = getWorkerThreadGroupDependency();
-        NetconfClientDispatcher dispatcher = null;
         if(getTcpOnly()) {
-            dispatcher = new NetconfClientDispatcher( bossGroup, workerGroup);
+            return new NetconfClientDispatcher( bossGroup, workerGroup);
         } else {
             AuthenticationHandler authHandler = new LoginPassword(getUsername(),getPassword());
-            dispatcher = new NetconfSshClientDispatcher(authHandler , bossGroup, workerGroup);
+            return new NetconfSshClientDispatcher(authHandler , bossGroup, workerGroup);
         }
-        getDomRegistryDependency().registerProvider(device, bundleContext);
-        
-        device.start(dispatcher);
-        return device;
     }
 
     public void setBundleContext(BundleContext bundleContext) {
index 7c4bf5facad6a3dd94b0f1bd6a73e301a7820143..21500e1da6441540344daf741dd6becec70ed5a6 100644 (file)
@@ -1,37 +1,61 @@
 package org.opendaylight.controller.sal.connect.netconf
 
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-import org.opendaylight.controller.md.sal.common.api.data.DataReader
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import org.opendaylight.controller.netconf.client.NetconfClient
-import org.opendaylight.controller.sal.core.api.RpcImplementation
-import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*
+import com.google.common.base.Optional
+import com.google.common.collect.FluentIterable
+import io.netty.util.concurrent.EventExecutor
+import java.io.InputStream
 import java.net.InetSocketAddress
-import org.opendaylight.yangtools.yang.data.api.Node
-import org.opendaylight.yangtools.yang.data.api.SimpleNode
-import org.opendaylight.yangtools.yang.common.QName
+import java.net.URI
 import java.util.Collections
+import java.util.List
+import java.util.Set
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Future
+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.netconf.api.NetconfMessage
+import org.opendaylight.controller.netconf.client.NetconfClient
 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.Provider
+import org.opendaylight.controller.sal.core.api.RpcImplementation
 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
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
 import org.opendaylight.protocol.framework.ReconnectStrategy
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState
+import org.opendaylight.yangtools.concepts.Registration
+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.api.SimpleNode
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders
+import org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl
+import org.opendaylight.yangtools.yang.parser.impl.util.YangSourceContext
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
 
-class NetconfDevice implements 
-    Provider, // 
-    DataReader<InstanceIdentifier, CompositeNode>, //
-    DataCommitHandler<InstanceIdentifier, CompositeNode>, //
-    RpcImplementation, //
-    AutoCloseable {
+import static com.google.common.base.Preconditions.*
+import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*
+
+import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*
+import org.opendaylight.controller.netconf.util.xml.XmlUtil
+
+class NetconfDevice implements Provider, // 
+DataReader<InstanceIdentifier, CompositeNode>, //
+DataCommitHandler<InstanceIdentifier, CompositeNode>, //
+RpcImplementation, //
+AutoCloseable {
 
     var NetconfClient client;
 
@@ -41,35 +65,105 @@ class NetconfDevice implements
     @Property
     var MountProvisionInstance mountInstance;
 
+    @Property
+    var EventExecutor eventExecutor;
+
+    @Property
+    var ExecutorService processingExecutor;
+
     @Property
     var InstanceIdentifier path;
 
     @Property
-    var ReconnectStrategy strategy;
+    var ReconnectStrategy reconnectStrategy;
+
+    @Property
+    var AbstractCachingSchemaSourceProvider<String, InputStream> schemaSourceProvider;
+
+    @Property
+    private NetconfDeviceSchemaContextProvider deviceContextProvider
+
+    protected val Logger logger
 
     Registration<DataReader<InstanceIdentifier, CompositeNode>> operReaderReg
     Registration<DataReader<InstanceIdentifier, CompositeNode>> confReaderReg
     Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> commitHandlerReg
-    
+
     val String name
     MountProvisionService mountService
-    
-    
+
+    int messegeRetryCount = 5;
+
+    int messageTimeoutCount = 5 * 1000;
+
+    Set<QName> cachedCapabilities
+
+    @Property
+    var NetconfClientDispatcher dispatcher
+
+    static val InstanceIdentifier ROOT_PATH = InstanceIdentifier.builder().toInstance();
+
+    @Property
+    var SchemaSourceProvider<InputStream> remoteSourceProvider
+
     public new(String name) {
         this.name = name;
+        this.logger = LoggerFactory.getLogger(NetconfDevice.name + "#" + name);
         this.path = InstanceIdentifier.builder(INVENTORY_PATH).nodeWithKey(INVENTORY_NODE,
             Collections.singletonMap(INVENTORY_ID, name)).toInstance;
     }
 
-    def start(NetconfClientDispatcher dispatcher) {
-        client = NetconfClient.clientFor(name, socketAddress, strategy, dispatcher);
-        confReaderReg = mountInstance.registerConfigurationReader(path, this);
-        operReaderReg = mountInstance.registerOperationalReader(path, this);
-        //commitHandlerReg = mountInstance.registerCommitHandler(path,this);
+    def start() {
+        checkState(dispatcher != null, "Dispatcher must be set.");
+        checkState(schemaSourceProvider != null, "Schema Source Provider must be set.")
+        checkState(eventExecutor != null, "Event executor must be set.");
+
+        val listener = new NetconfDeviceListener(this, eventExecutor);
+        val task = startClientTask(dispatcher, listener)
+        if (mountInstance != null) {
+            confReaderReg = mountInstance.registerConfigurationReader(ROOT_PATH, this);
+            operReaderReg = mountInstance.registerOperationalReader(ROOT_PATH, this);
+            commitHandlerReg = mountInstance.registerCommitHandler(ROOT_PATH, this)
+        }
+        return processingExecutor.submit(task) as Future<Void>;
+
+    //commitHandlerReg = mountInstance.registerCommitHandler(path,this);
+    }
+
+    def Optional<SchemaContext> getSchemaContext() {
+        if (deviceContextProvider == null) {
+            return Optional.absent();
+        }
+        return deviceContextProvider.currentContext;
+    }
+
+    private def Runnable startClientTask(NetconfClientDispatcher dispatcher, NetconfDeviceListener listener) {
+
+        return [ |
+            logger.info("Starting Netconf Client on: {}", socketAddress);
+            client = NetconfClient.clientFor(name, socketAddress, reconnectStrategy, dispatcher, listener);
+            logger.debug("Initial capabilities {}", initialCapabilities);
+            var SchemaSourceProvider<String> delegate;
+            if (NetconfRemoteSchemaSourceProvider.isSupportedFor(initialCapabilities)) {
+                delegate = new NetconfRemoteSchemaSourceProvider(this);
+            }  else if(client.capabilities.contains(NetconfRemoteSchemaSourceProvider.IETF_NETCONF_MONITORING.namespace.toString)) {
+                delegate = new NetconfRemoteSchemaSourceProvider(this);
+            } else {
+                logger.info("Netconf server {} does not support IETF Netconf Monitoring", socketAddress);
+                delegate = SchemaSourceProviders.<String>noopProvider();
+            }
+            remoteSourceProvider = schemaSourceProvider.createInstanceFor(delegate);
+            deviceContextProvider = new NetconfDeviceSchemaContextProvider(this, remoteSourceProvider);
+            deviceContextProvider.createContextFromCapabilities(initialCapabilities);
+            if (mountInstance != null && schemaContext.isPresent) {
+                mountInstance.schemaContext = schemaContext.get();
+            }
+        ]
     }
 
     override readConfigurationData(InstanceIdentifier path) {
-        val result = invokeRpc(NETCONF_GET_CONFIG_QNAME, wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure()));
+        val result = invokeRpc(NETCONF_GET_CONFIG_QNAME,
+            wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure()));
         val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME);
         return data?.findNode(path) as CompositeNode;
     }
@@ -84,10 +178,30 @@ class NetconfDevice implements
         Collections.emptySet;
     }
 
+    def createSubscription(String streamName) {
+        val it = ImmutableCompositeNode.builder()
+        QName = NETCONF_CREATE_SUBSCRIPTION_QNAME
+        addLeaf("stream", streamName);
+        invokeRpc(QName, toInstance())
+    }
+
     override invokeRpc(QName rpc, CompositeNode input) {
-        val message = rpc.toRpcMessage(input);
-        val result = client.sendMessage(message);
-        return result.toRpcResult();
+        try {
+            val message = rpc.toRpcMessage(input,schemaContext);
+            val result = sendMessageImpl(message, messegeRetryCount, messageTimeoutCount);
+            return result.toRpcResult(rpc, schemaContext);
+
+        } catch (Exception e) {
+            logger.error("Rpc was not processed correctly.", e)
+            throw e;
+        }
+    }
+
+    def NetconfMessage sendMessageImpl(NetconfMessage message, int retryCount, int timeout) {
+        logger.debug("Send message {}",XmlUtil.toString(message.document))
+        val result = client.sendMessage(message, retryCount, timeout);
+        NetconfMapping.checkValidReply(message, result)
+        return result;
     }
 
     override getProviderFunctionality() {
@@ -96,35 +210,33 @@ class NetconfDevice implements
 
     override onSessionInitiated(ProviderSession session) {
         val dataBroker = session.getService(DataBrokerService);
-        
-        
-        
+
         val transaction = dataBroker.beginTransaction
-        if(transaction.operationalNodeNotExisting) {
-            transaction.putOperationalData(path,nodeWithId)
+        if (transaction.operationalNodeNotExisting) {
+            transaction.putOperationalData(path, nodeWithId)
         }
-        if(transaction.configurationNodeNotExisting) {
-            transaction.putConfigurationData(path,nodeWithId)
+        if (transaction.configurationNodeNotExisting) {
+            transaction.putConfigurationData(path, nodeWithId)
         }
         transaction.commit().get();
         mountService = session.getService(MountProvisionService);
-        mountInstance = mountService.createOrGetMountPoint(path);
+        mountInstance = mountService?.createOrGetMountPoint(path);
     }
-    
+
     def getNodeWithId() {
-        val id = new SimpleNodeTOImpl(INVENTORY_ID,null,name);
-        return new CompositeNodeTOImpl(INVENTORY_NODE,null,Collections.singletonList(id));
+        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) {
+    static def Node<?> findNode(CompositeNode node, InstanceIdentifier identifier) {
 
         var Node<?> current = node;
         for (arg : identifier.path) {
@@ -132,12 +244,17 @@ class NetconfDevice implements
                 return null;
             } else if (current instanceof CompositeNode) {
                 val currentComposite = (current as CompositeNode);
-
+                
                 current = currentComposite.getFirstCompositeByName(arg.nodeType);
-                if (current == null) {
+                if(current == null) {
+                    current = currentComposite.getFirstCompositeByName(arg.nodeType.withoutRevision());
+                }
+                if(current == null) {
                     current = currentComposite.getFirstSimpleByName(arg.nodeType);
                 }
                 if (current == null) {
+                    current = currentComposite.getFirstSimpleByName(arg.nodeType.withoutRevision());
+                } if (current == null) {
                     return null;
                 }
             }
@@ -146,7 +263,38 @@ class NetconfDevice implements
     }
 
     override requestCommit(DataModification<InstanceIdentifier, CompositeNode> modification) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        val twoPhaseCommit = new NetconfDeviceTwoPhaseCommitTransaction(this, modification);
+        twoPhaseCommit.prepare()
+        return twoPhaseCommit;
+    }
+
+    def getInitialCapabilities() {
+        val capabilities = client?.capabilities;
+        if (capabilities == null) {
+            return null;
+        }
+        if (cachedCapabilities == null) {
+            cachedCapabilities = FluentIterable.from(capabilities).filter[
+                contains("?") && contains("module=") && contains("revision=")].transform [
+                val parts = split("\\?");
+                val namespace = parts.get(0);
+                val queryParams = FluentIterable.from(parts.get(1).split("&"));
+                var revision = queryParams.findFirst[startsWith("revision=")]?.replaceAll("revision=", "");
+                val moduleName = queryParams.findFirst[startsWith("module=")]?.replaceAll("module=", "");
+                if (revision === null) {
+                    logger.warn("Netconf device was not reporting revision correctly, trying to get amp;revision=");
+                    revision = queryParams.findFirst[startsWith("&amp;revision=")]?.replaceAll("revision=", "");
+                    if (revision != null) {
+                        logger.warn("Netconf device returned revision incorectly escaped for {}", it)
+                    }
+                }
+                if (revision == null) {
+                    return QName.create(URI.create(namespace), null, moduleName);
+                }
+                return QName.create(namespace, revision, moduleName);
+            ].toSet();
+        }
+        return cachedCapabilities;
     }
 
     override close() {
@@ -156,3 +304,53 @@ class NetconfDevice implements
     }
 
 }
+
+package class NetconfDeviceSchemaContextProvider {
+
+    @Property
+    val NetconfDevice device;
+
+    @Property
+    val SchemaSourceProvider<InputStream> sourceProvider;
+
+    @Property
+    var Optional<SchemaContext> currentContext;
+
+    new(NetconfDevice device, SchemaSourceProvider<InputStream> sourceProvider) {
+        _device = device
+        _sourceProvider = sourceProvider
+        _currentContext = Optional.absent();
+    }
+
+    def createContextFromCapabilities(Iterable<QName> capabilities) {
+        val sourceContext = YangSourceContext.createFrom(capabilities, sourceProvider)
+        if (!sourceContext.missingSources.empty) {
+            device.logger.warn("Sources for following models are missing {}", sourceContext.missingSources);
+        }
+        device.logger.debug("Trying to create schema context from {}", sourceContext.validSources)
+        val modelsToParse = YangSourceContext.getValidInputStreams(sourceContext);
+        if (!sourceContext.validSources.empty) {
+            val schemaContext = tryToCreateContext(modelsToParse);
+            currentContext = Optional.fromNullable(schemaContext);
+        } else {
+            currentContext = Optional.absent();
+        }
+        if (currentContext.present) {
+            device.logger.debug("Schema context successfully created.");
+        }
+
+    }
+
+    def SchemaContext tryToCreateContext(List<InputStream> modelsToParse) {
+        val parser = new YangParserImpl();
+        try {
+
+            val models = parser.parseYangModelsFromStreams(modelsToParse);
+            val result = parser.resolveSchemaContext(models);
+            return result;
+        } catch (Exception e) {
+            device.logger.debug("Error occured during parsing YANG schemas", e);
+            return null;
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java
new file mode 100644 (file)
index 0000000..8623d90
--- /dev/null
@@ -0,0 +1,155 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import com.google.common.base.Objects;
+
+import io.netty.util.concurrent.EventExecutor;
+import io.netty.util.concurrent.Promise;
+
+import java.util.List;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.eclipse.xtext.xbase.lib.Functions.Function0;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.client.NetconfClientSession;
+import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.controller.netconf.util.xml.XmlElement;
+import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
+import org.opendaylight.controller.sal.connect.netconf.NetconfMapping;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.w3c.dom.Document;
+
+@SuppressWarnings("all")
+class NetconfDeviceListener extends NetconfClientSessionListener {
+    private final NetconfDevice device;
+    private final EventExecutor eventExecutor;
+
+    public NetconfDeviceListener(final NetconfDevice device, final EventExecutor eventExecutor) {
+        this.device = device;
+        this.eventExecutor = eventExecutor;
+    }
+
+    private Promise<NetconfMessage> messagePromise;
+    private ConcurrentMap<String, Promise<NetconfMessage>> promisedMessages;
+
+    private final ReentrantLock promiseLock = new ReentrantLock();
+
+    public void onMessage(final NetconfClientSession session, final NetconfMessage message) {
+        if (isNotification(message)) {
+            this.onNotification(session, message);
+        } else {
+            try {
+                this.promiseLock.lock();
+                boolean _notEquals = (!Objects.equal(this.messagePromise, null));
+                if (_notEquals) {
+                    this.device.logger.debug("Setting promised reply {} with message {}", this.messagePromise, message);
+                    this.messagePromise.setSuccess(message);
+                    this.messagePromise = null;
+                }
+            } finally {
+                this.promiseLock.unlock();
+            }
+        }
+    }
+
+    /**
+     * Method intended to customize notification processing.
+     * 
+     * @param session
+     *            {@see
+     *            NetconfClientSessionListener#onMessage(NetconfClientSession,
+     *            NetconfMessage)}
+     * @param message
+     *            {@see
+     *            NetconfClientSessionListener#onMessage(NetconfClientSession,
+     *            NetconfMessage)}
+     */
+    public void onNotification(final NetconfClientSession session, final NetconfMessage message) {
+        this.device.logger.debug("Received NETCONF notification.", message);
+        CompositeNode _notificationBody = null;
+        CompositeNode _compositeNode = null;
+        if (message != null) {
+            _compositeNode = NetconfMapping.toCompositeNode(message,device.getSchemaContext());
+        }
+        if (_compositeNode != null) {
+            _notificationBody = NetconfDeviceListener.getNotificationBody(_compositeNode);
+        }
+        final CompositeNode domNotification = _notificationBody;
+        boolean _notEquals = (!Objects.equal(domNotification, null));
+        if (_notEquals) {
+            MountProvisionInstance _mountInstance = null;
+            if (this.device != null) {
+                _mountInstance = this.device.getMountInstance();
+            }
+            if (_mountInstance != null) {
+                _mountInstance.publish(domNotification);
+            }
+        }
+    }
+
+    private static CompositeNode getNotificationBody(final CompositeNode node) {
+        List<Node<? extends Object>> _children = node.getChildren();
+        for (final Node<? extends Object> child : _children) {
+            if ((child instanceof CompositeNode)) {
+                return ((CompositeNode) child);
+            }
+        }
+        return null;
+    }
+
+    public NetconfMessage getLastMessage(final int attempts, final int attemptMsDelay) throws InterruptedException {
+        final Promise<NetconfMessage> promise = this.promiseReply();
+        this.device.logger.debug("Waiting for reply {}", promise);
+        int _plus = (attempts * attemptMsDelay);
+        final boolean messageAvailable = promise.await(_plus);
+        if (messageAvailable) {
+            try {
+                try {
+                    return promise.get();
+                } catch (Throwable _e) {
+                    throw Exceptions.sneakyThrow(_e);
+                }
+            } catch (final Throwable _t) {
+                if (_t instanceof ExecutionException) {
+                    final ExecutionException e = (ExecutionException) _t;
+                    IllegalStateException _illegalStateException = new IllegalStateException(e);
+                    throw _illegalStateException;
+                } else {
+                    throw Exceptions.sneakyThrow(_t);
+                }
+            }
+        }
+        String _plus_1 = ("Unsuccessful after " + Integer.valueOf(attempts));
+        String _plus_2 = (_plus_1 + " attempts.");
+        IllegalStateException _illegalStateException_1 = new IllegalStateException(_plus_2);
+        throw _illegalStateException_1;
+    }
+
+    public synchronized Promise<NetconfMessage> promiseReply() {
+        this.device.logger.debug("Promising reply.");
+        this.promiseLock.lock();
+        try {
+            boolean _equals = Objects.equal(this.messagePromise, null);
+            if (_equals) {
+                Promise<NetconfMessage> _newPromise = this.eventExecutor.<NetconfMessage> newPromise();
+                this.messagePromise = _newPromise;
+                return this.messagePromise;
+            }
+            return this.messagePromise;
+        } finally {
+            this.promiseLock.unlock();
+        }
+    }
+
+    public boolean isNotification(final NetconfMessage message) {
+        Document _document = message.getDocument();
+        final XmlElement xmle = XmlElement.fromDomDocument(_document);
+        String _name = xmle.getName();
+        return XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME.equals(_name);
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java
new file mode 100644 (file)
index 0000000..6df34cd
--- /dev/null
@@ -0,0 +1,143 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.xtext.xbase.lib.IterableExtensions;
+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.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*;
+
+public class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction<InstanceIdentifier, CompositeNode> {
+
+    private NetconfDevice device;
+    private final DataModification<InstanceIdentifier, CompositeNode> modification;
+    private boolean candidateSupported = true;
+
+    public NetconfDeviceTwoPhaseCommitTransaction(NetconfDevice device,
+            DataModification<InstanceIdentifier, CompositeNode> modification) {
+        super();
+        this.device = device;
+        this.modification = modification;
+    }
+
+    public void prepare() {
+        for (InstanceIdentifier toRemove : modification.getRemovedConfigurationData()) {
+            sendRemove(toRemove);
+        }
+        for(Entry<InstanceIdentifier, CompositeNode> toUpdate : modification.getUpdatedConfigurationData().entrySet()) {
+            sendMerge(toUpdate.getKey(),toUpdate.getValue());
+        }
+
+    }
+
+    private void sendMerge(InstanceIdentifier key, CompositeNode value) {
+        sendEditRpc(createEditStructure(key, Optional.<String>absent(), Optional.of(value)));
+    }
+
+    private void sendRemove(InstanceIdentifier toRemove) {
+        sendEditRpc(createEditStructure(toRemove, Optional.of("remove"), Optional.<CompositeNode> absent()));
+    }
+
+    private void sendEditRpc(CompositeNode editStructure) {
+        CompositeNodeBuilder<ImmutableCompositeNode> builder = configurationRpcBuilder();
+        builder.setQName(NETCONF_EDIT_CONFIG_QNAME);
+        builder.add(editStructure);
+        
+        RpcResult<CompositeNode> rpcResult = device.invokeRpc(NETCONF_EDIT_CONFIG_QNAME, builder.toInstance());
+        Preconditions.checkState(rpcResult.isSuccessful(),"Rpc Result was unsuccessful");
+        
+    }
+
+    private CompositeNodeBuilder<ImmutableCompositeNode> configurationRpcBuilder() {
+        CompositeNodeBuilder<ImmutableCompositeNode> ret = ImmutableCompositeNode.builder();
+        
+        Node<?> targetNode;
+        if(candidateSupported) {
+            targetNode = ImmutableCompositeNode.create(NETCONF_CANDIDATE_QNAME, ImmutableList.<Node<?>>of());
+        } else {
+            targetNode = ImmutableCompositeNode.create(NETCONF_RUNNING_QNAME, ImmutableList.<Node<?>>of());
+        }
+        Node<?> targetWrapperNode = ImmutableCompositeNode.create(NETCONF_TARGET_QNAME, ImmutableList.<Node<?>>of(targetNode));
+        ret.add(targetWrapperNode);
+        return ret;
+    }
+
+    private CompositeNode createEditStructure(InstanceIdentifier dataPath, Optional<String> action,
+            Optional<CompositeNode> lastChildOverride) {
+        List<PathArgument> path = dataPath.getPath();
+        List<PathArgument> reversed = Lists.reverse(path);
+        CompositeNode previous = null;
+        boolean isLast = true;
+        for (PathArgument arg : reversed) {
+            CompositeNodeBuilder<ImmutableCompositeNode> builder = ImmutableCompositeNode.builder();
+            builder.setQName(arg.getNodeType());
+            Map<QName, Object> predicates = Collections.emptyMap();
+            if (arg instanceof NodeIdentifierWithPredicates) {
+                predicates = ((NodeIdentifierWithPredicates) arg).getKeyValues();
+            }
+            for (Entry<QName, Object> entry : predicates.entrySet()) {
+                builder.addLeaf(entry.getKey(), entry.getValue());
+            }
+            
+            if (isLast) {
+                if (action.isPresent()) {
+                    builder.setAttribute(NETCONF_ACTION_QNAME, action.get());
+                }
+                if (lastChildOverride.isPresent()) {
+                    List<Node<?>> children = lastChildOverride.get().getChildren();
+                    for(Node<?> child : children) {
+                        if(!predicates.containsKey(child.getKey())) {
+                            builder.add(child);
+                        }
+                    }
+                    
+                }
+            } else {
+                builder.add(previous);
+            }
+            previous = builder.toInstance();
+            isLast = false;
+        }
+        return ImmutableCompositeNode.create(NETCONF_CONFIG_QNAME, ImmutableList.<Node<?>>of(previous));
+    }
+
+    @Override
+    public RpcResult<Void> finish() throws IllegalStateException {
+        CompositeNodeBuilder<ImmutableCompositeNode> commitInput = ImmutableCompositeNode.builder();
+        commitInput.setQName(NETCONF_COMMIT_QNAME);
+        RpcResult<?> rpcResult = device.invokeRpc(NetconfMapping.NETCONF_COMMIT_QNAME, commitInput.toInstance());
+        return (RpcResult<Void>) rpcResult;
+    }
+
+    @Override
+    public DataModification<InstanceIdentifier, CompositeNode> getModification() {
+        return this.modification;
+    }
+
+    @Override
+    public RpcResult<Void> rollback() throws IllegalStateException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}
index 78f6d59f77ed2b2a7025b578d6090929ceead2dd..c151e42fbb803e26565e53eb965a6903ebfa98da 100644 (file)
@@ -20,93 +20,179 @@ import org.w3c.dom.Element
 import org.opendaylight.controller.sal.common.util.Rpcs
 import java.util.List
 import com.google.common.collect.ImmutableList
+import org.opendaylight.yangtools.yang.data.api.SimpleNode
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode
+import com.google.common.base.Preconditions
+import com.google.common.base.Optional
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils
 
 class NetconfMapping {
 
     public static val NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0")
-    public static val NETCONF_QNAME = new QName(NETCONF_URI,null,"netconf");
-    public static val NETCONF_RPC_QNAME = new QName(NETCONF_QNAME,"rpc");
-    public static val NETCONF_GET_QNAME = new QName(NETCONF_QNAME,"get");
-    public static val NETCONF_GET_CONFIG_QNAME = new QName(NETCONF_QNAME,"get-config");
-    public static val NETCONF_SOURCE_QNAME = new QName(NETCONF_QNAME,"source");
-    public static val NETCONF_RUNNING_QNAME = new QName(NETCONF_QNAME,"running");
-    public static val NETCONF_RPC_REPLY_QNAME = new QName(NETCONF_QNAME,"rpc-reply");
-    public static val NETCONF_OK_QNAME = new QName(NETCONF_QNAME,"ok");
-    public static val NETCONF_DATA_QNAME = new QName(NETCONF_QNAME,"data");
+    public static val NETCONF_MONITORING_URI = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"
+    public static val NETCONF_NOTIFICATION_URI = URI.create("urn:ietf:params:xml:ns:netconf:notification:1.0")
     
-     static List<Node<?>> RUNNING = Collections.<Node<?>>singletonList(new SimpleNodeTOImpl(NETCONF_RUNNING_QNAME,null,null));
-    public static val CONFIG_SOURCE_RUNNING = new CompositeNodeTOImpl(NETCONF_SOURCE_QNAME,null,RUNNING);
-
-    static val messageId = new AtomicInteger(0);
     
-   
+    public static val NETCONF_QNAME = QName.create(NETCONF_URI, null, "netconf");
+    public static val NETCONF_RPC_QNAME = QName.create(NETCONF_QNAME, "rpc");
+    public static val NETCONF_GET_QNAME = QName.create(NETCONF_QNAME, "get");
+    public static val NETCONF_FILTER_QNAME = QName.create(NETCONF_QNAME, "filter");
+    public static val NETCONF_TYPE_QNAME = QName.create(NETCONF_QNAME, "type");
+    public static val NETCONF_GET_CONFIG_QNAME = QName.create(NETCONF_QNAME, "get-config");
+    public static val NETCONF_EDIT_CONFIG_QNAME = QName.create(NETCONF_QNAME, "edit-config");
+    public static val NETCONF_DELETE_CONFIG_QNAME = QName.create(NETCONF_QNAME, "delete-config");
+    public static val NETCONF_ACTION_QNAME = QName.create(NETCONF_QNAME, "action");
+    public static val NETCONF_COMMIT_QNAME = QName.create(NETCONF_QNAME, "commit");
+    
+    public static val NETCONF_CONFIG_QNAME = QName.create(NETCONF_QNAME, "config");
+    public static val NETCONF_SOURCE_QNAME = QName.create(NETCONF_QNAME, "source");
+    public static val NETCONF_TARGET_QNAME = QName.create(NETCONF_QNAME, "target");
+    
+    public static val NETCONF_CANDIDATE_QNAME = QName.create(NETCONF_QNAME, "candidate");
+    public static val NETCONF_RUNNING_QNAME = QName.create(NETCONF_QNAME, "running");
+    
+    
+    public static val NETCONF_RPC_REPLY_QNAME = QName.create(NETCONF_QNAME, "rpc-reply");
+    public static val NETCONF_OK_QNAME = QName.create(NETCONF_QNAME, "ok");
+    public static val NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data");
+    public static val NETCONF_CREATE_SUBSCRIPTION_QNAME = QName.create(NETCONF_NOTIFICATION_URI,null,"create-subscription");
+    public static val NETCONF_CANCEL_SUBSCRIPTION_QNAME = QName.create(NETCONF_NOTIFICATION_URI,null,"cancel-subscription");
+    public static val IETF_NETCONF_MONITORING_MODULE = QName.create(NETCONF_MONITORING_URI, "2010-10-04","ietf-netconf-monitoring");
 
+    static List<Node<?>> RUNNING = Collections.<Node<?>>singletonList(
+        new SimpleNodeTOImpl(NETCONF_RUNNING_QNAME, null, null));
+    public static val CONFIG_SOURCE_RUNNING = new CompositeNodeTOImpl(NETCONF_SOURCE_QNAME, null, RUNNING);
 
+    static val messageId = new AtomicInteger(0);
 
     static def Node<?> toFilterStructure(InstanceIdentifier identifier) {
         var Node<?> previous = null;
-        for (component : identifier.path.reverse) {
+        if(identifier.path.empty) {
+            return null;
+        }
+        
+        for (component : identifier.path.reverseView) {
             val Node<?> current = component.toNode(previous);
             previous = current;
         }
-        return previous;
+        return filter("subtree",previous);
     }
-    
+
     static def dispatch Node<?> toNode(NodeIdentifierWithPredicates argument, Node<?> node) {
         val list = new ArrayList<Node<?>>();
-        forarg : argument.keyValues.entrySet) {
-            list.add = new SimpleNodeTOImpl(arg.key,null,arg.value);
+        for (arg : argument.keyValues.entrySet) {
+            list.add = new SimpleNodeTOImpl(arg.key, null, arg.value);
         }
-        return new CompositeNodeTOImpl(argument.nodeType,null,list)
+        return new CompositeNodeTOImpl(argument.nodeType, null, list)
     }
-    
+
     static def dispatch Node<?> toNode(PathArgument argument, Node<?> node) {
-        if(node != null) {
-            return new CompositeNodeTOImpl(argument.nodeType,null,Collections.singletonList(node));
+        if (node != null) {
+            return new CompositeNodeTOImpl(argument.nodeType, null, Collections.singletonList(node));
         } else {
-            return new SimpleNodeTOImpl(argument.nodeType,null,null);
+            return new SimpleNodeTOImpl(argument.nodeType, null, null);
         }
     }
 
-    static def CompositeNode toCompositeNode(NetconfMessage message) {
-        return message.toRpcResult().result;
+    static def CompositeNode toCompositeNode(NetconfMessage message,Optional<SchemaContext> ctx) {
+        return null//message.toRpcResult().result;
     }
 
-    static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node) {
-        val rpcPayload = wrap(NETCONF_RPC_QNAME,node);
+    static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node,Optional<SchemaContext> ctx) {
+        val rpcPayload = wrap(NETCONF_RPC_QNAME, flattenInput(node));
         val w3cPayload = NodeUtils.buildShadowDomTree(rpcPayload);
-        w3cPayload.documentElement.setAttribute("message-id","m-"+ messageId.andIncrement);
+        w3cPayload.documentElement.setAttribute("message-id", "m-" + messageId.andIncrement);
         return new NetconfMessage(w3cPayload);
     }
+    
+    def static flattenInput(CompositeNode node) {
+        val inputQName = QName.create(node.nodeType,"input");
+        val input = node.getFirstCompositeByName(inputQName);
+        if(input == null) return node;
+        if(input instanceof CompositeNode) {
+            
+            val nodes = ImmutableList.builder() //
+                .addAll(input.children) //
+                .addAll(node.children.filter[nodeType != inputQName]) //
+                .build()
+            return ImmutableCompositeNode.create(node.nodeType,nodes);
+        } 
+        
+    }
 
-    static def RpcResult<CompositeNode> toRpcResult(NetconfMessage message) {
-        val rawRpc = message.document.toCompositeNode() as CompositeNode;
+    static def RpcResult<CompositeNode> toRpcResult(NetconfMessage message,QName rpc,Optional<SchemaContext> context) {
+        var CompositeNode rawRpc;
+        if(context.present) {
+            if(isDataRetrievalReply(rpc)) {
+                
+                val xmlData = message.document.dataSubtree
+                val dataNodes = XmlDocumentUtils.toDomNodes(xmlData,Optional.of(context.get.dataDefinitions))
+                
+                val it = ImmutableCompositeNode.builder()
+                setQName(NETCONF_RPC_REPLY_QNAME)
+                add(ImmutableCompositeNode.create(NETCONF_DATA_QNAME,dataNodes));
+                
+                rawRpc = it.toInstance;
+                //sys(xmlData)
+            } else {
+                val rpcSchema = context.get.operations.findFirst[QName == rpc]
+                rawRpc = message.document.toCompositeNode() as CompositeNode;
+            }
+            
+            
+            
+        } else {
+            rawRpc = message.document.toCompositeNode() as CompositeNode;
+        }
         //rawRpc.
-        
-        return Rpcs.getRpcResult(true,rawRpc,Collections.emptySet());
+        return Rpcs.getRpcResult(true, rawRpc, Collections.emptySet());
     }
     
+    def static Element getDataSubtree(Document doc) {
+        doc.getElementsByTagNameNS(NETCONF_URI.toString,"data").item(0) as Element
+    }
     
-    static def wrap(QName name,Node<?> node) {
-        if(node != null) {
-            return new CompositeNodeTOImpl(name,null,Collections.singletonList(node));
-        }
-        else {
-            return new CompositeNodeTOImpl(name,null,Collections.emptyList());
+    def static boolean isDataRetrievalReply(QName it) {
+        return NETCONF_URI == namespace && ( localName == NETCONF_GET_CONFIG_QNAME.localName || localName == NETCONF_GET_QNAME.localName) 
+    }
+
+    static def wrap(QName name, Node<?> node) {
+        if (node != null) {
+            return new CompositeNodeTOImpl(name, null, Collections.singletonList(node));
+        } else {
+            return new CompositeNodeTOImpl(name, null, Collections.emptyList());
         }
     }
-    
-        static def wrap(QName name,Node<?> additional,Node<?> node) {
-        if(node != null) {
-            return new CompositeNodeTOImpl(name,null,ImmutableList.of(additional,node));
+
+    static def wrap(QName name, Node<?> additional, Node<?> node) {
+        if (node != null) {
+            return new CompositeNodeTOImpl(name, null, ImmutableList.of(additional, node));
+        } else {
+            return new CompositeNodeTOImpl(name, null, ImmutableList.of(additional));
         }
-        else {
-            return new CompositeNodeTOImpl(name,null,ImmutableList.of(additional));
+    }
+
+    static def filter(String type, Node<?> node) {
+        val it = ImmutableCompositeNode.builder(); //
+        setQName(NETCONF_FILTER_QNAME);
+        setAttribute(NETCONF_TYPE_QNAME,type);
+        if (node != null) {
+            return add(node).toInstance();
+        } else {
+            return toInstance();
         }
     }
-    
-    
+
     public static def Node<?> toCompositeNode(Document document) {
-        return XmlDocumentUtils.toCompositeNode(document) as Node<?>
+        return XmlDocumentUtils.toDomNode(document) as Node<?>
     }
+    
+    public static def checkValidReply(NetconfMessage input, NetconfMessage output) {
+        val inputMsgId = input.document.documentElement.getAttribute("message-id")
+        val outputMsgId = output.document.documentElement.getAttribute("message-id")
+        Preconditions.checkState(inputMsgId == outputMsgId,"Rpc request and reply message IDs must be same.");
+        
+    }
+    
 }
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java
new file mode 100644 (file)
index 0000000..12be689
--- /dev/null
@@ -0,0 +1,69 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.util.Set;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider<String> {
+
+    public static final QName IETF_NETCONF_MONITORING = QName.create(
+            "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring", "2010-10-04", "ietf-netconf-monitoring");
+    public static final QName GET_SCHEMA_QNAME = QName.create(IETF_NETCONF_MONITORING, "get-schema");
+    public static final QName GET_DATA_QNAME = QName.create(IETF_NETCONF_MONITORING, "data");
+
+    NetconfDevice device;
+
+    public NetconfRemoteSchemaSourceProvider(NetconfDevice device) {
+        super();
+        this.device = device;
+    }
+
+    @Override
+    public Optional<String> getSchemaSource(String moduleName, Optional<String> revision) {
+        CompositeNodeBuilder<ImmutableCompositeNode> request = ImmutableCompositeNode.builder(); //
+        request.setQName(GET_SCHEMA_QNAME) //
+                .addLeaf("format", "yang") //
+                .addLeaf("identifier", moduleName); //
+        if (revision.isPresent()) {
+            request.addLeaf("version", revision.get());
+        }
+
+        device.logger.info("Loading YANG schema source for {}:{}", moduleName, revision);
+        RpcResult<CompositeNode> schemaReply = device.invokeRpc(GET_SCHEMA_QNAME, request.toInstance());
+        if (schemaReply.isSuccessful()) {
+            String schemaBody = getSchemaFromRpc(schemaReply.getResult());
+            if (schemaBody != null) {
+                device.logger.info("YANG Schema successfully retrieved from remote for {}:{}", moduleName, revision);
+                return Optional.of(schemaBody);
+            }
+        }
+        device.logger.info("YANG shcema was not successfully retrieved.");
+        return Optional.absent();
+    }
+
+    private String getSchemaFromRpc(CompositeNode result) {
+        if (result == null) {
+            return null;
+        }
+        SimpleNode<?> simpleNode = result.getFirstSimpleByName(GET_DATA_QNAME.withoutRevision());
+        Object potential = simpleNode.getValue();
+        if (potential instanceof String) {
+            return (String) potential;
+        }
+        return null;
+    }
+    
+    public static final boolean isSupportedFor(Set<QName> capabilities) {
+        return capabilities.contains(IETF_NETCONF_MONITORING);
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java
deleted file mode 100644 (file)
index 3f6b4e1..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.opendaylight.controller.sal.connect.netconf;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-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.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-public class XmlDocumentUtils {
-
-    public static CompositeNode toCompositeNode(Document doc) {
-        return (CompositeNode) toCompositeNode(doc.getDocumentElement());
-    }
-
-    private static Node<?> toCompositeNode(Element element) {
-        String orgNamespace = element.getNamespaceURI();
-        URI biNamespace = null;
-        if (orgNamespace != null) {
-            biNamespace = URI.create(orgNamespace);
-        }
-        QName qname = new QName(biNamespace, element.getLocalName());
-
-        List<Node<?>> values = new ArrayList<>();
-        NodeList nodes = element.getChildNodes();
-        boolean isSimpleObject = false;
-        String value = null;
-        for (int i = 0; i < nodes.getLength(); i++) {
-            org.w3c.dom.Node child = nodes.item(i);
-            if (child instanceof Element) {
-                isSimpleObject = false;
-                values.add(toCompositeNode((Element) child));
-            }
-            if (!isSimpleObject && child instanceof org.w3c.dom.Text) {
-                value = element.getTextContent();
-                if (value.matches(".*\\w.*")) {
-                    isSimpleObject = true;
-                    break;
-                }
-            }
-        }
-
-        if (isSimpleObject) {
-            return new SimpleNodeTOImpl<>(qname, null, value);
-        }
-        return new CompositeNodeTOImpl(qname, null, values);
-    }
-}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java
new file mode 100644 (file)
index 0000000..0c0070c
--- /dev/null
@@ -0,0 +1,88 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringBufferInputStream;
+import java.io.StringReader;
+
+import org.opendaylight.yangtools.concepts.Delegator;
+import org.opendaylight.yangtools.yang.common.QName;
+
+/**
+ * 
+ *
+ */
+public class YangModelInputStreamAdapter extends InputStream implements Delegator<InputStream> {
+
+    final String source;
+    final QName moduleIdentifier;
+    final InputStream delegate;
+    
+    
+    
+    private YangModelInputStreamAdapter(String source, QName moduleIdentifier, InputStream delegate) {
+        super();
+        this.source = source;
+        this.moduleIdentifier = moduleIdentifier;
+        this.delegate = delegate;
+    }
+
+    public int read() throws IOException {
+        return delegate.read();
+    }
+
+    public int hashCode() {
+        return delegate.hashCode();
+    }
+
+    public int read(byte[] b) throws IOException {
+        return delegate.read(b);
+    }
+
+    public boolean equals(Object obj) {
+        return delegate.equals(obj);
+    }
+
+    public int read(byte[] b, int off, int len) throws IOException {
+        return delegate.read(b, off, len);
+    }
+
+    public long skip(long n) throws IOException {
+        return delegate.skip(n);
+    }
+
+    public int available() throws IOException {
+        return delegate.available();
+    }
+
+    public void close() throws IOException {
+        delegate.close();
+    }
+
+    public void mark(int readlimit) {
+        delegate.mark(readlimit);
+    }
+
+    public void reset() throws IOException {
+        delegate.reset();
+    }
+
+    public boolean markSupported() {
+        return delegate.markSupported();
+    }
+
+    @Override
+    public InputStream getDelegate() {
+        return delegate;
+    }
+
+    @Override
+    public String toString() {
+        return "YangModelInputStreamAdapter [moduleIdentifier=" + moduleIdentifier + ", delegate=" + delegate + "]";
+    }
+
+    public static YangModelInputStreamAdapter create(QName name, String module) {
+        InputStream stringInput = new StringBufferInputStream(module);
+        return new YangModelInputStreamAdapter(null, name, stringInput );
+    }
+}
index 923851411090a9c93f9b0cf1d59e9be1a197a92b..2fae7ee021d0bc074861e38b6b50fd042ac4a402 100644 (file)
@@ -81,6 +81,14 @@ module odl-sal-netconf-connector-cfg {
                     }
                 }
             }
+
+            container event-executor {
+                uses config:service-ref {
+                    refine type {
+                        config:required-identity netty:netty-event-executor;
+                    }
+                }
+            }
         }
     }
 }
\ No newline at end of file
index c973498e8549888e4b076d7e102c388c6222b9e8..d5648a0625d87fd698aafbd132e45400aaf7186d 100644 (file)
@@ -14,7 +14,7 @@
 
   <properties>
     <zeromq.version>0.3.1</zeromq.version>
-    <jackson.version>1.9.8</jackson.version>
+    <jackson.version>2.3.0</jackson.version>
     <stax.version>1.0.1</stax.version>
   </properties>
 
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yang-data-impl</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.opendaylight.yangtools</groupId>
-      <artifactId>yang-common</artifactId>
-    </dependency>
 
     <!-- Third Party -->
     <dependency>
       <groupId> org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
     </dependency>
+
     <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-core-asl</artifactId>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-annotations</artifactId>
       <version>${jackson.version}</version>
     </dependency>
+
     <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-mapper-asl</artifactId>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-core</artifactId>
       <version>${jackson.version}</version>
     </dependency>
+
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+      <version>${jackson.version}</version>
+    </dependency>
+
     <dependency>
       <groupId>stax</groupId>
       <artifactId>stax-api</artifactId>
index 6c5e5fbf1163c398b40ae67c5777039b6b6e8eb4..06107a8773a6213f79df91c3a2bd637e085647ff 100644 (file)
@@ -7,15 +7,15 @@
  */
 package org.opendaylight.controller.sal.connector.remoterpc.dto;
 
-import org.codehaus.jackson.JsonNode;
-import org.codehaus.jackson.map.ObjectMapper;
+import java.io.Serializable;
+import java.net.URI;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.opendaylight.controller.sal.connector.api.RpcRouter;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 
-import java.io.Serializable;
-import java.net.URI;
-
 public class RouteIdentifierImpl implements RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>,Serializable {
 
   transient ObjectMapper mapper = new ObjectMapper();
index 550d9ef125c39551699a538477e50ed001d8e78c..f6b9004eae3139a17773688eba17a528fb5d1ae0 100644 (file)
@@ -1,6 +1,8 @@
 package org.opendaylight.controller.sal.connector.remoterpc;
 
-import org.codehaus.jackson.JsonParseException;
+import java.net.URI;
+
+import com.fasterxml.jackson.core.JsonParseException;
 import org.junit.Assert;
 import org.junit.Test;
 import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl;
@@ -8,8 +10,6 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.net.URI;
-
 public class RouteIdentifierImplTest {
 
   Logger _logger = LoggerFactory.getLogger(RouteIdentifierImplTest.class);
index 4305a283e2f0ac2e374629005c85fd0dbc65c7e2..8ee61c3a3f6a72561f45f7cde92ee8bea9567f4a 100644 (file)
@@ -14,6 +14,7 @@
     </scm>
 
     <properties>
+        <jackson.version>2.3.0</jackson.version>
         <exam.version>3.0.0</exam.version>
         <url.version>1.5.0</url.version>
         <config.version>0.2.3-SNAPSHOT</config.version>
         </dependency>
 
         <dependency>
-            <groupId>org.codehaus.jackson</groupId>
-            <artifactId>jackson-mapper-asl</artifactId>
-            <version>1.9.2</version>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>${jackson.version}</version>
         </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+
         <dependency>
-            <groupId>org.codehaus.jackson</groupId>
-            <artifactId>jackson-core-asl</artifactId>
-            <version>1.9.2</version>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>${jackson.version}</version>
         </dependency>
+
         <dependency>
             <groupId>org.zeromq</groupId>
             <artifactId>jeromq</artifactId>
             <version>0.3.1</version>
         </dependency>
+
         <dependency>
             <groupId>org.opendaylight.yangtools.thirdparty</groupId>
             <artifactId>xtend-lib-osgi</artifactId>
index 62c094d7a6cd44ce90c19b773449c5b9a3e02c24..dd910ea34bdb760721d1cc3151ff961ea07e75d8 100644 (file)
@@ -416,8 +416,9 @@ public class RouterTest {
         mavenBundle(YANG + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), //
         mavenBundle("com.google.guava", "guava").versionAsInProject(), //
         mavenBundle("org.zeromq", "jeromq").versionAsInProject(),
-        mavenBundle("org.codehaus.jackson", "jackson-mapper-asl").versionAsInProject(),
-        mavenBundle("org.codehaus.jackson", "jackson-core-asl").versionAsInProject(),
+        mavenBundle("com.fasterxml.jackson.core", "jackson-annotations").versionAsInProject(),
+        mavenBundle("com.fasterxml.jackson.core", "jackson-core").versionAsInProject(),
+        mavenBundle("com.fasterxml.jackson.core", "jackson-databind").versionAsInProject(),
         //routingtable dependencies
         systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"),
         // List framework bundles
index 5e798b6720d23d73dc7da83ba5f12c491e6648ae..0bd86a3eadb6007d441eb6859d3a61593af8a451 100644 (file)
@@ -42,7 +42,7 @@
       <artifactId>yang-data-impl</artifactId>
       <version>${yang.version}</version>
     </dependency>
-        <dependency>
+    <dependency>
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yang-model-util</artifactId>
       <version>${yang.version}</version>
       <version>2.4</version>
       <scope>test</scope>
     </dependency>
-    <dependency>
-       <groupId>org.opendaylight.yangtools</groupId>
-       <artifactId>yang-model-util</artifactId>
-       <version>0.5.9-SNAPSHOT</version>
-    </dependency>
   </dependencies>
 
   <build>
index 012b51fb5e339b6a0a4332e44d146b72f7e7ee76..60a8f285a2cc17188dcd4ea1cbb25055bb171a81 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.controller.sal.rest.api;
 
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
@@ -66,30 +68,50 @@ public interface RestconfService extends RestconfServiceLegacy {
     @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})
+    @Consumes({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);
     
+    @POST
+    @Path("/operations/{identifier}")
+    @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);
+    
     @GET
     @Path("/config/{identifier:.+}")
     @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);
-    
-    @POST
-    @Path("/config/{identifier:.+}")
+
+    @GET
+    @Path("/operational/{identifier:.+}")
     @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);
+    public StructuredData readOperationalData(@PathParam("identifier") String identifier);
 
     @PUT
     @Path("/config/{identifier:.+}")
-    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+    @Consumes({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, 
+    @POST
+    @Path("/config/{identifier:.+}")
+    @Consumes({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
                MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
-    public StructuredData readOperationalData(@PathParam("identifier") String identifier);
+    public Response createConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
+
+    @POST
+    @Path("/config")
+    @Consumes({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
+    public Response createConfigurationData(CompositeNode payload);
+
+    @DELETE
+    @Path("/config/{identifier:.+}")
+    public Response deleteConfigurationData(@PathParam("identifier") String identifier);
 
 }
index 35da98b1a0db82e72d6cb32de8e0e34c858e1a41..9b69c1f09a9a3f546259b9cb4d0bc993ebb90b98 100644 (file)
@@ -1,5 +1,6 @@
 package org.opendaylight.controller.sal.rest.api;
 
+import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
@@ -33,14 +34,14 @@ public interface RestconfServiceLegacy {
     @Deprecated
     @POST
     @Path("/datastore/{identifier:.+}")
-    @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, 
+    @Consumes({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
     @PUT
     @Path("/datastore/{identifier:.+}")
-    @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, 
+    @Consumes({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 fb7872f8bcd4e1efdf27be0183fd20176651ac33..7f7e8606c3228d8b2cbebff176a81a5e2fbf9017 100644 (file)
@@ -43,7 +43,7 @@ class JsonMapper {
 
     private final Set<LeafListSchemaNode> foundLeafLists = new HashSet<>();
     private final Set<ListSchemaNode> foundLists = new HashSet<>();
-    private final Logger logger = LoggerFactory.getLogger(JsonMapper.class); 
+    private final Logger logger = LoggerFactory.getLogger(JsonMapper.class);
 
     public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema) throws IOException {
         Preconditions.checkNotNull(writer);
@@ -184,16 +184,23 @@ class JsonMapper {
 
         TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(type);
 
+        if (node.getValue() == null && !(baseType instanceof EmptyTypeDefinition)) {
+            logger.debug("While generationg JSON output null value was found for type "
+                    + baseType.getClass().getSimpleName() + ".");
+        }
+
         // TODO check InstanceIdentifierTypeDefinition
         if (baseType instanceof IdentityrefTypeDefinition) {
             if (node.getValue() instanceof QName) {
                 IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(baseType).serialize(node.getValue());
                 IdentityValue valueFromDTO = valueDTO.getValuesWithNamespaces().get(0);
-                String moduleName = ControllerContext.getInstance().findModuleByNamespace(URI.create(valueFromDTO.getNamespace()));
+                String moduleName = ControllerContext.getInstance().findModuleNameByNamespace(
+                        URI.create(valueFromDTO.getNamespace()));
                 writer.value(moduleName + ":" + valueFromDTO.getValue());
             } else {
                 logger.debug("Value of " + baseType.getQName().getNamespace() + ":"
-                        + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass());
+                        + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is "
+                        + node.getValue().getClass());
                 writer.value(String.valueOf(node.getValue()));
             }
         } else if (baseType instanceof DecimalTypeDefinition || baseType instanceof IntegerTypeDefinition
index 242f18d240122597bea4d1dac29a4f1a31ea9e31..1bceee88cb9b034ac1f17c6ef1ef2b467a9cbf7b 100644 (file)
@@ -9,6 +9,7 @@ import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
@@ -37,6 +38,7 @@ public class RestconfProvider implements BundleActivator, Provider, ServiceTrack
         SchemaService schemaService = session.getService(SchemaService.class);
         listenerRegistration = schemaService.registerSchemaServiceListener(ControllerContext.getInstance());
         ControllerContext.getInstance().setSchemas(schemaService.getGlobalContext());
+        ControllerContext.getInstance().setMountService(session.getService(MountService.class));
     }
 
     @Override
index a3d658e7bfec43bca4dc743a460cab8bd6cea9de..0dd4668a749fdd5b50af9e8e72a26d7a4636d009 100644 (file)
 package org.opendaylight.controller.sal.rest.impl;
 
-import java.util.Set;
-
 import javax.activation.UnsupportedDataTypeException;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
 
-import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
-import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
-import org.opendaylight.controller.sal.restconf.impl.RestCodec;
-import org.opendaylight.yangtools.yang.common.QName;
 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.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils;
 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.YangNode;
-import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.Leafref;
 import org.w3c.dom.Document;
-import org.w3c.dom.Element;
 
-import com.google.common.base.Preconditions;
+import com.google.common.base.Optional;
 
 public class XmlMapper {
-    
-    private final Logger logger = LoggerFactory.getLogger(XmlMapper.class); 
+    private static final LeafrefCodecImpl LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl(
+            Optional.<LeafrefTypeDefinition> absent());
 
-    public Document write(CompositeNode data, DataNodeContainer schema) throws UnsupportedDataTypeException {
-        Preconditions.checkNotNull(data);
-        Preconditions.checkNotNull(schema);
+    private static class LeafrefCodecImpl extends TypeDefinitionAwareCodec<Object, LeafrefTypeDefinition> implements
+            LeafrefCodec<String> {
 
-        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-        Document doc = null;
-        try {
-            DocumentBuilder bob = dbf.newDocumentBuilder();
-            doc = bob.newDocument();
-        } catch (ParserConfigurationException e) {
-            return null;
+        protected LeafrefCodecImpl(Optional<LeafrefTypeDefinition> typeDef) {
+            super(typeDef, Object.class);
         }
 
-        if (schema instanceof ContainerSchemaNode || schema instanceof ListSchemaNode) {
-            doc.appendChild(translateToXmlAndReturnRootElement(doc, data, schema));
-            return doc;
-        } else {
-            throw new UnsupportedDataTypeException(
-                    "Schema can be ContainerSchemaNode or ListSchemaNode. Other types are not supported yet.");
+        @Override
+        public String serialize(Object data) {
+            return String.valueOf(data);
         }
-    }
 
-    private Element translateToXmlAndReturnRootElement(Document doc, Node<?> data, YangNode schema)
-            throws UnsupportedDataTypeException {
-        QName dataType = data.getNodeType();
-        Element itemEl = doc.createElementNS(dataType.getNamespace().toString(), dataType.getLocalName());
-        if (data instanceof SimpleNode<?>) {
-            if (schema instanceof LeafListSchemaNode) {
-                writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafListSchemaNode) schema).getType(), (DataSchemaNode) schema);
-            } else if (schema instanceof LeafSchemaNode) {
-                writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafSchemaNode) schema).getType(), (DataSchemaNode) schema);
-            } else {
-                Object value = data.getValue();
-                if (value != null) {
-                    itemEl.setTextContent(String.valueOf(value));
-                }
-            }
-        } else { // CompositeNode
-            for (Node<?> child : ((CompositeNode) data).getChildren()) {
-                DataSchemaNode childSchema = null;
-                if(schema != null){
-                    childSchema = findFirstSchemaForNode(child, ((DataNodeContainer) schema).getChildNodes());
-                    if (logger.isDebugEnabled()) {
-                        if (childSchema == null) {
-                            logger.debug("Probably the data node \"" + ((child == null) ? "" : child.getNodeType().getLocalName())
-                                    + "\" is not conform to schema");
-                        }
-                    }
-                }
-                itemEl.appendChild(translateToXmlAndReturnRootElement(doc, child, childSchema));
-            }
+        @Override
+        public Object deserialize(String data) {
+            return data;
         }
-        return itemEl;
     }
 
-    private void writeValueOfNodeByType(Element element, SimpleNode<?> node, TypeDefinition<?> type, DataSchemaNode schema) {
-
-        TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(type);
+    private static class XmlCodecProviderImpl implements XmlCodecProvider {
+        @Override
+        public TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> codecFor(TypeDefinition<?> baseType) {
+            TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> codec = TypeDefinitionAwareCodec
+                    .from(baseType);
 
-        if (baseType instanceof IdentityrefTypeDefinition) {
-            if (node.getValue() instanceof QName) {
-                IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(type).serialize(node.getValue());
-                IdentityValue value = valueDTO.getValuesWithNamespaces().get(0);
-                String prefix = "x";
-                if (value.getPrefix() != null && !value.getPrefix().isEmpty()) {
-                    prefix = value.getPrefix();
+            if (codec == null) {
+                if (baseType instanceof Leafref) {
+                    return LEAFREF_DEFAULT_CODEC;
                 }
-                element.setAttribute("xmlns:" + prefix, value.getNamespace());
-                element.setTextContent(prefix + ":" + value.getValue());
-            } else {
-                logger.debug("Value of " + baseType.getQName().getNamespace() + ":"
-                        + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass());
-                element.setTextContent(String.valueOf(node.getValue()));
-            }
-        } else {
-            if (node.getValue() != null) {
-                String value = String.valueOf(RestCodec.from(baseType).serialize(node.getValue()));
-                if (value.equals("null")) {
-                    value = String.valueOf(node.getValue());
-                }
-                element.setTextContent(value);
             }
+            return codec;
         }
     }
 
-    private DataSchemaNode findFirstSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode) {
-        if (dataSchemaNode != null && node != null) {
-            for (DataSchemaNode dsn : dataSchemaNode) {
-                if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) {
-                    return dsn;
-                } else if (dsn instanceof ChoiceNode) {
-                    for (ChoiceCaseNode choiceCase : ((ChoiceNode) dsn).getCases()) {
-                        DataSchemaNode foundDsn = findFirstSchemaForNode(node, choiceCase.getChildNodes());
-                        if (foundDsn != null) {
-                            return foundDsn;
-                        }
-                    }
-                }
-            }
-        }
-        return null;
-    }
+    private static final XmlCodecProvider XML_CODEC_PROVIDER_IMPL = new XmlCodecProviderImpl();
 
+    public Document write(CompositeNode data, DataNodeContainer schema) throws UnsupportedDataTypeException {
+        return XmlDocumentUtils.toDocument(data, schema, XML_CODEC_PROVIDER_IMPL);
+    }
 }
index df6b58c8971331b74c89418a6e1ee039e1fcdf10..c57505829c5bde05dffbfda95ad8d21c3ac1ba26 100644 (file)
@@ -10,6 +10,7 @@ import org.opendaylight.yangtools.yang.common.RpcResult
 import org.opendaylight.yangtools.yang.data.api.CompositeNode
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
 import org.slf4j.LoggerFactory
+import org.opendaylight.controller.sal.core.api.mount.MountInstance
 
 class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
 
@@ -41,15 +42,27 @@ class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
 
     override readConfigurationData(InstanceIdentifier path) {
         checkPreconditions
-        LOG.info("Read Configuration via Restconf: {}",path)
+        LOG.info("Read Configuration via Restconf: {}", path)
         return dataService.readConfigurationData(path);
     }
+    
+    def readConfigurationDataBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
+        checkPreconditions
+        LOG.info("Read Configuration via Restconf: {}", path)
+        return mountPoint.readConfigurationData(path);
+    }
 
     override readOperationalData(InstanceIdentifier path) {
         checkPreconditions
-        LOG.info("Read Operational via Restconf: {}",path)
+        LOG.info("Read Operational via Restconf: {}", path)
         return dataService.readOperationalData(path);
     }
+    
+    def readOperationalDataBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
+        checkPreconditions
+        LOG.info("Read Operational via Restconf: {}", path)
+        return mountPoint.readOperationalData(path);
+    }
 
     def RpcResult<CompositeNode> invokeRpc(QName type, CompositeNode payload) {
         checkPreconditions
@@ -60,15 +73,55 @@ class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
     def commitConfigurationDataPut(InstanceIdentifier path, CompositeNode payload) {
         checkPreconditions
         val transaction = dataService.beginTransaction;
+        LOG.info("Put Configuration via Restconf: {}", path)
+        transaction.putConfigurationData(path, payload);
+        return transaction.commit
+    }
+    
+    def commitConfigurationDataPutBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path, CompositeNode payload) {
+        checkPreconditions
+        val transaction = mountPoint.beginTransaction;
+        LOG.info("Put Configuration via Restconf: {}", path)
+        transaction.putConfigurationData(path, payload);
+        return transaction.commit
+    }
+
+    def commitConfigurationDataPost(InstanceIdentifier path, CompositeNode payload) {
+        checkPreconditions
+        val transaction = dataService.beginTransaction;
+        transaction.putConfigurationData(path, payload);
+        if (payload == transaction.createdConfigurationData.get(path)) {
+            LOG.info("Post Configuration via Restconf: {}", path)
+            return transaction.commit
+        }
+        LOG.info("Post Configuration via Restconf was not executed because data already exists: {}", path)
+        return null;
+    }
+    
+    def commitConfigurationDataPostBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path, CompositeNode payload) {
+        checkPreconditions
+        val transaction = mountPoint.beginTransaction;
         transaction.putConfigurationData(path, payload);
-        return transaction.commit()
+        if (payload == transaction.createdConfigurationData.get(path)) {
+            LOG.info("Post Configuration via Restconf: {}", path)
+            return transaction.commit
+        }
+        LOG.info("Post Configuration via Restconf was not executed because data already exists: {}", path)
+        return null;
     }
 
-    def commitOperationalDataPut(InstanceIdentifier path, CompositeNode payload) {
+    def commitConfigurationDataDelete(InstanceIdentifier path) {
         checkPreconditions
         val transaction = dataService.beginTransaction;
-        transaction.putOperationalData(path, payload);
-        return transaction.commit()
+        transaction.removeConfigurationData(path)
+        return transaction.commit
     }
     
+    def commitConfigurationDataDeleteBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
+        checkPreconditions
+        val transaction = mountPoint.beginTransaction;
+        transaction.removeConfigurationData(path)
+        return transaction.commit
+    }
+
 }
index 0ded60dae4fc0131ad6eb9da0cef06aee6f2cdff..74a32d452e212682abee966adffad4f062577fcb 100644 (file)
@@ -78,6 +78,11 @@ public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, C
         Preconditions.checkState(compositeNode == null, "Data can be inconsistent.");
         return Collections.unmodifiableList(values);
     }
+    
+    @Override
+    public boolean isChangeAllowed() {
+        return compositeNode == null ? true : false;
+    }
 
     @Override
     public CompositeNode unwrap() {
@@ -230,4 +235,5 @@ public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, C
     public Set<java.util.Map.Entry<QName, List<Node<?>>>> entrySet() {
         return unwrap().entrySet();
     }
+
 }
index eec2d452a178c15da2f0c70befa8c1367aae31eb..61237f01a16933ef742041c787874ec9ee8fc957 100644 (file)
@@ -10,8 +10,8 @@ import java.util.HashMap
 import java.util.List
 import java.util.Map
 import java.util.concurrent.ConcurrentHashMap
-import javax.ws.rs.core.Response
 import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
+import org.opendaylight.controller.sal.core.api.mount.MountService
 import org.opendaylight.controller.sal.rest.impl.RestUtil
 import org.opendaylight.controller.sal.rest.impl.RestconfProvider
 import org.opendaylight.yangtools.yang.common.QName
@@ -26,21 +26,32 @@ import org.opendaylight.yangtools.yang.model.api.ChoiceNode
 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.Module
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition
 import org.opendaylight.yangtools.yang.model.api.SchemaContext
 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
 import org.slf4j.LoggerFactory
 
 import static com.google.common.base.Preconditions.*
+import static javax.ws.rs.core.Response.Status.*
+import org.opendaylight.controller.sal.core.api.mount.MountInstance
 
 class ControllerContext implements SchemaServiceListener {
     val static LOG = LoggerFactory.getLogger(ControllerContext)
     val static ControllerContext INSTANCE = new ControllerContext
     val static NULL_VALUE = "null"
+    val static MOUNT_MODULE = "yang-ext"
+    val static MOUNT_NODE = "mount"
+    val static MOUNT = "yang-ext:mount"
 
-    var SchemaContext schemas;
+    @Property
+    var SchemaContext globalSchema;
+    
+    @Property
+    var MountService mountService;
 
     private val BiMap<URI, String> uriToModuleName = HashBiMap.create();
     private val Map<String, URI> moduleNameToUri = uriToModuleName.inverse();
@@ -57,8 +68,8 @@ class ControllerContext implements SchemaServiceListener {
     }
 
     private def void checkPreconditions() {
-        if (schemas === null) {
-            throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
+        if (globalSchema === null) {
+            throw new ResponseException(SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
         }
     }
 
@@ -67,7 +78,7 @@ class ControllerContext implements SchemaServiceListener {
     }
 
     public def InstanceIdWithSchemaNode toInstanceIdentifier(String restconfInstance) {
-        val ret = InstanceIdentifier.builder();
+        checkPreconditions
         val pathArgs = restconfInstance.split("/");
         if (pathArgs.empty) {
             return null;
@@ -75,29 +86,26 @@ class ControllerContext implements SchemaServiceListener {
         if (pathArgs.head.empty) {
             pathArgs.remove(0)
         }
-        val schemaNode = ret.collectPathArguments(pathArgs, restconfInstance.findModule);
-        if (schemaNode === null) {
-            return null
+        val startModule = pathArgs.head.toModuleName();
+        if (startModule === null) {
+            throw new ResponseException(BAD_REQUEST, "First node in URI has to be in format \"moduleName:nodeName\"")
         }
-        return new InstanceIdWithSchemaNode(ret.toInstance, schemaNode)
-    }
-
-    private def findModule(String restconfInstance) {
-        checkPreconditions
-        checkNotNull(restconfInstance);
-        val pathArgs = restconfInstance.split("/");
-        if (pathArgs.empty) {
-            return null;
+        val iiWithSchemaNode = collectPathArguments(InstanceIdentifier.builder(), pathArgs,
+            globalSchema.getLatestModule(startModule), null);
+        if (iiWithSchemaNode === null) {
+            throw new ResponseException(BAD_REQUEST, "URI has bad format")
         }
-        val modulWithFirstYangStatement = pathArgs.filter[s|s.contains(":")].head
-        val startModule = modulWithFirstYangStatement.toModuleName();
-        return getLatestModule(startModule)
+        return iiWithSchemaNode
     }
 
-    def getLatestModule(String moduleName) {
-        checkPreconditions
+    private def getLatestModule(SchemaContext schema, String moduleName) {
+        checkArgument(schema !== null);
         checkArgument(moduleName !== null && !moduleName.empty)
-        val modules = schemas.modules.filter[m|m.name == moduleName]
+        val modules = schema.modules.filter[m|m.name == moduleName]
+        return modules.filterLatestModule
+    }
+    
+    private def filterLatestModule(Iterable<Module> modules) {
         var latestModule = modules.head
         for (module : modules) {
             if (module.revision.after(latestModule.revision)) {
@@ -106,13 +114,38 @@ class ControllerContext implements SchemaServiceListener {
         }
         return latestModule
     }
+    
+    def findModuleByName(String moduleName) {
+        checkPreconditions
+        checkArgument(moduleName !== null && !moduleName.empty)
+        return globalSchema.getLatestModule(moduleName)
+    }
+    
+    def findModuleByName(MountInstance mountPoint, String moduleName) {
+        checkArgument(moduleName !== null && mountPoint !== null)
+        val mountPointSchema = mountPoint.schemaContext;
+        return mountPointSchema?.getLatestModule(moduleName);
+    }
+    
+    def findModuleByNamespace(URI namespace) {
+        checkPreconditions
+        val moduleSchemas = globalSchema.findModuleByNamespace(namespace)
+        return moduleSchemas?.filterLatestModule
+    }
+    
+    def findModuleByNamespace(MountInstance mountPoint, URI namespace) {
+        checkArgument(namespace !== null && mountPoint !== null)
+        val mountPointSchema = mountPoint.schemaContext;
+        val moduleSchemas = mountPointSchema?.findModuleByNamespace(namespace)
+        return moduleSchemas?.filterLatestModule
+    }
 
     def String toFullRestconfIdentifier(InstanceIdentifier path) {
         checkPreconditions
         val elements = path.path;
         val ret = new StringBuilder();
         val startQName = elements.get(0).nodeType;
-        val initialModule = schemas.findModuleByNamespaceAndRevision(startQName.namespace, startQName.revision)
+        val initialModule = globalSchema.findModuleByNamespaceAndRevision(startQName.namespace, startQName.revision)
         var node = initialModule as DataSchemaNode;
         for (element : elements) {
             node = node.childByQName(element.nodeType);
@@ -135,18 +168,13 @@ class ControllerContext implements SchemaServiceListener {
         throw new IllegalArgumentException("Conversion of generic path argument is not supported");
     }
 
-    def findModuleByNamespace(URI namespace) {
+    def findModuleNameByNamespace(URI namespace) {
         checkPreconditions
         var module = uriToModuleName.get(namespace)
         if (module === null) {
-            val moduleSchemas = schemas.findModuleByNamespace(namespace);
+            val moduleSchemas = globalSchema.findModuleByNamespace(namespace);
             if(moduleSchemas === null) return null
-            var latestModule = moduleSchemas.head
-            for (m : moduleSchemas) {
-                if (m.revision.after(latestModule.revision)) {
-                    latestModule = m
-                }
-            }
+            var latestModule = moduleSchemas.filterLatestModule
             if(latestModule === null) return null
             uriToModuleName.put(namespace, latestModule.name)
             module = latestModule.name;
@@ -154,16 +182,10 @@ class ControllerContext implements SchemaServiceListener {
         return module
     }
 
-    def findNamespaceByModule(String module) {
+    def findNamespaceByModuleName(String module) {
         var namespace = moduleNameToUri.get(module)
         if (namespace === null) {
-            val moduleSchemas = schemas.modules.filter[it|it.name.equals(module)]
-            var latestModule = moduleSchemas.head
-            for (m : moduleSchemas) {
-                if (m.revision.after(latestModule.revision)) {
-                    latestModule = m
-                }
-            }
+            var latestModule = globalSchema.getLatestModule(module)
             if(latestModule === null) return null
             namespace = latestModule.namespace
             uriToModuleName.put(namespace, latestModule.name)
@@ -175,7 +197,7 @@ class ControllerContext implements SchemaServiceListener {
         checkPreconditions
         var module = uriToModuleName.get(qname.namespace)
         if (module === null) {
-            val moduleSchema = schemas.findModuleByNamespaceAndRevision(qname.namespace, qname.revision);
+            val moduleSchema = globalSchema.findModuleByNamespaceAndRevision(qname.namespace, qname.revision);
             if(moduleSchema === null) throw new IllegalArgumentException()
             uriToModuleName.put(qname.namespace, moduleSchema.name)
             module = moduleSchema.name;
@@ -232,38 +254,92 @@ class ControllerContext implements SchemaServiceListener {
         if(object === null) return "";
         return URLEncoder.encode(object.toString)
     }
-
-    private def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List<String> strings,
-        DataNodeContainer parentNode) {
+    
+    private def InstanceIdWithSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List<String> strings,
+        DataNodeContainer parentNode, MountInstance mountPoint) {
         checkNotNull(strings)
         if (parentNode === null) {
             return null;
         }
         if (strings.empty) {
-            return parentNode as DataSchemaNode;
+            return new InstanceIdWithSchemaNode(builder.toInstance, parentNode as DataSchemaNode, mountPoint)
         }
-        val nodeRef = strings.head;
-
-        val nodeName = nodeRef.toNodeName();
-        val targetNode = parentNode.getDataChildByName(nodeName);
-        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)
-                            return result
-                    }
+        
+        val nodeName = strings.head.toNodeName
+        val moduleName = strings.head.toModuleName
+        var DataSchemaNode targetNode = null
+        if (!moduleName.nullOrEmpty) {
+            // if it is mount point
+            if (moduleName == MOUNT_MODULE && nodeName == MOUNT_NODE) {
+                if (mountPoint !== null) {
+                    throw new ResponseException(BAD_REQUEST, "Restconf supports just one mount point in URI.")
+                }
+                
+                if (mountService === null) {
+                    throw new ResponseException(SERVICE_UNAVAILABLE, "MountService was not found. " 
+                        + "Finding behind mount points does not work."
+                    )
+                }
+                
+                val partialPath = builder.toInstance;
+                val mount = mountService.getMountPoint(partialPath)
+                if (mount === null) {
+                    LOG.debug("Instance identifier to missing mount point: {}", partialPath)
+                    throw new ResponseException(BAD_REQUEST, "Mount point does not exist.")
+                }
+                
+                val mountPointSchema = mount.schemaContext;
+                if (mountPointSchema === null) {
+                    throw new ResponseException(BAD_REQUEST, "Mount point does not contain any schema with modules.")
                 }
+                
+                if (strings.size == 1) { // any data node is not behind mount point
+                    return new InstanceIdWithSchemaNode(InstanceIdentifier.builder().toInstance, mountPointSchema, mount)
+                }
+                
+                val moduleNameBehindMountPoint = strings.get(1).toModuleName()
+                if (moduleNameBehindMountPoint === null) {
+                    throw new ResponseException(BAD_REQUEST,
+                        "First node after mount point in URI has to be in format \"moduleName:nodeName\"")
+                }
+                
+                val moduleBehindMountPoint = mountPointSchema.getLatestModule(moduleNameBehindMountPoint)
+                if (moduleBehindMountPoint === null) {
+                    throw new ResponseException(BAD_REQUEST,
+                        "URI has bad format. \"" + moduleName + "\" module does not exist in mount point.")
+                }
+                
+                return collectPathArguments(InstanceIdentifier.builder(), strings.subList(1, strings.size),
+                    moduleBehindMountPoint, mount);
+            }
+            
+            var Module module = null;
+            if (mountPoint === null) {
+                module = globalSchema.getLatestModule(moduleName)
+                if (module === null) {
+                    throw new ResponseException(BAD_REQUEST,
+                        "URI has bad format. \"" + moduleName + "\" module does not exist.")
+                }
+            } else {
+                module = mountPoint.schemaContext?.getLatestModule(moduleName)
+                if (module === null) {
+                    throw new ResponseException(BAD_REQUEST,
+                        "URI has bad format. \"" + moduleName + "\" module does not exist in mount point.")
+                }
+            }
+            targetNode = parentNode.findInstanceDataChild(nodeName, module.namespace)
+            if (targetNode === null) {
+                throw new ResponseException(BAD_REQUEST, "URI has bad format. Possible reasons:\n" + 
+                    "1. \"" + strings.head + "\" was not found in parent data node.\n" + 
+                    "2. \"" + strings.head + "\" is behind mount point. Then it should be in format \"/" + MOUNT + "/" + strings.head + "\".")
+            }
+        } else { // string without module name
+            targetNode = parentNode.findInstanceDataChild(nodeName, null)
+            if (targetNode === null) {
+                throw new ResponseException(BAD_REQUEST, "URI has bad format. \"" + nodeName + "\" was not found in parent data node.\n")
             }
-            return null
-        }
-        if (targetNode instanceof ChoiceNode) {
-            return null
         }
-
+        
         // Number of consumed elements
         var consumed = 1;
         if (targetNode instanceof ListSchemaNode) {
@@ -272,7 +348,7 @@ class ControllerContext implements SchemaServiceListener {
 
             // every key has to be filled
             if ((strings.length - consumed) < keysSize) {
-                return null;
+                throw new ResponseException(BAD_REQUEST,"Missing key for list \"" + listNode.QName.localName + "\".")
             }
             val uriKeyValues = strings.subList(consumed, consumed + keysSize);
             val keyValues = new HashMap<QName, Object>();
@@ -282,7 +358,9 @@ class ControllerContext implements SchemaServiceListener {
 
                 // key value cannot be NULL
                 if (uriKeyValue.equals(NULL_VALUE)) {
-                    return null
+                    throw new ResponseException(BAD_REQUEST, "URI has bad format. List \"" + listNode.QName.localName 
+                        + "\" cannot contain \"null\" value as a key."
+                    )
                 }
                 keyValues.addKeyValue(listNode.getDataChildByName(key), uriKeyValue);
                 i = i + 1;
@@ -296,11 +374,42 @@ class ControllerContext implements SchemaServiceListener {
         }
         if (targetNode instanceof DataNodeContainer) {
             val remaining = strings.subList(consumed, strings.length);
-            val result = builder.collectPathArguments(remaining, targetNode as DataNodeContainer);
+            val result = builder.collectPathArguments(remaining, targetNode as DataNodeContainer, mountPoint);
             return result
         }
 
-        return targetNode
+        return new InstanceIdWithSchemaNode(builder.toInstance, targetNode, mountPoint)
+    }
+
+    def DataSchemaNode findInstanceDataChild(DataNodeContainer container, String name, URI moduleNamespace) {
+        var DataSchemaNode potentialNode = null
+        if (moduleNamespace === null) {
+            potentialNode = container.getDataChildByName(name);
+        } else {
+            potentialNode = container.childNodes.filter[n|n.QName.localName == name && n.QName.namespace == moduleNamespace].head
+        }
+        
+        if (potentialNode.instantiatedDataSchema) {
+            return potentialNode;
+        }
+        val allCases = container.childNodes.filter(ChoiceNode).map[cases].flatten
+        for (caze : allCases) {
+            potentialNode = caze.findInstanceDataChild(name, moduleNamespace);
+            if (potentialNode !== null) {
+                return potentialNode;
+            }
+        }
+        return null;
+    }
+    
+    static def boolean isInstantiatedDataSchema(DataSchemaNode node) {
+        switch node {
+            LeafSchemaNode: return true
+            LeafListSchemaNode: return true
+            ContainerSchemaNode: return true
+            ListSchemaNode: return true
+            default: return false
+        }
     }
 
     private def void addKeyValue(HashMap<QName, Object> map, DataSchemaNode node, String uriValue) {
@@ -319,31 +428,31 @@ class ControllerContext implements SchemaServiceListener {
         map.put(node.QName, decoded);
     }
 
-    private def String toModuleName(String str) {
+    private static def String toModuleName(String str) {
         checkNotNull(str)
         if (str.contains(":")) {
             val args = str.split(":");
-            checkArgument(args.size === 2);
-            return args.get(0);
-        } else {
-            return null;
+            if (args.size === 2) {
+                return args.get(0);
+            }
         }
+        return null;
     }
 
     private def String toNodeName(String str) {
         if (str.contains(":")) {
             val args = str.split(":");
-            checkArgument(args.size === 2);
-            return args.get(1);
-        } else {
-            return str;
+            if (args.size === 2) {
+                return args.get(1);
+            }
         }
+        return str;
     }
 
     private def QName toQName(String name) {
         val module = name.toModuleName;
         val node = name.toNodeName;
-        val namespace = FluentIterable.from(schemas.modules.sort[o1,o2 | o1.revision.compareTo(o2.revision)]) //
+        val namespace = FluentIterable.from(globalSchema.modules.sort[o1,o2 | o1.revision.compareTo(o2.revision)]) //
             .transform[QName.create(namespace,revision,it.name)].findFirst[module == localName]
         ;
         return QName.create(namespace,node);
@@ -354,7 +463,7 @@ class ControllerContext implements SchemaServiceListener {
     }
 
     override onGlobalContextUpdated(SchemaContext context) {
-        this.schemas = context;
+        this.globalSchema = context;
         for (operation : context.operations) {
             val qname = operation.QName;
             qnameToRpc.put(qname, operation);
index c146954dcedad184d51181db8f4a4da395b6498c..cdb9599a4674e3691815eb6c3ad2895caddb029d 100644 (file)
@@ -64,6 +64,11 @@ public final class EmptyNodeWrapper implements NodeWrapper<Node<?>>, Node<Void>
         this.namespace = namespace;
     }
 
+    @Override
+    public boolean isChangeAllowed() {
+        return unwrapped == null ? true : false;
+    }
+
     @Override
     public Node<?> unwrap() {
         if (unwrapped == null) {
index ad0654af785bd13ac690409723ac45d0e55f22e9..1c958b901bf7039929a655ec84f088c3bdaf0192 100644 (file)
@@ -1,5 +1,6 @@
 package org.opendaylight.controller.sal.restconf.impl;
 
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
@@ -7,10 +8,12 @@ public class InstanceIdWithSchemaNode {
 
     private final InstanceIdentifier instanceIdentifier;
     private final DataSchemaNode schemaNode;
+    private final MountInstance mountPoint;
 
-    public InstanceIdWithSchemaNode(InstanceIdentifier instanceIdentifier, DataSchemaNode schemaNode) {
+    public InstanceIdWithSchemaNode(InstanceIdentifier instanceIdentifier, DataSchemaNode schemaNode, MountInstance mountPoint) {
         this.instanceIdentifier = instanceIdentifier;
         this.schemaNode = schemaNode;
+        this.mountPoint = mountPoint;
     }
 
     public InstanceIdentifier getInstanceIdentifier() {
@@ -21,4 +24,8 @@ public class InstanceIdWithSchemaNode {
         return schemaNode;
     }
 
+    public MountInstance getMountPoint() {
+        return mountPoint;
+    }
+
 }
index 675e1194396147334509e35d5a6b4ebb21e40b35..6b8665f7653c26e8881c685aa0e507231a0d8db6 100644 (file)
@@ -11,6 +11,8 @@ public interface NodeWrapper<T extends Node<?>> {
     
     T unwrap();
     
+    boolean isChangeAllowed();
+    
     URI getNamespace();
 
     void setNamespace(URI namespace);
index 450ba02b56071412d8aff89030db7b221a128605..45f3f7f30bd3de9b29117e27b50767ae7e5c5166 100644 (file)
@@ -19,16 +19,16 @@ public class RestCodec {
 
     private RestCodec() {
     }
-    
+
     public static final Codec<Object, Object> from(TypeDefinition<?> typeDefinition) {
         return new ObjectCodec(typeDefinition);
     }
-    
+
     @SuppressWarnings("rawtypes")
     public static final class ObjectCodec implements Codec<Object, Object> {
 
         private final Logger logger = LoggerFactory.getLogger(RestCodec.class);
-        
+
         public static final Codec IDENTITYREF_DEFAULT_CODEC = new IdentityrefCodecImpl();
         public static final Codec LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl();
 
@@ -37,7 +37,7 @@ public class RestCodec {
         private ObjectCodec(TypeDefinition<?> typeDefinition) {
             type = RestUtil.resolveBaseTypeFrom(typeDefinition);
         }
-        
+
         @SuppressWarnings("unchecked")
         @Override
         public Object deserialize(Object input) {
@@ -47,16 +47,21 @@ public class RestCodec {
                 } else if (type instanceof LeafrefTypeDefinition) {
                     return LEAFREF_DEFAULT_CODEC.deserialize(input);
                 } else {
-                    TypeDefinitionAwareCodec<Object,? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec.from(type);
+                    TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec
+                            .from(type);
                     if (typeAwarecodec != null) {
                         return typeAwarecodec.deserialize(String.valueOf(input));
                     } else {
-                        logger.debug("Codec for type \"" + type.getQName().getLocalName() + "\" is not implemented yet.");
+                        logger.debug("Codec for type \"" + type.getQName().getLocalName()
+                                + "\" is not implemented yet.");
                         return null;
                     }
                 }
-            } catch (ClassCastException e) { // TODO remove this catch when everyone use codecs
-                logger.error("ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), e);
+            } catch (ClassCastException e) { // TODO remove this catch when
+                                             // everyone use codecs
+                logger.error(
+                        "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input),
+                        e);
                 return input;
             }
         }
@@ -70,22 +75,27 @@ public class RestCodec {
                 } else if (type instanceof LeafrefTypeDefinition) {
                     return LEAFREF_DEFAULT_CODEC.serialize(input);
                 } else {
-                    TypeDefinitionAwareCodec<Object,? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec.from(type);
+                    TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec
+                            .from(type);
                     if (typeAwarecodec != null) {
                         return typeAwarecodec.serialize(input);
                     } else {
-                        logger.debug("Codec for type \"" + type.getQName().getLocalName() + "\" is not implemented yet.");
+                        logger.debug("Codec for type \"" + type.getQName().getLocalName()
+                                + "\" is not implemented yet.");
                         return null;
                     }
                 }
-            } catch (ClassCastException e) { // TODO remove this catch when everyone use codecs
-                logger.error("ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), e);
+            } catch (ClassCastException e) { // TODO remove this catch when
+                                             // everyone use codecs
+                logger.error(
+                        "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input),
+                        e);
                 return input;
             }
         }
-        
+
     }
-    
+
     public static class IdentityrefCodecImpl implements IdentityrefCodec<IdentityValuesDTO> {
 
         @Override
@@ -97,7 +107,7 @@ public class RestCodec {
         public QName deserialize(IdentityValuesDTO data) {
             IdentityValue valueWithNamespace = data.getValuesWithNamespaces().get(0);
             String namespace = valueWithNamespace.getNamespace();
-            URI validNamespace = ControllerContext.getInstance().findNamespaceByModule(namespace);
+            URI validNamespace = ControllerContext.getInstance().findNamespaceByModuleName(namespace);
             if (validNamespace == null) {
                 validNamespace = URI.create(namespace);
             }
@@ -105,7 +115,7 @@ public class RestCodec {
         }
 
     }
-    
+
     public static class LeafrefCodecImpl implements LeafrefCodec<String> {
 
         @Override
@@ -117,7 +127,7 @@ public class RestCodec {
         public Object deserialize(String data) {
             return data;
         }
-        
+
     }
-    
+
 }
index 4645a411c17c88baa7d55d94c21fcb944faf4d2f..5ad6f1eea88d1ec33fc1cc67c155c601d7f30880 100644 (file)
@@ -1,13 +1,20 @@
 package org.opendaylight.controller.sal.restconf.impl
 
+import com.google.common.base.Preconditions
+import java.net.URI
 import java.util.ArrayList
+import java.util.HashMap
 import java.util.List
 import java.util.Set
 import javax.ws.rs.core.Response
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus
+import org.opendaylight.controller.sal.core.api.mount.MountInstance
 import org.opendaylight.controller.sal.rest.api.RestconfService
 import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.common.RpcResult
 import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder
 import org.opendaylight.yangtools.yang.data.api.Node
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory
 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
@@ -17,6 +24,8 @@ 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.Module
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition
 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
 
@@ -55,41 +64,27 @@ class RestconfImpl implements RestconfService {
         return null;
     }
 
-    override readData(String identifier) {
-        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.resolveInstanceIdentifier
-        val value = normalizeNode(payload, identifierWithSchemaNode.schemaNode)
-        val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier, value).get();
-        switch status.result {
-            case TransactionStatus.COMMITED: Response.status(NO_CONTENT).build
-            default: Response.status(INTERNAL_SERVER_ERROR).build
-        }
+    override invokeRpc(String identifier, CompositeNode payload) {
+        return callRpc(identifier.rpcDefinition, payload)
     }
-
-    override updateConfigurationData(String identifier, CompositeNode payload) {
-        val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
-        val value = normalizeNode(payload, identifierWithSchemaNode.schemaNode)
-        val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier, value).get();
-        switch status.result {
-            case TransactionStatus.COMMITED: Response.status(OK).build
-            default: Response.status(INTERNAL_SERVER_ERROR).build
-        }
+    
+    override invokeRpc(String identifier) {
+        return callRpc(identifier.rpcDefinition, null)
     }
-
-    override invokeRpc(String identifier, CompositeNode payload) {
-        val rpc = identifier.rpcDefinition
+    
+    private def StructuredData callRpc(RpcDefinition rpc, CompositeNode payload) {
         if (rpc === null) {
             throw new ResponseException(NOT_FOUND, "RPC does not exist.");
         }
-        val value = normalizeNode(payload, rpc.input)
-        val List<Node<?>> input = new ArrayList
-        input.add(value)
-        val rpcRequest = NodeFactory.createMutableCompositeNode(rpc.QName, null, input, null, null)
+        var CompositeNode rpcRequest;
+        if (payload === null) {
+            rpcRequest = NodeFactory.createMutableCompositeNode(rpc.QName, null, null, null, null)
+        } else {
+            val value = normalizeNode(payload, rpc.input, null)
+            val List<Node<?>> input = new ArrayList
+            input.add(value)
+            rpcRequest = NodeFactory.createMutableCompositeNode(rpc.QName, null, input, null, null)
+        }
         val rpcResult = broker.invokeRpc(rpc.QName, rpcRequest);
         if (!rpcResult.successful) {
             throw new ResponseException(INTERNAL_SERVER_ERROR, "Operation failed")
@@ -100,46 +95,221 @@ class RestconfImpl implements RestconfService {
         return new StructuredData(rpcResult.result, rpc.output)
     }
 
+    override readData(String identifier) {
+        val iiWithData = identifier.toInstanceIdentifier
+        var CompositeNode data = null;
+        if (iiWithData.mountPoint !== null) {
+            data = broker.readOperationalDataBehindMountPoint(iiWithData.mountPoint, iiWithData.instanceIdentifier)
+        } else {
+            data = broker.readOperationalData(iiWithData.getInstanceIdentifier);
+        }
+        return new StructuredData(data, iiWithData.schemaNode)
+    }
+
     override readConfigurationData(String identifier) {
-        val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
-        val data = broker.readConfigurationData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
-        return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
+        val iiWithData = identifier.toInstanceIdentifier
+        var CompositeNode data = null;
+        if (iiWithData.mountPoint !== null) {
+            data = broker.readConfigurationDataBehindMountPoint(iiWithData.mountPoint, iiWithData.getInstanceIdentifier)
+        } else {
+            data = broker.readConfigurationData(iiWithData.getInstanceIdentifier);
+        }
+        return new StructuredData(data, iiWithData.schemaNode)
     }
 
     override readOperationalData(String identifier) {
-        val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
-        val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
-        return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
+        val iiWithData = identifier.toInstanceIdentifier
+        var CompositeNode data = null;
+        if (iiWithData.mountPoint !== null) {
+            data = broker.readOperationalDataBehindMountPoint(iiWithData.mountPoint, iiWithData.getInstanceIdentifier)
+        } else {
+            data = broker.readOperationalData(iiWithData.getInstanceIdentifier);
+        }
+        return new StructuredData(data, iiWithData.schemaNode)
     }
 
     override updateConfigurationDataLegacy(String identifier, CompositeNode payload) {
         updateConfigurationData(identifier, payload);
     }
 
+    override updateConfigurationData(String identifier, CompositeNode payload) {
+        val iiWithData = identifier.toInstanceIdentifier
+        val value = normalizeNode(payload, iiWithData.schemaNode, iiWithData.mountPoint)
+        var RpcResult<TransactionStatus> status = null
+        if (iiWithData.mountPoint !== null) {
+            status = broker.commitConfigurationDataPutBehindMountPoint(iiWithData.mountPoint,
+                iiWithData.instanceIdentifier, value).get()
+        } else {
+            status = broker.commitConfigurationDataPut(iiWithData.instanceIdentifier, value).get();
+        }
+        switch status.result {
+            case TransactionStatus.COMMITED: Response.status(OK).build
+            default: Response.status(INTERNAL_SERVER_ERROR).build
+        }
+    }
+
     override createConfigurationDataLegacy(String identifier, CompositeNode payload) {
         createConfigurationData(identifier, payload);
     }
 
-    private def InstanceIdWithSchemaNode resolveInstanceIdentifier(String identifier) {
-        val identifierWithSchemaNode = identifier.toInstanceIdentifier
-        if (identifierWithSchemaNode === null) {
-            throw new ResponseException(BAD_REQUEST, "URI has bad format");
+    override createConfigurationData(String identifier, CompositeNode payload) {
+        if (payload.namespace === null) {
+            throw new ResponseException(BAD_REQUEST,
+                "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)");
+        }
+        val uncompleteInstIdWithData = identifier.toInstanceIdentifier
+        val schemaNode = uncompleteInstIdWithData.mountPoint.findModule(payload)?.getSchemaChildNode(payload)
+        val value = normalizeNode(payload, schemaNode, uncompleteInstIdWithData.mountPoint)
+        val completeInstIdWithData = uncompleteInstIdWithData.addLastIdentifierFromData(value, schemaNode)
+        var RpcResult<TransactionStatus> status = null
+        if (completeInstIdWithData.mountPoint !== null) {
+            status = broker.commitConfigurationDataPostBehindMountPoint(completeInstIdWithData.mountPoint,
+                completeInstIdWithData.instanceIdentifier, value)?.get();
+        } else {
+            status = broker.commitConfigurationDataPost(completeInstIdWithData.instanceIdentifier, value)?.get();
+        }
+        if (status === null) {
+            return Response.status(ACCEPTED).build
+        }
+        switch status.result {
+            case TransactionStatus.COMMITED: Response.status(NO_CONTENT).build
+            default: Response.status(INTERNAL_SERVER_ERROR).build
+        }
+    }
+    
+    override createConfigurationData(CompositeNode payload) {
+        if (payload.namespace === null) {
+            throw new ResponseException(BAD_REQUEST,
+                "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)");
+        }
+        val schemaNode = findModule(null, payload)?.getSchemaChildNode(payload)
+        val value = normalizeNode(payload, schemaNode, null)
+        val iiWithData = addLastIdentifierFromData(null, value, schemaNode)
+        var RpcResult<TransactionStatus> status = null
+        if (iiWithData.mountPoint !== null) {
+            status = broker.commitConfigurationDataPostBehindMountPoint(iiWithData.mountPoint,
+                iiWithData.instanceIdentifier, value)?.get();
+        } else {
+            status = broker.commitConfigurationDataPost(iiWithData.instanceIdentifier, value)?.get();
+        }
+        if (status === null) {
+            return Response.status(ACCEPTED).build
+        }
+        switch status.result {
+            case TransactionStatus.COMMITED: Response.status(NO_CONTENT).build
+            default: Response.status(INTERNAL_SERVER_ERROR).build
+        }
+    }
+    
+    override deleteConfigurationData(String identifier) {
+        val iiWithData = identifier.toInstanceIdentifier
+        var RpcResult<TransactionStatus> status = null
+        if (iiWithData.mountPoint !== null) {
+            status = broker.commitConfigurationDataDeleteBehindMountPoint(iiWithData.mountPoint,
+                iiWithData.getInstanceIdentifier).get;
+        } else {
+            status = broker.commitConfigurationDataDelete(iiWithData.getInstanceIdentifier).get;
+        }
+        switch status.result {
+            case TransactionStatus.COMMITED: Response.status(OK).build
+            default: Response.status(INTERNAL_SERVER_ERROR).build
+        }
+    }
+    
+    private def dispatch URI namespace(CompositeNode data) {
+        return data.nodeType.namespace
+    }
+    
+    private def dispatch URI namespace(CompositeNodeWrapper data) {
+        return data.namespace
+    }
+
+    private def dispatch Module findModule(MountInstance mountPoint, CompositeNode data) {
+        if (mountPoint !== null) {
+            return mountPoint.findModuleByNamespace(data.nodeType.namespace)
+        } else {
+            return findModuleByNamespace(data.nodeType.namespace)
         }
-        return identifierWithSchemaNode
     }
 
-    private def CompositeNode normalizeNode(CompositeNode node, DataSchemaNode schema) {
+    private def dispatch Module findModule(MountInstance mountPoint, CompositeNodeWrapper data) {
+        Preconditions.checkNotNull(data.namespace)
+        var Module module = null;
+        if (mountPoint !== null) {
+            module = mountPoint.findModuleByNamespace(data.namespace) // namespace from XML
+            if (module === null) {
+                module = mountPoint.findModuleByName(data.namespace.toString) // namespace (module name) from JSON
+            }
+        } else {
+            module = data.namespace.findModuleByNamespace // namespace from XML
+            if (module === null) {
+                module = data.namespace.toString.findModuleByName // namespace (module name) from JSON
+            }
+        }
+        return module
+    }
+    
+    private def dispatch DataSchemaNode getSchemaChildNode(DataNodeContainer parentSchemaNode, CompositeNode data) {
+        return parentSchemaNode?.getDataChildByName(data.nodeType.localName)
+    }
+    
+    private def dispatch DataSchemaNode getSchemaChildNode(DataNodeContainer parentSchemaNode, CompositeNodeWrapper data) {
+        return parentSchemaNode?.getDataChildByName(data.localName)
+    }
+
+    private def InstanceIdWithSchemaNode addLastIdentifierFromData(InstanceIdWithSchemaNode identifierWithSchemaNode,
+        CompositeNode data, DataSchemaNode schemaOfData) {
+        val iiOriginal = identifierWithSchemaNode?.instanceIdentifier
+        var InstanceIdentifierBuilder iiBuilder = null
+        if (iiOriginal === null) {
+            iiBuilder = InstanceIdentifier.builder
+        } else {
+            iiBuilder = InstanceIdentifier.builder(iiOriginal)
+        }
+
+        if (schemaOfData instanceof ListSchemaNode) {
+            iiBuilder.nodeWithKey(schemaOfData.QName, (schemaOfData as ListSchemaNode).resolveKeysFromData(data))
+        } else {
+            iiBuilder.node(schemaOfData.QName)
+        }
+        return new InstanceIdWithSchemaNode(iiBuilder.toInstance, schemaOfData, identifierWithSchemaNode?.mountPoint)
+    }
+
+    private def resolveKeysFromData(ListSchemaNode listNode, CompositeNode dataNode) {
+        val keyValues = new HashMap<QName, Object>();
+        for (key : listNode.keyDefinition) {
+            val dataNodeKeyValueObject = dataNode.getSimpleNodesByName(key.localName)?.head?.value
+            if (dataNodeKeyValueObject === null) {
+                throw new ResponseException(BAD_REQUEST,
+                    "Data contains list \"" + dataNode.nodeType.localName + "\" which does not contain key: \"" +
+                        key.localName + "\"")
+            }
+            keyValues.put(key, dataNodeKeyValueObject);
+        }
+        return keyValues
+    }
+
+    private def CompositeNode normalizeNode(CompositeNode node, DataSchemaNode schema, MountInstance mountPoint) {
+        if (schema === null) {
+            throw new ResponseException(INTERNAL_SERVER_ERROR, "Data schema node was not found for " + node?.nodeType?.localName)
+        }
+        if (!(schema instanceof DataNodeContainer)) {
+            throw new ResponseException(BAD_REQUEST, "Root element has to be container or list yang datatype.");
+        }
         if (node instanceof CompositeNodeWrapper) {
-            normalizeNode(node as CompositeNodeWrapper, schema, null)
+            if ((node  as CompositeNodeWrapper).changeAllowed) {
+                normalizeNode(node as CompositeNodeWrapper, schema, null, mountPoint)
+            }
             return (node as CompositeNodeWrapper).unwrap()
         }
         return node
     }
 
-    private def void normalizeNode(NodeWrapper<?> nodeBuilder, DataSchemaNode schema, QName previousAugment) {
+    private def void normalizeNode(NodeWrapper<?> nodeBuilder, DataSchemaNode schema, QName previousAugment,
+        MountInstance mountPoint) {
         if (schema === null) {
             throw new ResponseException(BAD_REQUEST,
-                "Data has bad format\n" + nodeBuilder.localName + " does not exist in yang schema.");
+                "Data has bad format.\n\"" + nodeBuilder.localName + "\" does not exist in yang schema.");
         }
         var validQName = schema.QName
         var currentAugment = previousAugment;
@@ -148,15 +318,20 @@ class RestconfImpl implements RestconfService {
         } else if (previousAugment !== null && schema.QName.namespace !== previousAugment.namespace) {
             validQName = QName.create(currentAugment, schema.QName.localName);
         }
-        val moduleName = controllerContext.findModuleByNamespace(validQName.namespace);
+        var String moduleName = null;
+        if (mountPoint === null) {
+            moduleName = controllerContext.findModuleNameByNamespace(validQName.namespace);
+        } else {
+            moduleName = mountPoint.findModuleByNamespace(validQName.namespace)?.name
+        }
         if (nodeBuilder.namespace === null || nodeBuilder.namespace == validQName.namespace ||
             nodeBuilder.namespace.toString == moduleName) {
             nodeBuilder.qname = validQName
         } else {
             throw new ResponseException(BAD_REQUEST,
-                "Data has bad format\nIf data is in XML format then namespace for " + nodeBuilder.localName +
-                    " should be " + schema.QName.namespace + ".\n If data is in Json format then module name for " +
-                    nodeBuilder.localName + " should be " + moduleName + ".");
+                "Data has bad format.\nIf data is in XML format then namespace for \"" + nodeBuilder.localName +
+                    "\" should be \"" + schema.QName.namespace + "\".\nIf data is in Json format then module name for \"" +
+                    nodeBuilder.localName + "\" should be \"" + moduleName + "\".");
         }
 
         if (nodeBuilder instanceof CompositeNodeWrapper) {
@@ -164,7 +339,7 @@ class RestconfImpl implements RestconfService {
             for (child : children) {
                 normalizeNode(child,
                     findFirstSchemaByLocalName(child.localName, (schema as DataNodeContainer).childNodes),
-                    currentAugment)
+                    currentAugment, mountPoint)
             }
             if(schema instanceof ListSchemaNode) {
                 val listKeys = (schema as ListSchemaNode).keyDefinition
@@ -177,7 +352,7 @@ class RestconfImpl implements RestconfService {
                     }
                     if (!foundKey) {
                         throw new ResponseException(BAD_REQUEST,
-                            "Missing key \"" + listKey.localName + "\" of list \"" + schema.QName.localName + "\"")
+                            "Missing key in URI \"" + listKey.localName + "\" of list \"" + schema.QName.localName + "\"")
                     }
                 }
             }
index 97f8102127c2b71f69aaf729aeeeed598043aed0..6aa8ada5ee3135fa0ac7025d9efe0564205f78d8 100644 (file)
@@ -58,6 +58,11 @@ public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, Simp
         this.namespace = namespace;
     }
 
+    @Override
+    public boolean isChangeAllowed() {
+        return simpleNode == null ? true : false;
+    }
+
     @Override
     public SimpleNode<Object> unwrap() {
         if (simpleNode == null) {
@@ -1,22 +1,44 @@
 package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
 import java.io.StringReader;
 import java.util.Map;
 import java.util.Set;
 
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
 import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.controller.sal.restconf.impl.test.structures.*;
-import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.Cont;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.Lf;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.LfLst;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.Lst;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.LstItem;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 
 import com.google.gson.stream.JsonReader;
 import com.google.gson.stream.JsonToken;
 
-public class ToJsonBasicYangTypesTest {
+public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/cnsn-to-json/simple-yang-types", 1, "simple-yang-types", "cont1");
+    }
 
     /**
      * Test of json output when as input are specified composite node with empty
@@ -24,9 +46,16 @@ public class ToJsonBasicYangTypesTest {
      */
     @Test
     public void compositeNodeAndYangWithJsonReaderEmptyDataTest() {
-        String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(prepareCompositeNodeWithEmpties(),
-                "/cnsn-to-json/simple-yang-types", "/cnsn-to-json/simple-yang-types/xml", "simple-yang-types", "cont1");
-        verifyJsonOutputForEmpty(jsonOutput);
+        CompositeNode compositeNode = prepareCompositeNodeWithEmpties();
+        TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+        String jsonOutput = null;
+        try {
+            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+                    StructuredDataToJsonProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+        }
+
+        verifyJsonOutputForEmptyData(jsonOutput);
     }
 
     /**
@@ -35,13 +64,21 @@ public class ToJsonBasicYangTypesTest {
      */
     @Test
     public void xmlAndYangTypesWithJsonReaderTest() {
-        String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
-                TestUtils.loadCompositeNode("/cnsn-to-json/simple-yang-types/xml/data.xml"),
-                "/cnsn-to-json/simple-yang-types", "/cnsn-to-json/simple-yang-types/xml", "simple-yang-types", "cont1");
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-yang-types/xml/data.xml",
+                XmlToCompositeNodeProvider.INSTANCE);
+        TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+        String jsonOutput = null;
+        try {
+            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+                    StructuredDataToJsonProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+        }
+
         verifyJsonOutput(jsonOutput);
     }
 
-    private void verifyJsonOutputForEmpty(String jsonOutput) {
+    private void verifyJsonOutputForEmptyData(String jsonOutput) {
+        assertNotNull(jsonOutput);
         StringReader strReader = new StringReader(jsonOutput);
         JsonReader jReader = new JsonReader(strReader);
 
@@ -60,6 +97,7 @@ public class ToJsonBasicYangTypesTest {
     }
 
     private void verifyJsonOutput(String jsonOutput) {
+        assertNotNull(jsonOutput);
         StringReader strReader = new StringReader(jsonOutput);
         JsonReader jReader = new JsonReader(strReader);
 
@@ -8,11 +8,13 @@ import javax.ws.rs.WebApplicationException;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
-public class ToJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
+public class CnSnJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
 
     @BeforeClass
     public static void initialization() {
@@ -111,10 +113,11 @@ public class ToJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
     }
 
     private void testWrapper(String xmlPath, String pathToSchemaNode) {
-        CompositeNode compNode = TestUtils.loadCompositeNode(xmlPath);
-        TestUtils.normalizeCompositeNode(compNode, modules, dataSchemaNode, pathToSchemaNode);
+        CompositeNode compNode = TestUtils.readInputToCnSn(xmlPath, XmlToCompositeNodeProvider.INSTANCE);
+        TestUtils.normalizeCompositeNode(compNode, modules, pathToSchemaNode);
         try {
-            TestUtils.writeCompNodeWithSchemaContextToJson(compNode, modules, dataSchemaNode);
+            TestUtils.writeCompNodeWithSchemaContextToOutput(compNode, modules, dataSchemaNode,
+                    StructuredDataToJsonProvider.INSTANCE);
         } catch (WebApplicationException | IOException e) {
             // shouldn't end here
             assertTrue(false);
 package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
 import java.io.StringReader;
-import java.math.BigDecimal;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 import javax.ws.rs.WebApplicationException;
-import javax.xml.bind.DatatypeConverter;
 
+import org.junit.BeforeClass;
 import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 import com.google.gson.stream.JsonReader;
 import com.google.gson.stream.JsonToken;
 
-public class ToJsonBasicDataTypesTest {
+public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/cnsn-to-json/simple-data-types");
+    }
 
     @Test
     public void simpleYangDataTest() {
-        String jsonOutput = "";
-        CompositeNode compositeNode = TestUtils.loadCompositeNode("/cnsn-to-json/simple-data-types/xml/data.xml");
 
-        Set<Module> modules = TestUtils.resolveModules("/cnsn-to-json/simple-data-types");
-        assertEquals(1, modules.size());
-        Module module = TestUtils.resolveModule(null, modules);
-        assertNotNull(module);
-        DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null);
-        assertNotNull(dataSchemaNode);
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml",
+                XmlToCompositeNodeProvider.INSTANCE);
 
-        TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, "simple-data-types:cont");
+        String jsonOutput = null;
+
+        TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont");
 
         try {
-            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToJson(compositeNode, modules, dataSchemaNode);
+            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+                    StructuredDataToJsonProvider.INSTANCE);
         } catch (WebApplicationException | IOException e) {
-            assertTrue(false); // shouldn't get here
         }
+        assertNotNull(jsonOutput);
 
-        System.out.println(jsonOutput);
         verifyJsonOutput(jsonOutput);
     }
 
-    private CompositeNode prepareData() {
-        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
-                ModifyAction.CREATE, null);
-
-        List<Node<?>> childNodes = new ArrayList<>();
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint8Min"), cont, (byte) -128,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint8Max"), cont, (byte) 127,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint16Min"), cont, (short) -32768,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint16Max"), cont, (short) 32767,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint32Min"), cont,
-                (int) -2147483648, ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint32Max"), cont, (int) 2147483647,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint64Min"), cont, new Long(
-                "-9223372036854775807"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint64Max"), cont, new Long(
-                "9223372036854775807"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint8Max"), cont, (short) 255,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint16Max"), cont, (int) 65535,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint32Max"), cont, new Long(
-                "4294967295"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfstr"), cont, "lfstr",
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfstr1"), cont, "",
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbool1"), cont, Boolean.TRUE,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbool2"), cont, Boolean.FALSE,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal1"), cont, new BigDecimal(
-                "43.32"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal2"), cont, new BigDecimal(
-                "-0.43"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal3"), cont, new BigDecimal(
-                "43"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal4"), cont, new BigDecimal(
-                "43E3"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal6"), cont, new BigDecimal(
-                "33.12345"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfenum"), cont, "enum3",
-                ModifyAction.CREATE, null));
-
-        HashSet<String> bits = new HashSet<String>();
-        bits.add("bit3");
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbits"), cont, bits,
-                ModifyAction.CREATE, null));
-
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbinary"), cont, DatatypeConverter
-                .parseBase64Binary("AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"),
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfempty"), cont, null,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion1"), cont, (int) 324,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion2"), cont, new BigDecimal(
-                "33.3"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion3"), cont, "55",
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion4"), cont, Boolean.TRUE,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion5"), cont, "true",
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion6"), cont, "false",
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion7"), cont, null,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion8"), cont, "",
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion9"), cont, "",
-                ModifyAction.CREATE, null));
-
-        HashSet<String> bits2 = new HashSet<String>();
-        bits2.add("bt1");
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion10"), cont, bits2,
-                ModifyAction.CREATE, null));
-
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion11"), cont, (short) 33,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion12"), cont, Boolean.FALSE,
-                ModifyAction.CREATE, null));
-        try {
-            childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("identityref1"), cont, new QName(
-                    new URI("simple:data:types"), "iden"), ModifyAction.CREATE, null));
-        } catch (URISyntaxException e) {
-        }
-
-        cont.getChildren().addAll(childNodes);
-
-        cont.init();
-
-        return cont;
-    }
-
     private void verifyJsonOutput(String jsonOutput) {
         StringReader strReader = new StringReader(jsonOutput);
         JsonReader jReader = new JsonReader(strReader);
@@ -178,7 +82,6 @@ public class ToJsonBasicDataTypesTest {
     private void jsonReadContElements(JsonReader jReader) throws IOException {
         jReader.beginObject();
         List<String> loadedLfs = new ArrayList<>();
-        boolean exceptForDecimal5Raised = false;
         boolean enumChecked = false;
         boolean bitsChecked = false;
         boolean lfdecimal6Checked = false;
@@ -190,7 +93,6 @@ public class ToJsonBasicDataTypesTest {
         boolean lfbool2Checked = false;
         boolean lfstrChecked = false;
         boolean lfbinaryChecked = false;
-        // boolean lfref1Checked = false;
         boolean lfemptyChecked = false;
         boolean lfstr1Checked = false;
         boolean lfidentityrefChecked = false;
@@ -201,11 +103,7 @@ public class ToJsonBasicDataTypesTest {
             try {
                 peek = jReader.peek();
             } catch (IOException e) {
-                if (keyName.equals("lfdecimal5")) {
-                    exceptForDecimal5Raised = true;
-                } else {
-                    assertTrue("Key " + keyName + " has incorrect value for specifed type", false);
-                }
+                assertTrue("Key " + keyName + " has incorrect value for specifed type", false);
             }
 
             if (keyName.startsWith("lfnint") || keyName.startsWith("lfnuint")) {
@@ -11,12 +11,14 @@ import javax.ws.rs.WebApplicationException;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.*;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 
-public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
+public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
 
     @BeforeClass
     public static void initialization() {
@@ -27,7 +29,9 @@ public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
     public void identityrefToJsonTest() {
         String json = null;
         try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(prepareCompositeNode(), modules, dataSchemaNode);
+            QName valueAsQname = TestUtils.buildQName("name_test", "identityref:module", "2013-12-2");
+            json = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(valueAsQname), modules,
+                    dataSchemaNode, StructuredDataToJsonProvider.INSTANCE);
         } catch (WebApplicationException | IOException e) {
             // shouldn't end here
             assertTrue(false);
@@ -40,15 +44,35 @@ public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
         assertTrue(mtch.matches());
     }
 
-    private CompositeNode prepareCompositeNode() {
+    @Test
+    public void identityrefToJsonWithoutQNameTest() {
+        String json = null;
+        try {
+            String value = "not q name value";
+            json = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(value), modules,
+                    dataSchemaNode, StructuredDataToJsonProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+            // shouldn't end here
+            assertTrue(false);
+        }
+        System.out.println(json);
+        assertNotNull(json);
+        Pattern ptrn = Pattern.compile(".*\"lf1\"\\p{Space}*:\\p{Space}*\"not q name value\".*", Pattern.DOTALL);
+        Matcher mtch = ptrn.matcher(json);
+
+        assertTrue(mtch.matches());
+    }
+
+    private CompositeNode prepareCompositeNode(Object value) {
         MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
                 ModifyAction.CREATE, null);
         MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont1"), cont, null,
                 ModifyAction.CREATE, null);
         cont.getChildren().add(cont1);
 
-        MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont1,
-                TestUtils.buildQName("name_test", "identityref:module", "2013-12-2"), ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont1, value,
+                ModifyAction.CREATE, null);
+
         cont1.getChildren().add(lf1);
         cont1.init();
         cont.init();
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java
new file mode 100644 (file)
index 0000000..4722257
--- /dev/null
@@ -0,0 +1,163 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+import javax.activation.UnsupportedDataTypeException;
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import org.opendaylight.yangtools.yang.model.api.YangNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CnSnToJsonIncorrectTopLevelTest extends YangAndXmlAndDataSchemaLoader {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CnSnToJsonIncorrectTopLevelTest.class);
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/cnsn-to-json/simple-data-types");
+    }
+
+    private class IncorrectDataSchema implements DataSchemaNode, DataNodeContainer {
+
+        @Override
+        public String getDescription() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public SchemaPath getPath() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public QName getQName() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public String getReference() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Status getStatus() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Set<DataSchemaNode> getChildNodes() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public DataSchemaNode getDataChildByName(QName arg0) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public DataSchemaNode getDataChildByName(String arg0) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Set<GroupingDefinition> getGroupings() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Set<TypeDefinition<?>> getTypeDefinitions() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Set<UsesNode> getUses() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public ConstraintDefinition getConstraints() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        public boolean isAddedByUses() {
+            // TODO Auto-generated method stub
+            return false;
+        }
+
+        @Override
+        public boolean isAugmenting() {
+            // TODO Auto-generated method stub
+            return false;
+        }
+
+        @Override
+        public boolean isConfiguration() {
+            // TODO Auto-generated method stub
+            return false;
+        }
+
+    }
+
+    @Test
+    public void incorrectTopLevelElementTest() {
+
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml", XmlToCompositeNodeProvider.INSTANCE);
+        DataSchemaNode incorrectDataSchema = null;
+        incorrectDataSchema = new IncorrectDataSchema();
+
+        TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont");
+
+        boolean exceptionRaised = false;
+        try {
+            TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, incorrectDataSchema,
+                    StructuredDataToJsonProvider.INSTANCE);
+        } catch (UnsupportedDataTypeException e) {
+            exceptionRaised = true;
+        } catch (WebApplicationException | IOException e) {
+            LOG.error("WebApplicationException or IOException was raised");
+        }
+
+        assertTrue(exceptionRaised);
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java
new file mode 100644 (file)
index 0000000..3215e81
--- /dev/null
@@ -0,0 +1,103 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+/**
+ * 
+ * All tests are commented now because leafref isn't supported now
+ * 
+ */
+
+public class CnSnToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialization() {
+        dataLoad("/cnsn-to-json/leafref", 2, "main-module", "cont");
+    }
+
+    @Test
+    public void leafrefAbsolutePathToExistingLeafTest() {
+        String json = toJson("/cnsn-to-json/leafref/xml/data_absolut_ref_to_existing_leaf.xml");
+        validateJson(".*\"lf3\":\\p{Blank}*\"true\".*", json);
+    }
+
+    @Test
+    public void leafrefRelativePathToExistingLeafTest() {
+        String json = toJson("/cnsn-to-json/leafref/xml/data_relativ_ref_to_existing_leaf.xml");
+        validateJson(".*\"lf2\":\\p{Blank}*\"121\".*", json);
+    }
+
+    /**
+     * Tests case when reference to not existing element is present. In this
+     * case value from single node is printed as string.
+     */
+    @Test
+    public void leafrefToNonExistingLeafTest() {
+        String json = toJson("/cnsn-to-json/leafref/xml/data_ref_to_non_existing_leaf.xml");
+        validateJson(".*\"lf5\":\\p{Blank}*\"137\".*", json);
+    }
+
+    /**
+     * Tests case when non leaf element is referenced. In this case value from
+     * single node is printed as string.
+     */
+    @Test
+    public void leafrefToNotLeafTest() {
+        String json = toJson("/cnsn-to-json/leafref/xml/data_ref_to_not_leaf.xml");
+        validateJson(".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf6\":\\p{Blank}*\"44.33\".*", json);
+    }
+
+    /**
+     * Tests case when leaflist element is refers to leaf.
+     */
+    @Test
+    public void leafrefFromLeafListToLeafTest() {
+        String json = toJson("/cnsn-to-json/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml");
+        validateJson(
+                ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lflst1\":\\p{Blank}*.*\"345\",\\p{Space}*\"346\",\\p{Space}*\"347\".*",
+                json);
+    }
+
+    /**
+     * Tests case when leaflist element is refers to leaf.
+     */
+    @Test
+    public void leafrefFromLeafrefToLeafrefTest() {
+        String json = toJson("/cnsn-to-json/leafref/xml/data_from_leafref_to_leafref.xml");
+        validateJson(".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf7\":\\p{Blank}*\"200\".*", json);
+    }
+
+    private void validateJson(String regex, String value) {
+        assertNotNull(value);
+        Pattern ptrn = Pattern.compile(regex, Pattern.DOTALL);
+        Matcher mtch = ptrn.matcher(value);
+        assertTrue(mtch.matches());
+    }
+
+    private String toJson(String xmlDataPath) {
+        try {
+            CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlDataPath, XmlToCompositeNodeProvider.INSTANCE);
+            TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+            return TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+                    StructuredDataToJsonProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+        }
+        return "";
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java
new file mode 100644 (file)
index 0000000..7fdd6ca
--- /dev/null
@@ -0,0 +1,75 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.*;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CnSnToJsonNotExistingLeafTypeTest extends YangAndXmlAndDataSchemaLoader {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CnSnToJsonNotExistingLeafTypeTest.class);
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/cnsn-to-json/simple-data-types");
+    }
+
+    // FIXME
+    @Ignore
+    @Test
+    public void incorrectTopLevelElementTest() {
+
+        String jsonOutput = null;
+        try {
+            jsonOutput = TestUtils
+                    .writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(),
+                            (Set<Module>) Collections.EMPTY_SET, prepareDataSchemaNode(),
+                            StructuredDataToJsonProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+            LOG.error("WebApplicationException or IOException was raised");
+        }
+        assertNotNull(jsonOutput);
+        assertTrue(jsonOutput.contains("\"lf1\": \"\""));
+    }
+
+    private CompositeNode prepareCompositeNode() {
+        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(
+                TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null);
+        cont.getChildren().add(lf1);
+        cont.init();
+        return cont;
+    }
+
+    private DataSchemaNode prepareDataSchemaNode() {
+        ContainerSchemaNodeBuilder contBuild = new ContainerSchemaNodeBuilder("module", 1, TestUtils.buildQName("cont",
+                "simple:uri", "2012-12-17"), null);
+        LeafSchemaNodeBuilder leafBuild = new LeafSchemaNodeBuilder("module", 2, TestUtils.buildQName("lf1",
+                "simple:uri", "2012-12-17"), null);
+        leafBuild.setType(new DummyType());
+        leafBuild.setConfiguration(true);
+
+        contBuild.addChildNode(leafBuild);
+        return contBuild.build();
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java
new file mode 100644 (file)
index 0000000..3c2325c
--- /dev/null
@@ -0,0 +1,51 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public class CnSnToJsonWithAugmentTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/cnsn-to-json/augmentation", 5, "yang", "cont");
+    }
+
+    /**
+     * Test of json output when as input are specified composite node with empty
+     * data + YANG file
+     */
+    @Test
+    public void augmentedElementsToJson() {
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/augmentation/xml/data.xml",
+                XmlToCompositeNodeProvider.INSTANCE);
+        TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+
+        String jsonOutput = null;
+        try {
+            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+                    StructuredDataToJsonProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+        }
+        assertNotNull(jsonOutput);
+
+        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\": ["));
+    }
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java
new file mode 100644 (file)
index 0000000..fdc10b7
--- /dev/null
@@ -0,0 +1,108 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class CnSnToJsonWithDataFromSeveralModulesTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/xml-to-cnsn/data-of-several-modules/yang",2,"module1","cont_m1");
+    }
+
+    @Test
+    public void dataFromSeveralModulesToJsonTest() throws WebApplicationException, IOException, URISyntaxException {
+        SchemaContext schemaContext = TestUtils.loadSchemaContext(modules);
+        String output = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCnSn(), modules, schemaContext,
+                StructuredDataToJsonProvider.INSTANCE);
+
+//         String output =
+//         String.format("\"data\"   :   {\n" +
+//                             "\t\"cont_m1\"   :  {\n" +
+//                                 "\t\t\"lf1_m1\"   :  \"lf1 m1 value\"\n" +
+//                             "\t}\n" +
+//                             "\t\"cont_m2\"   :  {\n" +
+//                                 "\t\t\"lf1_m2\"   :  \"lf1 m2 value\"\n" +
+//                             "\t}\n" +
+//                     "}");
+
+        StringBuilder regex = new StringBuilder();
+        regex.append("^");
+
+        regex.append(".*\"data\"");
+        regex.append(".*:");
+        regex.append(".*\\{");
+        
+        regex.append(".*\"contB_m1\"");
+        regex.append(".*:");
+        regex.append(".*\\{");
+        regex.append(".*\\}");
+        
+        regex.append(".*\"cont_m1\"");
+        regex.append(".*:");
+        regex.append(".*\\{");
+        regex.append(".*\\}");
+
+        regex.append(".*\"contB_m2\"");
+        regex.append(".*:");
+        regex.append(".*\\{");
+        regex.append(".*\\}");
+        
+        regex.append(".*\"cont_m2\"");
+        regex.append(".*:");
+        regex.append(".*\\{");
+        regex.append(".*\\}");
+        
+        regex.append(".*\\}");
+
+        regex.append(".*");
+        regex.append("$");
+
+        Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
+        Matcher matcher = ptrn.matcher(output);
+
+        assertTrue(matcher.find());
+
+    }
+
+    private CompositeNode prepareCnSn() throws URISyntaxException {
+        CompositeNodeWrapper data = new CompositeNodeWrapper(new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), "data");
+
+        URI uriModule1 = new URI("module:one");
+        CompositeNodeWrapper cont_m1 = new CompositeNodeWrapper(uriModule1, "cont_m1");
+        SimpleNodeWrapper lf1_m1 = new SimpleNodeWrapper(uriModule1, "lf1_m1", "lf1 m1 value");
+        cont_m1.addValue(lf1_m1);
+        CompositeNodeWrapper contB_m1 = new CompositeNodeWrapper(uriModule1, "contB_m1");
+        
+        data.addValue(contB_m1);
+        data.addValue(cont_m1);
+
+        URI uriModule2 = new URI("module:two");
+        CompositeNodeWrapper cont_m2 = new CompositeNodeWrapper(uriModule2, "cont_m2");
+        SimpleNodeWrapper lf1_m2 = new SimpleNodeWrapper(uriModule2, "lf1_m2", "lf1 m2 value");
+        cont_m2.addValue(lf1_m2);
+        CompositeNodeWrapper contB_m2 = new CompositeNodeWrapper(uriModule2, "contB_m2");
+        data.addValue(contB_m2);
+        data.addValue(cont_m2);
+        return data;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java
deleted file mode 100644 (file)
index 1ac81a3..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.regex.Matcher;
-
-import javax.ws.rs.WebApplicationException;
-
-import org.junit.*;
-import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
-
-/**
- * 
- * All tests are commented now because leafref isn't supported now
- * 
- */
-
-public class ToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
-
-    @BeforeClass
-    public static void initialization() {
-        dataLoad("/cnsn-to-json/leafref", 2, "main-module", "cont");
-    }
-
-    @Ignore
-    @Test
-    public void leafrefAbsolutePathToExistingLeafTest() {
-        String json = null;
-        try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_absolut_ref_to_existing_leaf.xml"),
-                    modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-        assertNotNull(json);
-        java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf3\":\\p{Blank}*true.*",
-                java.util.regex.Pattern.DOTALL);
-        Matcher mtch = ptrn.matcher(json);
-        assertTrue(mtch.matches());
-    }
-
-    @Ignore
-    @Test
-    public void leafrefRelativePathToExistingLeafTest() {
-        String json = null;
-        try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_relativ_ref_to_existing_leaf.xml"),
-                    modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-        assertNotNull(json);
-        java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf2\":\\p{Blank}*121.*",
-                java.util.regex.Pattern.DOTALL);
-        Matcher mtch = ptrn.matcher(json);
-        assertTrue(mtch.matches());
-    }
-
-    /**
-     * Tests case when reference to not existing element is present. In this
-     * case value from single node is printed as string.
-     */
-    @Ignore
-    @Test
-    public void leafrefToNonExistingLeafTest() {
-        String json = null;
-        try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_ref_to_non_existing_leaf.xml"),
-                    modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-        assertNotNull(json);
-        java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf5\":\\p{Blank}*\"137\".*",
-                java.util.regex.Pattern.DOTALL);
-        Matcher mtch = ptrn.matcher(json);
-        assertTrue(mtch.matches());
-    }
-
-    /**
-     * Tests case when non leaf element is referenced. In this case value from
-     * single node is printed as string.
-     */
-    @Ignore
-    @Test
-    public void leafrefToNotLeafTest() {
-        String json = null;
-        try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_ref_to_not_leaf.xml"), modules,
-                    dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-        assertNotNull(json);
-        java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(
-                ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf6\":\\p{Blank}*\"44.33\".*",
-                java.util.regex.Pattern.DOTALL);
-        Matcher mtch = ptrn.matcher(json);
-        assertTrue(mtch.matches());
-    }
-
-    /**
-     * Tests case when leaflist element is refers to leaf.
-     */
-    @Ignore
-    @Test
-    public void leafrefFromLeafListToLeafTest() {
-        String json = null;
-        try {
-            json = TestUtils
-                    .writeCompNodeWithSchemaContextToJson(
-                            TestUtils
-                                    .loadCompositeNode("/cnsn-to-json/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml"),
-                            modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-        assertNotNull(json);
-        java.util.regex.Pattern ptrn = java.util.regex.Pattern
-                .compile(
-                        ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lflst1\":\\p{Blank}*.*345,\\p{Space}*346,\\p{Space}*347.*",
-                        java.util.regex.Pattern.DOTALL);
-        Matcher mtch = ptrn.matcher(json);
-        assertTrue(mtch.matches());
-    }
-
-    /**
-     * Tests case when leaflist element is refers to leaf.
-     */
-    @Ignore
-    @Test
-    public void leafrefFromLeafrefToLeafrefTest() {
-        String json = null;
-        try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_from_leafref_to_leafref.xml"), modules,
-                    dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-        assertNotNull(json);
-        java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(
-                ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf7\":\\p{Blank}*200.*", java.util.regex.Pattern.DOTALL);
-        Matcher mtch = ptrn.matcher(json);
-        assertTrue(mtch.matches());
-    }
-
-}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java
deleted file mode 100644 (file)
index 73bd178..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
-
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-
-public class ToJsonWithAugmentTest {
-
-    /**
-     * Test of json output when as input are specified composite node with empty
-     * data + YANG file
-     */
-    @Test
-    public void augmentedElementsToJson() {
-
-        CompositeNode compositeNode = TestUtils.loadCompositeNode("/cnsn-to-json/augmentation/xml/data.xml");
-        String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(compositeNode,
-                "/cnsn-to-json/augmentation", "/cnsn-to-json/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\": ["));
-    }
-}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java
new file mode 100644 (file)
index 0000000..555f2b3
--- /dev/null
@@ -0,0 +1,69 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.DummyType;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CnSnToXmlNotExistingLeafTypeTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CnSnToXmlNotExistingLeafTypeTest.class);
+
+    @Ignore
+    @Test
+    public void incorrectTopLevelElementTest() {
+
+        boolean nullPointerExceptionRaised = false;
+        try {
+            TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(),
+                    (Set<Module>) Collections.EMPTY_SET, prepareDataSchemaNode(), StructuredDataToXmlProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+            LOG.error("WebApplicationException or IOException was raised");
+        } catch (NullPointerException e) {
+            nullPointerExceptionRaised = true;
+        }
+        assertTrue(nullPointerExceptionRaised);
+
+    }
+
+    private CompositeNode prepareCompositeNode() {
+        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(
+                TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null);
+        cont.getChildren().add(lf1);
+        cont.init();
+        return cont;
+    }
+
+    private DataSchemaNode prepareDataSchemaNode() {
+        ContainerSchemaNodeBuilder contBuild = new ContainerSchemaNodeBuilder("module", 1, TestUtils.buildQName("cont",
+                "simple:uri", "2012-12-17"), null);
+        LeafSchemaNodeBuilder leafBuild = new LeafSchemaNodeBuilder("module", 2, TestUtils.buildQName("lf1",
+                "simple:uri", "2012-12-17"), null);
+        leafBuild.setType(new DummyType());
+        leafBuild.setConfiguration(true);
+
+        contBuild.addChildNode(leafBuild);
+        return contBuild.build();
+    }
+
+}
index d04337865a9e549c71838dc749d073218a9130c9..96e03a5a3ca4b8b6b0d619232457a8669f3dae06 100644 (file)
@@ -1,24 +1,21 @@
 package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
-import java.io.StringWriter;
-import java.util.Set;
+import java.io.IOException;
 
-import javax.activation.UnsupportedDataTypeException;
-import javax.xml.transform.*;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
+import javax.ws.rs.WebApplicationException;
+import javax.xml.transform.TransformerFactoryConfigurationError;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.opendaylight.controller.sal.rest.impl.XmlMapper;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
 import org.opendaylight.yangtools.yang.data.api.*;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
-import org.opendaylight.yangtools.yang.model.api.*;
-import org.w3c.dom.Document;
 
 /**
  * 
@@ -27,25 +24,31 @@ import org.w3c.dom.Document;
  * XML file
  * 
  */
-public class CnSnToXmlTest {
-
-    private static Set<Module> modules;
-    private static DataSchemaNode dataSchemaNode;
-
+public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader {
     @BeforeClass
     public static void initialization() {
-        modules = TestUtils.resolveModules("/cnsn-to-xml/yang");
-        assertEquals(2, modules.size());
-        Module module = TestUtils.resolveModule("basic-module", modules);
-        assertNotNull(module);
-        dataSchemaNode = TestUtils.resolveDataSchemaNode(module, "cont");
-        assertNotNull(dataSchemaNode);
-
+        dataLoad("/cnsn-to-xml/yang", 2, "basic-module", "cont");
     }
 
     @Test
     public void snAsYangIdentityrefToXMLTest() {
-        serializeToXml(prepareIdentityrefData(), "<lf11 xmlns:x=\"referenced:module\">x:iden</lf11>");
+        serializeToXml(prepareIdentityrefData(null, true), "<lf11 xmlns:x=\"referenced:module\">x:iden</lf11>");
+    }
+
+    @Test
+    public void snAsYangIdentityrefWithQNamePrefixToXMLTest() {
+        serializeToXml(prepareIdentityrefData("prefix", true),
+                "<lf11 xmlns:prefix=\"referenced:module\">prefix:iden</lf11>");
+    }
+
+    @Test
+    public void snAsYangIdentityrefWithPrefixToXMLTest() {
+        serializeToXml(prepareIdentityrefData("prefix", false), "<lf11>no qname value</lf11>");
+    }
+
+    @Test
+    public void snAsYangLeafrefWithPrefixToXMLTest() {
+        serializeToXml(prepareLeafrefData(), "<lfBoolean>true</lfBoolean>", "<lfLfref>true</lfLfref>");
     }
 
     @Test
@@ -186,22 +189,13 @@ public class CnSnToXmlTest {
 
     private void serializeToXml(CompositeNode compositeNode, String... xmlRepresentation)
             throws TransformerFactoryConfigurationError {
-        XmlMapper xmlMapper = new XmlMapper();
-        String xmlString = null;
-        if (dataSchemaNode instanceof DataNodeContainer) {
-            try {
-                Document doc = xmlMapper.write(compositeNode, (DataNodeContainer) dataSchemaNode);
-                DOMSource domSource = new DOMSource(doc);
-                StringWriter writer = new StringWriter();
-                StreamResult result = new StreamResult(writer);
-                TransformerFactory tf = TransformerFactory.newInstance();
-                Transformer transformer = tf.newTransformer();
-                transformer.transform(domSource, result);
-                xmlString = writer.toString();
-            } catch (UnsupportedDataTypeException | TransformerException e) {
-            }
+        String xmlString = "";
+        try {
+            xmlString = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+                    StructuredDataToXmlProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
         }
-        assertNotNull(xmlMapper);
+        assertNotNull(xmlString);
         boolean containSearchedStr = false;
         String strRepresentation = "";
         for (String searchedStr : xmlRepresentation) {
@@ -215,16 +209,21 @@ public class CnSnToXmlTest {
 
     }
 
-    private CompositeNode prepareIdentityrefData() {
+    private CompositeNode prepareIdentityrefData(String prefix, boolean valueAsQName) {
         MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
                 TestUtils.buildQName("cont", "basic:module", "2013-12-2"), null, null, ModifyAction.CREATE, null);
         MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(
                 TestUtils.buildQName("cont1", "basic:module", "2013-12-2"), cont, null, ModifyAction.CREATE, null);
         cont.getChildren().add(cont1);
 
+        Object value = null;
+        if (valueAsQName) {
+            value = TestUtils.buildQName("iden", "referenced:module", "2013-12-2", prefix);
+        } else {
+            value = "no qname value";
+        }
         MutableSimpleNode<Object> lf11 = NodeFactory.createMutableSimpleNode(
-                TestUtils.buildQName("lf11", "basic:module", "2013-12-2"), cont1,
-                TestUtils.buildQName("iden", "referenced:module", "2013-12-2"), ModifyAction.CREATE, null);
+                TestUtils.buildQName("lf11", "basic:module", "2013-12-2"), cont1, value, ModifyAction.CREATE, null);
         cont1.getChildren().add(lf11);
         cont1.init();
         cont.init();
@@ -244,4 +243,19 @@ public class CnSnToXmlTest {
         return cont;
     }
 
+    private CompositeNode prepareLeafrefData() {
+        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
+                ModifyAction.CREATE, null);
+
+        MutableSimpleNode<Object> lfBoolean = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfBoolean"),
+                cont, Boolean.TRUE, ModifyAction.CREATE, null);
+        MutableSimpleNode<Object> lfLfref = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfLfref"), cont,
+                "true", ModifyAction.CREATE, null);
+        cont.getChildren().add(lfBoolean);
+        cont.getChildren().add(lfLfref);
+        cont.init();
+
+        return cont;
+    }
+
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java
new file mode 100644 (file)
index 0000000..a23501c
--- /dev/null
@@ -0,0 +1,64 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+
+/**
+ * 
+ * CnSn = Composite node and Simple node data structure Class contains test of
+ * serializing simple nodes data values according data types from YANG schema to
+ * XML file
+ * 
+ */
+public class CnSnToXmlWithChoiceTest extends YangAndXmlAndDataSchemaLoader {
+    @BeforeClass
+    public static void initialization() {
+        dataLoad("/cnsn-to-xml/choice", 1, "module-with-choice", "cont");
+    }
+
+    @Test
+    public void cnSnToXmlWithYangChoice() {
+        String xmlOutput = "";
+        try {
+            xmlOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(
+                    prepareCnStructForYangData("lf1", "String data1"), modules, dataSchemaNode,
+                    StructuredDataToXmlProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+        }
+
+        assertTrue(xmlOutput.contains("<lf1>String data1</lf1>"));
+
+        try {
+            xmlOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(
+                    prepareCnStructForYangData("lf2", "String data2"), modules, dataSchemaNode,
+                    StructuredDataToXmlProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+        }
+        assertTrue(xmlOutput.contains("<lf2>String data2</lf2>"));
+
+    }
+
+    private CompositeNode prepareCnStructForYangData(String lfName, Object data) {
+        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
+                ModifyAction.CREATE, null);
+
+        MutableSimpleNode<Object> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName(lfName), cont, data,
+                ModifyAction.CREATE, null);
+        cont.getChildren().add(lf1);
+        cont.init();
+
+        return cont;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithDataFromSeveralModulesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithDataFromSeveralModulesTest.java
new file mode 100644 (file)
index 0000000..57a1495
--- /dev/null
@@ -0,0 +1,107 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class CnSnToXmlWithDataFromSeveralModulesTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/xml-to-cnsn/data-of-several-modules/yang",2,"module1","cont_m1");
+    }
+
+    @Test
+    public void dataFromSeveralModulesToXmlTest() throws WebApplicationException, IOException, URISyntaxException {
+        SchemaContext schemaContext = TestUtils.loadSchemaContext(modules);
+        String output = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCnSn(), modules, schemaContext,
+                StructuredDataToXmlProvider.INSTANCE);
+
+//         String output =
+//         String.format("<data>" +
+//                      "\n<cont_m1>" +
+//                             "\n\t<lf1_m1>" +
+//                                 "\n\t\tlf1 m1 value" +
+//                                     "\n\t</lf1_m1>" +
+//                         "\n</cont_m1>" +
+//                         "\n<cont_m2>" +
+//                             "\n\t<lf1_m2>" +
+//                                 "\n\t\tlf1 m2 value" +
+//                             "\n\t</lf1_m2>" +
+//                         "\n</cont_m2>" +
+//                     "\n</data>");
+
+        StringBuilder regex = new StringBuilder();
+        regex.append("^");
+
+        regex.append(".*<data.*");
+        regex.append(".*xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"");
+        regex.append(".*>");
+        
+        
+        regex.append(".*<contB_m1.*\\/>");
+        regex.append(".*xmlns=\"module:one\"");
+        regex.append(".*>");
+        regex.append(".*<lf1_m1.*>");
+        regex.append(".*<\\/lf1_m1>");
+        regex.append(".*<\\/cont_m1>");
+
+        regex.append(".*<contB_m2.*/>");
+        regex.append(".*<cont_m2.*");
+        regex.append(".*xmlns=\"module:two\"");
+        regex.append(".*>");
+        regex.append(".*<lf1_m2.*>");
+        regex.append(".*<\\/lf1_m2>");
+        regex.append(".*<\\/cont_m2>");
+
+        regex.append(".*<\\/data.*>");
+
+        regex.append(".*");
+        regex.append("$");
+
+        Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
+        Matcher matcher = ptrn.matcher(output);
+
+        assertTrue(matcher.find());
+
+    }
+
+    private CompositeNode prepareCnSn() throws URISyntaxException {
+        CompositeNodeWrapper data = new CompositeNodeWrapper(new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), "data");
+
+        URI uriModule1 = new URI("module:one");
+        CompositeNodeWrapper cont_m1 = new CompositeNodeWrapper(uriModule1, "cont_m1");
+        SimpleNodeWrapper lf1_m1 = new SimpleNodeWrapper(uriModule1, "lf1_m1", "lf1 m1 value");
+        cont_m1.addValue(lf1_m1);
+        CompositeNodeWrapper contB_m1 = new CompositeNodeWrapper(uriModule1, "contB_m1");
+        
+        data.addValue(contB_m1);
+        data.addValue(cont_m1);
+
+        URI uriModule2 = new URI("module:two");
+        CompositeNodeWrapper cont_m2 = new CompositeNodeWrapper(uriModule2, "cont_m2");
+        SimpleNodeWrapper lf1_m2 = new SimpleNodeWrapper(uriModule2, "lf1_m2", "lf1 m2 value");
+        cont_m2.addValue(lf1_m2);
+        CompositeNodeWrapper contB_m2 = new CompositeNodeWrapper(uriModule2, "contB_m2");
+        data.addValue(contB_m2);
+        data.addValue(cont_m2);
+        return data;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java
new file mode 100644 (file)
index 0000000..e9b1dbe
--- /dev/null
@@ -0,0 +1,74 @@
+package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.*;
+
+public class JsonIdentityrefToCnSnTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/json-to-cnsn/identityref", 2, "identityref-module", "cont");
+    }
+
+    @Test
+    public void jsonIdentityrefToCompositeNode() {
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false,
+                JsonToCompositeNodeProvider.INSTANCE);
+        assertNotNull(compositeNode);
+
+        TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+
+        assertEquals("cont", compositeNode.getNodeType().getLocalName());
+
+        List<Node<?>> childs = compositeNode.getChildren();
+        assertEquals(1, childs.size());
+        Node<?> nd = childs.iterator().next();
+        assertTrue(nd instanceof CompositeNode);
+        assertEquals("cont1", nd.getNodeType().getLocalName());
+
+        childs = ((CompositeNode) nd).getChildren();
+        assertEquals(4, childs.size());
+        SimpleNode<?> lf11 = null;
+        SimpleNode<?> lf12 = null;
+        SimpleNode<?> lf13 = null;
+        SimpleNode<?> lf14 = null;
+        for (Node<?> child : childs) {
+            assertTrue(child instanceof SimpleNode);
+            if (child.getNodeType().getLocalName().equals("lf11")) {
+                lf11 = (SimpleNode<?>) child;
+            } else if (child.getNodeType().getLocalName().equals("lf12")) {
+                lf12 = (SimpleNode<?>) child;
+            } else if (child.getNodeType().getLocalName().equals("lf13")) {
+                lf13 = (SimpleNode<?>) child;
+            } else if (child.getNodeType().getLocalName().equals("lf14")) {
+                lf14 = (SimpleNode<?>) child;
+            }
+        }
+
+        assertTrue(lf11.getValue() instanceof QName);
+        assertEquals("iden", ((QName) lf11.getValue()).getLocalName());
+        assertEquals("identity:module", ((QName) lf11.getValue()).getNamespace().toString());
+
+        assertTrue(lf12.getValue() instanceof QName);
+        assertEquals("iden_local", ((QName) lf12.getValue()).getLocalName());
+        assertEquals("identityref:module", ((QName) lf12.getValue()).getNamespace().toString());
+
+        assertTrue(lf13.getValue() instanceof QName);
+        assertEquals("iden_local", ((QName) lf13.getValue()).getLocalName());
+        assertEquals("identityref:module", ((QName) lf13.getValue()).getNamespace().toString());
+
+        assertTrue(lf14.getValue() instanceof QName);
+        assertEquals("iden_local", ((QName) lf14.getValue()).getLocalName());
+        assertEquals("identity:module", ((QName) lf14.getValue()).getNamespace().toString());
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java
new file mode 100644 (file)
index 0000000..2bb42d9
--- /dev/null
@@ -0,0 +1,48 @@
+package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test;
+
+import static org.junit.Assert.*;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.*;
+
+public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/json-to-cnsn/leafref");
+    }
+
+    /**
+     * JSON values which represents leafref are always loaded to simple node as
+     * string
+     */
+    @Test
+    public void jsonIdentityrefToCompositeNode() {
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/leafref/json/data.json", false,
+                JsonToCompositeNodeProvider.INSTANCE);
+        assertNotNull(compositeNode);
+        TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+
+        assertEquals("cont", compositeNode.getNodeType().getLocalName());
+
+        SimpleNode<?> lf2 = null;
+        for (Node<?> childNode : compositeNode.getChildren()) {
+            if (childNode instanceof SimpleNode) {
+                if (childNode.getNodeType().getLocalName().equals("lf2")) {
+                    lf2 = (SimpleNode<?>) childNode;
+                    break;
+                }
+            }
+        }
+
+        assertNotNull(lf2);
+        assertTrue(lf2.getValue() instanceof String);
+        assertEquals("121", (String) lf2.getValue());
+
+    }
+
+}
index b02ea9a3a28fe439efc1d04341449bf28bd5e28f..afe458d6e0917e25903d4f655cf7b3a49640f8b5 100644 (file)
@@ -1,9 +1,10 @@
 package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
-import java.io.*;
-import java.net.URISyntaxException;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -14,8 +15,9 @@ import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+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.Module;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -28,7 +30,7 @@ public class JsonToCnSnTest {
 
     @Test
     public void simpleListTest() {
-        simpleTest("/json-to-cnsn/simple-list.json", "/json-to-cnsn/simple-list-yang", "lst", "simple:list:yang1",
+        simpleTest("/json-to-cnsn/simple-list.json", "/json-to-cnsn/simple-list-yang/1", "lst", "simple:list:yang1",
                 "simple-list-yang1");
     }
 
@@ -43,7 +45,8 @@ public class JsonToCnSnTest {
      */
     @Test
     public void multipleItemsInLeafList() {
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-leaflist-items.json", true);
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-leaflist-items.json", true,
+                JsonToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
         assertEquals(3, compositeNode.getChildren().size());
 
@@ -76,9 +79,10 @@ public class JsonToCnSnTest {
      */
     @Test
     public void multipleItemsInListTest() {
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-items-in-list.json", true);
-        assertNotNull(compositeNode);
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-items-in-list.json", true,
+                JsonToCompositeNodeProvider.INSTANCE);
 
+        assertNotNull(compositeNode);
         assertEquals("lst", compositeNode.getNodeType().getLocalName());
 
         verityMultipleItemsInList(compositeNode);
@@ -86,7 +90,8 @@ public class JsonToCnSnTest {
 
     @Test
     public void nullArrayToSimpleNodeWithNullValueTest() {
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/array-with-null.json", true);
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/array-with-null.json", true,
+                JsonToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
 
@@ -103,7 +108,8 @@ public class JsonToCnSnTest {
     public void incorrectTopLevelElementsTest() {
         Throwable cause1 = null;
         try {
-            compositeContainerFromJson("/json-to-cnsn/wrong-top-level1.json", true);
+            TestUtils
+                    .readInputToCnSn("/json-to-cnsn/wrong-top-level1.json", true, JsonToCompositeNodeProvider.INSTANCE);
         } catch (WebApplicationException e) {
             cause1 = e;
         }
@@ -117,7 +123,8 @@ public class JsonToCnSnTest {
 
         Throwable cause2 = null;
         try {
-            compositeContainerFromJson("/json-to-cnsn/wrong-top-level2.json", true);
+            TestUtils
+                    .readInputToCnSn("/json-to-cnsn/wrong-top-level2.json", true, JsonToCompositeNodeProvider.INSTANCE);
         } catch (WebApplicationException e) {
             cause2 = e;
         }
@@ -126,7 +133,8 @@ public class JsonToCnSnTest {
 
         Throwable cause3 = null;
         try {
-            compositeContainerFromJson("/json-to-cnsn/wrong-top-level3.json", true);
+            TestUtils
+                    .readInputToCnSn("/json-to-cnsn/wrong-top-level3.json", true, JsonToCompositeNodeProvider.INSTANCE);
         } catch (WebApplicationException e) {
             cause3 = e;
         }
@@ -145,7 +153,8 @@ public class JsonToCnSnTest {
      */
     @Test
     public void emptyDataReadTest() {
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/empty-data.json", true);
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/empty-data.json", true,
+                JsonToCompositeNodeProvider.INSTANCE);
 
         assertNotNull(compositeNode);
 
@@ -158,7 +167,7 @@ public class JsonToCnSnTest {
 
         String reason = null;
         try {
-            compositeContainerFromJson("/json-to-cnsn/empty-data1.json", true);
+            TestUtils.readInputToCnSn("/json-to-cnsn/empty-data1.json", true, JsonToCompositeNodeProvider.INSTANCE);
         } catch (JsonSyntaxException e) {
             reason = e.getMessage();
         }
@@ -176,24 +185,20 @@ public class JsonToCnSnTest {
     @Test
     public void notSupplyNamespaceIfAlreadySupplied() {
 
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/simple-list.json");
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/simple-list.json", false,
+                JsonToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
 
-        DataSchemaNode dataSchemaNode1 = null;
-        DataSchemaNode dataSchemaNode2 = null;
-        try {
-            dataSchemaNode1 = TestUtils.obtainSchemaFromYang("/json-to-cnsn/simple-list-yang", "simple-list-yang1");
-            dataSchemaNode2 = TestUtils.obtainSchemaFromYang("/json-to-cnsn/simple-list-yang", "simple-list-yang2");
-        } catch (FileNotFoundException e) {
-            LOG.error(e.getMessage());
-            assertTrue(false);
-        }
-        assertNotNull(dataSchemaNode1);
-        assertNotNull(dataSchemaNode2);
-
         // supplement namespaces according to first data schema -
         // "simple:data:types1"
-        TestUtils.supplementNamespace(dataSchemaNode1, compositeNode);
+        Set<Module> modules1 = new HashSet<>();
+        Set<Module> modules2 = new HashSet<>();
+        modules1 = TestUtils.loadModulesFrom("/json-to-cnsn/simple-list-yang/1");
+        modules2 = TestUtils.loadModulesFrom("/json-to-cnsn/simple-list-yang/2");
+        assertNotNull(modules1);
+        assertNotNull(modules2);
+
+        TestUtils.normalizeCompositeNode(compositeNode, modules1, "simple-list-yang1:lst");
 
         assertTrue(compositeNode instanceof CompositeNodeWrapper);
         CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap();
@@ -201,26 +206,20 @@ public class JsonToCnSnTest {
         assertEquals("lst", compNode.getNodeType().getLocalName());
         verifyCompositeNode(compNode, "simple:list:yang1");
 
-        // dataSchemaNode2 should't be taken into account, because compNode
-        // isn't CompositeNodeWrapper
-        TestUtils.supplementNamespace(dataSchemaNode2, compNode);
+        TestUtils.normalizeCompositeNode(compositeNode, modules2, "simple-list-yang2:lst");
         verifyCompositeNode(compNode, "simple:list:yang1");
-
     }
 
     @Test
     public void jsonIdentityrefToCompositeNode() {
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/identityref/json/data.json");
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false,
+                JsonToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
 
-        Set<Module> modules = TestUtils.resolveModules("/json-to-cnsn/identityref");
+        Set<Module> modules = TestUtils.loadModulesFrom("/json-to-cnsn/identityref");
         assertEquals(2, modules.size());
-        Module module = TestUtils.resolveModule("identityref-module", modules);
-        assertNotNull(module);
-        DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null);
-        assertNotNull(dataSchemaNode);
 
-        TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, "identityref-module:cont");
+        TestUtils.normalizeCompositeNode(compositeNode, modules, "identityref-module:cont");
 
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
 
@@ -268,19 +267,14 @@ public class JsonToCnSnTest {
 
     private void simpleTest(String jsonPath, String yangPath, String topLevelElementName, String namespace,
             String moduleName) {
-        CompositeNode compositeNode = compositeContainerFromJson(jsonPath);
+        CompositeNode compositeNode = TestUtils.readInputToCnSn(jsonPath, false, JsonToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
 
-        DataSchemaNode dataSchemaNode = null;
-        try {
-            dataSchemaNode = TestUtils.obtainSchemaFromYang(yangPath, moduleName);
-        } catch (FileNotFoundException e) {
-            LOG.error(e.getMessage());
-            assertTrue(false);
-        }
-        assertNotNull(dataSchemaNode);
+        Set<Module> modules = null;
+        modules = TestUtils.loadModulesFrom(yangPath);
+        assertNotNull(modules);
 
-        TestUtils.supplementNamespace(dataSchemaNode, compositeNode);
+        TestUtils.normalizeCompositeNode(compositeNode, modules, moduleName + ":" + topLevelElementName);
 
         assertTrue(compositeNode instanceof CompositeNodeWrapper);
         CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap();
@@ -331,7 +325,8 @@ public class JsonToCnSnTest {
         boolean lflst1_2Found = false;
         boolean lf1Found = false;
 
-        assertEquals(namespace, compositeNode.getNodeType().getNamespace().toString());
+        // assertEquals(namespace,
+        // compositeNode.getNodeType().getNamespace().toString());
 
         for (Node<?> node : compositeNode.getChildren()) {
             if (node.getNodeType().getLocalName().equals("cont1")) {
@@ -369,34 +364,16 @@ public class JsonToCnSnTest {
         assertTrue(lf1Found);
     }
 
-    private CompositeNode compositeContainerFromJson(String jsonPath) {
-        return compositeContainerFromJson(jsonPath, false);
-    }
-
-    private CompositeNode compositeContainerFromJson(String jsonPath, boolean dummyNamespaces)
-            throws WebApplicationException {
-
-        JsonToCompositeNodeProvider jsonToCompositeNodeProvider = JsonToCompositeNodeProvider.INSTANCE;
-        InputStream jsonStream = JsonToCnSnTest.class.getResourceAsStream(jsonPath);
+    @Test
+    public void unsupportedDataFormatTest() {
+        String exceptionMessage = "";
         try {
-            CompositeNode compositeNode = jsonToCompositeNodeProvider
-                    .readFrom(null, null, null, null, null, jsonStream);
-            assertTrue(compositeNode instanceof CompositeNodeWrapper);
-            if (dummyNamespaces) {
-                try {
-                    TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode);
-                    return ((CompositeNodeWrapper) compositeNode).unwrap();
-                } catch (URISyntaxException e) {
-                    LOG.error(e.getMessage());
-                    assertTrue(e.getMessage(), false);
-                }
-            }
-            return compositeNode;
-        } catch (IOException e) {
-            LOG.error(e.getMessage());
-            assertTrue(e.getMessage(), false);
+            TestUtils.readInputToCnSn("/json-to-cnsn/unsupported-json-format.json", true,
+                    JsonToCompositeNodeProvider.INSTANCE);
+        } catch (WebApplicationException e) {
+            exceptionMessage = e.getCause().getMessage();
         }
-        return null;
+        assertTrue(exceptionMessage.contains("Root element of Json has to be Object"));
     }
 
 }
index 39c0d3b34f67159e7de8a1c1fc4a73809ae648b8..4c5922d73fa962b3aaea2d547846c8905e66bb8a 100644 (file)
@@ -1,14 +1,20 @@
 package org.opendaylight.controller.sal.restconf.impl.test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import java.io.FileNotFoundException;
 import java.util.Set;
 
+import org.junit.After;
 import org.junit.BeforeClass;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -17,16 +23,26 @@ public class ControllerContextTest {
 
     private static final ControllerContext controllerContext = ControllerContext.getInstance();
 
+    @Rule
+    public ExpectedException exception = ExpectedException.none();
+
     @BeforeClass
     public static void init() throws FileNotFoundException {
-        Set<Module> allModules = TestUtils.loadModules(ControllerContextTest.class.getResource("/full-versions/yangs").getPath());
+        Set<Module> allModules = TestUtils.loadModulesFrom("/full-versions/yangs");
+        assertNotNull(allModules);
         SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
         controllerContext.setSchemas(schemaContext);
     }
 
+    @After
+    public void releaseMountService() {
+        controllerContext.setMountService(null);
+    }
+
     @Test
     public void testToInstanceIdentifierList() throws FileNotFoundException {
-        InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:userWithoutClass/foo");
+        InstanceIdWithSchemaNode instanceIdentifier = controllerContext
+                .toInstanceIdentifier("simple-nodes:userWithoutClass/foo");
         assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "userWithoutClass");
 
         instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:userWithoutClass/foo/full-name");
@@ -40,13 +56,20 @@ public class ControllerContextTest {
 
         instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:users/user/foo");
         assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "user");
+    }
 
-        instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:user/null/boo");
-        assertNull(instanceIdentifier);
-
-        instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:user/foo");
-        assertNull(instanceIdentifier);
+    @Test
+    public void testToInstanceIdentifierListWithNullKey() {
+        exception.expect(ResponseException.class);
+        exception.expectMessage("HTTP 400 Bad Request");
+        controllerContext.toInstanceIdentifier("simple-nodes:user/null/boo");
+    }
 
+    @Test
+    public void testToInstanceIdentifierListWithMissingKey() {
+        exception.expect(ResponseException.class);
+        exception.expectMessage("HTTP 400 Bad Request");
+        controllerContext.toInstanceIdentifier("simple-nodes:user/foo");
     }
 
     @Test
@@ -54,23 +77,35 @@ public class ControllerContextTest {
         InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:users");
         assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "users");
         assertTrue(instanceIdentifier.getSchemaNode() instanceof ContainerSchemaNode);
-        assertEquals(2, ((ContainerSchemaNode)instanceIdentifier.getSchemaNode()).getChildNodes().size());
+        assertEquals(2, ((ContainerSchemaNode) instanceIdentifier.getSchemaNode()).getChildNodes().size());
     }
 
     @Test
     public void testToInstanceIdentifierChoice() throws FileNotFoundException {
-        InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/beer");
+        InstanceIdWithSchemaNode instanceIdentifier = controllerContext
+                .toInstanceIdentifier("simple-nodes:food/nonalcoholic/beer");
         assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "beer");
-        
-        instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/snack");
-        assertNull(instanceIdentifier);
-        
-        instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/sports-arena");
-        assertNull(instanceIdentifier);
-        
-        instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/snack/sports-arena");
-        assertNull(instanceIdentifier);
-        
+    }
+
+    @Test
+    public void testToInstanceIdentifierChoiceException() {
+        exception.expect(ResponseException.class);
+        exception.expectMessage("HTTP 400 Bad Request");
+        controllerContext.toInstanceIdentifier("simple-nodes:food/snack");
+    }
+
+    @Test
+    public void testToInstanceIdentifierCaseException() {
+        exception.expect(ResponseException.class);
+        exception.expectMessage("HTTP 400 Bad Request");
+        controllerContext.toInstanceIdentifier("simple-nodes:food/sports-arena");
+    }
+
+    @Test
+    public void testToInstanceIdentifierChoiceCaseException() {
+        exception.expect(ResponseException.class);
+        exception.expectMessage("HTTP 400 Bad Request");
+        controllerContext.toInstanceIdentifier("simple-nodes:food/snack/sports-arena");
     }
 
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java
new file mode 100644 (file)
index 0000000..0876584
--- /dev/null
@@ -0,0 +1,64 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import java.util.List;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.*;
+
+public class DummyType implements TypeDefinition<DummyType> {
+    QName dummyQName = TestUtils.buildQName("dummy type", "simple:uri", "2012-12-17");
+
+    @Override
+    public QName getQName() {
+        return dummyQName;
+    }
+
+    @Override
+    public SchemaPath getPath() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getDescription() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getReference() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Status getStatus() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public DummyType getBaseType() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getUnits() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Object getDefaultValue() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}
index d58b7e9dab0cecac48f4d5641dd2b6ff9bc8ba3a..c5f5a1eddc68d112858376d6c446192ac59394ab 100644 (file)
@@ -7,15 +7,25 @@ import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.net.*;
-import java.util.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Set;
 
-import org.junit.*;
+import org.junit.BeforeClass;
+import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.sal.restconf.impl.*;
-import org.opendaylight.yangtools.yang.common.*;
-import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.controller.sal.restconf.impl.StructuredData;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 import org.opendaylight.yangtools.yang.model.api.Module;
 
@@ -33,7 +43,7 @@ public class InvokeRpcMethodTest {
 
     @BeforeClass
     public static void initialization() {
-        modules = TestUtils.resolveModules("/invoke-rpc");
+        modules = TestUtils.loadModulesFrom("/invoke-rpc");
         assertEquals(1, modules.size());
         Module module = TestUtils.resolveModule("invoke-rpc-module", modules);
         assertNotNull(module);
@@ -50,7 +60,7 @@ public class InvokeRpcMethodTest {
         ControllerContext contContext = ControllerContext.getInstance();
         contContext.onGlobalContextUpdated(TestUtils.loadSchemaContext(modules));
         try {
-            contContext.findModuleByNamespace(new URI("invoke:rpc:module"));
+            contContext.findModuleNameByNamespace(new URI("invoke:rpc:module"));
         } catch (URISyntaxException e) {
             assertTrue("Uri wasn't created sucessfuly", false);
         }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java
new file mode 100644 (file)
index 0000000..bbedd2b
--- /dev/null
@@ -0,0 +1,225 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.JSON;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.api.Draft02;
+import org.opendaylight.controller.sal.rest.api.RestconfService;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public class MediaTypesTest extends JerseyTest {
+    
+    private static RestconfService restconfService;
+    private static String jsonData;
+    private static String xmlData;
+    
+    @BeforeClass
+    public static void init() throws IOException {
+        restconfService = mock(RestconfService.class);
+        String jsonPath = RestconfImplTest.class.getResource("/parts/ietf-interfaces_interfaces.json").getPath();
+        jsonData = TestUtils.loadTextFile(jsonPath);
+        InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
+        xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
+    }
+    
+    @Override
+    protected Application configure() {
+        /* enable/disable Jersey logs to console */
+//        enable(TestProperties.LOG_TRAFFIC);
+//        enable(TestProperties.DUMP_ENTITY);
+//        enable(TestProperties.RECORD_LOG_LEVEL);
+//        set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
+        ResourceConfig resourceConfig = new ResourceConfig();
+        resourceConfig = resourceConfig.registerInstances(restconfService, StructuredDataToXmlProvider.INSTANCE,
+                StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
+                JsonToCompositeNodeProvider.INSTANCE);
+        return resourceConfig;
+    }
+    
+  @Test
+  public void testPostOperationsWithInputDataMediaTypes() throws UnsupportedEncodingException {
+      String uriPrefix = "/operations/";
+      String uriPath = "ietf-interfaces:interfaces";
+      String uri = createUri(uriPrefix, uriPath);
+      when(restconfService.invokeRpc(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
+      post(uri, Draft02.MediaTypes.DATA+JSON, Draft02.MediaTypes.DATA+JSON, jsonData);
+      verify(restconfService, times(1)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+      post(uri, Draft02.MediaTypes.DATA+XML, Draft02.MediaTypes.DATA+XML, xmlData);
+      verify(restconfService, times(2)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+      post(uri, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, jsonData);
+      verify(restconfService, times(3)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+      post(uri, MediaType.APPLICATION_XML, MediaType.APPLICATION_XML, xmlData);
+      verify(restconfService, times(4)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+      post(uri, MediaType.TEXT_XML, MediaType.TEXT_XML, xmlData);
+      verify(restconfService, times(5)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+      post(uri, null, MediaType.TEXT_XML, xmlData);
+      verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+      
+      // negative tests
+      post(uri, MediaType.TEXT_PLAIN, MediaType.TEXT_XML, xmlData);
+      verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+      post(uri, MediaType.TEXT_XML, MediaType.TEXT_PLAIN, xmlData);
+      verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+  }
+  
+    @Test
+    public void testGetConfigMediaTypes() throws UnsupportedEncodingException {
+        String uriPrefix = "/config/";
+        String uriPath = "ietf-interfaces:interfaces";
+        String uri = createUri(uriPrefix, uriPath);
+        when(restconfService.readConfigurationData(uriPath)).thenReturn(null);
+        get(uri, Draft02.MediaTypes.DATA+JSON);
+        verify(restconfService, times(1)).readConfigurationData(uriPath);
+        get(uri, Draft02.MediaTypes.DATA+XML);
+        verify(restconfService, times(2)).readConfigurationData(uriPath);
+        get(uri, MediaType.APPLICATION_JSON);
+        verify(restconfService, times(3)).readConfigurationData(uriPath);
+        get(uri, MediaType.APPLICATION_XML);
+        verify(restconfService, times(4)).readConfigurationData(uriPath);
+        get(uri, MediaType.TEXT_XML);
+        verify(restconfService, times(5)).readConfigurationData(uriPath);
+        
+        // negative tests
+        get(uri, MediaType.TEXT_PLAIN);
+        verify(restconfService, times(5)).readConfigurationData(uriPath);
+    }
+    
+    @Test
+    public void testGetOperationalMediaTypes() throws UnsupportedEncodingException {
+        String uriPrefix = "/operational/";
+        String uriPath = "ietf-interfaces:interfaces";
+        String uri = createUri(uriPrefix, uriPath);
+        when(restconfService.readOperationalData(uriPath)).thenReturn(null);
+        get(uri, Draft02.MediaTypes.DATA+JSON);
+        verify(restconfService, times(1)).readOperationalData(uriPath);
+        get(uri, Draft02.MediaTypes.DATA+XML);
+        verify(restconfService, times(2)).readOperationalData(uriPath);
+        get(uri, MediaType.APPLICATION_JSON);
+        verify(restconfService, times(3)).readOperationalData(uriPath);
+        get(uri, MediaType.APPLICATION_XML);
+        verify(restconfService, times(4)).readOperationalData(uriPath);
+        get(uri, MediaType.TEXT_XML);
+        verify(restconfService, times(5)).readOperationalData(uriPath);
+        
+        // negative tests
+        get(uri, MediaType.TEXT_PLAIN);
+        verify(restconfService, times(5)).readOperationalData(uriPath);
+    }
+    
+    @Test
+    public void testPutConfigMediaTypes() throws UnsupportedEncodingException {
+        String uriPrefix = "/config/";
+        String uriPath = "ietf-interfaces:interfaces";
+        String uri = createUri(uriPrefix, uriPath);
+        when(restconfService.updateConfigurationData(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
+        put(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+        verify(restconfService, times(1)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+        put(uri, null, Draft02.MediaTypes.DATA+XML, xmlData);
+        verify(restconfService, times(2)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+        put(uri, null, MediaType.APPLICATION_JSON, jsonData);
+        verify(restconfService, times(3)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+        put(uri, null, MediaType.APPLICATION_XML, xmlData);
+        verify(restconfService, times(4)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+        put(uri, null, MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(5)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+        put(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(6)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+    }
+    
+    @Test
+    public void testPostConfigWithPathMediaTypes() throws UnsupportedEncodingException {
+        String uriPrefix = "/config/";
+        String uriPath = "ietf-interfaces:interfaces";
+        String uri = createUri(uriPrefix, uriPath);
+        when(restconfService.createConfigurationData(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
+        post(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+        verify(restconfService, times(1)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+        post(uri, null, Draft02.MediaTypes.DATA+XML, xmlData);
+        verify(restconfService, times(2)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+        post(uri, null, MediaType.APPLICATION_JSON, jsonData);
+        verify(restconfService, times(3)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+        post(uri, null, MediaType.APPLICATION_XML, xmlData);
+        verify(restconfService, times(4)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+        post(uri, null, MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(5)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+        post(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(6)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+    }
+    
+    @Test
+    public void testPostConfigMediaTypes() throws UnsupportedEncodingException {
+        String uriPrefix = "/config/";
+        String uri = createUri(uriPrefix, "");
+        when(restconfService.createConfigurationData(any(CompositeNode.class))).thenReturn(null);
+        post(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+        verify(restconfService, times(1)).createConfigurationData(any(CompositeNode.class));
+        post(uri, null, Draft02.MediaTypes.DATA+XML, xmlData);
+        verify(restconfService, times(2)).createConfigurationData(any(CompositeNode.class));
+        post(uri, null, MediaType.APPLICATION_JSON, jsonData);
+        verify(restconfService, times(3)).createConfigurationData(any(CompositeNode.class));
+        post(uri, null, MediaType.APPLICATION_XML, xmlData);
+        verify(restconfService, times(4)).createConfigurationData(any(CompositeNode.class));
+        post(uri, null, MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(5)).createConfigurationData(any(CompositeNode.class));
+        post(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(6)).createConfigurationData(any(CompositeNode.class));
+    }
+    
+    @Test
+    public void testDeleteConfigMediaTypes() throws UnsupportedEncodingException {
+        String uriPrefix = "/config/";
+        String uriPath = "ietf-interfaces:interfaces";
+        String uri = createUri(uriPrefix, uriPath);
+        when(restconfService.deleteConfigurationData(eq(uriPath))).thenReturn(null);
+        target(uri).request("fooMediaType").delete();
+        verify(restconfService, times(1)).deleteConfigurationData(uriPath);
+    }
+    
+    private int get(String uri, String acceptMediaType) {
+        return target(uri).request(acceptMediaType).get().getStatus();
+    }
+    
+    private int put(String uri, String acceptMediaType, String contentTypeMediaType, String data) {
+        if (acceptMediaType == null) {
+            return target(uri).request().put(Entity.entity(data, contentTypeMediaType)).getStatus();
+        }
+        return target(uri).request(acceptMediaType).put(Entity.entity(data, contentTypeMediaType)).getStatus();
+    }
+    
+    private int post(String uri, String acceptMediaType, String contentTypeMediaType, String data) {
+        if (acceptMediaType == null) {
+            if (contentTypeMediaType == null || data == null) {
+                return target(uri).request().post(null).getStatus();
+            }
+            return target(uri).request().post(Entity.entity(data, contentTypeMediaType)).getStatus();
+        }
+        if (contentTypeMediaType == null || data == null) {
+            return target(uri).request(acceptMediaType).post(null).getStatus();
+        }
+        return target(uri).request(acceptMediaType).post(Entity.entity(data, contentTypeMediaType)).getStatus();
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/NormalizeNodeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/NormalizeNodeTest.java
new file mode 100644 (file)
index 0000000..83e6ae5
--- /dev/null
@@ -0,0 +1,83 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.*;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public class NormalizeNodeTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialization() {
+        dataLoad("/normalize-node/yang/");
+    }
+
+    @Test
+    public void namespaceNotNullAndInvalidNamespaceAndNoModuleNameTest() {
+        boolean exceptionReised = false;
+        try {
+            TestUtils.normalizeCompositeNode(prepareCnSn("wrongnamespace"), modules, schemaNodePath);
+        } catch (ResponseException e) {
+            exceptionReised = true;
+        }
+        assertTrue(exceptionReised);
+    }
+
+    @Test
+    public void namespaceNullTest() {
+        String exceptionMessage = null;
+        try {
+            TestUtils.normalizeCompositeNode(prepareCnSn(null), modules, schemaNodePath);
+        } catch (ResponseException e) {
+            exceptionMessage = String.valueOf(e.getResponse().getEntity());
+        }
+        assertNull(exceptionMessage);
+    }
+
+    @Test
+    public void namespaceValidNamespaceTest() {
+        String exceptionMessage = null;
+        try {
+            TestUtils.normalizeCompositeNode(prepareCnSn("normalize:node:module"), modules, schemaNodePath);
+        } catch (ResponseException e) {
+            exceptionMessage = String.valueOf(e.getResponse().getEntity());
+        }
+        assertNull(exceptionMessage);
+    }
+
+    @Test
+    public void namespaceValidModuleNameTest() {
+        String exceptionMessage = null;
+        try {
+            TestUtils.normalizeCompositeNode(prepareCnSn("normalize-node-module"), modules, schemaNodePath);
+        } catch (ResponseException e) {
+            exceptionMessage = String.valueOf(e.getResponse().getEntity());
+        }
+        assertNull(exceptionMessage);
+    }
+
+    private CompositeNode prepareCnSn(String namespace) {
+        URI uri = null;
+        if (namespace != null) {
+            try {
+                uri = new URI(namespace);
+            } catch (URISyntaxException e) {
+            }
+            assertNotNull(uri);
+        }
+
+        SimpleNodeWrapper lf1 = new SimpleNodeWrapper(uri, "lf1", 43);
+        CompositeNodeWrapper cont = new CompositeNodeWrapper(uri, "cont");
+        cont.addValue(lf1);
+
+        return cont;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java
deleted file mode 100644 (file)
index cac77eb..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-package org.opendaylight.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.FileNotFoundException;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URLEncoder;
-import java.util.List;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.glassfish.jersey.test.TestProperties;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-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.RestconfImpl;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-import com.google.common.base.Charsets;
-
-public class ReadConfAndOperDataTest extends JerseyTest {
-
-    private static ControllerContext controllerContext;
-    private static BrokerFacade brokerFacade;
-    private static RestconfImpl restconfImpl;
-    private static final MediaType MEDIA_TYPE_DRAFT02 = new MediaType("application", "yang.data+xml");
-
-    @BeforeClass
-    public static void init() throws FileNotFoundException {
-        Set<Module> allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs")
-                .getPath());
-        SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
-        controllerContext = ControllerContext.getInstance();
-        controllerContext.setSchemas(schemaContext);
-        brokerFacade = mock(BrokerFacade.class);
-        restconfImpl = RestconfImpl.getInstance();
-        restconfImpl.setBroker(brokerFacade);
-        restconfImpl.setControllerContext(controllerContext);
-    }
-
-    @Before
-    public void logs() {
-        List<LogRecord> loggedRecords = getLoggedRecords();
-        for (LogRecord l : loggedRecords) {
-            System.out.println(l.getMessage());
-        }
-    }
-
-    @Test
-    public void testReadConfigurationData() throws UnsupportedEncodingException, FileNotFoundException {
-
-        String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
-
-        CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml");
-        when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
-
-        Response response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
-        assertEquals(200, response.getStatus());
-        
-        uri = createUri("/config/", "ietf-interfaces:interfaces/interface/example");
-        when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(null);
-        
-        response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
-        assertEquals(404, response.getStatus());
-    }
-
-    @Test
-    public void testReadOperationalData() throws UnsupportedEncodingException, FileNotFoundException {
-        String uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
-
-        CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml");
-        when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
-
-        Response response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
-        assertEquals(200, response.getStatus());
-        
-        uri = createUri("/config/", "ietf-interfaces:interfaces/interface/example");
-        when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(null);
-        
-        response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
-        assertEquals(404, response.getStatus());
-    }
-
-    private String createUri(String prefix, String encodedPart) throws UnsupportedEncodingException {
-        return URI.create(prefix + URLEncoder.encode(encodedPart, Charsets.US_ASCII.name()).toString()).toASCIIString();
-    }
-
-    @Override
-    protected Application configure() {
-        enable(TestProperties.LOG_TRAFFIC);
-        enable(TestProperties.DUMP_ENTITY);
-        enable(TestProperties.RECORD_LOG_LEVEL);
-        set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
-
-        ResourceConfig resourceConfig = new ResourceConfig();
-        resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
-                XmlToCompositeNodeProvider.INSTANCE);
-        return resourceConfig;
-    }
-}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java
new file mode 100644 (file)
index 0000000..fcc4c02
--- /dev/null
@@ -0,0 +1,33 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.restconf.impl.RestCodec;
+import org.opendaylight.yangtools.concepts.Codec;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.BitsType;
+
+public class RestCodecExceptionsTest {
+
+    @Test
+    public void serializeExceptionTest() {
+        Codec<Object, Object> codec = RestCodec.from(new BitsType(null));
+        String serializedValue = (String) codec.serialize("incorrect value"); // set
+                                                                              // expected
+        assertEquals("incorrect value", serializedValue);
+    }
+
+    @Test
+    public void deserializeExceptionTest() {
+        IdentityrefTypeDefinition mockedIidentityrefType = mock(IdentityrefTypeDefinition.class);
+
+        Codec<Object, Object> codec = RestCodec.from(mockedIidentityrefType);
+        String serializedValue = (String) codec.deserialize("incorrect value"); // IdentityValuesDTO
+                                                                                // object
+        // expected
+        assertEquals("incorrect value", serializedValue);
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestConfigDataTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestConfigDataTest.java
new file mode 100644 (file)
index 0000000..c6d0a93
--- /dev/null
@@ -0,0 +1,212 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.times;
+import static org.junit.Assert.assertEquals;
+
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLEncoder;
+import java.text.ParseException;
+import java.util.Set;
+import java.util.concurrent.Future;
+import java.util.logging.Level;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.test.TestProperties;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlMapper;
+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.RestconfImpl;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
+
+import com.google.common.base.Charsets;
+
+public class RestConfigDataTest extends JerseyTest {
+
+    private static ControllerContext controllerContext;
+    private static BrokerFacade brokerFacade;
+    private static RestconfImpl restconfImpl;
+    private static MountService mountService;
+    private static SchemaContext schemaContext;
+
+    private static final MediaType MEDIA_TYPE_XML_DRAFT02 = new MediaType("application", "yang.data+xml");
+
+    @BeforeClass
+    public static void init() throws FileNotFoundException {
+        Set<Module> modules = TestUtils.loadModulesFrom("/test-config-data/yang1");
+        schemaContext = TestUtils.loadSchemaContext(modules);
+        initMocking();
+    }
+    
+    private static void initMocking() {
+        controllerContext = ControllerContext.getInstance();
+        controllerContext.setSchemas(schemaContext);
+        mountService = mock(MountService.class);
+        controllerContext.setMountService(mountService);
+        brokerFacade = mock(BrokerFacade.class);
+        restconfImpl = RestconfImpl.getInstance();
+        restconfImpl.setBroker(brokerFacade);
+        restconfImpl.setControllerContext(controllerContext);
+    }
+
+//    @Test
+    // TODO 
+    public void createConfigurationDataTest() throws UnsupportedEncodingException, ParseException {
+        initMocking();
+        String URI_1 = createUri("/config", "");
+        String URI_2 = createUri("/config/", "");
+        String URI_3 = createUri("/config/", "test-interface:interfaces/");
+        String URI_4 = createUri("/config/", "test-interface:interfaces/");
+        String URI_5 = createUri("/config/", "test-interface:interfaces/test-interface2:class");
+
+        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(
+                TransactionStatus.COMMITED).build();
+        Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
+
+        when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class)))
+                .thenReturn(dummyFuture);
+
+        ArgumentCaptor<InstanceIdentifier> instanceIdCaptor = ArgumentCaptor.forClass(InstanceIdentifier.class);
+        ArgumentCaptor<CompositeNode> compNodeCaptor = ArgumentCaptor.forClass(CompositeNode.class);
+
+        // Test URI_1
+        Entity<String> entity = createEntity("/test-config-data/xml/test-interface.xml");
+        Response response = target(URI_1).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+        assertEquals(204, response.getStatus());
+        verify(brokerFacade).commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
+        String identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces]";
+        assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
+
+        // Test URI_2
+        response = target(URI_2).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+        assertEquals(204, response.getStatus());
+        verify(brokerFacade, times(2))
+                .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
+        assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
+
+        // Test URI_3
+        entity = createEntity("/test-config-data/xml/test-interface2.xml");
+        response = target(URI_3).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+        assertEquals(204, response.getStatus());
+        verify(brokerFacade, times(3))
+                .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
+
+        identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces, (urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interface[{(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)name=eth0}]]";
+        assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
+
+        // Test URI_4
+        Set<Module> modules2 = TestUtils.loadModulesFrom("/test-config-data/yang2");
+        SchemaContext schemaContext2 = TestUtils.loadSchemaContext(modules2);
+        MountInstance mountInstance = mock(MountInstance.class);
+        when(mountInstance.getSchemaContext()).thenReturn(schemaContext2);
+        when(mountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
+
+        entity = createEntity("/test-config-data/xml/test-interface3.xml");
+        response = target(URI_4).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+        assertEquals(204, response.getStatus());
+        verify(brokerFacade, times(4))
+                .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
+        identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces, (urn:ietf:params:xml:ns:yang:test-interface2?revision=2014-08-01)class]";
+        assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
+
+        // Test URI_5
+        response = target(URI_5).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+        assertEquals(204, response.getStatus());
+        verify(brokerFacade, times(5))
+                .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
+        identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces, (urn:ietf:params:xml:ns:yang:test-interface2?revision=2014-08-01)class, (urn:ietf:params:xml:ns:yang:test-interface2?revision=2014-08-01)class]";
+        assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
+    }
+    
+//    @Test
+    // TODO
+    public void testExistingData() throws UnsupportedEncodingException {
+        initMocking();
+        String URI_1 = createUri("/config", "");
+        String URI_2 = createUri("/config/", "");
+        String URI_3 = createUri("/config/", "test-interface:interfaces/");
+        String URI_4 = createUri("/config/", "test-interface:interfaces/");
+        String URI_5 = createUri("/config/", "test-interface:interfaces/test-interface2:class");
+
+        when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class)))
+                .thenReturn(null);
+
+        // Test URI_1
+        Entity<String> entity = createEntity("/test-config-data/xml/test-interface.xml");
+        Response response = target(URI_1).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+        assertEquals(202, response.getStatus());
+
+        // Test URI_2
+        response = target(URI_2).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+        assertEquals(202, response.getStatus());
+
+        // Test URI_3
+        entity = createEntity("/test-config-data/xml/test-interface2.xml");
+        response = target(URI_3).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+        assertEquals(202, response.getStatus());
+
+        // Test URI_4
+        Set<Module> modules2 = TestUtils.loadModulesFrom("/test-config-data/yang2");
+        SchemaContext schemaContext2 = TestUtils.loadSchemaContext(modules2);
+        MountInstance mountInstance = mock(MountInstance.class);
+        when(mountInstance.getSchemaContext()).thenReturn(schemaContext2);
+        when(mountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
+
+        entity = createEntity("/test-config-data/xml/test-interface3.xml");
+        response = target(URI_4).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+        assertEquals(202, response.getStatus());
+
+        // Test URI_5
+        response = target(URI_5).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
+        assertEquals(202, response.getStatus());
+    }
+
+    private String createUri(String prefix, String encodedPart) throws UnsupportedEncodingException {
+        return URI.create(prefix + URLEncoder.encode(encodedPart, Charsets.US_ASCII.name()).toString()).toASCIIString();
+    }
+
+    private Entity<String> createEntity(final String relativePathToXml) {
+        InputStream inputStream = XmlMapper.class.getResourceAsStream(relativePathToXml);
+        String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(inputStream));
+        Entity<String> entity = Entity.entity(xml, MEDIA_TYPE_XML_DRAFT02);
+
+        return entity;
+    }
+
+    @Override
+    protected Application configure() {
+        enable(TestProperties.LOG_TRAFFIC);
+        enable(TestProperties.DUMP_ENTITY);
+        enable(TestProperties.RECORD_LOG_LEVEL);
+        set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
+
+        ResourceConfig resourceConfig = new ResourceConfig();
+        resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
+                XmlToCompositeNodeProvider.INSTANCE);
+        return resourceConfig;
+    }
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestDeleteOperationTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestDeleteOperationTest.java
new file mode 100644 (file)
index 0000000..4b36d63
--- /dev/null
@@ -0,0 +1,85 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
+
+import java.io.FileNotFoundException;
+import java.io.UnsupportedEncodingException;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+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.RestconfImpl;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class RestDeleteOperationTest extends JerseyTest {
+
+    private static ControllerContext controllerContext;
+    private static BrokerFacade brokerFacade;
+    private static RestconfImpl restconfImpl;
+
+    @BeforeClass
+    public static void init() throws FileNotFoundException {
+        Set<Module> allModules = TestUtils.loadModulesFrom("/test-config-data/yang1");
+        assertNotNull(allModules);
+        SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
+        controllerContext = ControllerContext.getInstance();
+        controllerContext.setSchemas(schemaContext);
+        brokerFacade = mock(BrokerFacade.class);
+        restconfImpl = RestconfImpl.getInstance();
+        restconfImpl.setBroker(brokerFacade);
+        restconfImpl.setControllerContext(controllerContext);
+    }
+
+    @Override
+    protected Application configure() {
+        /* enable/disable Jersey logs to console */
+//        enable(TestProperties.LOG_TRAFFIC);
+//        enable(TestProperties.DUMP_ENTITY);
+//        enable(TestProperties.RECORD_LOG_LEVEL);
+//        set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
+        ResourceConfig resourceConfig = new ResourceConfig();
+        resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
+                XmlToCompositeNodeProvider.INSTANCE);
+        return resourceConfig;
+    }
+
+    @Test
+    public void deleteConfigStatusCodes() throws UnsupportedEncodingException {
+        String uri = createUri("/config/", "test-interface:interfaces");
+        Future<RpcResult<TransactionStatus>> dummyFuture = createFuture(TransactionStatus.COMMITED);
+        when(brokerFacade.commitConfigurationDataDelete(any(InstanceIdentifier.class))).thenReturn(dummyFuture);
+        Response response = target(uri).request(MediaType.APPLICATION_XML).delete();
+        assertEquals(200, response.getStatus());
+        
+        dummyFuture = createFuture(TransactionStatus.FAILED);
+        when(brokerFacade.commitConfigurationDataDelete(any(InstanceIdentifier.class))).thenReturn(dummyFuture);
+        response = target(uri).request(MediaType.APPLICATION_XML).delete();
+        assertEquals(500, response.getStatus());
+    }
+    
+    private Future<RpcResult<TransactionStatus>> createFuture(TransactionStatus statusName) {
+        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(statusName).build();
+        return DummyFuture.builder().rpcResult(rpcResult).build();
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java
new file mode 100644 (file)
index 0000000..ebc8a09
--- /dev/null
@@ -0,0 +1,183 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
+
+import java.io.FileNotFoundException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.sal.rest.api.Draft02;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+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.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+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.model.api.SchemaContext;
+
+public class RestGetOperationTest extends JerseyTest {
+
+    private static BrokerFacade brokerFacade;
+    private static RestconfImpl restconfImpl;
+    private static SchemaContext schemaContextYangsIetf;
+    private static SchemaContext schemaContextTestModule;
+    private static CompositeNode answerFromGet;
+
+    @BeforeClass
+    public static void init() throws FileNotFoundException {
+        schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
+        schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
+        ControllerContext controllerContext = ControllerContext.getInstance();
+        controllerContext.setSchemas(schemaContextYangsIetf);
+        brokerFacade = mock(BrokerFacade.class);
+        restconfImpl = RestconfImpl.getInstance();
+        restconfImpl.setBroker(brokerFacade);
+        restconfImpl.setControllerContext(controllerContext);
+        answerFromGet = prepareCompositeNodeWithIetfInterfacesInterfacesData();
+    }
+
+    @Override
+    protected Application configure() {
+        /* enable/disable Jersey logs to console */
+//        enable(TestProperties.LOG_TRAFFIC);
+//        enable(TestProperties.DUMP_ENTITY);
+//        enable(TestProperties.RECORD_LOG_LEVEL);
+//        set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
+        ResourceConfig resourceConfig = new ResourceConfig();
+        resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
+                StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
+                JsonToCompositeNodeProvider.INSTANCE);
+        return resourceConfig;
+    }
+
+    /**
+     * Tests of status codes for "/datastore/{identifier}".
+     */
+    @Test
+    public void getDatastoreStatusCodes() throws FileNotFoundException, UnsupportedEncodingException {
+        mockReadOperationalDataMethod();
+        String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
+        assertEquals(200, get(uri, MediaType.APPLICATION_XML));
+        
+        uri = createUri("/datastore/", "wrong-module:interfaces/interface/eth0");
+        assertEquals(400, get(uri, MediaType.APPLICATION_XML));
+        
+        // Test of request for not existing data. Returning status code 404
+        uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
+        when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
+        assertEquals(404, get(uri, MediaType.APPLICATION_XML));
+    }
+
+    /**
+     * Tests of status codes for "/operational/{identifier}".
+     */
+    @Test
+    public void getOperationalStatusCodes() throws UnsupportedEncodingException {
+        mockReadOperationalDataMethod();
+        String uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
+        assertEquals(200, get(uri, MediaType.APPLICATION_XML));
+        
+        uri = createUri("/operational/", "wrong-module:interfaces/interface/eth0");
+        assertEquals(400, get(uri, MediaType.APPLICATION_XML));
+    }
+
+    /**
+     * Tests of status codes for "/config/{identifier}".
+     */
+    @Test
+    public void getConfigStatusCodes() throws UnsupportedEncodingException {
+        mockReadConfigurationDataMethod();
+        String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
+        assertEquals(200, get(uri, MediaType.APPLICATION_XML));
+        
+        uri = createUri("/config/", "wrong-module:interfaces/interface/eth0");
+        assertEquals(400, get(uri, MediaType.APPLICATION_XML));
+    }
+
+    /**
+     * MountPoint test. URI represents mount point.
+     */
+    @Test
+    public void getDataWithUrlMountPoint() throws UnsupportedEncodingException, URISyntaxException {
+        when(brokerFacade.readConfigurationDataBehindMountPoint(any(MountInstance.class),
+                        any(InstanceIdentifier.class))).thenReturn(prepareCnDataForMountPointTest());
+        MountInstance mountInstance = mock(MountInstance.class);
+        when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
+        MountService mockMountService = mock(MountService.class);
+        when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
+
+        ControllerContext.getInstance().setMountService(mockMountService);
+
+        String uri = createUri("/config/",
+                "ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont/cont1");
+        Response response = target(uri).request(Draft02.MediaTypes.DATA + XML).get();
+        assertEquals(200, response.getStatus());
+        
+        uri = createUri("/config/",
+                "ietf-interfaces:interfaces/yang-ext:mount/test-module:cont/cont1");
+        response = target(uri).request(Draft02.MediaTypes.DATA + XML).get();
+        assertEquals(200, response.getStatus());
+    }
+    
+    private int get(String uri, String mediaType) {
+        return target(uri).request(mediaType).get().getStatus();
+    }
+
+    private CompositeNode prepareCnDataForMountPointTest() throws URISyntaxException {
+        CompositeNodeWrapper cont1 = new CompositeNodeWrapper(new URI("test:module"), "cont1");
+        SimpleNodeWrapper lf11 = new SimpleNodeWrapper(new URI("test:module"), "lf11", "lf11 value");
+        cont1.addValue(lf11);
+        return cont1.unwrap();
+    }
+
+    private void mockReadOperationalDataMethod() {
+        when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(answerFromGet);
+    }
+
+    private void mockReadConfigurationDataMethod() {
+        when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(answerFromGet);
+    }
+
+    private static CompositeNode prepareCompositeNodeWithIetfInterfacesInterfacesData() {
+        CompositeNode intface;
+        try {
+            intface = new CompositeNodeWrapper(new URI("interface"), "interface");
+            List<Node<?>> childs = new ArrayList<>();
+
+            childs.add(new SimpleNodeWrapper(new URI("name"), "name", "eth0"));
+            childs.add(new SimpleNodeWrapper(new URI("type"), "type", "ethernetCsmacd"));
+            childs.add(new SimpleNodeWrapper(new URI("enabled"), "enabled", Boolean.FALSE));
+            childs.add(new SimpleNodeWrapper(new URI("description"), "description", "some interface"));
+            intface.setValue(childs);
+            return intface;
+        } catch (URISyntaxException e) {
+        }
+
+        return null;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestOperationUtils.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestOperationUtils.java
new file mode 100644 (file)
index 0000000..186dafb
--- /dev/null
@@ -0,0 +1,20 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLEncoder;
+
+import com.google.common.base.Charsets;
+
+public class RestOperationUtils {
+
+    static final String JSON = "+json";
+    static final String XML = "+xml";
+
+    private RestOperationUtils() {
+    }
+
+    static String createUri(String prefix, String encodedPart) throws UnsupportedEncodingException {
+        return URI.create(prefix + URLEncoder.encode(encodedPart, Charsets.US_ASCII.name()).toString()).toASCIIString();
+    }
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPostOperationTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPostOperationTest.java
new file mode 100644 (file)
index 0000000..833d030
--- /dev/null
@@ -0,0 +1,203 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.concurrent.Future;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.sal.rest.api.Draft02;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+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.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class RestPostOperationTest extends JerseyTest {
+
+    private static String xmlDataAbsolutePath;
+    private static String xmlDataRpcInput;
+    private static CompositeNodeWrapper cnSnDataOutput;
+    private static String xmlData2;
+
+    private static ControllerContext controllerContext;
+    private static BrokerFacade brokerFacade;
+    private static RestconfImpl restconfImpl;
+    private static SchemaContext schemaContextYangsIetf;
+    private static SchemaContext schemaContextTestModule;
+
+    @BeforeClass
+    public static void init() throws URISyntaxException, IOException {
+        schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
+        schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
+        controllerContext = ControllerContext.getInstance();
+        brokerFacade = mock(BrokerFacade.class);
+        restconfImpl = RestconfImpl.getInstance();
+        restconfImpl.setBroker(brokerFacade);
+        restconfImpl.setControllerContext(controllerContext);
+        loadData();
+    }
+
+    @Override
+    protected Application configure() {
+        /* enable/disable Jersey logs to console */
+//        enable(TestProperties.LOG_TRAFFIC);
+//        enable(TestProperties.DUMP_ENTITY);
+//        enable(TestProperties.RECORD_LOG_LEVEL);
+//        set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
+        ResourceConfig resourceConfig = new ResourceConfig();
+        resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
+                StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
+                JsonToCompositeNodeProvider.INSTANCE);
+        return resourceConfig;
+    }
+
+    @Test
+    public void postOperationsStatusCodes() throws UnsupportedEncodingException {
+        controllerContext.setSchemas(schemaContextTestModule);
+        mockInvokeRpc(cnSnDataOutput, true);
+        String uri = createUri("/operations/", "test-module:rpc-test");
+        assertEquals(200, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
+        
+        mockInvokeRpc(null, true);
+        assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
+        
+        mockInvokeRpc(null, false);
+        assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
+        
+        uri = createUri("/operations/", "test-module:rpc-wrongtest");
+        assertEquals(404, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
+    }
+
+    @Test
+    public void postConfigOnlyStatusCodes() throws UnsupportedEncodingException {
+        controllerContext.setSchemas(schemaContextYangsIetf);
+        mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED);
+        String uri = createUri("/config", "");
+        assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+        
+        mockCommitConfigurationDataPostMethod(null);
+        assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+        
+        mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED);
+        assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+    }
+
+    @Test
+    public void postConfigStatusCodes() throws UnsupportedEncodingException {
+        controllerContext.setSchemas(schemaContextYangsIetf);
+        mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED);
+        String uri = createUri("/config/", "ietf-interfaces:interfaces");
+        assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+        
+        mockCommitConfigurationDataPostMethod(null);
+        assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+        
+        mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED);
+        assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+    }
+
+    @Test
+    public void postDatastoreStatusCodes() throws UnsupportedEncodingException {
+        controllerContext.setSchemas(schemaContextYangsIetf);
+        mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED);
+        String uri = createUri("/datastore/", "ietf-interfaces:interfaces");
+        assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+        
+        mockCommitConfigurationDataPostMethod(null);
+        assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+        
+        mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED);
+        assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+    }
+
+    @Test
+    public void postDataViaUrlMountPoint() throws UnsupportedEncodingException {
+        controllerContext.setSchemas(schemaContextYangsIetf);
+        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
+                .build();
+        Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
+        when(brokerFacade.commitConfigurationDataPostBehindMountPoint(any(MountInstance.class),
+                        any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
+
+        MountInstance mountInstance = mock(MountInstance.class);
+        when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
+        MountService mockMountService = mock(MountService.class);
+        when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
+
+        ControllerContext.getInstance().setMountService(mockMountService);
+
+        String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont/cont1");
+        assertEquals(204, post(uri, Draft02.MediaTypes.DATA + XML, xmlData2));
+    }
+    
+    private void mockInvokeRpc(CompositeNode result, boolean sucessful) {
+        RpcResult<CompositeNode> rpcResult = new DummyRpcResult.Builder<CompositeNode>().result(result)
+                .isSuccessful(sucessful).build();
+        when(brokerFacade.invokeRpc(any(QName.class), any(CompositeNode.class))).thenReturn(rpcResult);
+    }
+
+    private void mockCommitConfigurationDataPostMethod(TransactionStatus statusName) {
+        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(statusName)
+                .build();
+        Future<RpcResult<TransactionStatus>> dummyFuture = null;
+        if (statusName != null) {
+            dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
+        } else {
+            dummyFuture = DummyFuture.builder().build();
+        }
+
+        when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class)))
+                .thenReturn(dummyFuture);
+    }
+    
+    private int post(String uri, String mediaType, String data) {
+        return target(uri).request(mediaType).post(Entity.entity(data, mediaType)).getStatus();
+    }
+
+    private static void loadData() throws IOException, URISyntaxException {
+        InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces_absolute_path.xml");
+        xmlDataAbsolutePath = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
+        String xmlPathRpcInput = RestconfImplTest.class.getResource("/full-versions/test-data2/data-rpc-input.xml")
+                .getPath();
+        xmlDataRpcInput = TestUtils.loadTextFile(xmlPathRpcInput);
+        cnSnDataOutput = prepareCnSnRpcOutput();
+        String data2Input = RestconfImplTest.class.getResource("/full-versions/test-data2/data2.xml").getPath();
+        xmlData2 = TestUtils.loadTextFile(data2Input);
+    }
+
+    private static CompositeNodeWrapper prepareCnSnRpcOutput() throws URISyntaxException {
+        CompositeNodeWrapper cnSnDataOutput = new CompositeNodeWrapper(new URI("test:module"), "output");
+        CompositeNodeWrapper cont = new CompositeNodeWrapper(new URI("test:module"), "cont-output");
+        cnSnDataOutput.addValue(cont);
+        cnSnDataOutput.unwrap();
+        return cnSnDataOutput;
+    }
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPutOperationTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPutOperationTest.java
new file mode 100644 (file)
index 0000000..2df68af
--- /dev/null
@@ -0,0 +1,153 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URISyntaxException;
+import java.util.concurrent.Future;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.sal.rest.api.Draft02;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+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.RestconfImpl;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class RestPutOperationTest extends JerseyTest {
+
+    private static String xmlData;
+
+    private static BrokerFacade brokerFacade;
+    private static RestconfImpl restconfImpl;
+    private static SchemaContext schemaContextYangsIetf;
+    private static SchemaContext schemaContextTestModule;
+
+    @BeforeClass
+    public static void init() throws IOException {
+        schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
+        schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
+        ControllerContext controllerContext = ControllerContext.getInstance();
+        controllerContext.setSchemas(schemaContextYangsIetf);
+        brokerFacade = mock(BrokerFacade.class);
+        restconfImpl = RestconfImpl.getInstance();
+        restconfImpl.setBroker(brokerFacade);
+        restconfImpl.setControllerContext(controllerContext);
+        loadData();
+    }
+
+    private static void loadData() throws IOException {
+        InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
+        xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
+    }
+
+    @Override
+    protected Application configure() {
+        /* enable/disable Jersey logs to console */
+//        enable(TestProperties.LOG_TRAFFIC);
+//        enable(TestProperties.DUMP_ENTITY);
+//        enable(TestProperties.RECORD_LOG_LEVEL);
+//        set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
+        ResourceConfig resourceConfig = new ResourceConfig();
+        resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
+                StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
+                JsonToCompositeNodeProvider.INSTANCE);
+        return resourceConfig;
+    }
+
+    /**
+     * Tests of status codes for "/config/{identifier}".
+     */
+    @Test
+    public void putConfigStatusCodes() throws UnsupportedEncodingException {
+        String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
+        mockCommitConfigurationDataPutMethod(TransactionStatus.COMMITED);
+        assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData));
+        
+        mockCommitConfigurationDataPutMethod(TransactionStatus.FAILED);
+        assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
+    }
+
+
+    /**
+     * Tests of status codes for "/datastore/{identifier}".
+     */
+    @Test
+    public void putDatastoreStatusCodes() throws UnsupportedEncodingException {
+        String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
+        mockCommitConfigurationDataPutMethod(TransactionStatus.COMMITED);
+        assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData));
+        
+        mockCommitConfigurationDataPutMethod(TransactionStatus.FAILED);
+        assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
+    }
+
+    @Test
+    public void testRpcResultCommitedToStatusCodesWithMountPoint() throws UnsupportedEncodingException,
+            FileNotFoundException, URISyntaxException {
+
+        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
+                .build();
+        Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
+        when(brokerFacade.commitConfigurationDataPutBehindMountPoint(any(MountInstance.class),
+                        any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
+        
+
+        InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/full-versions/test-data2/data2.xml");
+        String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
+        Entity<String> entity = Entity.entity(xml, Draft02.MediaTypes.DATA + XML);
+
+        MountInstance mountInstance = mock(MountInstance.class);
+        when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
+        MountService mockMountService = mock(MountService.class);
+        when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
+
+        ControllerContext.getInstance().setMountService(mockMountService);
+
+        String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont");
+        Response response = target(uri).request(Draft02.MediaTypes.DATA + XML).put(entity);
+        assertEquals(200, response.getStatus());
+        
+        uri = createUri("/config/", "ietf-interfaces:interfaces/yang-ext:mount/test-module:cont");
+        response = target(uri).request(Draft02.MediaTypes.DATA + XML).put(entity);
+        assertEquals(200, response.getStatus());
+    }
+
+    private int put(String uri, String mediaType, String data) throws UnsupportedEncodingException {
+        return target(uri).request(mediaType).put(Entity.entity(data, mediaType)).getStatus();
+    }
+
+    private void mockCommitConfigurationDataPutMethod(TransactionStatus statusName) {
+        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(statusName)
+                .build();
+        Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
+        when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class)))
+                .thenReturn(dummyFuture);
+    }
+
+}
index 41cc0ddb5130f0fc49e4b76f51e9d423f25fd47a..c15cd530823fd06a49321946c1fe8e33bdaf4e9a 100644 (file)
@@ -1,17 +1,20 @@
 package org.opendaylight.controller.sal.restconf.impl.test;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import java.io.FileNotFoundException;
-import java.io.InputStream;
 import java.util.Set;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.opendaylight.controller.sal.restconf.impl.*;
+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.RestconfImpl;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Module;
@@ -23,8 +26,8 @@ public class RestconfImplTest {
 
     @BeforeClass
     public static void init() throws FileNotFoundException {
-        Set<Module> allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs")
-                .getPath());
+        Set<Module> allModules = TestUtils.loadModulesFrom("/full-versions/yangs");
+        assertNotNull(allModules);
         SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
         ControllerContext controllerContext = ControllerContext.getInstance();
         controllerContext.setSchemas(schemaContext);
@@ -33,8 +36,7 @@ public class RestconfImplTest {
 
     @Test
     public void testExample() throws FileNotFoundException {
-        InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
-        CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder(xmlStream);
+        CompositeNode loadedCompositeNode = TestUtils.readInputToCnSn("/parts/ietf-interfaces_interfaces.xml", XmlToCompositeNodeProvider.INSTANCE);
         BrokerFacade brokerFacade = mock(BrokerFacade.class);
         when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
         assertEquals(loadedCompositeNode, brokerFacade.readOperationalData(null));
index 366d99dbcb88a3dcb18f55c826b0b1c2dcc09b93..5ef66c3b257da4af2811a9e40b7c5d1908b4f474 100644 (file)
@@ -1,32 +1,52 @@
 package org.opendaylight.controller.sal.restconf.impl.test;
 
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.sql.Date;
-import java.util.*;
-import java.util.concurrent.Future;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
 
 import javax.ws.rs.WebApplicationException;
-import javax.xml.parsers.*;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.*;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.sal.rest.impl.*;
-import org.opendaylight.controller.sal.restconf.impl.*;
+import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.NodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.controller.sal.restconf.impl.StructuredData;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
-import org.opendaylight.yangtools.yang.model.api.*;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 import org.slf4j.Logger;
@@ -38,11 +58,11 @@ import com.google.common.base.Preconditions;
 
 public final class TestUtils {
 
-    private static final Logger logger = LoggerFactory.getLogger(TestUtils.class);
+    private static final Logger LOG = LoggerFactory.getLogger(TestUtils.class);
 
     private final static YangModelParser parser = new YangParserImpl();
 
-    public static Set<Module> loadModules(String resourceDirectory) throws FileNotFoundException {
+    private static Set<Module> loadModules(String resourceDirectory) throws FileNotFoundException {
         final File testDir = new File(resourceDirectory);
         final String[] fileList = testDir.list();
         final List<File> testFiles = new ArrayList<File>();
@@ -58,34 +78,40 @@ public final class TestUtils {
         return parser.parseYangModels(testFiles);
     }
 
+    public static Set<Module> loadModulesFrom(String yangPath) {
+        try {
+            return TestUtils.loadModules(TestUtils.class.getResource(yangPath).getPath());
+        } catch (FileNotFoundException e) {
+            LOG.error("Yang files at path: " + yangPath + " weren't loaded.");
+        }
+
+        return null;
+    }
+
     public static SchemaContext loadSchemaContext(Set<Module> modules) {
         return parser.resolveSchemaContext(modules);
     }
 
     public static SchemaContext loadSchemaContext(String resourceDirectory) throws FileNotFoundException {
-        return parser.resolveSchemaContext(loadModules(resourceDirectory));
+        return parser.resolveSchemaContext(loadModulesFrom(resourceDirectory));
     }
 
     public static Module findModule(Set<Module> modules, String moduleName) {
-        Module result = null;
         for (Module module : modules) {
             if (module.getName().equals(moduleName)) {
-                result = module;
-                break;
+                return module;
             }
         }
-        return result;
+        return null;
     }
 
-
-
     public static Document loadDocumentFrom(InputStream inputStream) {
         try {
             DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
             DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
             return docBuilder.parse(inputStream);
         } catch (SAXException | IOException | ParserConfigurationException e) {
-            logger.error("Error during loading Document from XML", e);
+            LOG.error("Error during loading Document from XML", e);
             return null;
         }
     }
@@ -107,288 +133,84 @@ public final class TestUtils {
             return new String(charData, "UTF-8");
         } catch (IOException | TransformerException e) {
             String msg = "Error during transformation of Document into String";
-            logger.error(msg, e);
+            LOG.error(msg, e);
             return msg;
         }
 
     }
 
-    public static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath,
-            String outputPath, String searchedModuleName, String searchedDataSchemaName) {
-        Set<Module> modules = resolveModules(yangPath);
-        Module module = resolveModule(searchedModuleName, modules);
-        DataSchemaNode dataSchemaNode = resolveDataSchemaNode(module, searchedDataSchemaName);
-
-        normalizeCompositeNode(compositeNode, modules, dataSchemaNode, searchedModuleName + ":"
-                + searchedDataSchemaName);
-
-        try {
-            return writeCompNodeWithSchemaContextToJson(compositeNode, modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        return null;
-
-    }
-
-    public static void normalizeCompositeNode(CompositeNode compositeNode, Set<Module> modules,
-            DataSchemaNode dataSchemaNode, String schemaNodePath) {
+    /**
+     * 
+     * Fill missing data (namespaces) and build correct data type in
+     * {@code compositeNode} according to {@code dataSchemaNode}. The method
+     * {@link RestconfImpl#createConfigurationData createConfigurationData} is
+     * used because it contains calling of method {code normalizeNode}
+     */
+    public static void normalizeCompositeNode(CompositeNode compositeNode, Set<Module> modules, String schemaNodePath) {
         RestconfImpl restconf = RestconfImpl.getInstance();
         ControllerContext.getInstance().setSchemas(TestUtils.loadSchemaContext(modules));
 
-        TestUtils.prepareMockForRestconfBeforeNormalization(modules, dataSchemaNode, restconf);
-        restconf.createConfigurationData(schemaNodePath, compositeNode);
+        prepareMocksForRestconf(modules, restconf);
+        restconf.updateConfigurationData(schemaNodePath, compositeNode);
     }
 
+    /**
+     * Searches module with name {@code searchedModuleName} in {@code modules}.
+     * If module name isn't specified and module set has only one element then
+     * this element is returned.
+     * 
+     */
     public static Module resolveModule(String searchedModuleName, Set<Module> modules) {
-        assertNotNull("modules can't be null.", modules);
-        Module module = null;
+        assertNotNull("Modules can't be null.", modules);
         if (searchedModuleName != null) {
             for (Module m : modules) {
                 if (m.getName().equals(searchedModuleName)) {
-                    module = m;
-                    break;
+                    return m;
                 }
             }
         } else if (modules.size() == 1) {
-            module = modules.iterator().next();
+            return modules.iterator().next();
         }
-        return module;
-    }
-
-    public static Set<Module> resolveModules(String yangPath) {
-        Set<Module> modules = null;
-
-        try {
-            modules = TestUtils.loadModules(TestUtils.class.getResource(yangPath).getPath());
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-        }
-
-        return modules;
+        return null;
     }
 
-    public static DataSchemaNode resolveDataSchemaNode(Module module, String searchedDataSchemaName) {
-        assertNotNull("Module is missing", module);
+    public static DataSchemaNode resolveDataSchemaNode(String searchedDataSchemaName, Module module) {
+        assertNotNull("Module can't be null", module);
 
-        DataSchemaNode dataSchemaNode = null;
         if (searchedDataSchemaName != null) {
             for (DataSchemaNode dsn : module.getChildNodes()) {
                 if (dsn.getQName().getLocalName().equals(searchedDataSchemaName)) {
-                    dataSchemaNode = dsn;
+                    return dsn;
                 }
             }
         } else if (module.getChildNodes().size() == 1) {
-            dataSchemaNode = module.getChildNodes().iterator().next();
-        }
-        return dataSchemaNode;
-    }
-
-    public static String writeCompNodeWithSchemaContextToJson(CompositeNode compositeNode, Set<Module> modules,
-            DataSchemaNode dataSchemaNode) throws IOException, WebApplicationException {
-        String jsonResult;
-
-        assertNotNull(dataSchemaNode);
-        assertNotNull("Composite node can't be null", compositeNode);
-        ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
-
-        ControllerContext.getInstance().setSchemas(loadSchemaContext(modules));
-
-        StructuredDataToJsonProvider structuredDataToJsonProvider = StructuredDataToJsonProvider.INSTANCE;
-        structuredDataToJsonProvider.writeTo(new StructuredData(compositeNode, dataSchemaNode), null, null, null, null,
-                null, byteArrayOS);
-
-        jsonResult = byteArrayOS.toString();
-
-        return jsonResult;
-    }
-
-    public static CompositeNode loadCompositeNode(String xmlDataPath) {
-        InputStream xmlStream = TestUtils.class.getResourceAsStream(xmlDataPath);
-        CompositeNode compositeNode = null;
-        try {
-            XmlReader xmlReader = new XmlReader();
-            compositeNode = xmlReader.read(xmlStream);
-
-        } catch (UnsupportedFormatException | XMLStreamException e) {
-            e.printStackTrace();
-        }
-        return compositeNode;
-    }
-
-    static void outputToFile(ByteArrayOutputStream outputStream, String outputDir) throws IOException {
-        FileOutputStream fileOS = null;
-        try {
-            String path = TestUtils.class.getResource(outputDir).getPath();
-            File outFile = new File(path + "/data.json");
-            fileOS = new FileOutputStream(outFile);
-            try {
-                fileOS.write(outputStream.toByteArray());
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-            fileOS.close();
-        } catch (FileNotFoundException e1) {
-            e1.printStackTrace();
-        }
-    }
-
-    static String readJsonFromFile(String path, boolean removeWhiteChars) {
-        FileReader fileReader = getFileReader(path);
-
-        StringBuilder strBuilder = new StringBuilder();
-        char[] buffer = new char[1000];
-
-        while (true) {
-            int loadedCharNum;
-            try {
-                loadedCharNum = fileReader.read(buffer);
-            } catch (IOException e) {
-                break;
-            }
-            if (loadedCharNum == -1) {
-                break;
-            }
-            strBuilder.append(buffer, 0, loadedCharNum);
-        }
-        try {
-            fileReader.close();
-        } catch (IOException e) {
-            System.out.println("The file wasn't closed");
-        }
-        String rawStr = strBuilder.toString();
-        if (removeWhiteChars) {
-            rawStr = rawStr.replace("\n", "");
-            rawStr = rawStr.replace("\r", "");
-            rawStr = rawStr.replace("\t", "");
-            rawStr = removeSpaces(rawStr);
-        }
-
-        return rawStr;
-    }
-
-    private static FileReader getFileReader(String path) {
-        String fullPath = TestUtils.class.getResource(path).getPath();
-        assertNotNull("Path to file can't be null.", fullPath);
-        File file = new File(fullPath);
-        assertNotNull("File can't be null", file);
-        FileReader fileReader = null;
-        try {
-            fileReader = new FileReader(file);
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-        }
-        assertNotNull("File reader can't be null.", fileReader);
-        return fileReader;
-    }
-
-    private static String removeSpaces(String rawStr) {
-        StringBuilder strBuilder = new StringBuilder();
-        int i = 0;
-        int quoteCount = 0;
-        while (i < rawStr.length()) {
-            if (rawStr.substring(i, i + 1).equals("\"")) {
-                quoteCount++;
-            }
-
-            if (!rawStr.substring(i, i + 1).equals(" ") || (quoteCount % 2 == 1)) {
-                strBuilder.append(rawStr.charAt(i));
-            }
-            i++;
+            return module.getChildNodes().iterator().next();
         }
-
-        return strBuilder.toString();
+        return null;
     }
 
-    public static QName buildQName(String name, String uri, String date) {
+    public static QName buildQName(String name, String uri, String date, String prefix) {
         try {
             URI u = new URI(uri);
             Date dt = null;
             if (date != null) {
                 dt = Date.valueOf(date);
             }
-            return new QName(u, dt, name);
+            return new QName(u, dt, prefix, name);
         } catch (URISyntaxException e) {
             return null;
         }
     }
 
-    public static QName buildQName(String name) {
-        return buildQName(name, "", null);
-    }
-
-    public static void supplementNamespace(DataSchemaNode dataSchemaNode, CompositeNode compositeNode) {
-        RestconfImpl restconf = RestconfImpl.getInstance();
-
-        InstanceIdWithSchemaNode instIdAndSchema = new InstanceIdWithSchemaNode(mock(InstanceIdentifier.class),
-                dataSchemaNode);
-
-        ControllerContext controllerContext = mock(ControllerContext.class);
-        BrokerFacade broker = mock(BrokerFacade.class);
-
-        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().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);
-
-        restconf.setControllerContext(controllerContext);
-        restconf.setBroker(broker);
-
-        // method is called only because it contains call of method which
-        // supplement namespaces to compositeNode
-        restconf.createConfigurationData("something", compositeNode);
-    }
-
-    public static DataSchemaNode obtainSchemaFromYang(String yangFolder) throws FileNotFoundException {
-        return obtainSchemaFromYang(yangFolder, null);
+    public static QName buildQName(String name, String uri, String date) {
+        return buildQName(name, uri, date, null);
     }
 
-    public static DataSchemaNode obtainSchemaFromYang(String yangFolder, String moduleName)
-            throws FileNotFoundException {
-        Set<Module> modules = null;
-        modules = TestUtils.loadModules(TestUtils.class.getResource(yangFolder).getPath());
-
-        if (modules == null) {
-            return null;
-        }
-        if (modules.size() < 1) {
-            return null;
-        }
-
-        Module moduleRes = null;
-        if (modules.size() > 1) {
-            if (moduleName == null) {
-                return null;
-            } else {
-                for (Module module : modules) {
-                    if (module.getName().equals(moduleName)) {
-                        moduleRes = module;
-                    }
-                }
-                if (moduleRes == null) {
-                    return null;
-                }
-            }
-        } else {
-            moduleRes = modules.iterator().next();
-        }
-
-        if (moduleRes.getChildNodes() == null) {
-            return null;
-        }
-
-        if (moduleRes.getChildNodes().size() != 1) {
-            return null;
-        }
-        DataSchemaNode dataSchemaNode = moduleRes.getChildNodes().iterator().next();
-        return dataSchemaNode;
-
+    public static QName buildQName(String name) {
+        return buildQName(name, "", null);
     }
 
-    public static void addDummyNamespaceToAllNodes(NodeWrapper<?> wrappedNode) throws URISyntaxException {
+    private static void addDummyNamespaceToAllNodes(NodeWrapper<?> wrappedNode) throws URISyntaxException {
         wrappedNode.setNamespace(new URI(""));
         if (wrappedNode instanceof CompositeNodeWrapper) {
             for (NodeWrapper<?> childNodeWrapper : ((CompositeNodeWrapper) wrappedNode).getValues()) {
@@ -397,56 +219,77 @@ public final class TestUtils {
         }
     }
 
-    public static void prepareMockForRestconfBeforeNormalization(Set<Module> modules, DataSchemaNode dataSchemaNode,
-            RestconfImpl restconf) {
-        ControllerContext instance = ControllerContext.getInstance();
-        instance.setSchemas(TestUtils.loadSchemaContext(modules));
-        restconf.setControllerContext(ControllerContext.getInstance());
-
+    private static void prepareMocksForRestconf(Set<Module> modules, RestconfImpl restconf) {
+        ControllerContext controllerContext = ControllerContext.getInstance();
         BrokerFacade mockedBrokerFacade = mock(BrokerFacade.class);
+
+        controllerContext.setSchemas(TestUtils.loadSchemaContext(modules));
+
         when(mockedBrokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class)))
                 .thenReturn(
                         new DummyFuture.Builder().rpcResult(
                                 new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
                                         .build()).build());
+
+        restconf.setControllerContext(controllerContext);
         restconf.setBroker(mockedBrokerFacade);
     }
-    
-    static CompositeNode loadCompositeNodeWithXmlTreeBuilder(String xmlDataPath) {
-        InputStream xmlStream = TestUtils.class.getResourceAsStream(xmlDataPath);
-        CompositeNode compositeNode = null;
+
+    public static CompositeNode readInputToCnSn(String path, boolean dummyNamespaces,
+            MessageBodyReader<CompositeNode> reader) throws WebApplicationException {
+
+        InputStream inputStream = TestUtils.class.getResourceAsStream(path);
         try {
-            compositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder(xmlStream);
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
+            CompositeNode compositeNode = reader.readFrom(null, null, null, null, null, inputStream);
+            assertTrue(compositeNode instanceof CompositeNodeWrapper);
+            if (dummyNamespaces) {
+                try {
+                    TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode);
+                    return ((CompositeNodeWrapper) compositeNode).unwrap();
+                } catch (URISyntaxException e) {
+                    LOG.error(e.getMessage());
+                    assertTrue(e.getMessage(), false);
+                }
+            }
+            return compositeNode;
+        } catch (IOException e) {
+            LOG.error(e.getMessage());
+            assertTrue(e.getMessage(), false);
         }
-        return compositeNode;
-        
-        
-        
+        return null;
     }
-    
-    
-    public static CompositeNode loadCompositeNodeWithXmlTreeBuilder(InputStream xmlInputStream) throws FileNotFoundException {
-        if (xmlInputStream == null) {
-            throw new IllegalArgumentException();
-        }
-        Node<?> dataTree;
-        try {
-            dataTree = XmlTreeBuilder.buildDataTree(xmlInputStream);
-        } catch (XMLStreamException e) {
-            logger.error("Error during building data tree from XML", e);
-            return null;
-        }
-        if (dataTree == null) {
-            logger.error("data tree is null");
-            return null;
-        }
-        if (dataTree instanceof SimpleNode) {
-            logger.error("RPC XML was resolved as SimpleNode");
-            return null;
+
+    public static CompositeNode readInputToCnSn(String path, MessageBodyReader<CompositeNode> reader) {
+        return readInputToCnSn(path, false, reader);
+    }
+
+    public static String writeCompNodeWithSchemaContextToOutput(CompositeNode compositeNode, Set<Module> modules,
+            DataSchemaNode dataSchemaNode, MessageBodyWriter<StructuredData> messageBodyWriter) throws IOException,
+            WebApplicationException {
+
+        assertNotNull(dataSchemaNode);
+        assertNotNull("Composite node can't be null", compositeNode);
+        ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
+
+        ControllerContext.getInstance().setSchemas(loadSchemaContext(modules));
+
+        messageBodyWriter.writeTo(new StructuredData(compositeNode, dataSchemaNode), null, null, null, null, null,
+                byteArrayOS);
+
+        return byteArrayOS.toString();
+    }
+
+    public static String loadTextFile(String filePath) throws IOException {
+        FileReader fileReader = new FileReader(filePath);
+        BufferedReader bufReader = new BufferedReader(fileReader);
+
+        String line = null;
+        StringBuilder result = new StringBuilder();
+        while ((line = bufReader.readLine()) != null) {
+            result.append(line);
         }
-        return (CompositeNode) dataTree;
-    }        
+        bufReader.close();
+        return result.toString();
 
+    }
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java
deleted file mode 100644 (file)
index 4cea120..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-package org.opendaylight.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URLEncoder;
-import java.util.*;
-import java.util.concurrent.Future;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.glassfish.jersey.test.TestProperties;
-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.*;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-import com.google.common.base.Charsets;
-
-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.data+xml");
-    private static final MediaType MEDIA_TYPE_DRAFT02 = new MediaType("application", "yang.data+xml");
-
-    @BeforeClass
-    public static void init() throws FileNotFoundException {
-        Set<Module> allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs")
-                .getPath());
-        SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
-        controllerContext = ControllerContext.getInstance();
-        controllerContext.setSchemas(schemaContext);
-        brokerFacade = mock(BrokerFacade.class);
-        restconfImpl = RestconfImpl.getInstance();
-        restconfImpl.setBroker(brokerFacade);
-        restconfImpl.setControllerContext(controllerContext);
-    }
-
-    @Before
-    public void logs() {
-        List<LogRecord> loggedRecords = getLoggedRecords();
-        for (LogRecord l : loggedRecords) {
-            System.out.println(l.getMessage());
-        }
-    }
-
-    @Test
-    public void testStructuredDataToXmlProvider() throws FileNotFoundException, UnsupportedEncodingException {
-        String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
-
-        CompositeNode loadedCompositeNode = prepareCompositeNodeWithIetfInterfacesInterfacesData();
-        when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
-
-        Response response = target(uri).request(MEDIA_TYPE).get();
-        assertEquals(200, response.getStatus());
-    }
-
-    private CompositeNode prepareCompositeNodeWithIetfInterfacesInterfacesData() {
-        CompositeNode intface;
-        try {
-            intface = new CompositeNodeWrapper(new URI("interface"), "interface");
-            List<Node<?>> childs = new ArrayList<>();
-
-            childs.add(new SimpleNodeWrapper(new URI("name"), "name", "eth0"));
-            childs.add(new SimpleNodeWrapper(new URI("type"), "type", "ethernetCsmacd"));
-            childs.add(new SimpleNodeWrapper(new URI("enabled"), "enabled", Boolean.FALSE));
-            childs.add(new SimpleNodeWrapper(new URI("description"), "description", "some interface"));
-            intface.setValue(childs);
-            return intface;
-        } catch (URISyntaxException e) {
-        }
-
-        return null;
-    }
-
-    @Test
-    public void testBadFormatXmlToCompositeNodeProvider() throws UnsupportedEncodingException, URISyntaxException {
-        String uri = createUri("/operations/", "ietf-interfaces:interfaces/interface/eth0");
-
-        Response response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).post(
-                Entity.entity("<SimpleNode/>", MEDIA_TYPE));
-        assertEquals(400, response.getStatus());
-
-        response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).post(
-                Entity.entity("<SimpleNode>", MEDIA_TYPE));
-        assertEquals(400, response.getStatus());
-    }
-
-    @Test
-    public void testXmlToCompositeNode404NotFound() throws UnsupportedEncodingException, URISyntaxException {
-        String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
-
-        when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
-
-        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_DRAFT02);
-        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().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_DRAFT02).put(entity);
-        assertEquals(200, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
-        assertEquals(204, response.getStatus());
-
-        uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
-        response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
-        assertEquals(200, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
-        assertEquals(204, 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());
-    }
-
-    @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_DRAFT02);
-        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().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_DRAFT02).put(entity);
-        assertEquals(500, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
-        assertEquals(500, response.getStatus());
-
-        uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
-        response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
-        assertEquals(500, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
-        assertEquals(500, response.getStatus());
-
-        uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
-        response = target(uri).request(MEDIA_TYPE).put(entity);
-        assertEquals(500, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE).post(entity);
-        assertEquals(500, response.getStatus());
-    }
-
-    private String createUri(String prefix, String encodedPart) throws UnsupportedEncodingException {
-        return URI.create(prefix + URLEncoder.encode(encodedPart, Charsets.US_ASCII.name()).toString()).toASCIIString();
-    }
-
-    @Override
-    protected Application configure() {
-        enable(TestProperties.LOG_TRAFFIC);
-        enable(TestProperties.DUMP_ENTITY);
-        enable(TestProperties.RECORD_LOG_LEVEL);
-        set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
-
-        ResourceConfig resourceConfig = new ResourceConfig();
-        resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
-                XmlToCompositeNodeProvider.INSTANCE);
-        return resourceConfig;
-    }
-
-}
index 7e3da0e4b4bd98ee8a6a04442001b91e10da37ad..3d24c6ba67ec1fc3a18ea1e290988f1e52fc8289 100644 (file)
@@ -4,24 +4,32 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
 import java.util.Set;
-import org.opendaylight.yangtools.yang.model.api.*;
+
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
 
 public abstract class YangAndXmlAndDataSchemaLoader {
 
     protected static Set<Module> modules;
     protected static DataSchemaNode dataSchemaNode;
+    protected static String searchedModuleName;
+    protected static String searchedDataSchemaName;
+    protected static String schemaNodePath;
 
     protected static void dataLoad(String yangPath) {
         dataLoad(yangPath, 1, null, null);
     }
 
     protected static void dataLoad(String yangPath, int modulesNumber, String moduleName, String dataSchemaName) {
-        modules = TestUtils.resolveModules(yangPath);
+        modules = TestUtils.loadModulesFrom(yangPath);
         assertEquals(modulesNumber, modules.size());
         Module module = TestUtils.resolveModule(moduleName, modules);
+        searchedModuleName = module == null ? "" : module.getName();
         assertNotNull(module);
-        dataSchemaNode = TestUtils.resolveDataSchemaNode(module, dataSchemaName);
+        dataSchemaNode = TestUtils.resolveDataSchemaNode(dataSchemaName, module);
+        searchedDataSchemaName = dataSchemaNode == null ? "" : dataSchemaNode.getQName().getLocalName();
         assertNotNull(dataSchemaNode);
+        schemaNodePath = searchedModuleName + ":" + searchedDataSchemaName;
     }
 
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java
new file mode 100644 (file)
index 0000000..beff572
--- /dev/null
@@ -0,0 +1,351 @@
+package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class XmlLeafrefToCnSnTest {
+    private static final Logger LOG = LoggerFactory.getLogger(XmlLeafrefToCnSnTest.class);
+
+    /**
+     * top level element represents container. second level element is list with
+     * two elements.
+     */
+    @Test
+    public void testXmlDataContainer() {
+        CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/data-container.xml", false,
+                XmlToCompositeNodeProvider.INSTANCE);
+        assertNotNull(compNode);
+        Set<Module> modules = TestUtils.loadModulesFrom("/xml-to-cnsn/data-container-yang");
+
+        assertNotNull(modules);
+        TestUtils.normalizeCompositeNode(compNode, modules, "data-container-yang:cont");
+
+        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 = TestUtils.readInputToCnSn("/xml-to-cnsn/data-list.xml", false,
+                XmlToCompositeNodeProvider.INSTANCE);
+        assertNotNull(compNode);
+
+        Set<Module> modules = TestUtils.loadModulesFrom("/xml-to-cnsn/data-list-yang");
+        assertNotNull(modules);
+
+        TestUtils.normalizeCompositeNode(compNode, modules, "data-container-yang:cont");
+
+        String nameSpaceList = "data:list:yang";
+        String nameSpaceCont = "data:container:yang";
+        assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
+        assertEquals("cont", compNode.getNodeType().getLocalName());
+        assertEquals(3, compNode.getChildren().size());
+        CompositeNode lst1_1 = null;
+        CompositeNode lst1_2 = null;
+        int loopCount = 0;
+        for (Node<?> node : compNode.getChildren()) {
+            if (node.getNodeType().getLocalName().equals("lf1")) {
+                assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString());
+                assertTrue(node instanceof SimpleNode<?>);
+                assertEquals("lf1", node.getValue());
+            } else {
+                assertTrue(node instanceof CompositeNode);
+                switch (loopCount++) {
+                case 0:
+                    lst1_1 = (CompositeNode) node;
+                    break;
+                case 1:
+                    lst1_2 = (CompositeNode) node;
+                    break;
+                }
+                assertEquals(nameSpaceCont, node.getNodeType().getNamespace().toString());
+            }
+        }
+        // lst1_1
+        verifyCommonPartAOfXml(lst1_1, "1", nameSpaceCont);
+        // :lst1_1
+
+        // lst1_2
+        SimpleNode<?> lflst11 = null;
+        CompositeNode cont11 = null;
+        for (Node<?> node : lst1_2.getChildren()) {
+            String nodeName = node.getNodeType().getLocalName();
+            if (nodeName.equals("lflst11")) {
+                assertTrue(node instanceof SimpleNode<?>);
+                lflst11 = (SimpleNode<?>) node;
+
+            } else if (nodeName.equals("cont11")) {
+                assertTrue(node instanceof CompositeNode);
+                cont11 = (CompositeNode) node;
+            }
+            assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
+        }
+        assertEquals("221", lflst11.getValue());
+
+        assertEquals(1, cont11.getChildren().size());
+        assertTrue(cont11.getChildren().get(0) instanceof SimpleNode<?>);
+        SimpleNode<?> cont11_lf111 = (SimpleNode<?>) cont11.getChildren().get(0);
+        assertEquals(nameSpaceCont, cont11_lf111.getNodeType().getNamespace().toString());
+        assertEquals("lf111", cont11_lf111.getNodeType().getLocalName());
+        assertEquals((short) 100, cont11_lf111.getValue());
+        // :lst1_2
+
+    }
+
+    @Test
+    public void testXmlEmptyData() {
+        CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/empty-data.xml", true,
+                XmlToCompositeNodeProvider.INSTANCE);
+        assertEquals("cont", compNode.getNodeType().getLocalName());
+        SimpleNode<?> lf1 = null;
+        SimpleNode<?> lflst1_1 = null;
+        SimpleNode<?> lflst1_2 = null;
+        CompositeNode lst1 = null;
+        int lflst1Count = 0;
+        for (Node<?> node : compNode.getChildren()) {
+            if (node.getNodeType().getLocalName().equals("lf1")) {
+                assertTrue(node instanceof SimpleNode<?>);
+                lf1 = (SimpleNode<?>) node;
+            } else if (node.getNodeType().getLocalName().equals("lflst1")) {
+                assertTrue(node instanceof SimpleNode<?>);
+
+                switch (lflst1Count++) {
+                case 0:
+                    lflst1_1 = (SimpleNode<?>) node;
+                    break;
+                case 1:
+                    lflst1_2 = (SimpleNode<?>) node;
+                    break;
+                }
+            } else if (node.getNodeType().getLocalName().equals("lst1")) {
+                assertTrue(node instanceof CompositeNode);
+                lst1 = (CompositeNode) node;
+            }
+        }
+
+        assertNotNull(lf1);
+        assertNotNull(lflst1_1);
+        assertNotNull(lflst1_2);
+        assertNotNull(lst1);
+
+        assertEquals("", lf1.getValue());
+        assertEquals("", lflst1_1.getValue());
+        assertEquals("", lflst1_2.getValue());
+        assertEquals(1, lst1.getChildren().size());
+        assertEquals("lf11", lst1.getChildren().get(0).getNodeType().getLocalName());
+
+        assertTrue(lst1.getChildren().get(0) instanceof SimpleNode<?>);
+        assertEquals("", lst1.getChildren().get(0).getValue());
+
+    }
+
+    /**
+     * Test case like this <lf11 xmlns:x="namespace">x:identity</lf11>
+     */
+    @Test
+    public void testIdentityrefNmspcInElement() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml", "/xml-to-cnsn/identityref",
+                "identityref-module", "cont", 2, "iden", "identity:module");
+    }
+
+    /**
+     * 
+     * Test case like <lf11 xmlns="namespace1"
+     * xmlns:x="namespace">identity</lf11>
+     */
+
+    @Test
+    public void testIdentityrefDefaultNmspcInElement() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml",
+                "/xml-to-cnsn/identityref/yang-augments", "general-module", "cont", 3, "iden", "identityref:module");
+    }
+
+    /**
+     * 
+     * Test case like <cont1 xmlns="namespace1"> <lf11
+     * xmlns:x="namespace">identity</lf11> </cont1>
+     */
+    @Test
+    public void testIdentityrefDefaultNmspcInParrentElement() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml",
+                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
+    }
+
+    /**
+     * 
+     * Test case like <cont1 xmlns="namespace1" xmlns:x="namespace">
+     * <lf11>x:identity</lf11> </cont1>
+     */
+    @Test
+    public void testIdentityrefNmspcInParrentElement() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml",
+                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "z:namespace");
+
+    }
+
+    /**
+     * 
+     * Test case like (without namespace in xml) <cont1> <lf11>x:identity</lf11>
+     * </cont1>
+     */
+    @Test
+    public void testIdentityrefNoNmspcValueWithPrefix() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml",
+                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "x:iden", "identityref:module");
+    }
+
+    /**
+     * 
+     * Test case like (without namespace in xml) <cont1> <lf11>identity</lf11>
+     * </cont1>
+     */
+    @Test
+    public void testIdentityrefNoNmspcValueWithoutPrefix() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml",
+                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
+    }
+
+    private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) {
+        SimpleNode<?> lf1suf = null;
+        SimpleNode<?> lflst1suf_1 = null;
+        SimpleNode<?> lflst1suf_2 = null;
+        SimpleNode<?> lflst1suf_3 = null;
+        CompositeNode cont1suf = null;
+        CompositeNode lst1suf = null;
+
+        int lflstCount = 0;
+
+        for (Node<?> node : compNode.getChildren()) {
+            String localName = node.getNodeType().getLocalName();
+            if (localName.equals("lf1" + suf)) {
+                assertTrue(node instanceof SimpleNode<?>);
+                lf1suf = (SimpleNode<?>) node;
+            } else if (localName.equals("lflst1" + suf)) {
+                assertTrue(node instanceof SimpleNode<?>);
+                switch (lflstCount++) {
+                case 0:
+                    lflst1suf_1 = (SimpleNode<?>) node;
+                    break;
+                case 1:
+                    lflst1suf_2 = (SimpleNode<?>) node;
+                    break;
+                case 2:
+                    lflst1suf_3 = (SimpleNode<?>) node;
+                    break;
+                }
+            } else if (localName.equals("lst1" + suf)) {
+                assertTrue(node instanceof CompositeNode);
+                lst1suf = (CompositeNode) node;
+            } else if (localName.equals("cont1" + suf)) {
+                assertTrue(node instanceof CompositeNode);
+                cont1suf = (CompositeNode) node;
+            }
+            assertEquals(nameSpace, node.getNodeType().getNamespace().toString());
+        }
+
+        assertNotNull(lf1suf);
+        assertNotNull(lflst1suf_1);
+        assertNotNull(lflst1suf_2);
+        assertNotNull(lflst1suf_3);
+        assertNotNull(lst1suf);
+        assertNotNull(cont1suf);
+
+        assertEquals("str0", lf1suf.getValue());
+        assertEquals("121", lflst1suf_1.getValue());
+        assertEquals("131", lflst1suf_2.getValue());
+        assertEquals("str1", lflst1suf_3.getValue());
+
+        assertEquals(1, lst1suf.getChildren().size());
+
+        assertTrue(lst1suf.getChildren().get(0) instanceof SimpleNode<?>);
+        SimpleNode<?> lst11_lf11 = (SimpleNode<?>) lst1suf.getChildren().get(0);
+        assertEquals(nameSpace, lst11_lf11.getNodeType().getNamespace().toString());
+        assertEquals("lf11" + suf, lst11_lf11.getNodeType().getLocalName());
+        assertEquals("str2", lst11_lf11.getValue());
+
+        assertTrue(cont1suf.getChildren().get(0) instanceof SimpleNode<?>);
+        SimpleNode<?> cont1_lf11 = (SimpleNode<?>) cont1suf.getChildren().get(0);
+        assertEquals(nameSpace, cont1_lf11.getNodeType().getNamespace().toString());
+        assertEquals("lf11" + suf, cont1_lf11.getNodeType().getLocalName());
+        assertEquals((short) 100, cont1_lf11.getValue());
+    }
+
+    private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName,
+            int moduleCount, String resultLocalName, String resultNamespace) {
+        CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlPath, false, XmlToCompositeNodeProvider.INSTANCE);
+        assertNotNull(compositeNode);
+
+        Set<Module> modules = TestUtils.loadModulesFrom(yangPath);
+        assertEquals(moduleCount, modules.size());
+
+        TestUtils.normalizeCompositeNode(compositeNode, modules, moduleName + ":" + schemaName);
+
+        SimpleNode<?> lf11 = getLf11(compositeNode);
+        assertTrue(lf11.getValue() instanceof QName);
+        QName qName = (QName) lf11.getValue();
+        assertEquals(resultLocalName, qName.getLocalName());
+        assertEquals(resultNamespace, qName.getNamespace().toString());
+    }
+
+    private SimpleNode<?> getLf11(CompositeNode compositeNode) {
+        assertEquals("cont", compositeNode.getNodeType().getLocalName());
+
+        List<Node<?>> childs = compositeNode.getChildren();
+        assertEquals(1, childs.size());
+        Node<?> nd = childs.iterator().next();
+        assertTrue(nd instanceof CompositeNode);
+        assertEquals("cont1", nd.getNodeType().getLocalName());
+
+        childs = ((CompositeNode) nd).getChildren();
+        SimpleNode<?> lf11 = null;
+        for (Node<?> child : childs) {
+            assertTrue(child instanceof SimpleNode);
+            if (child.getNodeType().getLocalName().equals("lf11")) {
+                lf11 = (SimpleNode<?>) child;
+            }
+        }
+        assertNotNull(lf11);
+        return lf11;
+    }
+
+}
index 50ab0857b79534ea1e61b956b58391d6fde87897..7c7df56133abd44e67a9a912a2e603bc817b9ed4 100644 (file)
@@ -2,391 +2,43 @@ package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test;
 
 import static org.junit.Assert.*;
 
-import java.io.*;
-import java.net.URISyntaxException;
-import java.util.List;
-import java.util.Set;
-
-import javax.ws.rs.WebApplicationException;
-
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
-import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
 import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class XmlToCnSnTest {
-    private static final Logger LOG = LoggerFactory.getLogger(XmlToCnSnTest.class);
-
-    /**
-     * top level element represents container. second level element is list with
-     * two elements.
-     */
-    @Test
-    public void testXmlDataContainer() {
-        CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-container.xml", false);
-        assertNotNull(compNode);
-        DataSchemaNode dataSchemaNode = null;
-        try {
-            dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-container-yang");
-        } catch (FileNotFoundException e) {
-            LOG.error(e.getMessage());
-            assertTrue(false);
-        }
-
-        assertNotNull(dataSchemaNode);
-        TestUtils.supplementNamespace(dataSchemaNode, compNode);
-
-        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());
-        }
+public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader {
 
-        assertEquals("", lf2.getValue());
-        assertEquals(null, lf3.getValue());
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/xml-to-cnsn/leafref");
     }
 
     @Test
-    public void testXmlDataList() {
-        CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-list.xml", false);
-        assertNotNull(compNode);
-
-        DataSchemaNode dataSchemaNode = null;
-        try {
-            dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-list-yang", "data-container-yang");
-        } catch (FileNotFoundException e) {
-            LOG.error(e.getMessage());
-        }
+    public void testXmlLeafrefToCnSn() {
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/xml-to-cnsn/leafref/xml/data.xml", false,
+                XmlToCompositeNodeProvider.INSTANCE);
+        assertNotNull(compositeNode);
         assertNotNull(dataSchemaNode);
-        TestUtils.supplementNamespace(dataSchemaNode, compNode);
-
-        String nameSpaceList = "data:list:yang";
-        String nameSpaceCont = "data:container:yang";
-        assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
-        assertEquals("cont", compNode.getNodeType().getLocalName());
-        assertEquals(3, compNode.getChildren().size());
-        CompositeNode lst1_1 = null;
-        CompositeNode lst1_2 = null;
-        int loopCount = 0;
-        for (Node<?> node : compNode.getChildren()) {
-            if (node.getNodeType().getLocalName().equals("lf1")) {
-                assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString());
-                assertTrue(node instanceof SimpleNode<?>);
-                assertEquals("lf1", node.getValue());
-            } else {
-                assertTrue(node instanceof CompositeNode);
-                switch (loopCount++) {
-                case 0:
-                    lst1_1 = (CompositeNode) node;
-                    break;
-                case 1:
-                    lst1_2 = (CompositeNode) node;
-                    break;
-                }
-                assertEquals(nameSpaceCont, node.getNodeType().getNamespace().toString());
-            }
-        }
-        // lst1_1
-        verifyCommonPartAOfXml(lst1_1, "1", nameSpaceCont);
-        // :lst1_1
-
-        // lst1_2
-        SimpleNode<?> lflst11 = null;
-        CompositeNode cont11 = null;
-        for (Node<?> node : lst1_2.getChildren()) {
-            String nodeName = node.getNodeType().getLocalName();
-            if (nodeName.equals("lflst11")) {
-                assertTrue(node instanceof SimpleNode<?>);
-                lflst11 = (SimpleNode<?>) node;
-
-            } else if (nodeName.equals("cont11")) {
-                assertTrue(node instanceof CompositeNode);
-                cont11 = (CompositeNode) node;
-            }
-            assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
-        }
-        assertEquals("221", lflst11.getValue());
-
-        assertEquals(1, cont11.getChildren().size());
-        assertTrue(cont11.getChildren().get(0) instanceof SimpleNode<?>);
-        SimpleNode<?> cont11_lf111 = (SimpleNode<?>) cont11.getChildren().get(0);
-        assertEquals(nameSpaceCont, cont11_lf111.getNodeType().getNamespace().toString());
-        assertEquals("lf111", cont11_lf111.getNodeType().getLocalName());
-        assertEquals((short) 100, cont11_lf111.getValue());
-        // :lst1_2
-
-    }
-
-    @Test
-    public void testXmlEmptyData() {
-        CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/empty-data.xml", true);
-        assertEquals("cont", compNode.getNodeType().getLocalName());
-        SimpleNode<?> lf1 = null;
-        SimpleNode<?> lflst1_1 = null;
-        SimpleNode<?> lflst1_2 = null;
-        CompositeNode lst1 = null;
-        int lflst1Count = 0;
-        for (Node<?> node : compNode.getChildren()) {
-            if (node.getNodeType().getLocalName().equals("lf1")) {
-                assertTrue(node instanceof SimpleNode<?>);
-                lf1 = (SimpleNode<?>) node;
-            } else if (node.getNodeType().getLocalName().equals("lflst1")) {
-                assertTrue(node instanceof SimpleNode<?>);
-
-                switch (lflst1Count++) {
-                case 0:
-                    lflst1_1 = (SimpleNode<?>) node;
-                    break;
-                case 1:
-                    lflst1_2 = (SimpleNode<?>) node;
-                    break;
-                }
-            } else if (node.getNodeType().getLocalName().equals("lst1")) {
-                assertTrue(node instanceof CompositeNode);
-                lst1 = (CompositeNode) node;
-            }
-        }
-
-        assertNotNull(lf1);
-        assertNotNull(lflst1_1);
-        assertNotNull(lflst1_2);
-        assertNotNull(lst1);
-
-        assertEquals("", lf1.getValue());
-        assertEquals("", lflst1_1.getValue());
-        assertEquals("", lflst1_2.getValue());
-        assertEquals(1, lst1.getChildren().size());
-        assertEquals("lf11", lst1.getChildren().get(0).getNodeType().getLocalName());
-
-        assertTrue(lst1.getChildren().get(0) instanceof SimpleNode<?>);
-        assertEquals("", lst1.getChildren().get(0).getValue());
-
-    }
-
-    /**
-     * Test case like this <lf11 xmlns:x="namespace">x:identity</lf11>
-     */
-    @Test
-    public void testIdentityrefNmspcInElement() {
-        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml", "/xml-to-cnsn/identityref",
-                "identityref-module", "cont", 2, "iden", "identity:module");
-    }
+        TestUtils.normalizeCompositeNode(compositeNode, modules, schemaNodePath);
 
-    /**
-     * 
-     * Test case like <lf11 xmlns="namespace1"
-     * xmlns:x="namespace">identity</lf11>
-     */
-
-    @Test
-    public void testIdentityrefDefaultNmspcInElement() {
-        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml",
-                "/xml-to-cnsn/identityref/yang-augments", "general-module", "cont", 3, "iden", "identityref:module");
-    }
-
-    /**
-     * 
-     * Test case like <cont1 xmlns="namespace1"> <lf11
-     * xmlns:x="namespace">identity</lf11> </cont1>
-     */
-    @Test
-    public void testIdentityrefDefaultNmspcInParrentElement() {
-        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml",
-                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
-    }
-
-    /**
-     * 
-     * Test case like <cont1 xmlns="namespace1" xmlns:x="namespace">
-     * <lf11>x:identity</lf11> </cont1>
-     */
-    @Test
-    public void testIdentityrefNmspcInParrentElement() {
-        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml",
-                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "z:namespace");
-
-    }
-
-    /**
-     * 
-     * Test case like (without namespace in xml) <cont1> <lf11>x:identity</lf11>
-     * </cont1>
-     */
-    @Test
-    public void testIdentityrefNoNmspcValueWithPrefix() {
-        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml",
-                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "x:iden", "identityref:module");
-    }
-
-    /**
-     * 
-     * Test case like (without namespace in xml) <cont1> <lf11>identity</lf11>
-     * </cont1>
-     */
-    @Test
-    public void testIdentityrefNoNmspcValueWithoutPrefix() {
-        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml",
-                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
-    }
-
-    private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) {
-        SimpleNode<?> lf1suf = null;
-        SimpleNode<?> lflst1suf_1 = null;
-        SimpleNode<?> lflst1suf_2 = null;
-        SimpleNode<?> lflst1suf_3 = null;
-        CompositeNode cont1suf = null;
-        CompositeNode lst1suf = null;
-
-        int lflstCount = 0;
+        assertEquals("cont", compositeNode.getNodeType().getLocalName());
 
-        for (Node<?> node : compNode.getChildren()) {
-            String localName = node.getNodeType().getLocalName();
-            if (localName.equals("lf1" + suf)) {
-                assertTrue(node instanceof SimpleNode<?>);
-                lf1suf = (SimpleNode<?>) node;
-            } else if (localName.equals("lflst1" + suf)) {
-                assertTrue(node instanceof SimpleNode<?>);
-                switch (lflstCount++) {
-                case 0:
-                    lflst1suf_1 = (SimpleNode<?>) node;
-                    break;
-                case 1:
-                    lflst1suf_2 = (SimpleNode<?>) node;
-                    break;
-                case 2:
-                    lflst1suf_3 = (SimpleNode<?>) node;
+        SimpleNode<?> lf2 = null;
+        for (Node<?> childNode : compositeNode.getChildren()) {
+            if (childNode instanceof SimpleNode) {
+                if (childNode.getNodeType().getLocalName().equals("lf2")) {
+                    lf2 = (SimpleNode<?>) childNode;
                     break;
                 }
-            } else if (localName.equals("lst1" + suf)) {
-                assertTrue(node instanceof CompositeNode);
-                lst1suf = (CompositeNode) node;
-            } else if (localName.equals("cont1" + suf)) {
-                assertTrue(node instanceof CompositeNode);
-                cont1suf = (CompositeNode) node;
             }
-            assertEquals(nameSpace, node.getNodeType().getNamespace().toString());
         }
 
-        assertNotNull(lf1suf);
-        assertNotNull(lflst1suf_1);
-        assertNotNull(lflst1suf_2);
-        assertNotNull(lflst1suf_3);
-        assertNotNull(lst1suf);
-        assertNotNull(cont1suf);
-
-        assertEquals("str0", lf1suf.getValue());
-        assertEquals("121", lflst1suf_1.getValue());
-        assertEquals("131", lflst1suf_2.getValue());
-        assertEquals("str1", lflst1suf_3.getValue());
-
-        assertEquals(1, lst1suf.getChildren().size());
-
-        assertTrue(lst1suf.getChildren().get(0) instanceof SimpleNode<?>);
-        SimpleNode<?> lst11_lf11 = (SimpleNode<?>) lst1suf.getChildren().get(0);
-        assertEquals(nameSpace, lst11_lf11.getNodeType().getNamespace().toString());
-        assertEquals("lf11" + suf, lst11_lf11.getNodeType().getLocalName());
-        assertEquals("str2", lst11_lf11.getValue());
-
-        assertTrue(cont1suf.getChildren().get(0) instanceof SimpleNode<?>);
-        SimpleNode<?> cont1_lf11 = (SimpleNode<?>) cont1suf.getChildren().get(0);
-        assertEquals(nameSpace, cont1_lf11.getNodeType().getNamespace().toString());
-        assertEquals("lf11" + suf, cont1_lf11.getNodeType().getLocalName());
-        assertEquals((short) 100, cont1_lf11.getValue());
-    }
-
-    private CompositeNode compositeNodeFromXml(String xmlPath, boolean dummyNamespaces) {
-        XmlToCompositeNodeProvider xmlToCompositeNodeProvider = XmlToCompositeNodeProvider.INSTANCE;
-        try {
-            InputStream xmlStream = XmlToCnSnTest.class.getResourceAsStream(xmlPath);
-            CompositeNode compositeNode = xmlToCompositeNodeProvider.readFrom(null, null, null, null, null, xmlStream);
-            if (dummyNamespaces) {
-                try {
-                    TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode);
-                    return ((CompositeNodeWrapper) compositeNode).unwrap();
-                } catch (URISyntaxException e) {
-                    LOG.error(e.getMessage());
-                    assertTrue(e.getMessage(), false);
-                }
-            }
-            return compositeNode;
-
-        } catch (WebApplicationException | IOException e) {
-            LOG.error(e.getMessage());
-            assertTrue(false);
-        }
-        return null;
-    }
-
-    private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName,
-            int moduleCount, String resultLocalName, String resultNamespace) {
-        CompositeNode compositeNode = compositeNodeFromXml(xmlPath, false);
-        assertNotNull(compositeNode);
-
-        Set<Module> modules = TestUtils.resolveModules(yangPath);
-        assertEquals(moduleCount, modules.size());
-        Module module = TestUtils.resolveModule(moduleName, modules);
-        assertNotNull(module);
-        DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null);
-        assertNotNull(dataSchemaNode);
-
-        TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, moduleName + ":" + schemaName);
-
-        SimpleNode<?> lf11 = getLf11(compositeNode);
-        assertTrue(lf11.getValue() instanceof QName);
-        QName qName = (QName) lf11.getValue();
-        assertEquals(resultLocalName, qName.getLocalName());
-        assertEquals(resultNamespace, qName.getNamespace().toString());
-
-    }
-
-    private SimpleNode<?> getLf11(CompositeNode compositeNode) {
-        assertEquals("cont", compositeNode.getNodeType().getLocalName());
-
-        List<Node<?>> childs = compositeNode.getChildren();
-        assertEquals(1, childs.size());
-        Node<?> nd = childs.iterator().next();
-        assertTrue(nd instanceof CompositeNode);
-        assertEquals("cont1", nd.getNodeType().getLocalName());
-
-        childs = ((CompositeNode) nd).getChildren();
-        SimpleNode<?> lf11 = null;
-        for (Node<?> child : childs) {
-            assertTrue(child instanceof SimpleNode);
-            if (child.getNodeType().getLocalName().equals("lf11")) {
-                lf11 = (SimpleNode<?>) child;
-            }
-        }
-        assertNotNull(lf11);
-        return lf11;
+        assertNotNull(lf2);
+        assertTrue(lf2.getValue() instanceof String);
+        assertEquals("121", (String) lf2.getValue());
     }
 
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang
new file mode 100644 (file)
index 0000000..a9df486
--- /dev/null
@@ -0,0 +1,13 @@
+module invalid-top-level-element {
+  namespace "invalid:top:level:element";  
+
+  prefix "intoleel";
+   revision 2013-12-17 {    
+  }
+  
+
+    leaf lf {
+        type string;
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module
new file mode 100644 (file)
index 0000000..9bdea81
--- /dev/null
@@ -0,0 +1,274 @@
+module simple-data-types {
+  namespace "simple:data:types";  
+
+  prefix "smpdtp";
+  revision 2013-11-12 {    
+  }
+  
+  identity iden {
+  }
+  
+  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; 
+         }
+         leaf lfnint8Max {
+               type int8; 
+         }
+         leaf lfnint16Min {
+               type int16; 
+         }
+         leaf lfnint16Max {
+               type int16; 
+         }
+         leaf lfnint32Min {
+               type int32; 
+         }
+         leaf lfnint32Max {
+               type int32; 
+         }
+         leaf lfnint64Min {
+               type int64; 
+         }
+         leaf lfnint64Max {
+               type int64; 
+         }
+         
+         leaf lfnuint8Max {
+               type uint8; 
+         }
+         leaf lfnuint16Max {
+               type uint16; 
+         }
+         leaf lfnuint32Max {
+               type uint32; 
+         }
+         leaf lfuint64Max {
+               type uint64; 
+         }
+         leaf lfstr {
+               type string;
+         }       
+         leaf lfstr1 {
+               type string;
+         }       
+         leaf lfbool1 {
+               type boolean;
+         }       
+         leaf lfbool2 {
+               type boolean;
+         }       
+         leaf lfbool3 {
+               type boolean;
+         }       
+         leaf lfdecimal1 {
+               type decimal64 {
+                       fraction-digits 2;
+               }       
+         }       
+         leaf lfdecimal2 {
+               type decimal64 {
+                       fraction-digits 2;
+               }       
+         }       
+         leaf lfdecimal3 {
+               type decimal64 {
+                       fraction-digits 2;
+               }       
+         }      
+          
+         leaf lfdecimal4 {
+               type decimal64 {
+                       fraction-digits 2;
+               }       
+         }
+                 
+         
+         leaf lfdecimal6 {
+               type decimal64 {
+                       fraction-digits 2;
+               }       
+         }       
+
+    leaf lfenum {
+      type enumeration {
+        enum enum1;
+        enum enum2;
+        enum enum3;
+        enum enum4;
+      }
+    }
+
+    leaf lfbits {
+      type bits {
+        bit bit1;
+        bit bit2;
+        bit bit3;
+        bit bit4;
+      }
+    }  
+    
+    leaf lfbinary {
+       type binary;
+    }  
+    
+    leaf lfref1 {                  //reference to string type
+       type leafref {
+               path "../lfstr";
+       }
+    }
+    
+    leaf lfref2 {                  //reference to number type
+       type leafref {
+               path "../lfnint8Max";
+       }
+    }
+    
+    leaf lfempty {
+       type empty;
+    }
+    
+    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;
+    }
+    
+    leaf lfunion13 {
+        type tpdfbit;    
+    }
+        
+    leaf lfunion14 {
+        type union {
+            type enumeration {
+                enum zero;
+                enum one;
+            }
+            type uint16;
+        }    
+    }    
+    
+    leaf identityref1 {
+        type identityref {
+            base iden;
+        }
+    }
+         
+         
+  }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang
new file mode 100644 (file)
index 0000000..8454784
--- /dev/null
@@ -0,0 +1,25 @@
+module module-with-choice {
+  namespace "module:with:choice";  
+
+  prefix "mowicho";
+  
+  revision 2013-12-18 {    
+  }
+  
+
+  container cont {
+    choice choA {
+        case caA1 {
+            leaf lf1 {
+                type string;
+            }
+        }
+        case caA2 {
+            leaf lf2 {
+                type string;
+            }
+        } 
+    }
+  }    
+         
+}
\ No newline at end of file
index 7023c94f2f0df55d00efaf6c675629a184deba78..81d77329c69eaa74d28c19d942ec1b2593a538ec 100644 (file)
@@ -91,6 +91,12 @@ module basic-module {
                  }
                }
                
+               leaf lfLfref {
+                 type leafref {
+                     path "/cont/lfBoolean";
+                 }    
+               }
+               
        }
          
 }
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data-rpc-input.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data-rpc-input.json
new file mode 100644 (file)
index 0000000..0eae37a
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "test-module:input":{
+        "cont":{
+            "cont1":{
+                "lf11":"lf1 data",
+                "lf12":"lf2 data"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data-rpc-input.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data-rpc-input.xml
new file mode 100644 (file)
index 0000000..5954c09
--- /dev/null
@@ -0,0 +1,8 @@
+<input xmlns="test:module">
+       <cont>
+           <cont1>
+               <lf11>lf1 data</lf11>
+               <lf12>lf2 data</lf12>
+           </cont1>
+       </cont>
+</input>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data2.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-data2/data2.xml
new file mode 100644 (file)
index 0000000..8fbc0a9
--- /dev/null
@@ -0,0 +1,6 @@
+<cont xmlns="test:module">
+    <cont1>
+           <lf11>lf1 data</lf11>
+           <lf12>lf2 data</lf12>
+    </cont1>
+</cont>
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-module/test-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-module/test-module
new file mode 100644 (file)
index 0000000..ad0716b
--- /dev/null
@@ -0,0 +1,43 @@
+module test-module {
+  namespace "test:module";
+  prefix tstmod;
+
+  revision 2014-01-09 {
+  }
+  
+  container cont {
+    container cont1 {
+        leaf lf11 {
+            type string;
+        }
+        leaf lf12 {
+            type string;
+        }
+    }
+  } 
+  
+  
+  rpc rpc-test {
+    input {
+      container cont {
+        container cont1 {
+            leaf lf11 {
+                type string;
+            }
+            leaf lf12 {
+                type string;
+            }
+        }
+      }    
+    }
+    output {
+        container cont-output {
+        }
+    } 
+  
+  }
+  
+  
+
+}
\ No newline at end of file
index 674b8b09beb2bb0e1e33559dc00a2f48d400c138..0dec051ac7380a5aa92235e4ca9deb9ca0168c9b 100644 (file)
@@ -54,6 +54,11 @@ module simple-nodes {
                leaf beer {
                    type string;
                }
+               container nonalcoholic {
+                   leaf beer {
+                       type string;
+                   }
+               }
            }
            case late-night {
                leaf chocolate {
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json
new file mode 100644 (file)
index 0000000..235666e
--- /dev/null
@@ -0,0 +1,6 @@
+{
+    "cont":{
+        "lf1":121,
+        "lf2":121
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module
new file mode 100644 (file)
index 0000000..8ca9f09
--- /dev/null
@@ -0,0 +1,19 @@
+module leafref-module {
+  namespace "leafref:module";  
+
+  prefix "lfrfmo";
+  revision 2013-11-18 {    
+  }
+
+    container cont {
+        leaf lf1 {
+            type int32;
+        }
+        leaf lf2 {
+            type leafref {
+                path "/cont/lf1"; 
+            }
+        }
+    }
+  
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json
new file mode 100644 (file)
index 0000000..abc6267
--- /dev/null
@@ -0,0 +1 @@
+fffff
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/normalize-node/yang/normalize-node-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/normalize-node/yang/normalize-node-module
new file mode 100644 (file)
index 0000000..15e68ef
--- /dev/null
@@ -0,0 +1,14 @@
+module normalize-node-module {
+  namespace "normalize:node:module";  
+
+  prefix "nonomo";
+  revision 2014-01-09 {    
+  }
+
+    container cont {
+        leaf lf1 {
+            type int32;
+        }
+    }
+  
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces.json
new file mode 100644 (file)
index 0000000..0b39dc7
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "interface":[
+        {
+            "name":"eth0",
+            "type":"ethernetCsmacd",
+            "enabled":false,
+            "description": "some interface"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.json
new file mode 100644 (file)
index 0000000..7de7fac
--- /dev/null
@@ -0,0 +1,12 @@
+{
+    "ietf-interfaces:interfaces":{
+        "interface":[
+            {
+                "name":"eth0",
+                "type":"ethernetCsmacd",
+                "enabled":false,
+                "description": "some interface"
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.xml
new file mode 100644 (file)
index 0000000..7e3aa97
--- /dev/null
@@ -0,0 +1,8 @@
+<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces" >
+       <interface>
+         <name>eth0</name>
+         <type>ethernetCsmacd</type>
+         <enabled>false</enabled>
+         <description>some interface</description>
+       </interface>
+</interfaces>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface.xml
new file mode 100644 (file)
index 0000000..755c8a9
--- /dev/null
@@ -0,0 +1,8 @@
+<interfaces xmlns="urn:ietf:params:xml:ns:yang:test-interface">
+    <interface>
+        <name>eth0</name>
+        <type>ethernetCsmacd</type>
+        <enabled>false</enabled>
+    </interface>
+</interfaces>
+
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface2.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface2.xml
new file mode 100644 (file)
index 0000000..05db4a5
--- /dev/null
@@ -0,0 +1,5 @@
+<interface>
+    <name>eth0</name>
+    <type>ethernetCsmacd</type>
+    <enabled>false</enabled>
+</interface>
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface3.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/xml/test-interface3.xml
new file mode 100644 (file)
index 0000000..e59ba17
--- /dev/null
@@ -0,0 +1,6 @@
+<class xmlns="urn:ietf:params:xml:ns:yang:test-interface2">
+    <student>
+        <name>Thomas</name>
+        <age>23</age>
+    </student>
+</class>
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/yang1/test-interface.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/yang1/test-interface.yang
new file mode 100644 (file)
index 0000000..f683a69
--- /dev/null
@@ -0,0 +1,30 @@
+module test-interface {
+    yang-version 1;
+    namespace "urn:ietf:params:xml:ns:yang:test-interface";
+    prefix "sn";
+
+    description
+        "test file";   
+
+    revision "2014-07-01" {
+        description
+            "Initial revision";
+        reference "will be defined";
+    }
+    
+    container interfaces {
+        list interface {
+            key "name";
+         
+            leaf name {
+                type string;
+            }
+            leaf type {
+                type string;
+            }
+            leaf enabled {
+                type string;
+            }
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/yang2/test-interface2.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/test-config-data/yang2/test-interface2.yang
new file mode 100644 (file)
index 0000000..13bc0eb
--- /dev/null
@@ -0,0 +1,27 @@
+module test-interface2 {
+    yang-version 1;
+    namespace "urn:ietf:params:xml:ns:yang:test-interface2";
+    prefix "snn";
+
+    description
+        "test file";   
+
+    revision "2014-08-01" {
+        description
+            "Initial revision";
+        reference "will be defined";
+    }
+    
+    container class {
+        list student {
+            key "name";
+         
+            leaf name {
+                type string;
+            }
+            leaf age {
+                type string;
+            }
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-of-several-modules/yang/module1.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-of-several-modules/yang/module1.yang
new file mode 100644 (file)
index 0000000..f6a81ae
--- /dev/null
@@ -0,0 +1,16 @@
+module module1 {
+  namespace "module:one";  
+
+  prefix "m1";
+  revision 2014-01-17 {    
+  }
+
+    container cont_m1 {
+        leaf lf1_m1 {
+            type string;
+        }
+    }
+    container contB_m1 {
+    }
+  
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-of-several-modules/yang/module2.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-of-several-modules/yang/module2.yang
new file mode 100644 (file)
index 0000000..bdd8ece
--- /dev/null
@@ -0,0 +1,17 @@
+module module2 {
+  namespace "module:two";  
+
+  prefix "m2";
+  revision 2014-01-17 {    
+  }
+
+    container cont_m2 {
+        leaf lf1_m2 {
+            type string;
+        }
+    }
+    container contB_m2 {
+    }
+
+  
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module
new file mode 100644 (file)
index 0000000..8ca9f09
--- /dev/null
@@ -0,0 +1,19 @@
+module leafref-module {
+  namespace "leafref:module";  
+
+  prefix "lfrfmo";
+  revision 2013-11-18 {    
+  }
+
+    container cont {
+        leaf lf1 {
+            type int32;
+        }
+        leaf lf2 {
+            type leafref {
+                path "/cont/lf1"; 
+            }
+        }
+    }
+  
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml
new file mode 100644 (file)
index 0000000..06200a6
--- /dev/null
@@ -0,0 +1,4 @@
+<cont>
+    <lf1>121</lf1>
+    <lf2>121</lf2>
+</cont>
\ No newline at end of file
index 521de7e394ee69fd3d5dfdda4bf8f546a1b513c0..738c2cb9a8f6375d8681a5e824b0d2f953d1a211 100644 (file)
@@ -5,12 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-/*
- * TODO: Handle multipart messages with following flag true 
- * OFPMPF_REPLY_MORE = 1 << 0
- * Better accumulate all the messages and update local cache 
- * and configurational data store
- */
+
 package org.opendaylight.controller.md.statistics.manager;
 
 import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
index 95ba01cd54bb333a6fbd6076f70f9d6581ec9530..bb5dea3bd5ad753ca7069169e32a9207b1599715 100644 (file)
@@ -44,8 +44,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllPortsStatisticsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllPortsStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutput;
@@ -177,42 +177,32 @@ public class StatisticsProvider implements AutoCloseable {
 
         for (Node targetNode : targetNodes){
             
-            InstanceIdentifier<Node> targetInstanceId = InstanceIdentifier.builder(Nodes.class).child(Node.class,targetNode.getKey()).toInstance();
-            NodeRef targetNodeRef = new NodeRef(targetInstanceId);
-            
-            System.out.println("ANIL: Target Node object ::"+targetNode.toString());
-            
-            System.out.println("ANIL: FlowCapableNode augmentations ::"+targetNode.getAugmentation(FlowCapableNode.class));
+            if(targetNode.getAugmentation(FlowCapableNode.class) != null){
+
+                spLogger.info("Send request for stats collection to node : {})",targetNode.getId());
+                
+                InstanceIdentifier<Node> targetInstanceId = InstanceIdentifier.builder(Nodes.class).child(Node.class,targetNode.getKey()).toInstance();
+                
+                NodeRef targetNodeRef = new NodeRef(targetInstanceId);
             
-            try {
+                try{
+                    sendAggregateFlowsStatsFromAllTablesRequest(targetNode.getKey());
                 
-                sendAggregateFlowsStatsFromAllTablesRequest(targetNode.getKey());
+                    sendAllFlowsStatsFromAllTablesRequest(targetNodeRef);
 
-                sendAllFlowsStatsFromAllTablesRequest(targetNodeRef);
-
-                sendAllPortStatisticsRequest(targetNodeRef);
+                    sendAllNodeConnectorsStatisticsRequest(targetNodeRef);
                 
-                sendAllFlowTablesStatisticsRequest(targetNodeRef);
+                    sendAllFlowTablesStatisticsRequest(targetNodeRef);
                 
-                sendAllQueueStatsFromAllNodeConnector (targetNodeRef);
-
-            }catch(Exception e){
-                spLogger.error("Exception occured while sending statistics requests : {}",e);
-            }
-
-            if(targetNode.getAugmentation(FlowCapableNode.class) != null){
-
-                spLogger.info("Send request for stats collection to node : {})",targetNode.getId());
-
-                try{
-                  sendAllGroupStatisticsRequest(targetNodeRef);
-                  Thread.sleep(1000);
-                  sendAllMeterStatisticsRequest(targetNodeRef);
-                  Thread.sleep(1000);
-                  sendGroupDescriptionRequest(targetNodeRef);
-                  Thread.sleep(1000);
-                  sendMeterConfigStatisticsRequest(targetNodeRef);
-                  Thread.sleep(1000);
+                    sendAllQueueStatsFromAllNodeConnector (targetNodeRef);
+
+                    sendAllGroupStatisticsRequest(targetNodeRef);
+                    
+                    sendAllMeterStatisticsRequest(targetNodeRef);
+                    
+                    sendGroupDescriptionRequest(targetNodeRef);
+                    
+                    sendMeterConfigStatisticsRequest(targetNodeRef);
                 }catch(Exception e){
                     spLogger.error("Exception occured while sending statistics requests : {}", e);
                 }
@@ -268,32 +258,19 @@ public class StatisticsProvider implements AutoCloseable {
                 this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
                         , StatsRequestType.AGGR_FLOW);
             }
+        }else{
+            spLogger.debug("No details found in data store for flow tables associated with Node {}",targetNodeKey);
         }
-        
-        //Note: Just for testing, because i am not able to fetch table list from datastore
-        // Bug-225 is raised for investigation.
-        
-//                spLogger.info("Send aggregate stats request for flow table {} to node {}",1,targetNodeKey);
-//                GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input = 
-//                        new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder();
-//                
-//                input.setNode(new NodeRef(InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).toInstance()));
-//                input.setTableId(new TableId((short)1));
-//                Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> response = 
-//                        flowStatsService.getAggregateFlowStatisticsFromFlowTableForAllFlows(input.build());`
-//                
-//                multipartMessageManager.setTxIdAndTableIdMapEntry(response.get().getResult().getTransactionId(), (short)1);
-        
     }
 
-    private void sendAllPortStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
+    private void sendAllNodeConnectorsStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
         
-        final GetAllPortsStatisticsInputBuilder input = new GetAllPortsStatisticsInputBuilder();
+        final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder();
         
         input.setNode(targetNode);
 
-        Future<RpcResult<GetAllPortsStatisticsOutput>> response = 
-                portStatsService.getAllPortsStatistics(input.build());
+        Future<RpcResult<GetAllNodeConnectorsStatisticsOutput>> response = 
+                portStatsService.getAllNodeConnectorsStatistics(input.build());
         this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
                 , StatsRequestType.ALL_PORT);
 
@@ -384,7 +361,7 @@ public class StatisticsProvider implements AutoCloseable {
     private List<Short> getTablesFromNode(NodeKey nodeKey){
         InstanceIdentifier<FlowCapableNode> nodesIdentifier = InstanceIdentifier.builder(Nodes.class).child(Node.class,nodeKey).augmentation(FlowCapableNode.class).toInstance();
         
-        FlowCapableNode node = (FlowCapableNode)dps.readConfigurationData(nodesIdentifier);
+        FlowCapableNode node = (FlowCapableNode)dps.readOperationalData(nodesIdentifier);
         List<Short> tablesId = new ArrayList<Short>();
         if(node != null && node.getTable()!=null){
             spLogger.info("Number of tables {} supported by node {}",node.getTable().size(),nodeKey);
index edffb976c6f87148badc8aa3c48b7db3595e67a1..62ba04687e67eb368f47e61f07d64d4ee3de0618 100644 (file)
@@ -7,10 +7,6 @@
  */
 package org.opendaylight.controller.md.statistics.manager;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.ConcurrentMap;
-
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
@@ -29,10 +25,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.A
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowTableStatisticsUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.NodeConnectorStatisticsUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.aggregate.flow.statistics.AggregateFlowStatisticsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
@@ -48,6 +41,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.q
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated;
@@ -90,12 +84,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericQueueStatistics;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.PortStatisticsUpdate;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatisticsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
@@ -109,6 +107,10 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdenti
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ConcurrentMap;
+
 /**
  * Class implement statistics manager related listener interface and augment all the 
  * received statistics data to data stores.
@@ -485,7 +487,7 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
                                 .child(Flow.class,existingFlow.getKey()).toInstance();
                         flowBuilder.setKey(existingFlow.getKey());
                         flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
-                        sucLogger.debug("Found matching flow in the datastore, augmenting statistics");
+                        sucLogger.info("Found matching flow in the datastore, augmenting statistics");
                         foundOriginalFlow = true;
                         it.putOperationalData(flowRef, flowBuilder.build());
                         it.commit();
@@ -495,10 +497,10 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
             }
             
             if(!foundOriginalFlow){
-                sucLogger.info("Associated original flow is not found in data store. Augmenting flow in operational data st");
-                //TODO: Temporary fix: format [ 0+tableid+0+unaccounted flow counter]
-                long flowKey = Long.getLong(new String("0"+Short.toString(tableId)+"0"+Integer.toString(this.unaccountedFlowsCounter)));
-                FlowKey newFlowKey = new FlowKey(new FlowId(flowKey));
+                sucLogger.debug("Associated original flow is not found in data store. Augmenting flow in operational data store");
+                //TODO: Temporary fix: format [ 1+tableid+1+unaccounted flow counter]
+                long flowKey = Long.parseLong(new String("1"+Short.toString(tableId)+"1"+Integer.toString(this.unaccountedFlowsCounter)));
+                FlowKey newFlowKey = new FlowKey(new FlowId(Long.toString(flowKey)));
                 InstanceIdentifier<Flow> flowRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
                         .augmentation(FlowCapableNode.class)
                         .child(Table.class, new TableKey(tableId))
@@ -554,7 +556,7 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
     }
 
     @Override
-    public void onPortStatisticsUpdate(PortStatisticsUpdate notification) {
+    public void onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
         //Check if response is for the request statistics-manager sent.
         if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
             return;
@@ -714,28 +716,6 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
         
     }
 
-    @Override
-    public void onFlowStatisticsUpdated(FlowStatisticsUpdated notification) {
-        // TODO Auto-generated method stub
-        //TODO: Depricated, will clean it up once sal-compatibility is fixed.
-        //Sal-Compatibility code usage this notification event.
-        
-    }
-
-    @Override
-    public void onFlowTableStatisticsUpdated(FlowTableStatisticsUpdated notification) {
-        // TODO Auto-generated method stub
-        //TODO: Need to implement it yet
-        
-    }
-
-    @Override
-    public void onNodeConnectorStatisticsUpdated(NodeConnectorStatisticsUpdated notification) {
-        // TODO Auto-generated method stub
-        //TODO: Need to implement it yet
-        
-    }
-
     private NodeRef getNodeRef(NodeKey nodeKey){
         InstanceIdentifierBuilder<?> builder = InstanceIdentifier.builder(Nodes.class).child(Node.class, nodeKey);
         return new NodeRef(builder.toInstance());
@@ -770,14 +750,8 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
             if (storedFlow.getMatch() != null) {
                 return false;
             }
-        } else if(!statsFlow.getMatch().equals(storedFlow.getMatch())) {
-            return false;
-        }
-        if (statsFlow.getCookie()== null) {
-            if (storedFlow.getCookie()!= null) {
-                return false;
-            }
-        } else if(!statsFlow.getCookie().equals(storedFlow.getCookie())) {
+        } //else if(!statsFlow.getMatch().equals(storedFlow.getMatch())) {
+        else if(!matchEquals(statsFlow.getMatch(), storedFlow.getMatch())) {
             return false;
         }
         if (statsFlow.getHardTimeout() == null) {
@@ -810,5 +784,177 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
         }
         return true;
     }
+    
+    /**
+     * Explicit equals method to compare the 'match' for flows stored in the data-stores and flow fetched from the switch.
+     * Usecase: e.g If user don't set any ethernet source and destination address for match,data store will store null for 
+     * these address.
+     * e.g [_ethernetMatch=EthernetMatch [_ethernetDestination=null, _ethernetSource=null, _ethernetType=
+     * EthernetType [_type=EtherType [_value=2048], _mask=null, augmentation=[]]
+     * 
+     * But when you fetch the flows from switch, openflow driver library converts all zero bytes of mac address in the 
+     * message stream to 00:00:00:00:00:00. Following string shows how library interpret the zero mac address bytes and 
+     * eventually when translator convert it to MD-SAL match, this is how it looks 
+     * [_ethernetDestination=EthernetDestination [_address=MacAddress [_value=00:00:00:00:00:00], _mask=null, augmentation=[]], 
+     * _ethernetSource=EthernetSource [_address=MacAddress [_value=00:00:00:00:00:00], _mask=null, augmentation=[]], 
+     * _ethernetType=EthernetType [_type=EtherType [_value=2048], _mask=null, augmentation=[]]
+     * 
+     * Similarly for inPort, if user/application don't set any value for it, FRM will store null value for it in data store. 
+     * When we fetch the same flow (with its statistics) from switch, plugin converts its value to openflow:X:0.
+     *  e.g _inPort=Uri [_value=openflow:1:0]  
+     * 
+     * So this custom equals method add additional check to take care of these scenario, in case any match element is null in data-store-flow, but not
+     * in the flow fetched from switch.
+     * 
+     * @param statsFlow
+     * @param storedFlow
+     * @return
+     */
+    public boolean matchEquals(Match statsFlow, Match storedFlow) {
+        if (statsFlow == storedFlow) {
+            return true;
+        }
+        if (storedFlow.getClass() != statsFlow.getClass()) {
+            return false;
+        }
+        if (storedFlow.getEthernetMatch() == null) {
+            if (statsFlow.getEthernetMatch() != null) {
+                if(!statsFlow.getEthernetMatch().getEthernetDestination().getAddress().getValue().equals("00:00:00:00:00:00") ||
+                        !statsFlow.getEthernetMatch().getEthernetSource().getAddress().getValue().equals("00:00:00:00:00:00")){
+                    return false;
+                }
+            }
+        } else if(!EthernetMatchEquals(statsFlow.getEthernetMatch(),storedFlow.getEthernetMatch())) {
+            return false;
+        }
+        if (storedFlow.getIcmpv4Match()== null) {
+            if (statsFlow.getIcmpv4Match() != null) {
+                return false;
+            }
+        } else if(!storedFlow.getIcmpv4Match().equals(statsFlow.getIcmpv4Match())) {
+            return false;
+        }
+        if (storedFlow.getIcmpv6Match() == null) {
+            if (statsFlow.getIcmpv6Match() != null) {
+                return false;
+            }
+        } else if(!storedFlow.getIcmpv6Match().equals(statsFlow.getIcmpv6Match())) {
+            return false;
+        }
+        if (storedFlow.getInPhyPort() == null) {
+            if (statsFlow.getInPhyPort() != null) {
+                return false;
+            }
+        } else if(!storedFlow.getInPhyPort().equals(statsFlow.getInPhyPort())) {
+            return false;
+        }
+        if (storedFlow.getInPort()== null) {
+            if (statsFlow.getInPort() != null) {
+                String[] portArr = statsFlow.getInPort().getValue().split(":");
+                if(portArr.length >= 3){
+                    if(Integer.parseInt(portArr[2]) != 0){
+                        return false;
+                    }
+                }
+            }
+        } else if(!storedFlow.getInPort().equals(statsFlow.getInPort())) {
+            return false;
+        }
+        if (storedFlow.getIpMatch()== null) {
+            if (statsFlow.getIpMatch() != null) {
+                return false;
+            }
+        } else if(!storedFlow.getIpMatch().equals(statsFlow.getIpMatch())) {
+            return false;
+        }
+        if (storedFlow.getLayer3Match()== null) {
+            if (statsFlow.getLayer3Match() != null) {
+                Ipv4Match ipv4Match = (Ipv4Match)statsFlow.getLayer3Match();
+                if(!ipv4Match.getIpv4Source().getValue().equals("0.0.0.0/0") ||
+                        !ipv4Match.getIpv4Destination().getValue().equals("0.0.0.0/0")){
+                    return false;
+                }
+            }
+        } else if(!storedFlow.getLayer3Match().equals(statsFlow.getLayer3Match())) {
+            return false;
+        }
+        if (storedFlow.getLayer4Match()== null) {
+            if (statsFlow.getLayer4Match() != null) {
+                TcpMatch tcpMatch = (TcpMatch)statsFlow.getLayer4Match();
+                if(!tcpMatch.getTcpDestinationPort().getValue().equals(0) ||
+                    !tcpMatch.getTcpSourcePort().getValue().equals(0)){
+                        return false;
+                }
+            }
+        } else if(!storedFlow.getLayer4Match().equals(statsFlow.getLayer4Match())) {
+            return false;
+        }
+        if (storedFlow.getMetadata() == null) {
+            if (statsFlow.getMetadata() != null) {
+                return false;
+            }
+        } else if(!storedFlow.getMetadata().equals(statsFlow.getMetadata())) {
+            return false;
+        }
+        if (storedFlow.getProtocolMatchFields() == null) {
+            if (statsFlow.getProtocolMatchFields() != null) {
+                return false;
+            }
+        } else if(!storedFlow.getProtocolMatchFields().equals(statsFlow.getProtocolMatchFields())) {
+            return false;
+        }
+        if (storedFlow.getTunnel()== null) {
+            if (statsFlow.getTunnel() != null) {
+                return false;
+            }
+        } else if(!storedFlow.getTunnel().equals(statsFlow.getTunnel())) {
+            return false;
+        }
+        if (storedFlow.getVlanMatch()== null) {
+            if (statsFlow.getVlanMatch() != null) {
+                VlanMatch vlanMatch = statsFlow.getVlanMatch();
+                if(!vlanMatch.getVlanId().getVlanId().getValue().equals(0) ||
+                        !vlanMatch.getVlanPcp().getValue().equals((short)0)){
+                    return false;
+                }
+            }
+        } else if(!storedFlow.getVlanMatch().equals(statsFlow.getVlanMatch())) {
+            return false;
+        }
+        return true;
+    }
 
+    public boolean EthernetMatchEquals(EthernetMatch statsEtherMatch, EthernetMatch storedEtherMatch) {
+        if (statsEtherMatch == storedEtherMatch) {
+            return true;
+        }
+        if (storedEtherMatch.getEthernetDestination()== null) {
+            if (statsEtherMatch.getEthernetDestination() != null) {
+                if(!statsEtherMatch.getEthernetDestination().getAddress().getValue().equals("00:00:00:00:00:00")){
+                    return false;
+                }
+            }
+        } else if(!storedEtherMatch.getEthernetDestination().equals(statsEtherMatch.getEthernetDestination())) {
+            return false;
+        }
+        if (storedEtherMatch.getEthernetSource() == null) {
+            if (statsEtherMatch.getEthernetSource() != null) {
+                if(!statsEtherMatch.getEthernetSource().getAddress().getValue().equals("00:00:00:00:00:00")){
+                    return false;
+                }
+            }
+        } else if(!storedEtherMatch.getEthernetSource().equals(statsEtherMatch.getEthernetSource())) {
+            return false;
+        }
+        if (storedEtherMatch.getEthernetType() == null) {
+            if (statsEtherMatch.getEthernetType() != null) {
+                if(!statsEtherMatch.getEthernetType().getType().getValue().equals(0)){
+                    return false;
+                }
+            }
+        } else if(!storedEtherMatch.getEthernetType().equals(statsEtherMatch.getEthernetType())) {
+            return false;
+        }
+        return true;
+    }
 }
index 8569783ad79818056eb45303692ec869f57c0671..e49fb33780dd1b16d2dbcaf47245e80611c652d4 100644 (file)
             <artifactId>jersey-client</artifactId>
             <version>${jersey.version}</version>
         </dependency>
-        <dependency>
-            <groupId>com.sun.jersey</groupId>
-            <artifactId>jersey-json</artifactId>
-            <version>${jersey.version}</version>
-        </dependency>
+
         <dependency>
             <groupId>eclipselink</groupId>
             <artifactId>javax.resource</artifactId>
index fda1e264e6babd472799340faeda579174c497b8..b8ebedfdfbdf36034f203e8f66e3c9796e7a8327 100644 (file)
@@ -182,10 +182,13 @@ public class ServiceProviderController {
 
                 // Northbound bundles
                 mavenBundle("org.opendaylight.controller", "commons.northbound").versionAsInProject(),
-                mavenBundle("org.codehaus.jackson", "jackson-mapper-asl").versionAsInProject(),
-                mavenBundle("org.codehaus.jackson", "jackson-core-asl").versionAsInProject(),
-                mavenBundle("org.codehaus.jackson", "jackson-jaxrs").versionAsInProject(),
-                mavenBundle("org.codehaus.jackson", "jackson-xc").versionAsInProject(),
+
+                mavenBundle("com.fasterxml.jackson.core", "jackson-annotations").versionAsInProject(),
+                mavenBundle("com.fasterxml.jackson.core", "jackson-core").versionAsInProject(),
+                mavenBundle("com.fasterxml.jackson.core", "jackson-databind").versionAsInProject(),
+                mavenBundle("com.fasterxml.jackson.jaxrs", "jackson-jaxrs-json-provider").versionAsInProject(),
+                mavenBundle("com.fasterxml.jackson.module", "jackson-module-jaxb-annotations").versionAsInProject(),
+
                 mavenBundle("org.codehaus.jettison", "jettison").versionAsInProject(),
 
                 mavenBundle("commons-io", "commons-io").versionAsInProject(),
@@ -318,8 +321,6 @@ public class ServiceProviderController {
                 mavenBundle("com.sun.jersey", "jersey-client").versionAsInProject(),
                 mavenBundle("com.sun.jersey", "jersey-server").versionAsInProject().startLevel(2),
                 mavenBundle("com.sun.jersey", "jersey-core").versionAsInProject().startLevel(2),
-                mavenBundle("com.sun.jersey", "jersey-json").versionAsInProject().startLevel(2),
-
                 junitBundles());
     }
 
diff --git a/opendaylight/md-sal/topology-lldp-discovery/pom.xml b/opendaylight/md-sal/topology-lldp-discovery/pom.xml
new file mode 100644 (file)
index 0000000..ed94c8d
--- /dev/null
@@ -0,0 +1,129 @@
+<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>
+        <relativePath>../</relativePath>
+    </parent>
+    <groupId>org.opendaylight.controller.md</groupId>
+    <artifactId>topology-lldp-discovery</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>
+    </scm>
+    <properties>
+        <guava.version>14.0.1</guava.version>
+        <xtend.version>2.4.3</xtend.version>
+        <bundle.plugin.version>2.4.0</bundle.plugin.version>
+        <maven.clean.plugin.version>2.5</maven.clean.plugin.version>
+    </properties>
+    <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.model</groupId>
+            <artifactId>model-flow-service</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>    
+           <dependency>
+             <groupId>org.opendaylight.controller.model</groupId>
+             <artifactId>model-flow-base</artifactId>
+             <version>1.0-SNAPSHOT</version>
+           </dependency>
+          <dependency>
+             <groupId>org.opendaylight.controller.model</groupId>
+             <artifactId>model-flow-management</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.eclipse.xtend</groupId>
+            <artifactId>org.eclipse.xtend.lib</artifactId>
+        </dependency>
+         <dependency>
+               <groupId>equinoxSDK381</groupId>
+               <artifactId>org.eclipse.osgi</artifactId>
+               <version>3.8.1.v20120830-144521</version>
+             </dependency>
+             <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.6</version>
+          </dependency>
+          <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+          </dependency>
+          <dependency>
+                   <groupId>commons-codec</groupId>
+                   <artifactId>commons-codec</artifactId>
+                   <version>1.8</version>
+                 </dependency>
+    <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal</artifactId>
+            <version>0.7.0-SNAPSHOT</version>
+        </dependency>
+             
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Bundle-Activator>org.opendaylight.md.controller.topology.lldp.LLDPActivator</Bundle-Activator>
+                        <Export-Package>org.opendaylight.md.controller.topology.lldp.utils</Export-Package>
+                        <Embed-Dependency>commons-lang</Embed-Dependency>>
+                        <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+                    </instructions>
+                    <manifestLocation>${project.basedir}/META-INF</manifestLocation>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.eclipse.xtend</groupId>
+                <artifactId>xtend-maven-plugin</artifactId>
+                <executions>
+                  <execution>
+                      <goals>
+                          <goal>compile</goal>
+                      </goals>
+                      <configuration>
+                          <outputDirectory>${basedir}/src/main/xtend-gen</outputDirectory>
+                      </configuration>
+                  </execution>
+              </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-clean-plugin</artifactId>
+                <configuration>
+                    <filesets>
+                        <fileset>
+                            <directory>${basedir}/src/main/xtend-gen</directory>
+                            <includes>
+                                <include>**</include>
+                            </includes>
+                        </fileset>
+                    </filesets>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend
new file mode 100644 (file)
index 0000000..674e919
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.md.controller.topology.lldp
+
+import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.osgi.framework.BundleContext
+
+class LLDPActivator extends AbstractBindingAwareProvider {
+
+    static var LLDPDiscoveryProvider provider = new LLDPDiscoveryProvider();
+
+    override onSessionInitiated(ProviderContext session) {
+        provider.dataService = session.getSALService(DataProviderService)
+        provider.notificationService = session.getSALService(NotificationProviderService)
+        provider.start();
+    }
+
+    override protected stopImpl(BundleContext context) {
+        provider.close();
+    }
+
+}
diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryListener.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryListener.java
new file mode 100644 (file)
index 0000000..095d12e
--- /dev/null
@@ -0,0 +1,34 @@
+package org.opendaylight.md.controller.topology.lldp;
+
+import org.opendaylight.md.controller.topology.lldp.utils.LLDPDiscoveryUtils;
+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.LinkDiscoveredBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class LLDPDiscoveryListener implements PacketProcessingListener {
+    static Logger LOG = LoggerFactory.getLogger(LLDPDiscoveryListener.class);
+
+    private LLDPDiscoveryProvider manager;
+
+    LLDPDiscoveryListener(LLDPDiscoveryProvider manager) {
+        this.manager = manager;
+    }
+    
+    public void onPacketReceived(PacketReceived lldp) {
+        NodeConnectorRef src = LLDPDiscoveryUtils.lldpToNodeConnectorRef(lldp.getPayload());
+        if(src != null) {
+            LinkDiscoveredBuilder ldb = new LinkDiscoveredBuilder();
+            ldb.setDestination(lldp.getIngress());
+            ldb.setSource(new NodeConnectorRef(src));
+            LinkDiscovered ld = ldb.build();
+            
+            manager.getNotificationService().publish(ld);
+            LLDPLinkAger.getInstance().put(ld);
+        }
+    }
+    
+}
diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend
new file mode 100644 (file)
index 0000000..fc724ac
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.md.controller.topology.lldp
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.yangtools.yang.binding.NotificationListener
+import org.slf4j.LoggerFactory
+
+class LLDPDiscoveryProvider implements AutoCloseable {
+
+
+    static val LOG = LoggerFactory.getLogger(LLDPDiscoveryProvider);
+
+    @Property
+    DataProviderService dataService;        
+
+    @Property
+    NotificationProviderService notificationService;
+
+    val LLDPDiscoveryListener commiter = new LLDPDiscoveryListener(this);
+
+    Registration<NotificationListener> listenerRegistration
+
+    def void start() {
+        listenerRegistration = notificationService.registerNotificationListener(commiter);
+        LLDPLinkAger.instance.manager = this;
+        LOG.info("LLDPDiscoveryListener Started.");
+        
+    }   
+    
+    override close() {
+       LOG.info("LLDPDiscoveryListener stopped.");
+        listenerRegistration?.close();
+        LLDPLinkAger.instance.close();
+    }
+    
+}
+
+
diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPLinkAger.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPLinkAger.java
new file mode 100644 (file)
index 0000000..171783b
--- /dev/null
@@ -0,0 +1,65 @@
+package org.opendaylight.md.controller.topology.lldp;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.Timer;
+import java.util.Map.Entry;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.opendaylight.md.controller.topology.lldp.utils.LLDPDiscoveryUtils;
+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.LinkRemovedBuilder;
+
+
+public class LLDPLinkAger {
+    private static final LLDPLinkAger instance = new LLDPLinkAger();
+    private Map<LinkDiscovered,Date> linkToDate = new ConcurrentHashMap<LinkDiscovered,Date>();
+    private LLDPDiscoveryProvider manager;
+    private Timer timer = new Timer();
+
+    public LLDPDiscoveryProvider getManager() {
+        return manager;
+    }
+    public void setManager(LLDPDiscoveryProvider manager) {
+        this.manager = manager;
+    }
+    private LLDPLinkAger() {
+        timer.schedule(new LLDPAgingTask(), 0,LLDPDiscoveryUtils.LLDP_INTERVAL);
+    }
+    public static LLDPLinkAger getInstance() {
+        return instance;
+    }
+    
+    public void put(LinkDiscovered link) {
+        Date expires = new Date();
+        expires.setTime(expires.getTime() + LLDPDiscoveryUtils.LLDP_EXPIRATION_TIME);
+        linkToDate.put(link, expires);
+    }
+    
+    public void close() {
+        timer.cancel();
+    }
+    
+    private class LLDPAgingTask extends TimerTask {
+
+        @Override
+        public void run() {
+            for (Entry<LinkDiscovered,Date> entry : linkToDate.entrySet()) {
+                LinkDiscovered link = entry.getKey();
+                Date expires = entry.getValue();
+                Date now = new Date();
+                if(now.after(expires)) {
+                    if(getInstance().getManager() != null) {
+                        LinkRemovedBuilder lrb = new LinkRemovedBuilder(link);
+                        getInstance().getManager().getNotificationService().publish(lrb.build());
+                        linkToDate.remove(link);
+                    }
+                }
+            }
+            
+        }
+        
+    }
+}
+
diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/utils/LLDPDiscoveryUtils.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/utils/LLDPDiscoveryUtils.java
new file mode 100644 (file)
index 0000000..c0bcbaa
--- /dev/null
@@ -0,0 +1,72 @@
+package org.opendaylight.md.controller.topology.lldp.utils;
+
+import java.nio.charset.Charset;
+
+import org.opendaylight.controller.sal.packet.Ethernet;
+import org.opendaylight.controller.sal.packet.LLDP;
+import org.opendaylight.controller.sal.packet.LLDPTLV;
+import org.opendaylight.controller.sal.utils.NetUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+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.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LLDPDiscoveryUtils {
+    static Logger LOG = LoggerFactory.getLogger(LLDPDiscoveryUtils.class);
+    
+    public static final Long LLDP_INTERVAL = (long) (1000*5); // Send LLDP every five seconds
+    public static final Long LLDP_EXPIRATION_TIME = LLDP_INTERVAL*3; // Let up to three intervals pass before we decide we are expired.
+    
+    public static String macToString(byte[] mac) {
+        StringBuilder b = new StringBuilder();
+        for (int i = 0; i < mac.length; i++) {
+            b.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? ":" : ""));
+        }
+
+        return b.toString();
+    }
+    
+    public static NodeConnectorRef lldpToNodeConnectorRef(byte[] payload)  {
+        Ethernet ethPkt = new Ethernet();
+        try {
+            ethPkt.deserialize(payload, 0,payload.length * NetUtils.NumBitsInAByte);
+        } catch (Exception e) {
+            LOG.warn("Failed to decode LLDP packet {}", e);
+        }
+
+        if (ethPkt.getPayload() instanceof LLDP) {
+            LLDP lldp = (LLDP) ethPkt.getPayload();
+    
+            try {
+                NodeId srcNodeId = null;
+                NodeConnectorId srcNodeConnectorId = null;
+                for (LLDPTLV lldptlv : lldp.getOptionalTLVList()) {
+                    if (lldptlv.getType() == LLDPTLV.TLVType.Custom.getValue()) {
+                        srcNodeConnectorId = new NodeConnectorId(LLDPTLV.getCustomString(lldptlv.getValue(), lldptlv.getLength()));
+                    }
+                    if (lldptlv.getType() == LLDPTLV.TLVType.SystemName.getValue()) {
+                        String srcNodeIdString = new String(lldptlv.getValue(),Charset.defaultCharset());
+                        srcNodeId = new NodeId(srcNodeIdString);
+                    }
+                }
+                if(srcNodeId != null && srcNodeConnectorId != null) {
+                    InstanceIdentifier<NodeConnector> srcInstanceId = InstanceIdentifier.builder(Nodes.class)
+                            .child(Node.class,new NodeKey(srcNodeId))
+                            .child(NodeConnector.class, new NodeConnectorKey(srcNodeConnectorId))
+                            .toInstance();
+                    return new NodeConnectorRef(srcInstanceId);
+                }
+            } catch (Exception e) {
+                LOG.warn("Caught exception ", e);
+            }
+        }
+        return null;
+    }
+}
index 6e50f9ce73aab798124ea7c9624cda5f881104d5..76300864fd3367092babd58b6d0d97595851e640 100644 (file)
@@ -42,7 +42,7 @@
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller.model</groupId>
-            <artifactId>model-topology-view</artifactId>
+            <artifactId>model-topology</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
         <dependency>
@@ -58,8 +58,8 @@
                 <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>
+                        <Bundle-Activator>org.opendaylight.md.controller.topology.manager.FlowCapableTopologyProvider</Bundle-Activator>
+                        <Private-Package>org.opendaylight.md.controller.topology.manager</Private-Package>
                     </instructions>
                 </configuration>
             </plugin>
index 46f5d2b406916d5f46bc9e7ab5527278a8090914..05f7fe12729384590459ed9a41bb271ca2ffa157 100644 (file)
@@ -5,7 +5,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeCon
 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.node.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
@@ -14,6 +14,17 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 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
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.SourceBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.DestinationBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.LinkBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.LinkKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.LinkId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNode
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnector
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnectorBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
 
 class FlowCapableNodeMapping {
 
@@ -29,12 +40,6 @@ class FlowCapableNodeMapping {
         (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);
     }
@@ -42,4 +47,36 @@ class FlowCapableNodeMapping {
     static def toTerminationPointId(NodeConnectorId id) {
         return new TpId(id);
     }
+    
+    static def toTopologyNode(NodeId nodeId,NodeRef invNodeRef) {
+        val nb = new NodeBuilder();
+        nb.setNodeId(nodeId)
+        val inb = new InventoryNodeBuilder
+        inb.setInventoryNodeRef(invNodeRef)
+        nb.addAugmentation(InventoryNode,inb.build)
+        return nb.build();
+    }
+    
+    static def toTerminationPoint(TpId id, NodeConnectorRef invNodeConnectorRef) {
+        val tpb = new TerminationPointBuilder
+        tpb.setTpId(id);
+        val incb = new InventoryNodeConnectorBuilder
+        incb.setInventoryNodeConnectorRef(invNodeConnectorRef)
+        tpb.addAugmentation(InventoryNodeConnector,incb.build())
+        return tpb.build();
+    }
+    
+    static def toTopologyLink(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link link) {
+        val sb = new SourceBuilder();
+        sb.setSourceNode(link.source.nodeKey.id.toToplogyNodeId)
+        sb.setSourceTp(link.source.nodeConnectorKey.id.toTerminationPointId)
+        val db = new DestinationBuilder();
+        db.setDestNode(link.destination.nodeKey.id.toToplogyNodeId)
+        db.setDestTp(link.destination.nodeConnectorKey.id.toTerminationPointId)
+        val lb = new LinkBuilder();
+        lb.setSource(sb.build())
+        lb.setDestination(db.build());
+        lb.setLinkId(new LinkId(lb.source.sourceTp.value))
+        return lb.build();
+    } 
 }
index fb129e47106a363d99f6729a3fd53490448b488c..92a2277b4c613abdf858ca28a3dbebb4c3a429f9 100644 (file)
 package org.opendaylight.md.controller.topology.manager
 
+import com.google.common.collect.FluentIterable
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated
 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.NodeConnectorRef
 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.NodeRef
 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.opendaylight.inventory.rev130819.OpendaylightInventoryListener
+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.NodeId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
 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.TopologyBuilder
 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.Link
 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.TerminationPoint
 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 org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+
 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;
+    var TopologyKey topology = new TopologyKey(new TopologyId("flow:1"));
 
     @Property
     var DataProviderService dataService;
+    
+    def start() {
+        val tb = new TopologyBuilder();
+        tb.setKey(topology);
+        val path = InstanceIdentifier.builder(NetworkTopology).child(Topology,topology).toInstance;
+        val top = tb.build();
+        val it = dataService.beginTransaction
+        putOperationalData(path,top);
+        commit()       
+    }
 
     override onNodeRemoved(NodeRemoved notification) {
-        val invNodeKey = notification.nodeRef.nodeKey
-        val tpNodeId = invNodeKey.id.toToplogyNodeId()
-        val tpNodeInstance = notification.nodeRef.toNodeIdentifier()
+        val nodeId = notification.nodeRef.nodeKey.id.toToplogyNodeId()
+        val nodeInstance = notification.nodeRef.toNodeIdentifier()
 
         val it = dataService.beginTransaction
-        removeRuntimeData(tpNodeInstance);
-        removeAffectedLinks(tpNodeId)
+        removeOperationalData(nodeInstance);
+        removeAffectedLinks(it,nodeId)
         commit()
 
     }
 
     override onNodeUpdated(NodeUpdated notification) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        val fcnu = notification.getAugmentation(FlowCapableNodeUpdated)
+        if(fcnu != null) {
+            val node = notification.id.toToplogyNodeId.toTopologyNode(notification.nodeRef)
+            val path = notification.id.toToplogyNodeId.nodePath;
+            val it = dataService.beginTransaction
+            putOperationalData(path, node);
+            commit()
+        }
     }
 
     override onNodeConnectorRemoved(NodeConnectorRemoved notification) {
-        val tpRef = notification.nodeConnectorRef.toTerminationPointIdentifier();
+        val tpInstance = notification.nodeConnectorRef.toTerminationPointIdentifier;
+        val tpId = notification.nodeConnectorRef.nodeConnectorKey.id.toTerminationPointId;
         val it = dataService.beginTransaction
-        removeRuntimeData(tpRef);
+        removeOperationalData(tpInstance);
+        removeAffectedLinks(it,tpId)
         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()
+        val fcncu = notification.getAugmentation(FlowCapableNodeConnectorUpdated)
+        if(fcncu != null) {
+            val nodeId = notification.nodeConnectorRef.nodeKey.id.toToplogyNodeId;
+            val TerminationPoint point = notification.id.toTerminationPointId.toTerminationPoint(notification.nodeConnectorRef);
+            val path = tpPath(nodeId, point.key.tpId);
+    
+            val it = dataService.beginTransaction
+            putOperationalData(path, point);
+            if((fcncu.state != null && fcncu.state.linkDown) || (fcncu.configuration != null && fcncu.configuration.PORTDOWN)) {
+                removeAffectedLinks(it,point.tpId)
+            }
+            commit()     
+       }
     }
 
     override onLinkDiscovered(LinkDiscovered notification) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        val link = notification.toTopologyLink;
+        val path = link.linkPath;
+        val it = dataService.beginTransaction
+        putOperationalData(path, link);
+        commit()
     }
 
     override onLinkOverutilized(LinkOverutilized notification) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        // NOOP
     }
 
     override onLinkRemoved(LinkRemoved notification) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
-
+        val path = notification.toTopologyLink.linkPath
+        val it = dataService.beginTransaction
+        removeOperationalData(path);
+        commit()
     }
 
     override onLinkUtilizationNormal(LinkUtilizationNormal notification) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        // NOOP
     }
 
     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).
+        return InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
             toInstance;
     }
 
@@ -107,7 +141,7 @@ OpendaylightInventoryListener //
 
     private def void removeAffectedLinks(DataModificationTransaction transaction, NodeId id) {
         val reader = TypeSafeDataReader.forReader(transaction)
-        val topologyPath = InstanceIdentifier.builder().node(NetworkTopology).child(Topology, topology).toInstance;
+        val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).toInstance;
         val topologyData = reader.readOperationalData(topologyPath);
         if (topologyData === null) {
             return;
@@ -115,18 +149,52 @@ OpendaylightInventoryListener //
         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
+            InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Link, key).toInstance
         //
         ]
         for(affectedLink : affectedLinkInstances) {
-            transaction.removeRuntimeData(affectedLink);
+            transaction.removeOperationalData(affectedLink);
         }
     }
     
+    private def void removeAffectedLinks(DataModificationTransaction transaction, TpId id) {
+        val reader = TypeSafeDataReader.forReader(transaction)
+        val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).toInstance;
+        val topologyData = reader.readOperationalData(topologyPath);
+        if (topologyData === null) {
+            return;
+        }
+        val affectedLinkInstances = FluentIterable.from(topologyData.link).filter[
+            source.sourceTp == id || destination.destTp == id].transform [
+            //
+            InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Link, key).toInstance
+        //
+        ]
+        for(affectedLink : affectedLinkInstances) {
+            transaction.removeOperationalData(affectedLink);
+        }
+    }
+    
+    private def InstanceIdentifier<Node> nodePath(NodeId nodeId) {
+        val nodeKey = new NodeKey(nodeId);
+        return InstanceIdentifier.builder(NetworkTopology)
+            .child(Topology, topology)
+            .child(Node, nodeKey)
+            .toInstance;
+    }
+    
     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).
+        return InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
             child(TerminationPoint, tpKey).toInstance;
     }
+    
+    private def InstanceIdentifier<Link> linkPath(Link link) {
+        val linkInstanceId = InstanceIdentifier.builder(NetworkTopology)
+            .child(Topology, topology)
+            .child(Link, link.key)
+            .toInstance;
+        return linkInstanceId;
+    }    
 }
diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend
new file mode 100644 (file)
index 0000000..036fe73
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.md.controller.topology.manager
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.yangtools.yang.binding.NotificationListener
+import org.slf4j.LoggerFactory
+import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
+
+class FlowCapableTopologyProvider extends AbstractBindingAwareProvider implements AutoCloseable {
+
+
+
+    static val LOG = LoggerFactory.getLogger(FlowCapableTopologyProvider);
+
+    @Property
+    DataProviderService dataService;        
+
+    @Property
+    NotificationProviderService notificationService;
+
+    val FlowCapableTopologyExporter exporter = new FlowCapableTopologyExporter();
+
+    Registration<NotificationListener> listenerRegistration
+    
+    override close() {
+       LOG.info("FlowCapableTopologyProvider stopped.");
+        listenerRegistration?.close();
+    }
+    
+    override onSessionInitiated(ProviderContext session) {
+        dataService = session.getSALService(DataProviderService)
+        notificationService = session.getSALService(NotificationProviderService)
+        exporter.setDataService(dataService);
+        exporter.start();
+        listenerRegistration = notificationService.registerNotificationListener(exporter);
+    }
+    
+}
+
+
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java
deleted file mode 100644 (file)
index 23cdabf..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes;
-
-public class AttributesConstants {
-
-    /**
-     * Property placed into object names for dependencies to preserve reference name
-     */
-    public static final String REF_NAME_ON_PROPERTY_KEY = "X-refName";
-}
index a1f46dde54ff078596b709e12e0eeeb8914e7056..dbc1b48d4f9abebe5fc89c306f65b68fcee924d2 100644 (file)
@@ -43,7 +43,6 @@ public class AttributeConfigElement {
         resolvedValue = attributeResolvingStrategy.parseAttribute(attrName, value);
         Optional<?> resolvedDefault = attributeResolvingStrategy.parseAttribute(attrName, dafaultValue);
         resolvedDefaultValue = resolvedDefault.isPresent() ? resolvedDefault.get() : null;
-
     }
 
     public static AttributeConfigElement create(Object nullableDefault, Object value) {
index fb385221c8877b9ffceadf53cd355f8c78197811..506d7d61c347016ef76a6601500ed773762dafb0 100644 (file)
@@ -16,7 +16,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 
 import javax.management.openmbean.ArrayType;
 import javax.management.openmbean.CompositeType;
@@ -27,9 +27,9 @@ import java.util.Map.Entry;
 
 public class ObjectMapper extends AttributeIfcSwitchStatement<AttributeMappingStrategy<?, ? extends OpenType<?>>> {
 
-    private final Services dependencyTracker;
+    private final ServiceRegistryWrapper dependencyTracker;
 
-    public ObjectMapper(Services depTracker) {
+    public ObjectMapper(ServiceRegistryWrapper depTracker) {
         this.dependencyTracker = depTracker;
     }
 
index 842634163607315bd018d00d43c29b1db2dd83d0..83e8086eef2507b648d918cf4592d9d7c553c1b6 100644 (file)
@@ -10,8 +10,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributesConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
 
 import javax.management.ObjectName;
@@ -20,11 +20,11 @@ import javax.management.openmbean.SimpleType;
 public class ObjectNameAttributeMappingStrategy extends
         AbstractAttributeMappingStrategy<ObjectNameAttributeMappingStrategy.MappedDependency, SimpleType<?>> {
 
-    private final Services tracker;
+    private final ServiceRegistryWrapper tracker;
     private final String serviceName;
     private final String namespace;
 
-    public ObjectNameAttributeMappingStrategy(SimpleType<?> openType, Services dependencyTracker, String serviceName, String namespace) {
+    public ObjectNameAttributeMappingStrategy(SimpleType<?> openType, ServiceRegistryWrapper dependencyTracker, String serviceName, String namespace) {
         super(openType);
         this.tracker = dependencyTracker;
         this.serviceName = serviceName;
@@ -44,10 +44,7 @@ public class ObjectNameAttributeMappingStrategy extends
 
         ObjectName on = (ObjectName) value;
 
-        String expectedRefName = on.getKeyProperty(AttributesConstants.REF_NAME_ON_PROPERTY_KEY);
-
-        String refName = expectedRefName == null ? tracker.getRefName(namespace, serviceName, on, Optional.<String> absent())
-                : tracker.getRefName(namespace, serviceName, on, Optional.of(expectedRefName));
+        String refName = ObjectNameUtil.getReferenceName(on);
 
         return Optional.of(new MappedDependency(namespace, serviceName, refName));
     }
index d8f0e2357ea0fb57063121b2758aca908b553eb5..57a44d8af0ec2d11cb30f3a86393ac015bac814c 100644 (file)
@@ -9,11 +9,8 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributesConstants;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectNameAttributeMappingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services.ServiceInstance;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -23,10 +20,10 @@ import javax.management.openmbean.SimpleType;
 
 public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResolvingStrategy<ObjectName, SimpleType<?>> {
 
-    private final Services serviceTracker;
+    private final ServiceRegistryWrapper serviceTracker;
     private static final Logger logger = LoggerFactory.getLogger(ObjectNameAttributeResolvingStrategy.class);
 
-    ObjectNameAttributeResolvingStrategy(Services serviceTracker) {
+    ObjectNameAttributeResolvingStrategy(ServiceRegistryWrapper serviceTracker) {
         super(SimpleType.OBJECTNAME);
         this.serviceTracker = serviceTracker;
     }
@@ -45,9 +42,7 @@ public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResol
         String namespace = mappedDep.getNamespace();
         logger.trace("Getting service instance by service name {} : {} and ref name {}", namespace, serviceName, refName);
 
-        ServiceInstance byRefName = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName);
-        ObjectName on = ObjectNameUtil.createReadOnlyModuleON(byRefName.getModuleName(), byRefName.getInstanceName());
-        on = ObjectNameUtil.createON(on.toString() + "," + AttributesConstants.REF_NAME_ON_PROPERTY_KEY + "=" + refName);
+        ObjectName on = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName);
 
         logger.debug("Attribute {} : {} parsed to type {}", attrName, value, getOpenType());
         return Optional.of(on);
index a3e2813fa0d383f6db78c6a2c2d52e32d03dc5e1..82c8c1ec6b537f2ca25cc585dfe4c795cd2b7350 100644 (file)
@@ -15,7 +15,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 
 import javax.management.openmbean.ArrayType;
 import javax.management.openmbean.CompositeType;
@@ -26,9 +26,9 @@ import java.util.Map.Entry;
 
 public class ObjectResolver extends AttributeIfcSwitchStatement<AttributeResolvingStrategy<?, ? extends OpenType<?>>> {
 
-    private final Services serviceTracker;
+    private final ServiceRegistryWrapper serviceTracker;
 
-    public ObjectResolver(Services serviceTracker) {
+    public ObjectResolver(ServiceRegistryWrapper serviceTracker) {
         this.serviceTracker = serviceTracker;
     }
 
index 3a5fa1170fec28922155e8e7b2748eb7393448b5..ec73cd6068662f825e9d115457174c05ef49726d 100644 (file)
@@ -14,7 +14,6 @@ import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Multimap;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 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;
@@ -99,7 +98,7 @@ public class Config {
     // }
 
     public Element toXml(Set<ObjectName> instancesToMap, Optional<String> maybeNamespace, Document document,
-            Element dataElement, Services serviceTracker) {
+            Element dataElement, ServiceRegistryWrapper serviceTracker) {
 
         Map<String, Map<String, Collection<ObjectName>>> moduleToInstances = getMappedInstances(instancesToMap,
                 moduleConfigs);
@@ -120,81 +119,84 @@ public class Config {
                 ModuleConfig mapping = moduleConfigs.get(moduleNamespace).get(moduleMappingEntry.getKey());
 
                 if (moduleMappingEntry.getValue().isEmpty()) {
-                    addEmptyModulesCommented(document, modulesElement, moduleNamespace, moduleMappingEntry);
-                } else {
-                    for (ObjectName objectName : moduleMappingEntry.getValue()) {
-                        modulesElement
-                                .appendChild(mapping.toXml(objectName, serviceTracker, document, moduleNamespace));
-                    }
+                    continue;
+                }
+
+                for (ObjectName objectName : moduleMappingEntry.getValue()) {
+                    modulesElement.appendChild(mapping.toXml(objectName, serviceTracker, document, moduleNamespace));
                 }
 
             }
         }
 
-        root.appendChild(serviceTracker.toXml(serviceTracker.getMappedServices(), document));
+        root.appendChild(Services.toXml(serviceTracker, document));
 
         return root;
     }
 
-    // TODO remove commented modules from output
-    private void addEmptyModulesCommented(Document document, Element root, String moduleNamespace,
-            Entry<String, Collection<ObjectName>> moduleMappingEntry) {
-        Element emptyModule = document.createElement(XmlNetconfConstants.MODULE_KEY);
-
-        Element typeElement = XmlUtil.createTextElement(document, XmlNetconfConstants.TYPE_KEY,
-                moduleMappingEntry.getKey());
-        emptyModule.appendChild(typeElement);
-
-        root.appendChild(document.createComment(XmlUtil.toString(emptyModule, false)));
-    }
-
     // TODO refactor, replace string representing namespace with namespace class
     // TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved
     // class
-    public ConfigElementResolved fromXml(XmlElement xml,
-                                         EditStrategyType defaultEditStrategyType, ServiceReferenceReadableRegistry taClient) {
-        Map<String, Multimap<String, ModuleElementResolved>> retVal = Maps.newHashMap();
 
-        List<XmlElement> recognisedChildren = Lists.newArrayList();
+    public Map<String, Multimap<String, ModuleElementResolved>> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) {
+        Optional<XmlElement> modulesElement = getModulesElement(xml);
+        List<XmlElement> moduleElements = getModulesElementList(modulesElement);
 
-        Services serviceTracker = fromXmlServices(xml, recognisedChildren, taClient);
-        List<XmlElement> moduleElements = fromXmlModules(xml, recognisedChildren);
-
-        xml.checkUnrecognisedElements(recognisedChildren);
+        Map<String, Multimap<String, ModuleElementResolved>> retVal = Maps.newHashMap();
 
         for (XmlElement moduleElement : moduleElements) {
-            resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType);
-        }
+            ResolvingStrategy<ModuleElementResolved> resolvingStrategy = new ResolvingStrategy<ModuleElementResolved>() {
+                @Override
+                public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) {
+                    return moduleMapping.fromXml(moduleElement, serviceTracker,
+                            instanceName, moduleNamespace, defaultStrategy);
+                }
+            };
 
-        return new ConfigElementResolved(retVal, serviceTracker);
+            resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy);
+        }
+        return retVal;
     }
 
-    public static class ConfigElementResolved {
+    /**
+     * return a map containing namespace -> moduleName -> instanceName map. Attribute parsing is omitted.
+     */
+    public Map<String, Multimap<String, ModuleElementDefinition>> fromXmlModulesMap(XmlElement xml,
+            EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) {
+        Optional<XmlElement> modulesElement = getModulesElement(xml);
+        List<XmlElement> moduleElements = getModulesElementList(modulesElement);
 
-        private final Map<String, Multimap<String, ModuleElementResolved>> resolvedModules;
-        private final Services services;
+        Map<String, Multimap<String, ModuleElementDefinition>> retVal = Maps.newHashMap();
 
-        public ConfigElementResolved(Map<String, Multimap<String, ModuleElementResolved>> retVal, Services serviceTracker) {
-            this.resolvedModules = retVal;
-            this.services = serviceTracker;
-        }
+        for (XmlElement moduleElement : moduleElements) {
+            ResolvingStrategy<ModuleElementDefinition> resolvingStrategy = new ResolvingStrategy<ModuleElementDefinition>() {
+                @Override
+                public ModuleElementDefinition resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement,
+                        ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace,
+                        EditStrategyType defaultStrategy) {
+                    // TODO: add check for conflicts between global and local
+                    // edit strategy
+                    String perInstanceEditStrategy = moduleElement.getAttribute(XmlNetconfConstants.OPERATION_ATTR_KEY,
+                            XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+                    return new ModuleElementDefinition(instanceName, perInstanceEditStrategy, defaultStrategy);
+                }
+            };
 
-        public Map<String, Multimap<String, ModuleElementResolved>> getResolvedModules() {
-            return resolvedModules;
+            resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy);
         }
+        return retVal;
+    }
 
-        public Services getServices() {
-            return services;
-        }
+    private static Optional<XmlElement> getModulesElement(XmlElement xml) {
+        return xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY,
+                    XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
     }
 
-    private List<XmlElement> fromXmlModules(XmlElement xml, List<XmlElement> recognisedChildren) {
-        Optional<XmlElement> modulesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY,
-                XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+    private List<XmlElement> getModulesElementList(Optional<XmlElement> modulesElement) {
         List<XmlElement> moduleElements;
+
         if (modulesElement.isPresent()) {
             moduleElements = modulesElement.get().getChildElementsWithSameNamespace(XmlNetconfConstants.MODULE_KEY);
-            recognisedChildren.add(modulesElement.get());
             modulesElement.get().checkUnrecognisedElements(moduleElements);
         } else {
             moduleElements = Lists.newArrayList();
@@ -202,8 +204,8 @@ public class Config {
         return moduleElements;
     }
 
-    private void resolveModule(Map<String, Multimap<String, ModuleElementResolved>> retVal, Services serviceTracker,
-            XmlElement moduleElement, EditStrategyType defaultStrategy) {
+    private <T> void resolveModule(Map<String, Multimap<String, T>> retVal, ServiceRegistryWrapper serviceTracker,
+            XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy<T> resolvingStrategy) {
         XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
         Entry<String, String> prefixToNamespace = typeElement.findNamespaceOfTextContent();
         String moduleNamespace = prefixToNamespace.getValue();
@@ -215,35 +217,49 @@ public class Config {
 
         ModuleConfig moduleMapping = getModuleMapping(moduleNamespace, instanceName, factoryName);
 
-        Multimap<String, ModuleElementResolved> innerMap = retVal.get(moduleNamespace);
+        Multimap<String, T> innerMap = retVal.get(moduleNamespace);
         if (innerMap == null) {
             innerMap = HashMultimap.create();
             retVal.put(moduleNamespace, innerMap);
         }
 
-        ModuleElementResolved moduleElementResolved = moduleMapping.fromXml(moduleElement, serviceTracker,
+        T resolvedElement = resolvingStrategy.resolveElement(moduleMapping, moduleElement, serviceTracker,
                 instanceName, moduleNamespace, defaultStrategy);
 
-        innerMap.put(factoryName, moduleElementResolved);
+        innerMap.put(factoryName, resolvedElement);
     }
 
-    private Services fromXmlServices(XmlElement xml, List<XmlElement> recognisedChildren,
-                                     ServiceReferenceReadableRegistry taClient) {
-        Optional<XmlElement> servicesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY,
-                XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+    public Services fromXmlServices(XmlElement xml) {
+        Optional<XmlElement> servicesElement = getServicesElement(xml);
 
-        Map<String, Map<String, Map<String, String>>> mappedServices;
+        Services services;
         if (servicesElement.isPresent()) {
-            mappedServices = Services.fromXml(servicesElement.get());
-            recognisedChildren.add(servicesElement.get());
+            services = Services.fromXml(servicesElement.get());
         } else {
-            mappedServices = new HashMap<>();
+            services = new Services();
         }
-        Services services = Services.resolveServices(mappedServices, taClient);
 
         return services;
     }
 
+    private static Optional<XmlElement> getServicesElement(XmlElement xml) {
+        return xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY,
+                    XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+    }
+
+    public static void checkUnrecognisedChildren(XmlElement parent) {
+        Optional<XmlElement> servicesOpt = getServicesElement(parent);
+        Optional<XmlElement> modulesOpt = getModulesElement(parent);
+
+        List<XmlElement> recognised = Lists.newArrayList();
+        if(servicesOpt.isPresent())
+            recognised.add(servicesOpt.get());
+        if(modulesOpt.isPresent())
+            recognised.add(modulesOpt.get());
+
+        parent.checkUnrecognisedElements(recognised);
+    }
+
     private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) {
         checkState(
                 factoryNameWithPrefix.startsWith(prefixOrEmptyString),
@@ -271,4 +287,8 @@ public class Config {
         return moduleMapping;
     }
 
+    private interface ResolvingStrategy<T> {
+        public T resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker,
+                String instanceName, String moduleNamespace, EditStrategyType defaultStrategy);
+    }
 }
index aae1636165c07c6822fbadf10ddfeafad2d28653..b8870e51ce8bd0907655054a0b9c4566e1343cf4 100644 (file)
@@ -52,7 +52,7 @@ public final class InstanceConfig {
         this.configRegistryClient = configRegistryClient;
     }
 
-    private Map<String, Object> getMappedConfiguration(ObjectName on, Services depTracker) {
+    private Map<String, Object> getMappedConfiguration(ObjectName on, ServiceRegistryWrapper depTracker) {
 
         // TODO make field, mappingStrategies can be instantiated only once
         Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> mappingStrategies = new ObjectMapper(depTracker)
@@ -84,7 +84,7 @@ public final class InstanceConfig {
         return toXml;
     }
 
-    public Element toXml(ObjectName on, Services depTracker, String namespace, Document document, Element rootElement) {
+    public Element toXml(ObjectName on, ServiceRegistryWrapper depTracker, String namespace, Document document, Element rootElement) {
 
         Element cfgElement = rootElement;
 
@@ -104,7 +104,7 @@ public final class InstanceConfig {
         return cfgElement;
     }
 
-    private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, Services depTracker) {
+    private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, ServiceRegistryWrapper depTracker) {
 
         // TODO make field, resolvingStrategies can be instantiated only once
         Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> resolvingStrategies = new ObjectResolver(
@@ -128,7 +128,7 @@ public final class InstanceConfig {
         }
     }
 
-    public InstanceConfigElementResolved fromXml(XmlElement moduleElement, Services services, String moduleNamespace,
+    public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace,
             EditStrategyType defaultStrategy, Multimap<String, String> providedServices) {
         Map<String, AttributeConfigElement> retVal = Maps.newHashMap();
 
index 55cb60bed5e7df0268908b160650ecd46101e137..0bb4191bf2f33817d4bd395e3f29c0110139835b 100644 (file)
@@ -28,7 +28,7 @@ public class InstanceConfigElementResolved {
     private final Multimap<String, String> providedServices;
 
     public InstanceConfigElementResolved(String currentStrategy, Map<String, AttributeConfigElement> configuration, EditStrategyType defaultStrategy, Multimap<String, String> providedServices) {
-        EditStrategyType valueOf = checkStrategy(currentStrategy, defaultStrategy);
+        EditStrategyType valueOf = parseStrategy(currentStrategy, defaultStrategy);
         this.editStrategy = valueOf;
         this.configuration = configuration;
         this.providedServices = providedServices;
@@ -41,19 +41,19 @@ public class InstanceConfigElementResolved {
     }
 
 
-    EditStrategyType checkStrategy(String currentStrategy, EditStrategyType defaultStrategy) {
-        EditStrategyType valueOf = EditStrategyType.valueOf(currentStrategy);
+    static EditStrategyType parseStrategy(String currentStrategy, EditStrategyType defaultStrategy) {
+        EditStrategyType parsedStrategy = EditStrategyType.valueOf(currentStrategy);
         if (defaultStrategy.isEnforcing()) {
             Preconditions
                     .checkArgument(
-                            valueOf == defaultStrategy,
+                            parsedStrategy == defaultStrategy,
                             "With "
                                     + defaultStrategy
                                     + " as "
                                     + EditConfigXmlParser.DEFAULT_OPERATION_KEY
                                     + " operations on module elements are not permitted since the default option is restrictive");
         }
-        return valueOf;
+        return parsedStrategy;
     }
 
 
index 2ac6fe0a9bb650116e5f3591fb35cdf8655ee311..48ff835a451e789d51826c4a9c65ba4241d3329b 100644 (file)
@@ -53,7 +53,7 @@ public class ModuleConfig {
         return providedServices;
     }
 
-    public Element toXml(ObjectName instanceON, Services depTracker, Document document, String namespace) {
+    public Element toXml(ObjectName instanceON, ServiceRegistryWrapper depTracker, Document document, String namespace) {
         Element root = document.createElement(XmlNetconfConstants.MODULE_KEY);
         // Xml.addNamespaceAttr(document, root, namespace);
 
@@ -84,7 +84,7 @@ public class ModuleConfig {
 
     }
 
-    public ModuleElementResolved fromXml(XmlElement moduleElement, Services depTracker, String instanceName,
+    public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName,
             String moduleNamespace, EditStrategyType defaultStrategy) {
 
         InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, providedServices);
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java
new file mode 100644 (file)
index 0000000..9111701
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
+
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigStrategy;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.MissingInstanceHandlingStrategy;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.NoneEditConfigStrategy;
+
+public class ModuleElementDefinition {
+
+    public static final NoneEditConfigStrategy NONE_EDIT_CONFIG_STRATEGY = new NoneEditConfigStrategy();
+    public static final MissingInstanceHandlingStrategy MISSING_INSTANCE_HANDLING_STRATEGY = new MissingInstanceHandlingStrategy();
+
+    private final String instanceName;
+    private final EditStrategyType editStrategy;
+
+    public ModuleElementDefinition(String instanceName, String currentStrategy, EditStrategyType defaultStrategy) {
+        this.instanceName = instanceName;
+        if (currentStrategy == null || currentStrategy.isEmpty())
+            this.editStrategy = defaultStrategy;
+        else
+            this.editStrategy = InstanceConfigElementResolved.parseStrategy(currentStrategy, defaultStrategy);
+    }
+
+    public String getInstanceName() {
+        return instanceName;
+    }
+
+    public EditStrategyType getEditStrategyType() {
+        return editStrategy;
+    }
+
+    public EditConfigStrategy getEditStrategy() {
+        switch (editStrategy) {
+            case delete :
+            case remove :
+            case none : return NONE_EDIT_CONFIG_STRATEGY;
+            default : return MISSING_INSTANCE_HANDLING_STRATEGY;
+        }
+    }
+}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java
new file mode 100644 (file)
index 0000000..7df6712
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ServiceRegistryWrapper {
+
+    private ServiceReferenceReadableRegistry configServiceRefRegistry;
+
+    private long suffix = 1;
+
+    public ServiceRegistryWrapper(ServiceReferenceReadableRegistry configServiceRefRegistry) {
+        this.configServiceRefRegistry = configServiceRefRegistry;
+    }
+
+
+    public boolean hasRefName(String namespace, String serviceName, ObjectName on) {
+        String qname = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName);
+        Map<String, ObjectName> forQName = configServiceRefRegistry.getServiceMapping().get(qname);
+        if(forQName==null) return false;
+        return forQName.values().contains(on);
+    }
+
+    public ObjectName getByServiceAndRefName(String namespace, String serviceName, String refName) {
+        Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
+
+        Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace);
+
+        Map<String, String> refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
+        Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , "
+                + serviceNameToRefNameToInstance.keySet());
+
+        String instanceId = refNameToInstance.get(refName);
+        Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":"
+                + refName + ", " + serviceNameToRefNameToInstance.keySet());
+
+        Services.ServiceInstance serviceInstance = Services.ServiceInstance.fromString(instanceId);
+        Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName
+                + " under service name " + serviceName + " , " + refNameToInstance.keySet());
+
+        String qNameOfService = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName);
+        try {
+            return configServiceRefRegistry.getServiceReference(qNameOfService, refName);
+        } catch (InstanceNotFoundException e) {
+            throw new IllegalArgumentException("No serviceInstance mapped to " + refName
+                    + " under service name " + serviceName + " , " + refNameToInstance.keySet(), e);
+
+        }
+    }
+
+    public Map<String, Map<String, Map<String, String>>> getMappedServices() {
+        Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
+
+        Map<String, Map<String, ObjectName>> serviceMapping = configServiceRefRegistry.getServiceMapping();
+        for (String serviceQName : serviceMapping.keySet())
+            for (String refName : serviceMapping.get(serviceQName).keySet()) {
+
+                ObjectName on = serviceMapping.get(serviceQName).get(refName);
+                Services.ServiceInstance si = Services.ServiceInstance.fromObjectName(on);
+
+                // FIXME use QName's new String constructor, after it is fixed
+//                QName qname;
+//                try {
+//                    qname = new QName(serviceQName);
+//                } catch (ParseException e) {
+//                    throw new IllegalStateException("Unable to parse qname of a service " + serviceQName, e);
+//                }
+                Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)");
+                Matcher matcher = p.matcher(serviceQName);
+                Preconditions.checkArgument(matcher.matches());
+                String namespace = matcher.group(1);
+                String localName = matcher.group(2);
+
+//                String namespace = qname.getNamespace().toString();
+                Map<String, Map<String, String>> serviceToRefs = retVal.get(namespace);
+                if(serviceToRefs==null) {
+                    serviceToRefs = Maps.newHashMap();
+                    retVal.put(namespace, serviceToRefs);
+                }
+
+//                String localName = qname.getLocalName();
+                Map<String, String> refsToSis = serviceToRefs.get(localName);
+                if(refsToSis==null) {
+                    refsToSis = Maps.newHashMap();
+                    serviceToRefs.put(localName, refsToSis);
+                }
+
+                Preconditions.checkState(refsToSis.containsKey(refName) == false,
+                        "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace,
+                        localName, on);
+                refsToSis.put(refName, si.toString());
+            }
+
+        return retVal;
+    }
+
+    @VisibleForTesting
+    public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) {
+        String refName;
+        refName = "ref_" + instanceName;
+
+        Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
+
+        Map<String, String> refNameToInstance;
+        if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) {
+            refNameToInstance = Collections.emptyMap();
+        } else
+            refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
+
+        final Set<String> refNamesAsSet = toSet(refNameToInstance.keySet());
+        if (refNamesAsSet.contains(refName)) {
+            refName = findAvailableRefName(refName, refNamesAsSet);
+        }
+
+        return refName;
+    }
+
+
+    private Set<String> toSet(Collection<String> values) {
+        Set<String> refNamesAsSet = Sets.newHashSet();
+
+        for (String refName : values) {
+            boolean resultAdd = refNamesAsSet.add(refName);
+            Preconditions.checkState(resultAdd,
+                    "Error occurred building services element, reference name {} was present twice", refName);
+        }
+
+        return refNamesAsSet;
+    }
+
+    private String findAvailableRefName(String refName, Set<String> refNamesAsSet) {
+        String intitialRefName = refName;
+
+        while (true) {
+            refName = intitialRefName + "_" + suffix++;
+            if (refNamesAsSet.contains(refName) == false)
+                return refName;
+        }
+    }
+}
index 77f3cf283fc2daf77c18766c4a9dacd4185f2536..7de7ea8c7169086afe4aa6ce1a2cf858718d20e3 100644 (file)
@@ -8,14 +8,8 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectNameAttributeReadingStrategy;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
@@ -27,12 +21,9 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 import javax.management.ObjectName;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -45,124 +36,8 @@ public final class Services {
     public static final String TYPE_KEY = "type";
     public static final String SERVICE_KEY = "service";
 
-    private long suffix = 1;
-
     private final Map<String /*Namespace*/, Map<String/* ServiceName */, Map<String/* refName */, ServiceInstance>>> namespaceToServiceNameToRefNameToInstance = Maps
             .newHashMap();
-    private ServiceReferenceReadableRegistry configServiceRefRegistry;
-
-    public Services(ServiceReferenceReadableRegistry configServiceRefRegistry) {
-        this.configServiceRefRegistry = configServiceRefRegistry;
-    }
-
-    @VisibleForTesting
-    public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) {
-        String refName;
-        refName = "ref_" + instanceName;
-
-        Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
-
-        Map<String, String> refNameToInstance;
-        if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) {
-            refNameToInstance = Collections.emptyMap();
-        } else
-            refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
-
-        final Set<String> refNamesAsSet = toSet(refNameToInstance.keySet());
-        if (refNamesAsSet.contains(refName)) {
-            refName = findAvailableRefName(refName, refNamesAsSet);
-        }
-
-        return refName;
-    }
-
-    private Set<String> toSet(Collection<String> values) {
-        Set<String> refNamesAsSet = Sets.newHashSet();
-
-        for (String refName : values) {
-            boolean resultAdd = refNamesAsSet.add(refName);
-            Preconditions.checkState(resultAdd,
-                    "Error occurred building services element, reference name {} was present twice", refName);
-        }
-
-        return refNamesAsSet;
-    }
-
-    public ServiceInstance getByServiceAndRefName(String namespace, String serviceName, String refName) {
-        Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
-
-        Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace);
-
-        Map<String, String> refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
-        Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , "
-                + serviceNameToRefNameToInstance.keySet());
-
-        String instanceId = refNameToInstance.get(refName);
-        Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":"
-                + refName + ", " + serviceNameToRefNameToInstance.keySet());
-
-        ServiceInstance serviceInstance = ServiceInstance.fromString(instanceId);
-        Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName
-                + " under service name " + serviceName + " , " + refNameToInstance.keySet());
-        return serviceInstance;
-    }
-
-    // TODO hide getMappedServices, call it explicitly in toXml
-
-    public Map<String, Map<String, Map<String, String>>> getMappedServices() {
-        Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
-
-        for (String namespace : namespaceToServiceNameToRefNameToInstance.keySet()) {
-
-            Map<String, Map<String, ServiceInstance>> serviceNameToRefNameToInstance = namespaceToServiceNameToRefNameToInstance
-                    .get(namespace);
-            Map<String, Map<String, String>> innerRetVal = Maps.newHashMap();
-
-            for (String serviceName : serviceNameToRefNameToInstance.keySet()) {
-
-                Map<String, String> innerInnerRetVal = Maps.newHashMap();
-                for (Entry<String, ServiceInstance> refNameToSi : serviceNameToRefNameToInstance.get(serviceName).entrySet()) {
-                    innerInnerRetVal.put(refNameToSi.getKey(), refNameToSi.getValue().toString());
-                }
-                innerRetVal.put(serviceName, innerInnerRetVal);
-            }
-            retVal.put(namespace, innerRetVal);
-        }
-
-        Map<String, Map<String, ObjectName>> serviceMapping = configServiceRefRegistry.getServiceMapping();
-        for (String serviceQName : serviceMapping.keySet())
-            for (String refName : serviceMapping.get(serviceQName).keySet()) {
-
-                ObjectName on = serviceMapping.get(serviceQName).get(refName);
-                ServiceInstance si = ServiceInstance.fromObjectName(on);
-
-                // FIXME use QName's new String constructor, after its implemented
-                Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)");
-                Matcher matcher = p.matcher(serviceQName);
-                Preconditions.checkArgument(matcher.matches());
-                String namespace = matcher.group(1);
-                String localName = matcher.group(2);
-
-                Map<String, Map<String, String>> serviceToRefs = retVal.get(namespace);
-                if(serviceToRefs==null) {
-                    serviceToRefs = Maps.newHashMap();
-                    retVal.put(namespace, serviceToRefs);
-                }
-
-                Map<String, String> refsToSis = serviceToRefs.get(localName);
-                if(refsToSis==null) {
-                    refsToSis = Maps.newHashMap();
-                    serviceToRefs.put(localName, refsToSis);
-                }
-
-                Preconditions.checkState(refsToSis.containsKey(refName) == false,
-                        "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace,
-                        localName, on);
-                refsToSis.put(refName, si.toString());
-            }
-
-        return retVal;
-    }
 
     /**
      *
@@ -171,10 +46,8 @@ public final class Services {
         return namespaceToServiceNameToRefNameToInstance;
     }
 
-    // TODO hide resolveServices, call it explicitly in fromXml
-
-    public static Services resolveServices(Map<String, Map<String, Map<String, String>>> mappedServices, ServiceReferenceReadableRegistry taClient) {
-        Services tracker = new Services(taClient);
+    private static Services resolveServices(Map<String, Map<String, Map<String, String>>> mappedServices) {
+        Services tracker = new Services();
 
         for (Entry<String, Map<String, Map<String, String>>> namespaceEntry : mappedServices.entrySet()) {
             String namespace = namespaceEntry.getKey();
@@ -210,7 +83,7 @@ public final class Services {
 
     // TODO support edit strategies on services
 
-    public static Map<String, Map<String, Map<String, String>>> fromXml(XmlElement xml) {
+    public static Services fromXml(XmlElement xml) {
         Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
 
         List<XmlElement> services = xml.getChildElements(SERVICE_KEY);
@@ -250,23 +123,14 @@ public final class Services {
             }
         }
 
-        return retVal;
-    }
-
-    private String findAvailableRefName(String refName, Set<String> refNamesAsSet) {
-        String intitialRefName = refName;
-
-        while (true) {
-            refName = intitialRefName + "_" + suffix++;
-            if (refNamesAsSet.contains(refName) == false)
-                return refName;
-        }
+        return resolveServices(retVal);
     }
 
-    public Element toXml(Map<String, Map<String, Map<String, String>>> mappedServices, Document document) {
+    public static Element toXml(ServiceRegistryWrapper serviceRegistryWrapper, Document document) {
         Element root = document.createElement(XmlNetconfConstants.SERVICES_KEY);
         XmlUtil.addNamespaceAttr(root, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
 
+        Map<String, Map<String, Map<String, String>>> mappedServices = serviceRegistryWrapper.getMappedServices();
         for (String namespace : mappedServices.keySet()) {
 
             for (Entry<String, Map<String, String>> serviceEntry : mappedServices.get(namespace).entrySet()) {
@@ -294,51 +158,6 @@ public final class Services {
         return root;
     }
 
-    public String getRefName(String namespace, String serviceName, ObjectName on, Optional<String> expectedRefName) {
-        Optional<String> refNameOptional = getRefNameOptional(namespace, serviceName, on, expectedRefName);
-        Preconditions.checkState(refNameOptional.isPresent(), "No reference names mapped to %s, %s, %s", namespace,
-                serviceName, on);
-        return refNameOptional.get();
-    }
-
-    public Optional<String> getRefNameOptional(String namespace, String serviceName, ObjectName on,
-            Optional<String> expectedRefName) {
-        Map<String, Map<String, String>> services = getMappedServices().get(namespace);
-
-        if(services == null) return Optional.absent();
-        Map<String, String> refs = services.get(serviceName);
-
-        if(refs == null) return Optional.absent();
-        Multimap<ServiceInstance, String> reverted = revertMap(refs);
-
-        ServiceInstance serviceInstance = ServiceInstance.fromObjectName(on);
-        Collection<String> references = reverted.get(serviceInstance);
-
-        if (expectedRefName.isPresent() && references.contains(expectedRefName.get())) {
-            logger.debug("Returning expected ref name {} for {}", expectedRefName.get(), on);
-            return expectedRefName;
-        } else if (references.size() > 0) {
-            String next = references.iterator().next();
-            logger.debug("Returning random ref name {} for {}", next, on);
-            return Optional.of(next);
-        } else
-            return Optional.absent();
-    }
-
-    private Multimap<ServiceInstance, String> revertMap(Map<String, String> refs) {
-        Multimap<ServiceInstance, String> multimap = HashMultimap.create();
-
-        for (Entry<String, String> e : refs.entrySet()) {
-            multimap.put(ServiceInstance.fromString(e.getValue()), e.getKey());
-        }
-
-        return multimap;
-    }
-
-    public boolean hasRefName(String key, String value, ObjectName on) {
-        return getRefNameOptional(key, value, on, Optional.<String>absent()).isPresent();
-    }
-
     public static final class ServiceInstance {
         public ServiceInstance(String moduleName, String instanceName) {
             this.moduleName = moduleName;
index 70b10d00191cd04c01e83dee8be44fd0c4db0f9d..6a0d7508c849ee12c16e0d742fd7dfcadae5fe65 100644 (file)
@@ -88,7 +88,6 @@ public class InstanceRuntime {
 
     public Element toXml(ObjectName rootOn, Set<ObjectName> childRbeOns, Document document, String instanceIndex,
                          Element parentElement, String namespace) {
-        // TODO namespace
         Element xml = instanceMapping.toXml(rootOn, null, namespace, document, parentElement);
 
         if (instanceIndex != null) {
index 11e97ebdbb9fc27c63e87d71c9962bcc494217ce..4936d1dbcda833b7fb5fdfe904d8b5e1493f6b34 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runti
 
 import com.google.common.collect.Sets;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -41,7 +41,7 @@ public class ModuleRuntime {
     }
 
     public Element toXml(String namespace, Collection<ObjectName> runtimeBeanOns,
-                         Document document, ModuleConfig moduleConfig, ObjectName configBeanON, Services serviceTracker) {
+                         Document document, ModuleConfig moduleConfig, ObjectName configBeanON, ServiceRegistryWrapper serviceTracker) {
 
         Element moduleElement = moduleConfig.toXml(configBeanON, serviceTracker, document, namespace);
 
index 89c782c51c86e6acda56b426e6d76a70c2bc0c30..129143835fd024e53c290509662f968f9e691b6c 100644 (file)
@@ -11,11 +11,10 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runti
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Multimap;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
@@ -61,9 +60,7 @@ public class Runtime {
         return retVal;
     }
 
-    public Element toXml(Set<ObjectName> instancesToMap, Set<ObjectName> configBeans, Document document, ServiceReferenceReadableRegistry serviceRegistry) {
-        Services serviceTracker = new Services(serviceRegistry);
-
+    public Element toXml(Set<ObjectName> instancesToMap, Set<ObjectName> configBeans, Document document, ServiceRegistryWrapper serviceRegistry) {
         Element root = document.createElement(XmlNetconfConstants.DATA_KEY);
 
         Element modulesElement = document.createElement(XmlNetconfConstants.MODULES_KEY);
@@ -88,11 +85,11 @@ public class Runtime {
                     Element runtimeXml;
                     ModuleConfig moduleConfig = moduleConfigs.get(localNamespace).get(moduleName);
                     if(instanceToRbe==null || instanceToRbe.containsKey(instanceName) == false) {
-                        runtimeXml = moduleConfig.toXml(instanceON, serviceTracker, document, localNamespace);
+                        runtimeXml = moduleConfig.toXml(instanceON, serviceRegistry, document, localNamespace);
                     } else {
                         ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName);
                         runtimeXml = moduleRuntime.toXml(localNamespace, instanceToRbe.get(instanceName), document,
-                                moduleConfig, instanceON, serviceTracker);
+                                moduleConfig, instanceON, serviceRegistry);
                     }
                     modulesElement.appendChild(runtimeXml);
                 }
index 65df965afd1e08167c63f70ba0c56159a085d2db..1d37fcd49378de3d577db338b034f987634f9518 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed
 
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -24,7 +24,7 @@ public abstract class AbstractEditConfigStrategy implements EditConfigStrategy {
 
     @Override
     public void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
-                                     ConfigTransactionClient ta, Services services) {
+                                     ConfigTransactionClient ta, ServiceRegistryWrapper services) {
 
         try {
             ObjectName on = ta.lookupConfigBean(module, instance);
@@ -36,10 +36,13 @@ public abstract class AbstractEditConfigStrategy implements EditConfigStrategy {
 
     }
 
+    // TODO split missing instances handling strategies from edit config strategies in this hierarchy = REFACTOR
+    // edit configs should not handle missing
+
     abstract void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                                        String module, String instance, Services services);
+                                        String module, String instance, ServiceRegistryWrapper services);
 
     abstract void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                                  ObjectName objectName, Services services);
+                                  ObjectName objectName, ServiceRegistryWrapper services);
 
 }
index 12beaf8f8e19ff29048cb12c426c372ff047d14c..13e8c30211539485e0ac91ca1eb0ec06704e8409 100644 (file)
@@ -12,7 +12,7 @@ import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,12 +36,12 @@ public class DeleteEditConfigStrategy extends AbstractEditConfigStrategy {
 
     @Override
     void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                               String module, String instance, Services services) {
+                               String module, String instance, ServiceRegistryWrapper services) {
         throw new IllegalStateException("Unable to delete " + module + ":" + instance + " , ServiceInstance not found");
     }
 
     @Override
-    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
         try {
             ta.destroyModule(on);
             logger.debug("ServiceInstance {} deleted successfully", on);
index 1bb1d9bfba7babf8fa2dc504909e4f89b6730530..709573c2414c3249917aae4e03851e0f9ada4da8 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
@@ -105,8 +106,8 @@ public class EditConfig extends AbstractConfigNetconfOperation {
         logger.debug("Test phase for {} operation successful", EditConfigXmlParser.EDIT_CONFIG);
     }
 
-    private void test(ConfigRegistryClient configRegistryClient,
-                      EditConfigExecution execution, EditStrategyType editStrategyType) {
+    private void test(ConfigRegistryClient configRegistryClient, EditConfigExecution execution,
+            EditStrategyType editStrategyType) {
         ObjectName taON = transactionProvider.getTestTransaction();
         try {
 
@@ -115,8 +116,11 @@ public class EditConfig extends AbstractConfigNetconfOperation {
                 transactionProvider.wipeTestTransaction(taON);
             }
 
-            setOnTransaction(configRegistryClient, execution.getResolvedXmlElements(), execution.getServices(), taON);
-            // TODO add service reference persistance testing here
+            ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+
+            handleMisssingInstancesOnTransaction(ta, execution);
+            setServicesOnTransaction(ta, execution);
+            setOnTransaction(ta, execution);
             transactionProvider.validateTestTransaction(taON);
         } finally {
             transactionProvider.abortTestTransaction(taON);
@@ -132,14 +136,16 @@ public class EditConfig extends AbstractConfigNetconfOperation {
             transactionProvider.wipeTransaction();
         }
 
-        setOnTransaction(configRegistryClient, editConfigExecution.getResolvedXmlElements(),
-                editConfigExecution.getServices(), taON);
-        setServicesOnTransaction(configRegistryClient, editConfigExecution.getServices(), taON);
+        ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+
+        handleMisssingInstancesOnTransaction(ta, editConfigExecution);
+        setServicesOnTransaction(ta, editConfigExecution);
+        setOnTransaction(ta, editConfigExecution);
     }
 
-    private void setServicesOnTransaction(ConfigRegistryClient configRegistryClient, Services services,
-                ObjectName taON) {
-        ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+    private void setServicesOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) {
+
+        Services services = execution.getServices();
 
         Map<String, Map<String, Map<String, Services.ServiceInstance>>> namespaceToServiceNameToRefNameToInstance = services
                 .getNamespaceToServiceNameToRefNameToInstance();
@@ -153,9 +159,10 @@ public class EditConfig extends AbstractConfigNetconfOperation {
 
                 for (String refName : refNameToInstance.keySet()) {
                     ObjectName on = refNameToInstance.get(refName).getObjectName(ta.getTransactionName());
-                    // TODO check for duplicates
                     try {
-                        ta.saveServiceReference(qnameOfService, refName, on);
+                        ObjectName saved = ta.saveServiceReference(qnameOfService, refName, on);
+                        logger.debug("Saving service {} with on {} under name {} with service on {}", qnameOfService,
+                                on, refName, saved);
                     } catch (InstanceNotFoundException e) {
                         throw new IllegalStateException("Unable to save ref name " + refName + " for instance " + on, e);
                     }
@@ -168,11 +175,10 @@ public class EditConfig extends AbstractConfigNetconfOperation {
         return ta.getServiceInterfaceName(namespace, serviceName);
     }
 
-    private void setOnTransaction(ConfigRegistryClient configRegistryClient,
-                                  Map<String, Multimap<String, ModuleElementResolved>> resolvedXmlElements, Services services, ObjectName taON) {
-        ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+    private void setOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) {
+
+        for (Multimap<String, ModuleElementResolved> modulesToResolved : execution.getResolvedXmlElements(ta).values()) {
 
-        for (Multimap<String, ModuleElementResolved> modulesToResolved : resolvedXmlElements.values()) {
             for (Entry<String, ModuleElementResolved> moduleToResolved : modulesToResolved.entries()) {
                 String moduleName = moduleToResolved.getKey();
 
@@ -181,7 +187,22 @@ public class EditConfig extends AbstractConfigNetconfOperation {
 
                 InstanceConfigElementResolved ice = moduleElementResolved.getInstanceConfigElementResolved();
                 EditConfigStrategy strategy = ice.getEditStrategy();
-                strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, services);
+                strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, execution.getServiceRegistryWrapper(ta));
+            }
+        }
+    }
+
+    private void handleMisssingInstancesOnTransaction(ConfigTransactionClient ta,
+            EditConfigExecution execution) {
+
+        for (Multimap<String,ModuleElementDefinition> modulesToResolved : execution.getModulesDefinition(ta).values()) {
+            for (Entry<String, ModuleElementDefinition> moduleToResolved : modulesToResolved.entries()) {
+                String moduleName = moduleToResolved.getKey();
+
+                ModuleElementDefinition moduleElementDefinition = moduleToResolved.getValue();
+
+                EditConfigStrategy strategy = moduleElementDefinition.getEditStrategy();
+                strategy.executeConfiguration(moduleName, moduleElementDefinition.getInstanceName(), null, ta, execution.getServiceRegistryWrapper(ta));
             }
         }
     }
@@ -189,32 +210,38 @@ public class EditConfig extends AbstractConfigNetconfOperation {
     public static Config getConfigMapping(ConfigRegistryClient configRegistryClient,
             Map<String/* Namespace from yang file */,
                     Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> mBeanEntries) {
-        Map<String, Map<String, ModuleConfig>> factories = transform(configRegistryClient, mBeanEntries);
+        Map<String, Map<String, ModuleConfig>> factories = transformMbeToModuleConfigs(configRegistryClient, mBeanEntries);
 
         return new Config(factories);
     }
 
-    // TODO refactor
-    private static Map<String/* Namespace from yang file */,
-            Map<String /* Name of module entry from yang file */, ModuleConfig>> transform
-    (final ConfigRegistryClient configRegistryClient, Map<String/* Namespace from yang file */,
+    public static Map<String/* Namespace from yang file */,
+            Map<String /* Name of module entry from yang file */, ModuleConfig>> transformMbeToModuleConfigs
+            (final ConfigRegistryClient configRegistryClient, Map<String/* Namespace from yang file */,
                     Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> mBeanEntries) {
-        return Maps.transformEntries(mBeanEntries,
-                new Maps.EntryTransformer<String, Map<String, ModuleMXBeanEntry>, Map<String, ModuleConfig>>() {
-
-                    @Override
-                    public Map<String, ModuleConfig> transformEntry(String arg0, Map<String, ModuleMXBeanEntry> arg1) {
-                        return Maps.transformEntries(arg1,
-                                new Maps.EntryTransformer<String, ModuleMXBeanEntry, ModuleConfig>() {
-
-                                    @Override
-                                    public ModuleConfig transformEntry(String key, ModuleMXBeanEntry moduleMXBeanEntry) {
-                                        return new ModuleConfig(key, new InstanceConfig(configRegistryClient, moduleMXBeanEntry
-                                                .getAttributes()), moduleMXBeanEntry.getProvidedServices().values());
-                                    }
-                                });
-                    }
-                });
+
+        Map<String, Map<String, ModuleConfig>> namespaceToModuleNameToModuleConfig = Maps.newHashMap();
+
+        for (String namespace : mBeanEntries.keySet()) {
+            for (Entry<String, ModuleMXBeanEntry> moduleNameToMbe : mBeanEntries.get(namespace).entrySet()) {
+                String moduleName = moduleNameToMbe.getKey();
+                ModuleMXBeanEntry moduleMXBeanEntry = moduleNameToMbe.getValue();
+
+                ModuleConfig moduleConfig = new ModuleConfig(moduleName, new InstanceConfig(configRegistryClient,
+                        moduleMXBeanEntry.getAttributes()), moduleMXBeanEntry
+                        .getProvidedServices().values());
+
+                Map<String, ModuleConfig> moduleNameToModuleConfig = namespaceToModuleNameToModuleConfig.get(namespace);
+                if(moduleNameToModuleConfig == null) {
+                    moduleNameToModuleConfig = Maps.newHashMap();
+                    namespaceToModuleNameToModuleConfig.put(namespace, moduleNameToModuleConfig);
+                }
+
+                moduleNameToModuleConfig.put(moduleName, moduleConfig);
+            }
+        }
+
+        return namespaceToModuleNameToModuleConfig;
     }
 
     @Override
index 23166e8cca5c6e0d4c6fbc955de83de8db94a6f3..cebcb0239bc81cda1d7ef6a83bc0f15b8c3bdd90 100644 (file)
@@ -10,13 +10,13 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed
 
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 
 import java.util.Map;
 
 public interface EditConfigStrategy {
 
     void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
-                              ConfigTransactionClient ta, Services services);
+                              ConfigTransactionClient ta, ServiceRegistryWrapper services);
 
 }
index 81327133b82a440c9b7599672134e7b63fd00f49..e481bbe57f68bf4d043a8365362ce2c90ab46893 100644 (file)
@@ -14,10 +14,11 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Multimap;
 import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
 import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
@@ -26,7 +27,6 @@ import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.management.ObjectName;
 import java.util.Arrays;
 import java.util.Map;
 
@@ -98,11 +98,7 @@ public class EditConfigXmlParser {
 
         XmlElement configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY);
 
-        ObjectName taON = transactionProvider.getOrCreateTransaction();
-        ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
-
-        return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption,
-                ta, editStrategyType);
+        return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption, editStrategyType);
     }
 
     @VisibleForTesting
@@ -132,15 +128,17 @@ public class EditConfigXmlParser {
     @VisibleForTesting
     static class EditConfigExecution {
 
-        private final Map<String, Multimap<String, ModuleElementResolved>> resolvedXmlElements;
         private final TestOption testOption;
         private final EditStrategyType defaultEditStrategyType;
         private final Services services;
-
-        EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, ServiceReferenceReadableRegistry ta, EditStrategyType defaultStrategy) {
-            Config.ConfigElementResolved configElementResolved = configResolver.fromXml(configElement, defaultStrategy, ta);
-            this.resolvedXmlElements = configElementResolved.getResolvedModules();
-            this.services = configElementResolved.getServices();
+        private final Config configResolver;
+        private final XmlElement configElement;
+
+        EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, EditStrategyType defaultStrategy) {
+            Config.checkUnrecognisedChildren(configElement);
+            this.configResolver = configResolver;
+            this.configElement = configElement;
+            this.services = configResolver.fromXmlServices(configElement);
             this.testOption = testOption;
             this.defaultEditStrategyType = defaultStrategy;
         }
@@ -153,8 +151,17 @@ public class EditConfigXmlParser {
             return testOption == TestOption.set || testOption == TestOption.testThenSet;
         }
 
-        Map<String, Multimap<String, ModuleElementResolved>> getResolvedXmlElements() {
-            return resolvedXmlElements;
+        Map<String, Multimap<String, ModuleElementResolved>> getResolvedXmlElements(ServiceReferenceReadableRegistry serviceRegistry) {
+            return configResolver.fromXmlModulesResolved(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry));
+        }
+
+        ServiceRegistryWrapper getServiceRegistryWrapper(ServiceReferenceReadableRegistry serviceRegistry) {
+            // TODO cache service registry
+            return new ServiceRegistryWrapper(serviceRegistry);
+        }
+
+        Map<String, Multimap<String,ModuleElementDefinition>> getModulesDefinition(ServiceReferenceReadableRegistry serviceRegistry) {
+            return configResolver.fromXmlModulesMap(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry));
         }
 
         EditStrategyType getDefaultStrategy() {
index 06befb0565067592b58465782d66caa74a568100..f2e2b193a8f1b7d90380c3cee6916a1a9b0514c1 100644 (file)
@@ -10,14 +10,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed
 
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.management.Attribute;
-import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
 import javax.management.ObjectName;
 import java.util.Map;
@@ -38,22 +38,13 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy {
 
     @Override
     void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                               String module, String instance, Services services) {
-        ObjectName on = null;
-        try {
-            on = ta.createModule(module, instance);
-            logger.info("New instance for {} {} created under name {}", module, instance, on);
-            addRefNames(services, providedServices, module, instance, ta, on);
-            executeStrategy(configuration, ta, on, services);
-        } catch (InstanceAlreadyExistsException e1) {
-            throw new IllegalStateException("Unable to create instance for " + module + " : " + instance);
-        } catch (InstanceNotFoundException e) {
-            throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
-        }
+            String module, String instance, ServiceRegistryWrapper services) {
+        throw new IllegalStateException(
+                "Unable to handle missing instance, no missing instances should appear at this point, missing: "
+                        + module + ":" + instance);
     }
 
-    private void addRefNames(Services services, Multimap<String, String> providedServices, String module,
-            String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
+    private void addRefNames(ServiceRegistryWrapper services, Multimap<String, String> providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
         for (Entry<String, String> namespaceToService : providedServices.entries()) {
 
             if(services.hasRefName(namespaceToService.getKey(),
@@ -61,14 +52,20 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy {
                 continue;
 
             String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(),
-                    module, instance);
+                    ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on));
             ta.saveServiceReference(
                     ta.getServiceInterfaceName(namespaceToService.getKey(), namespaceToService.getValue()), refName, on);
         }
     }
 
     @Override
-    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
+        try {
+            addRefNames(services, providedServices, ta, on);
+        } catch (InstanceNotFoundException e) {
+            throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
+        }
+
         for (Entry<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
             try {
                 AttributeConfigElement ace = configAttributeEntry.getValue();
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java
new file mode 100644 (file)
index 0000000..8ed9eb8
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
+
+import org.opendaylight.controller.config.util.ConfigTransactionClient;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+import java.util.Map;
+
+public class MissingInstanceHandlingStrategy extends AbstractEditConfigStrategy {
+
+    private static final Logger logger = LoggerFactory.getLogger(MissingInstanceHandlingStrategy.class);
+
+    @Override
+    void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
+            String module, String instance, ServiceRegistryWrapper services) {
+        ObjectName on = null;
+        try {
+            on = ta.createModule(module, instance);
+            logger.info("New instance for {} {} created under name {}", module, instance, on);
+        } catch (InstanceAlreadyExistsException e1) {
+            throw new IllegalStateException("Unable to create instance for " + module + " : " + instance);
+        }
+    }
+
+    @Override
+    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
+            ObjectName objectName, ServiceRegistryWrapper services) {
+        return;
+    }
+}
index 8347c6b88e23325fa579527a5f30785a99216b7d..bd182a4267280021ef2c6a66f50db98af020c26b 100644 (file)
@@ -8,21 +8,21 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
 
-import java.util.Map;
-
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Map;
+
 public class NoneEditConfigStrategy implements EditConfigStrategy {
 
     private static final Logger logger = LoggerFactory.getLogger(NoneEditConfigStrategy.class);
 
     @Override
     public void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
-                                     ConfigTransactionClient ta, Services services) {
+                                     ConfigTransactionClient ta, ServiceRegistryWrapper services) {
         logger.debug("Skipping configuration element for {}:{}", module, instance);
     }
 
index 64f082da40773b4a6dab473bed7e45722847ffca..df1f65372aea4068fdea45fde41c20c4217a9181 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed
 
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -22,7 +22,7 @@ public class RemoveEditConfigStrategy extends DeleteEditConfigStrategy {
 
     @Override
     void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                               String module, String instance, Services services) {
+                               String module, String instance, ServiceRegistryWrapper services) {
         logger.warn("Unable to delete {}:{}, ServiceInstance not found", module, instance);
     }
 }
index 43d852e76a32f3b35a8bee016b6ca4ab4f8c6d04..4976244eae57cb6eadfec806620a10f43a2387d4 100644 (file)
@@ -10,14 +10,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed
 
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.management.Attribute;
-import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
 import javax.management.ObjectName;
 import java.util.Map;
@@ -39,23 +39,13 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy {
 
     @Override
     void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                               String module, String instance, Services services) {
-        ObjectName on = null;
-        try {
-            on = ta.createModule(module, instance);
-            logger.debug("New instance for {} {} created under name {}", module, instance, on);
-            addRefNames(services, providedServices, module, instance, ta, on);
-            executeStrategy(configuration, ta, on, services);
-        } catch (InstanceAlreadyExistsException e) {
-            logger.warn("Error creating instance {}:{}, replace failed", module, instance, e);
-            throw new IllegalStateException("Unable to create new instance for " + module + " : " + instance, e);
-        } catch (InstanceNotFoundException e) {
-            throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
-        }
+                               String module, String instance, ServiceRegistryWrapper services) {
+        throw new IllegalStateException(
+                "Unable to handle missing instance, no missing instances should appear at this point, missing: "
+                        + module + ":" + instance);
     }
 
-    private void addRefNames(Services services, Multimap<String, String> providedServices, String module,
-                             String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
+    private void addRefNames(ServiceRegistryWrapper services, Multimap<String, String> providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
         for (Entry<String, String> namespaceToService : providedServices.entries()) {
 
             if(services.hasRefName(namespaceToService.getKey(),
@@ -63,13 +53,20 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy {
                 continue;
 
             String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(),
-                    module, instance);
+                    ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on));
             ta.saveServiceReference(
                     ta.getServiceInterfaceName(namespaceToService.getKey(), namespaceToService.getValue()), refName, on);
         }
     }
+
     @Override
-    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
+        try {
+            addRefNames(services, providedServices, ta, on);
+        } catch (InstanceNotFoundException e) {
+            throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
+        }
+
         for (Entry<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
             try {
                 AttributeConfigElement ace = configAttributeEntry.getValue();
index efe4f7dde9b483bd488e753a90cee2a335b4de05..ea602091a0423ec0957a5c0974f163b89f0fd72a 100644 (file)
@@ -20,12 +20,13 @@ import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorT
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.InstanceRuntime;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.ModuleRuntime;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.Runtime;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.GetConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
@@ -143,14 +144,14 @@ public class Get extends AbstractConfigNetconfOperation {
 
         final Map<String, Map<String, ModuleRuntime>> moduleRuntimes = createModuleRuntimes(configRegistryClient,
                 yangStoreSnapshot.getModuleMXBeanEntryMap());
-        final Map<String, Map<String, ModuleConfig>> moduleConfigs = GetConfig.transform(configRegistryClient,
-                yangStoreSnapshot.getModuleMXBeanEntryMap());
+        final Map<String, Map<String, ModuleConfig>> moduleConfigs = EditConfig.transformMbeToModuleConfigs(
+                configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap());
 
         final Runtime runtime = new Runtime(moduleRuntimes, moduleConfigs);
 
         ObjectName txOn = transactionProvider.getOrCreateTransaction();
         ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(txOn);
-        final Element element = runtime.toXml(runtimeBeans, configBeans, document, ta);
+        final Element element = runtime.toXml(runtimeBeans, configBeans, document, new ServiceRegistryWrapper(ta));
 
         logger.info("{} operation successful", XmlNetconfConstants.GET);
 
index d75cfd5d6f049d9d586ac856fa0ccd7b70b3c00c..16dd5ad80a695aa791ec5b8e86ebacec9dac50ab 100644 (file)
@@ -9,21 +9,18 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig;
 
 import com.google.common.base.Optional;
-import com.google.common.collect.Maps;
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
@@ -83,14 +80,14 @@ public class GetConfig extends AbstractConfigNetconfOperation {
         final Set<ObjectName> instances = Datastore.getInstanceQueryStrategy(source, this.transactionProvider)
                 .queryInstances(configRegistryClient);
 
-        final Config configMapping = new Config(transform(configRegistryClient,
+        final Config configMapping = new Config(EditConfig.transformMbeToModuleConfigs(configRegistryClient,
                 yangStoreSnapshot.getModuleMXBeanEntryMap()));
 
 
         ObjectName on = transactionProvider.getOrCreateTransaction();
         ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(on);
 
-        Services serviceTracker = new Services(ta);
+        ServiceRegistryWrapper serviceTracker = new ServiceRegistryWrapper(ta);
         dataElement = configMapping.toXml(instances, this.maybeNamespace, document, dataElement, serviceTracker);
 
         logger.info("{} operation successful", GET_CONFIG);
@@ -98,27 +95,6 @@ public class GetConfig extends AbstractConfigNetconfOperation {
         return dataElement;
     }
 
-    // TODO refactor ... duplicate code
-    public static Map<String, Map<String, ModuleConfig>> transform(final ConfigRegistryClient configRegistryClient,
-            Map<String, Map<String, ModuleMXBeanEntry>> mBeanEntries) {
-        return Maps.transformEntries(mBeanEntries,
-                new Maps.EntryTransformer<String, Map<String, ModuleMXBeanEntry>, Map<String, ModuleConfig>>() {
-
-                    @Override
-                    public Map<String, ModuleConfig> transformEntry(String arg0, Map<String, ModuleMXBeanEntry> arg1) {
-                        return Maps.transformEntries(arg1,
-                                new Maps.EntryTransformer<String, ModuleMXBeanEntry, ModuleConfig>() {
-
-                                    @Override
-                                    public ModuleConfig transformEntry(String key, ModuleMXBeanEntry value) {
-                                        return new ModuleConfig(key, new InstanceConfig(configRegistryClient, value
-                                                .getAttributes()), value.getProvidedServices().values());
-                                    }
-                                });
-                    }
-                });
-    }
-
     @Override
     protected String getOperationName() {
         return GET_CONFIG;
index 7463bdd429e4dc9552dfc390d59bcaba32fe5e5b..f838c6f9f5e69160b4c889d799f7e42ed2c7338c 100644 (file)
@@ -127,7 +127,6 @@ 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 35695f75102870a00c31f631ca6f26a3b7e5320f..2db3c9d4f1d538893da1b9de420c696ef555e242 100644 (file)
@@ -45,6 +45,7 @@ public class NetconfOperationServiceFactoryImpl implements NetconfOperationServi
                 try {
                     Thread.sleep(ATTEMPT_TIMEOUT_MS);
                 } catch (InterruptedException e1) {
+                    Thread.currentThread().interrupt();
                     throw new RuntimeException(e1);
                 }
                 continue;
index 1c806742e9b141c7f836d9565a9f449255406b69..fc8ddc01bdfb2da52ef0aa6cd0bd28f519878377 100644 (file)
@@ -9,13 +9,6 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.util;
 
 import com.google.common.base.Preconditions;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
 
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -41,15 +34,4 @@ public final class Util {
                 + " should be " + clazz + " of " + value);
     }
 
-    // TODO: add message and proper error types
-    public static YangStoreSnapshot getYangStore(final YangStoreService yangStoreService)
-            throws NetconfDocumentedException {
-        try {
-            return yangStoreService.getYangStoreSnapshot();
-        } catch (final YangStoreException e) {
-            throw new NetconfDocumentedException("TODO", e, ErrorType.application, ErrorTag.bad_attribute,
-                    ErrorSeverity.error);
-        }
-    }
-
 }
index 11cf1aae6a42bc184dda8288dddcafa9ba47f419..f236a8d36ecda2d706c59eb425470cbda0799028 100644 (file)
@@ -143,12 +143,19 @@ public class NetconfMappingTest extends AbstractConfigTest {
                 "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
                 "ref_from_code_to_instance-from-code_1");
 
+
         edit("netconfMessages/editConfig_addServiceName.xml");
         config = getConfigCandidate();
         assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user",
                 "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
                 "ref_from_code_to_instance-from-code_1", "ref_dep_user_another");
 
+        edit("netconfMessages/editConfig_addServiceNameOnTest.xml");
+        config = getConfigCandidate();
+        assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user",
+                "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
+                "ref_from_code_to_instance-from-code_1", "ref_dep_user_another");
+
         commit();
         config = getConfigRunning();
         assertCorrectRefNamesForDependencies(config);
@@ -229,6 +236,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
 
         edit("netconfMessages/editConfig.xml");
         Element configCandidate = getConfigCandidate();
+        System.err.println(XmlUtil.toString(configCandidate));
         checkBinaryLeafEdited(configCandidate);
 
 
@@ -252,10 +260,8 @@ public class NetconfMappingTest extends AbstractConfigTest {
         commit();
         response = getConfigCandidate();
         final String responseFromCandidate = XmlUtil.toString(response).replaceAll("\\s+", "");
-        // System.out.println(responseFromCandidate);
         response = getConfigRunning();
         final String responseFromRunning = XmlUtil.toString(response).replaceAll("\\s+", "");
-        // System.out.println(responseFromRunning);
         assertEquals(responseFromCandidate, responseFromRunning);
 
         final String expectedResult = XmlFileLoader.fileToString("netconfMessages/editConfig_expectedResult.xml")
index 6e7a225f38452250ca4803c17ac56a2d2999822f..505a91c6cec4ba7f4ce1139059538d322cf8ed69 100644 (file)
@@ -23,7 +23,9 @@ import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.ValidateTest;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser.EditConfigExecution;
@@ -35,7 +37,7 @@ import java.util.Collections;
 import java.util.Map;
 
 import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyMap;
+import static org.mockito.Matchers.anyMapOf;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
@@ -82,8 +84,8 @@ public class EditConfigTest {
                 ValidateTest.NETCONF_SESSION_ID_FOR_REPORTING);
         EditConfigStrategy editStrat = mock(EditConfigStrategy.class);
 
-        doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMap(),
-                any(ConfigTransactionClient.class), any(Services.class));
+        doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMapOf(String.class, AttributeConfigElement.class),
+                any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class));
 
         EditConfigExecution editConfigExecution = mockExecution(editStrat);
 
@@ -96,20 +98,44 @@ public class EditConfigTest {
         verify(provider).getOrCreateTransaction();
 
         // For every instance execute strat
-        verify(editStrat, times(2/* Test */+ 2/* Set */)).executeConfiguration(anyString(), anyString(), anyMap(),
-                any(ConfigTransactionClient.class), any(Services.class));
+        verify(editStrat, times(2/* Test */+ 2/* Set */ + 2/*Handle missing instance Test*/ + 2 /*Handle missing instance Set*/)).executeConfiguration(anyString(),
+                anyString(), anyMapOf(String.class, AttributeConfigElement.class),
+                any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class));
     }
 
     private EditConfigExecution mockExecution(EditConfigStrategy editStrat) {
         EditConfigExecution mock = mock(EditConfigExecution.class);
-        doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements();
+        doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements(any(ConfigTransactionClient.class));
+        doReturn(getMappingDefinition(editStrat)).when(mock).getModulesDefinition(any(ConfigTransactionClient.class));
         doReturn(EditStrategyType.merge).when(mock).getDefaultStrategy();
         doReturn(true).when(mock).shouldSet();
         doReturn(true).when(mock).shouldTest();
-        doReturn(mockServices()).when(mock).getServices();
+        doReturn(mockServices()).when(mock).getServiceRegistryWrapper(any(ConfigTransactionClient.class));
+        doReturn(new Services()).when(mock).getServices();
         return mock;
     }
 
+    private Object getMappingDefinition(EditConfigStrategy editStrat) {
+        Map<String, Multimap<String, ModuleElementDefinition>> result = Maps.newHashMap();
+
+        Multimap<String, ModuleElementDefinition> innerMultimap = HashMultimap.create();
+        Map<String, AttributeConfigElement> attributes = getSimpleAttributes();
+
+        ModuleElementDefinition mockedDefinition = mock(ModuleElementDefinition.class);
+        doReturn(editStrat).when(mockedDefinition).getEditStrategy();
+        doReturn("i1").when(mockedDefinition).getInstanceName();
+        innerMultimap.put("m1", mockedDefinition);
+
+        ModuleElementDefinition mockedDefinition2 = mock(ModuleElementDefinition.class);
+        doReturn(editStrat).when(mockedDefinition2).getEditStrategy();
+        doReturn("i2").when(mockedDefinition2).getInstanceName();
+        innerMultimap.put("m1", mockedDefinition2);
+
+        result.put("n1", innerMultimap);
+
+        return result;
+    }
+
     private static ServiceReferenceReadableRegistry mockServiceRegistry() {
         ServiceReferenceReadableRegistry mock = mock(ServiceReferenceReadableRegistry.class);
         doReturn(
@@ -120,8 +146,8 @@ public class EditConfigTest {
         return mock;
     }
 
-    static Services mockServices() {
-        return new Services(mockServiceRegistry());
+    static ServiceRegistryWrapper mockServices() {
+        return new ServiceRegistryWrapper(mockServiceRegistry());
     }
 
     private Map<String, Multimap<String, ModuleElementResolved>> getMapping(EditConfigStrategy editStrat) {
index 1c3ac7a455c4f80eb8a1607f1e942bb2c91f3977..b66a1a57c20c9288b60e79cdb54daa1cf53bbec3 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.netconf.persist.impl;
 
+import org.opendaylight.controller.config.persist.api.Persister;
 import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
 import org.opendaylight.controller.netconf.api.jmx.DefaultCommitOperationMXBean;
 import org.opendaylight.controller.netconf.api.jmx.NetconfJMXNotification;
@@ -36,11 +37,11 @@ public class ConfigPersisterNotificationHandler implements NotificationListener,
     private static final Logger logger = LoggerFactory.getLogger(ConfigPersisterNotificationHandler.class);
     private final MBeanServerConnection mBeanServerConnection;
     private final NetconfClient netconfClient;
-    private final PersisterAggregator persisterAggregator;
+    private final Persister persisterAggregator;
     private final Pattern ignoredMissingCapabilityRegex;
 
     public ConfigPersisterNotificationHandler(MBeanServerConnection mBeanServerConnection, NetconfClient netconfClient,
-                                              PersisterAggregator persisterAggregator, Pattern ignoredMissingCapabilityRegex) {
+                                              Persister persisterAggregator, Pattern ignoredMissingCapabilityRegex) {
         this.mBeanServerConnection = mBeanServerConnection;
         this.netconfClient = netconfClient;
         this.persisterAggregator = persisterAggregator;
@@ -72,8 +73,9 @@ public class ConfigPersisterNotificationHandler implements NotificationListener,
         if (notification instanceof CommitJMXNotification) {
             try {
                 handleAfterCommitNotification((CommitJMXNotification) notification);
-            } catch (Exception e) {
-                // TODO: notificationBroadcast support logs only DEBUG
+            } catch (Throwable e) {
+                // log exceptions from notification Handler here since
+                // notificationBroadcastSupport logs only DEBUG level
                 logger.warn("Exception occured during notification handling: ", e);
                 throw e;
             }
index 811ba38c10068d470492a93073a656f6b0c42f79..86a024a240db6b97ba45cb493dba36b8fe1d1d62 100644 (file)
@@ -40,8 +40,6 @@ public final class Util {
         return true;
     }
 
-
-    // TODO: check if closing in correct order
     public static void closeClientAndDispatcher(NetconfClient client) {
         NetconfClientDispatcher dispatcher = client.getNetconfClientDispatcher();
         Exception fromClient = null;
index 656091115c8907aa5de61394e1a6a6f9da516317..3c901c3f59e1f45194a5d17cc7979f48932a623b 100644 (file)
@@ -78,7 +78,10 @@ public class ConfigPersisterActivator implements BundleActivator {
                             ignoredMissingCapabilityRegex);
                     jmxNotificationHandler.init();
                 } catch (InterruptedException e) {
-                    logger.info("Interrupted while waiting for netconf connection");
+                    Thread.currentThread().interrupt();
+                    logger.error("Interrupted while waiting for netconf connection");
+                    // uncaught exception handler will deal with this failure
+                    throw new RuntimeException("Interrupted while waiting for netconf connection", e);
                 }
             }
         };
index 15ed5c48fab01635635ea6578c3017d1bcd94a82..2a95cca937ddbee88a7f0723b47f2991d0c64a5f 100644 (file)
@@ -1,10 +1,9 @@
-/**
- * @author Tomas Olvecky
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
- * 11 2013
- *
- * Copyright (c) 2013 by Cisco Systems, Inc.
- * All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 package org.opendaylight.controller.netconf.persist.impl.osgi;
 
index 2ce779a1f54e9ce4f68b9c7f1db478d9de4e0201..67d95bb90f74ac2098c4677e5cdab002cb1624da 100644 (file)
@@ -71,6 +71,10 @@ public class NetconfClient implements Closeable {
         return new NetconfClient(clientLabelForLogging,address,strat,netconfClientDispatcher);
     }
 
+    public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strat, NetconfClientDispatcher netconfClientDispatcher,NetconfClientSessionListener listener) throws InterruptedException {
+        return new NetconfClient(clientLabelForLogging,address,strat,netconfClientDispatcher,listener);
+    }
+
     public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectTimeoutMs,
             NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
         this(clientLabelForLogging, address,
@@ -83,6 +87,17 @@ public class NetconfClient implements Closeable {
                 DEFAULT_CONNECT_TIMEOUT), netconfClientDispatcher);
     }
 
+    public NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strat,
+            NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException{
+        this.label = clientLabelForLogging;
+        dispatch = netconfClientDispatcher;
+        sessionListener = listener;
+        Future<NetconfClientSession> clientFuture = dispatch.createClient(address, sessionListener, strat);
+        this.address = address;
+        clientSession = get(clientFuture);
+        this.sessionId = clientSession.getSessionId();
+    }
+
     public NetconfMessage sendMessage(NetconfMessage message) {
         return sendMessage(message, 5, 1000);
     }
@@ -90,10 +105,12 @@ public class NetconfClient implements Closeable {
     public NetconfMessage sendMessage(NetconfMessage message, int attempts, int attemptMsDelay) {
         long startTime = System.currentTimeMillis();
         Preconditions.checkState(clientSession.isUp(), "Session was not up yet");
+        //logger.debug("Sending message: {}",XmlUtil.toString(message.getDocument()));
         clientSession.sendMessage(message);
         try {
             return sessionListener.getLastMessage(attempts, attemptMsDelay);
         } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
             throw new RuntimeException(this + " Cannot read message from " + address, e);
         } catch (IllegalStateException e) {
             throw new IllegalStateException(this + " Cannot read message from " + address, e);
index 1d2e039b290d9eef4c77e90fa99ef36257c29c5c..8dbdb26bff1934d1f2071be7114363985a16d5f7 100644 (file)
@@ -15,6 +15,8 @@ import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot;
 import org.opendaylight.controller.netconf.mapping.api.Capability;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.Collections;
 import java.util.Map;
@@ -24,6 +26,8 @@ public class CapabilityProviderImpl implements CapabilityProvider {
     private final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot;
     private final Set<String> capabilityURIs;
 
+    private static final Logger logger = LoggerFactory.getLogger(DefaultCommitNotificationProducer.class);
+
     public CapabilityProviderImpl(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) {
         this.netconfOperationServiceSnapshot = netconfOperationServiceSnapshot;
         Map<String, Capability> urisToCapabilitiesInternalMap = getCapabilitiesInternal(netconfOperationServiceSnapshot);
@@ -38,7 +42,11 @@ public class CapabilityProviderImpl implements CapabilityProvider {
             final Set<Capability> caps = netconfOperationService.getCapabilities();
 
             for (Capability cap : caps) {
-                // TODO check for duplicates ?
+
+                if(capabilityMap.containsKey(cap.getCapabilityUri())) {
+                    logger.debug("Duplicate capability {} from service {}", cap.getCapabilityUri(), netconfOperationService);
+                }
+
                 capabilityMap.put(cap.getCapabilityUri(), cap);
             }
         }
index 4f60788975fb910f5ae29a4fbac35b8f28d4fe08..7c5bd0cb21dcc25988c3e66c17f7821b3a780d11 100644 (file)
@@ -12,12 +12,13 @@ import io.netty.channel.ChannelFuture;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.util.concurrent.Promise;
-import java.net.InetSocketAddress;
 import org.opendaylight.controller.netconf.api.NetconfSession;
 import org.opendaylight.controller.netconf.impl.util.DeserializerExceptionHandler;
 import org.opendaylight.controller.netconf.util.AbstractChannelInitializer;
 import org.opendaylight.protocol.framework.AbstractDispatcher;
 
+import java.net.InetSocketAddress;
+
 public class NetconfServerDispatcher extends AbstractDispatcher<NetconfSession, NetconfServerSessionListener> {
 
     private final ServerChannelInitializer initializer;
@@ -28,7 +29,6 @@ public class NetconfServerDispatcher extends AbstractDispatcher<NetconfSession,
         this.initializer = serverChannelInitializer;
     }
 
-    // TODO test create server with same address twice
     public ChannelFuture createServer(InetSocketAddress address) {
 
         return super.createServer(address, new PipelineInitializer<NetconfSession>() {
index e74723032d247888c65b22c1eed7d9b62a543d71..91734beacbf57f3e164411b6832dcfda1ac93a02 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.netconf.impl;
 
+import com.google.common.base.Preconditions;
 import io.netty.channel.Channel;
 import io.netty.util.Timer;
 import io.netty.util.concurrent.Promise;
@@ -28,9 +29,12 @@ import org.w3c.dom.Node;
 
 import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathExpression;
+import java.io.InputStream;
 
 public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorFactory {
 
+    public static final String SERVER_HELLO_XML_LOCATION = "/server_hello.xml";
+
     private final Timer timer;
 
     private static final Document helloMessageTemplate = loadHelloMessageTemplate();
@@ -45,8 +49,11 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF
     }
 
     private static Document loadHelloMessageTemplate() {
-        return NetconfUtil.createMessage(
-                NetconfServerSessionNegotiatorFactory.class.getResourceAsStream("/server_hello.xml")).getDocument();
+        InputStream resourceAsStream = NetconfServerSessionNegotiatorFactory.class
+                .getResourceAsStream(SERVER_HELLO_XML_LOCATION);
+        Preconditions.checkNotNull(resourceAsStream, "Unable to load server hello message blueprint from %s",
+                SERVER_HELLO_XML_LOCATION);
+        return NetconfUtil.createMessage(resourceAsStream).getDocument();
     }
 
     @Override
index 1b3542595f319132820d6b762d305cff740d7a75..505c74714a71c269ad9721497cdbffaedd4fb706 100644 (file)
@@ -68,6 +68,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S
     @Override
     public Schemas getSchemas() {
         // FIXME, session ID
+        // capabilities should be split from operations (it will allow to move getSchema operation to monitoring module)
         return transformSchemas(factoriesListener.getSnapshot(0));
     }
 
@@ -78,6 +79,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S
 
         for (NetconfOperationService netconfOperationService : snapshot.getServices()) {
             // TODO check for duplicates ? move capability merging to snapshot
+            // Split capabilities from operations first and delete this duplicate code
             caps.addAll(netconfOperationService.getCapabilities());
         }
 
@@ -115,8 +117,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S
         monitoringLocations.add(new Schema.Location(Schema.Location.Enumeration.NETCONF));
 
         for (String location : locations) {
-            // TODO how to create enumerration from string location ?
-            // monitoringLocations.add(new Schema.Location(Schema.Location.Enumeration.valueOf(location)));
+            monitoringLocations.add(new Schema.Location(new Uri(location)));
         }
 
         return monitoringLocations;
index ee474dbba01f4068de6190662c50d25f8339749d..d70a15c18bdf933d56df70d7f7e9be07df6653da 100644 (file)
@@ -185,7 +185,6 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
     private NetconfOperationExecution getNetconfOperationWithHighestPriority(
             Document message, NetconfSession session) {
 
-        // TODO test
         TreeMap<HandlingPriority, Set<NetconfOperation>> sortedPriority = getSortedNetconfOperationsWithCanHandle(
                 message, session);
 
index f2c70d61011294d72ba798078bbc3dfc5254ceb2..621c8eaa8654c3de256d04cd5fdd54842b721b31 100644 (file)
@@ -1,11 +1,13 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.netconf.impl.util;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
+import com.google.common.base.Preconditions;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
@@ -13,12 +15,18 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 
-// TODO purge nulls
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
 public class NetconfUtil {
 
     private static final Logger logger = LoggerFactory.getLogger(NetconfUtil.class);
 
     public static NetconfMessage createMessage(final File f) {
+        Preconditions.checkNotNull(f, "File parameter was null");
         try {
             return createMessage(new FileInputStream(f));
         } catch (final FileNotFoundException e) {
@@ -28,6 +36,7 @@ public class NetconfUtil {
     }
 
     public static NetconfMessage createMessage(final InputStream is) {
+        Preconditions.checkNotNull(is, "InputStream parameter was null");
         Document doc = null;
         try {
             doc = XmlUtil.readXmlToDocument(is);
index 6b0316b6fcbba8b92b5823c44d51aa45661f7ae0..73eb608f0b7bac686c9dd02b5dbf656b723ed3c8 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.controller.netconf.impl;\r
 \r
 import static junit.framework.Assert.assertNotNull;\r
index 0140b65c146e4389ecc92e117d23685740ad3f4c..0ecc1cb38324ede5b3443706a071a68a3d21a9dc 100644 (file)
@@ -24,21 +24,14 @@ import java.net.InetSocketAddress;
 public class NetconfDispatcherImplTest {
 
     private EventLoopGroup nettyGroup;
+    private NetconfServerDispatcher dispatch;
+    private DefaultCommitNotificationProducer commitNot;
 
     @Before
     public void setUp() throws Exception {
         nettyGroup = new NioEventLoopGroup();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        nettyGroup.shutdownGracefully();
-    }
 
-    @Test
-    public void test() throws Exception {
-
-        DefaultCommitNotificationProducer commitNot = new DefaultCommitNotificationProducer(
+        commitNot = new DefaultCommitNotificationProducer(
                 ManagementFactory.getPlatformMBeanServer());
         NetconfOperationServiceFactoryListener factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
 
@@ -50,13 +43,20 @@ public class NetconfDispatcherImplTest {
                 factoriesListener, commitNot, idProvider, null);
         NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(serverNegotiatorFactory, listenerFactory);
 
-
-        NetconfServerDispatcher dispatch = new NetconfServerDispatcher(
+        dispatch = new NetconfServerDispatcher(
                 serverChannelInitializer, nettyGroup, nettyGroup);
+    }
 
+    @After
+    public void tearDown() throws Exception {
+        commitNot.close();
+        nettyGroup.shutdownGracefully();
+    }
+
+    @Test
+    public void test() throws Exception {
         InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 8333);
         ChannelFuture s = dispatch.createServer(addr);
-
-        commitNot.close();
+        s.get();
     }
 }
diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java
new file mode 100644 (file)
index 0000000..14f70d3
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.it;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.matchers.JUnitMatchers;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.opendaylight.controller.config.yang.store.api.YangStoreException;
+import org.opendaylight.controller.config.yang.store.impl.HardcodedYangStoreService;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
+import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
+import org.opendaylight.controller.netconf.client.NetconfClient;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
+import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
+import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
+import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory;
+import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
+import org.opendaylight.controller.netconf.impl.SessionIdProvider;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot;
+import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
+import org.opendaylight.controller.netconf.mapping.api.Capability;
+import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
+import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringActivator;
+import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringOperationService;
+import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler;
+import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+import static junit.framework.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+public class NetconfConfigPersisterITTest extends AbstractConfigTest {
+
+    private static final Logger logger =  LoggerFactory.getLogger(NetconfConfigPersisterITTest.class);
+
+    private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023);
+
+    private EventLoopGroup nettyThreadgroup;
+
+    private NetconfClientDispatcher clientDispatcher;
+
+    @Before
+    public void setUp() throws Exception {
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray(
+                new ModuleFactory[0])));
+
+        NetconfMonitoringServiceImpl monitoringService = new NetconfMonitoringServiceImpl(getFactoriesListener());
+
+        NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
+        factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore()));
+        factoriesListener
+                .onAddNetconfOperationServiceFactory(new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(
+                        new NetconfMonitoringOperationService(monitoringService)));
+
+        nettyThreadgroup = new NioEventLoopGroup();
+
+        NetconfServerDispatcher dispatch = createDispatcher(factoriesListener);
+        ChannelFuture s = dispatch.createServer(tcpAddress);
+        s.await();
+
+        clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup);
+    }
+
+    private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException {
+        final Collection<InputStream> yangDependencies = NetconfITTest.getBasicYangs();
+        return new HardcodedYangStoreService(yangDependencies);
+    }
+
+    private NetconfServerDispatcher createDispatcher(
+                                                     NetconfOperationServiceFactoryListenerImpl factoriesListener) {
+        SessionIdProvider idProvider = new SessionIdProvider();
+        NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
+                new HashedWheelTimer(5000, TimeUnit.MILLISECONDS), factoriesListener, idProvider);
+
+        NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
+                factoriesListener, new DefaultCommitNotificationProducer(platformMBeanServer), idProvider, mockSessionMonitoringService());
+
+        NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(
+                serverNegotiatorFactory, listenerFactory);
+        return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
+    }
+
+    private SessionMonitoringService mockSessionMonitoringService() {
+        SessionMonitoringService mockedSessionMonitor = mock(SessionMonitoringService.class);
+        doNothing().when(mockedSessionMonitor).onSessionUp(any(NetconfManagementSession.class));
+        doNothing().when(mockedSessionMonitor).onSessionDown(any(NetconfManagementSession.class));
+        return mockedSessionMonitor;
+    }
+
+    @Test
+    public void testNetconfCommitNotifications() throws Exception {
+
+        VerifyingNotificationListener notificationVerifier = createCommitNotificationListener();
+        VerifyingPersister mockedAggregator = mockAggregator();
+
+        try (NetconfClient persisterClient = new NetconfClient("persister", tcpAddress, 4000, clientDispatcher)) {
+            ConfigPersisterNotificationHandler configPersisterNotificationHandler = new ConfigPersisterNotificationHandler(
+                    platformMBeanServer, persisterClient, mockedAggregator,
+                    Pattern.compile(""));
+            configPersisterNotificationHandler.init();
+
+            try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, 4000, clientDispatcher)) {
+                NetconfMessage response = netconfClient.sendMessage(loadGetConfigMessage());
+                assertResponse(response, "<modules");
+                assertResponse(response, "<services");
+                response = netconfClient.sendMessage(loadCommitMessage());
+                assertResponse(response, "ok");
+
+                response = netconfClient.sendMessage(loadEditConfigMessage());
+                assertResponse(response, "ok");
+                response = netconfClient.sendMessage(loadCommitMessage());
+                assertResponse(response, "ok");
+            }
+        }
+
+        notificationVerifier.assertNotificationCount(2);
+        notificationVerifier.assertNotificationContent(0, 0, 0, 9);
+        notificationVerifier.assertNotificationContent(1, 4, 4, 9);
+
+        mockedAggregator.assertSnapshotCount(2);
+        // Capabilities are stripped for persister
+        mockedAggregator.assertSnapshotContent(0, 0, 0, 1);
+        mockedAggregator.assertSnapshotContent(1, 4, 4, 3);
+    }
+
+    private VerifyingPersister mockAggregator() throws IOException {
+        return new VerifyingPersister();
+    }
+
+    private VerifyingNotificationListener createCommitNotificationListener() throws InstanceNotFoundException {
+        VerifyingNotificationListener listener = new VerifyingNotificationListener();
+        platformMBeanServer.addNotificationListener(DefaultCommitNotificationProducer.objectName, listener, null, null);
+        return listener;
+    }
+
+    private void assertResponse(NetconfMessage response, String content) {
+        Assert.assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString(content));
+    }
+
+    private NetconfMessage loadGetConfigMessage() throws Exception {
+        return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
+    }
+
+    private NetconfMessage loadEditConfigMessage() throws Exception {
+        return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig.xml");
+    }
+
+    private NetconfMessage loadCommitMessage() throws Exception {
+        return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml");
+    }
+
+
+    public NetconfOperationServiceFactoryListener getFactoriesListener() {
+        NetconfOperationServiceFactoryListener factoriesListener = mock(NetconfOperationServiceFactoryListener.class);
+        NetconfOperationServiceSnapshot snap = mock(NetconfOperationServiceSnapshot.class);
+        NetconfOperationService service = mock(NetconfOperationService.class);
+        Set<Capability> caps = Sets.newHashSet();
+        doReturn(caps).when(service).getCapabilities();
+        Set<NetconfOperationService> services = Sets.newHashSet(service);
+        doReturn(services).when(snap).getServices();
+        doReturn(snap).when(factoriesListener).getSnapshot(anyLong());
+
+        return factoriesListener;
+    }
+
+    private static class VerifyingNotificationListener implements NotificationListener {
+        public List<Notification> notifications = Lists.newArrayList();
+
+        @Override
+        public void handleNotification(Notification notification, Object handback) {
+            this.notifications.add(notification);
+        }
+
+        void assertNotificationCount(Object size) {
+            assertEquals(size, notifications.size());
+        }
+
+        void assertNotificationContent(int notificationIndex, int expectedModulesSize, int expectedServicesSize, int expectedCapsSize) {
+            Notification notification = notifications.get(notificationIndex);
+            assertEquals(CommitJMXNotification.class, notification.getClass());
+            int capsSize = ((CommitJMXNotification) notification).getCapabilities().size();
+            assertEquals("Expected capabilities count", expectedCapsSize, capsSize);
+            Element configSnapshot = ((CommitJMXNotification) notification).getConfigSnapshot();
+            int modulesSize = configSnapshot.getElementsByTagName("module").getLength();
+            assertEquals("Expected modules count", expectedModulesSize, modulesSize);
+            int servicesSize = configSnapshot.getElementsByTagName("instance").getLength();
+            assertEquals("Expected services count", expectedServicesSize, servicesSize);
+        }
+    }
+
+    private static class VerifyingPersister implements Persister {
+
+        public List<ConfigSnapshotHolder> snapshots = Lists.newArrayList();
+        private Persister mockedPersister;
+
+        public VerifyingPersister() throws IOException {
+            Persister mockedAggregator = mock(Persister.class);
+
+            doAnswer(new Answer() {
+                @Override
+                public Object answer(InvocationOnMock invocation) throws Throwable {
+                    ConfigSnapshotHolder configSnapshot = (ConfigSnapshotHolder) invocation.getArguments()[0];
+                    snapshots.add(configSnapshot);
+                    return null;
+                }
+            }).when(mockedAggregator).persistConfig(any(ConfigSnapshotHolder.class));
+
+            this.mockedPersister = mockedAggregator;
+        }
+
+        void assertSnapshotCount(Object size) {
+            assertEquals(size, snapshots.size());
+        }
+
+        void assertSnapshotContent(int notificationIndex, int expectedModulesSize, int expectedServicesSize, int expectedCapsSize) {
+            ConfigSnapshotHolder snapshot = snapshots.get(notificationIndex);
+            int capsSize = snapshot.getCapabilities().size();
+            assertEquals("Expected capabilities count", expectedCapsSize, capsSize);
+            String configSnapshot = snapshot.getConfigSnapshot();
+            int modulesSize = StringUtils.countMatches(configSnapshot, "<module>");
+            assertEquals("Expected modules count", expectedModulesSize, modulesSize);
+            int servicesSize = StringUtils.countMatches(configSnapshot, "<instance>");
+            assertEquals("Expected services count", expectedServicesSize, servicesSize);
+        }
+
+        @Override
+        public void persistConfig(ConfigSnapshotHolder configSnapshotHolder) throws IOException {
+            mockedPersister.persistConfig(configSnapshotHolder);
+        }
+
+        @Override
+        public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
+            return mockedPersister.loadLastConfigs();
+        }
+
+        @Override
+        public void close() {
+            mockedPersister.close();
+        }
+    }
+}
index 4818b5f0a3c7868be0a02dafd19e8c1657e0d777..36f30dd328f66367cf2582af790dde7b91263134 100644 (file)
@@ -16,19 +16,6 @@ import io.netty.channel.ChannelFuture;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.HashedWheelTimer;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.management.ManagementFactory;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import javax.management.ObjectName;
-import javax.xml.parsers.ParserConfigurationException;
 import junit.framework.Assert;
 import org.junit.After;
 import org.junit.Before;
@@ -74,6 +61,21 @@ import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.xml.sax.SAXException;
+
+import javax.management.ObjectName;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
 import static java.util.Collections.emptyList;
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
@@ -215,20 +217,6 @@ public class NetconfITTest extends AbstractConfigTest {
         }
     }
 
-
-    //TODO: test persister actually
-    @Ignore
-    @Test(timeout = 10000)
-    public void testPersister() throws Exception {
-//        Persister persister = mock(Persister.class);
-//        doReturn("mockPersister").when(persister).toString();
-//        doReturn(Collections.emptyList()).when(persister).loadLastConfigs();
-//        ConfigPersisterNotificationHandler h =
-//                new ConfigPersisterNotificationHandler(persister, tcpAddress, ManagementFactory.getPlatformMBeanServer(),
-//                        Pattern.compile(ConfigPersisterActivator.DEFAULT_IGNORED_REGEX));
-//        h.init();
-    }
-
     @Ignore
     @Test
     public void waitingTest() throws Exception {
@@ -432,7 +420,8 @@ public class NetconfITTest extends AbstractConfigTest {
     private void startSSHServer() throws Exception{
         logger.info("Creating SSH server");
         StubUserManager um = new StubUserManager(USERNAME,PASSWORD);
-        AuthProvider ap = new AuthProvider(um);
+        InputStream is = getClass().getResourceAsStream("/RSA.pk");
+        AuthProvider ap = new AuthProvider(um, is);
         Thread sshServerThread = new Thread(NetconfSSHServer.start(10830,tcpAddress,ap));
         sshServerThread.setDaemon(true);
         sshServerThread.start();
index 3a7b7de7a0b2a589b410ddd76996556412e64434..b0821799b0b57ad94682fe6ec58cba61ac0dee97 100644 (file)
@@ -7,27 +7,14 @@
  */
 package org.opendaylight.controller.netconf.it;
 
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
+import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.HashedWheelTimer;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
 import junit.framework.Assert;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.matchers.JUnitMatchers;
@@ -61,9 +48,20 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 
 public class NetconfMonitoringITTest extends AbstractConfigTest {
 
@@ -177,7 +175,6 @@ public class NetconfMonitoringITTest extends AbstractConfigTest {
 
                 responseBuilder.append(line);
                 responseBuilder.append(System.lineSeparator());
-                System.out.println(responseBuilder.toString());
 
                 if(line.contains("</rpc-reply>"))
                     break;
@@ -197,7 +194,7 @@ public class NetconfMonitoringITTest extends AbstractConfigTest {
         return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/get.xml");
     }
 
-    public NetconfOperationServiceFactoryListener getFactoriesListener() {
+    public static NetconfOperationServiceFactoryListener getFactoriesListener() {
         NetconfOperationServiceFactoryListener factoriesListener = mock(NetconfOperationServiceFactoryListener.class);
         NetconfOperationServiceSnapshot snap = mock(NetconfOperationServiceSnapshot.class);
         NetconfOperationService service = mock(NetconfOperationService.class);
diff --git a/opendaylight/netconf/netconf-it/src/test/resources/RSA.pk b/opendaylight/netconf/netconf-it/src/test/resources/RSA.pk
new file mode 100644 (file)
index 0000000..c0266c7
--- /dev/null
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAuC9hbEacpewvylI0mwFwjy3Wou2hpr/ncN9BBiFDSaG5yW2k
+3Oy+SCAcFCL+ZKWb6cc6Ch4gUeCwyEHRojZguuhliKtak9YQf6qbvpPLe00842Lx
+iqNAGurMpzizCDsGFq8ChaAkBZQI3TvcHuPoSUWSMJ+K8xHpRyUdVr6g2yEjezKJ
+sTXBtWaeCCh6YUafFujuDJk7fvYcPW7Je5KRBBStIKvxcMW0zB+7eq04deTHwGbJ
+gGjKWilQ72hsDDP3Hbp5CJMAYg1r4GlCmFx3KyHRGztgWgNgaD7nNpKCkTLjtmA6
+b4x7TA+jrzZ6Af2z5TMrI4dv5w1SrxHaZ+ziLQIDAQABAoIBAHTndeGgq/rQf8De
+Do+4CTaHtK0zQSAyu/azbXUzlZ7drKuCEVs8VMY4wzmwwGEnkF+A2YDkgEUX5X0l
+8aYQ97KKoS9u+43MGCrAIhyDeGrpqlT1TzRcy+qJz53v6gq2U/X/3QztiQ+VV078
+mIluxNgE9XYxPaNsYfGLSCTv1+9c8y/hjGVX2kwFK+u4ut0ZZETggNa8UxfaHVDS
+fIJQX9Gm3J3GSUV30fDGMBIUW6ESLc2L8b7u8Mp9TRP39ZeQSuEUjBe8MYKv0Rel
+oEpjZvcnniMTpFbLpndBYn7/AoIiEBvtCN8faVTuRRcvvLcsRm09IctzKQYnMh6M
+6PLKV+ECgYEA8HFRYaKHUzxpzE/fyon82GQbzqFFY0/bbWrfWICMfNbIgshJUie6
+FmH5iUFMfeqaT7v557HFM0GB9FeIeSbvd88YmiBAcRopZ3DfMkDH+DT73yJ+/TKG
+2nrQtdhyuTIs4bwHqeS2BBJYs7PK9R2rratF3l34Tf7mjlvyOgygHdUCgYEAxBo2
+8hEBlAVNcNb1hTYUxe1w1B6675/mFlmw98Xmj9dRYfICXNhahs8tX3/lsBEd+vBu
+fI0oyHaff8m5bPgGzD1ZMybfeROujNrgxaKVk7Ef0FDRRCop4bm18OroFlFAt9l8
+wMp++ToACbdvQvL/mjWMPYlIxhB/YxHswICZZvkCgYAexxKYwdo6sGAGlC7cWT9x
+X5cjowcjyEQZRHXkeUgCbufpvcOM7aLnXJE5nY8yCwbHsBM0MlBA2GDPKylAANjk
+aDEJAZneIHAuWodngl1Wi0m2bU7+ECqs6s2uiU9eH2sZVh1RBQK7kLGkBx6ys6KX
+L3ZZGYRAT6GplWFzRsx0JQKBgCeVlxPD5QqpC1nEumi6YvUVGdpnnZpzL3HBhxxs
+wT612wKnZFyze4qM1X7ahVXGDsQxtkvD/sCAWW/lG13orw6ZL6FIroF1PJ3ILOkY
+CZN3hJF7TtKwpCWhZB2OfWzL2AGEkE8mUP0j/Q/5DCd6f6f0OSvOw3bfq6cm3iB5
+lP2ZAoGAXsRN5TZTX4AQ2xTlrDQ8A5XgcvyWQpJOmEXMTyHV7VaJVzmNWFVAvndK
+5UIq8ALDwB2t7vjmMUW6euvIwqtXiop7G79UOb3e3NhzeyWFGQyBLqCRznGaXQTT
+dlFy73xhukZMhFnj006bjKCYvOPnwuGl3+0fuWil5Rq3jOuY5c8=
+-----END RSA PRIVATE KEY-----
index f6f05f6bde6344f089ad14151fa3f60645ca886d..816650c4bb457c14ffff7a0ebe759d016ad1b0fd 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.controller.netconf.mapping.api;\r
 \r
 import org.opendaylight.controller.netconf.api.NetconfSession;\r
index 5a0688c8d14dd4fd4d2d3de0be37b7ca40c5a802..176cf2d28c02d54dbaeedc39abe23357e27d8324 100644 (file)
@@ -36,8 +36,6 @@ public class HandlingPriority implements Comparable<HandlingPriority> {
         return Optional.of(priority).or(Optional.<Integer> absent());
     }
 
-    // TODO test
-
     @Override
     public int compareTo(HandlingPriority o) {
         if (this == o)
index 8771421a111514f0ba064f7ae108fa366809252a..85da5975d1f22caaf4485ebea88484e9ad1f242c 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 @XmlSchema(
         elementFormDefault = XmlNsForm.QUALIFIED,
 //        xmlns = {
index 1e3f343624726e9ff0af80f98c3da32e9233f7c5..d4462f85d99e2f3cf267b3e7cffca82670b9d0a3 100644 (file)
@@ -7,15 +7,10 @@
 */
 package org.opendaylight.controller.netconf.monitoring.xml;
 
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import java.util.Date;
-
+import com.google.common.collect.Lists;
 import org.junit.Test;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.controller.netconf.monitoring.xml.model.NetconfState;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.DomainName;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.Session1;
@@ -30,7 +25,10 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.ZeroBasedCounter32;
 import org.w3c.dom.Element;
 
-import com.google.common.collect.Lists;
+import java.util.Date;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 
 public class JaxBSerializerTest {
 
@@ -51,7 +49,6 @@ public class JaxBSerializerTest {
         };
         NetconfState model = new NetconfState(service);
         Element xml = new JaxBSerializer().toXml(model);
-        System.out.println(XmlUtil.toString(xml));
     }
 
     private Session getMockSession() {
index 5dde0448bd03ac6b16b49aee77f5589969ea77d1..d91564ba0ba3a6b70292f83e028debeb318ce261 100644 (file)
                 <configuration>
                     <instructions>
                         <Bundle-Activator>org.opendaylight.controller.netconf.osgi.NetconfSSHActivator</Bundle-Activator>
-                        <Export-Package>
-                            org.opendaylight.controller.netconf.ssh,
-                        </Export-Package>
                         <Import-Package>
                             com.google.common.base,
                             ch.ethz.ssh2,
                             ch.ethz.ssh2.signature,
-                            java.net,
-                            javax.annotation,
                             org.apache.commons.io,
-                            org.opendaylight.controller.netconf.util,
                             org.opendaylight.controller.netconf.util.osgi,
                             org.opendaylight.controller.usermanager,
                             org.opendaylight.controller.sal.authorization,
                             org.opendaylight.controller.sal.utils,
-                            org.opendaylight.protocol.framework,
                             org.osgi.framework,
                             org.osgi.util.tracker,
                             org.slf4j,
index 3b513790bd128806a7ef1bec2561bd90fee6420a..1bce3143d5a8fc29831bc5b90a62fdad8d9376ad 100644 (file)
@@ -8,6 +8,8 @@
 package org.opendaylight.controller.netconf.osgi;
 
 import com.google.common.base.Optional;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.net.InetSocketAddress;
 import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
 import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
@@ -42,7 +44,7 @@ public class NetconfSSHActivator implements BundleActivator{
     ServiceTrackerCustomizer<IUserManager, IUserManager> customizer = new ServiceTrackerCustomizer<IUserManager, IUserManager>(){
         @Override
         public IUserManager addingService(ServiceReference<IUserManager> reference) {
-            logger.info("Service IUserManager added, let there be SSH bridge.");
+            logger.info("Service {} added, let there be SSH bridge.", reference);
             iUserManager =  context.getService(reference);
             try {
                 onUserManagerFound(iUserManager);
@@ -53,13 +55,13 @@ public class NetconfSSHActivator implements BundleActivator{
         }
         @Override
         public void modifiedService(ServiceReference<IUserManager> reference, IUserManager service) {
-            logger.info("Replacing modified service IUserManager in netconf SSH.");
+            logger.info("Replacing modified service {} in netconf SSH.", reference);
             server.addUserManagerService(service);
         }
         @Override
         public void removedService(ServiceReference<IUserManager> reference, IUserManager service) {
-            logger.info("Removing service IUserManager from netconf SSH. " +
-                    "SSH won't authenticate users until IUserManeger service will be started.");
+            logger.info("Removing service {} from netconf SSH. " +
+                    "SSH won't authenticate users until IUserManeger service will be started.", reference);
             removeUserManagerService();
         }
     };
@@ -85,7 +87,28 @@ public class NetconfSSHActivator implements BundleActivator{
                 EXCEPTION_MESSAGE, true);
 
         if (sshSocketAddressOptional.isPresent()){
-            AuthProvider authProvider = new AuthProvider(iUserManager);
+            String path = NetconfConfigUtil.getPrivateKeyPath(context);
+            path = path.replace("\\", "/");
+            if (path.equals("")){
+                throw new Exception("Missing netconf.ssh.pk.path key in configuration file.");
+            }
+            FileInputStream fis = null;
+            try {
+                fis = new FileInputStream(path);
+            } catch (FileNotFoundException e){
+                throw new Exception("Missing file described by netconf.ssh.pk.path key in configuration file.");
+            } catch (SecurityException e){
+                throw new Exception("Read access denied to file described by netconf.ssh.pk.path key in configuration file.");
+            }
+            AuthProvider authProvider = null;
+            try {
+                authProvider = new AuthProvider(iUserManager,fis);
+            } catch (Exception e){
+                if (fis!=null){
+                    fis.close();
+                }
+                throw (e);
+            }
             this.server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress,authProvider);
             Thread serverThread = new  Thread(server,"netconf SSH server thread");
             serverThread.setDaemon(true);
index a73dfdfd49eca56129a5ba0e98efb13fba001556..22dda95064c092c286a1046edc90595943485a0d 100644 (file)
@@ -7,8 +7,6 @@
  */
 package org.opendaylight.controller.netconf.ssh.authentication;
 
-import ch.ethz.ssh2.signature.RSAPrivateKey;
-import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
@@ -17,26 +15,30 @@ import org.opendaylight.controller.sal.authorization.AuthResultEnum;
 import org.opendaylight.controller.sal.authorization.UserLevel;
 import org.opendaylight.controller.usermanager.IUserManager;
 import org.opendaylight.controller.usermanager.UserConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class AuthProvider implements AuthProviderInterface {
 
-    private static RSAPrivateKey hostkey = null;
     private static IUserManager um;
-    private static final String DEAFULT_USER = "netconf";
-    private static final String DEAFULT_PASSWORD = "netconf";
+    private static final String DEFAULT_USER = "netconf";
+    private static final String DEFAULT_PASSWORD = "netconf";
+    private static InputStream privateKeyFileInputStream;
 
+    private static final Logger logger =  LoggerFactory.getLogger(AuthProvider.class);
 
-    public AuthProvider(IUserManager ium) throws Exception {
+    public AuthProvider(IUserManager ium,InputStream privateKeyFileInputStream) throws Exception {
 
         this.um = ium;
-
         if (this.um  == null){
             throw new Exception("No usermanager service available.");
         }
 
+        this.privateKeyFileInputStream = privateKeyFileInputStream;
+
         List<String> roles = new ArrayList<String>(1);
         roles.add(UserLevel.SYSTEMADMIN.toString());
-        this.um.addLocalUser(new UserConfig(DEAFULT_USER, DEAFULT_PASSWORD, roles));
+        this.um.addLocalUser(new UserConfig(DEFAULT_USER, DEFAULT_PASSWORD, roles));
     }
     @Override
     public boolean authenticated(String username, String password)  throws Exception {
@@ -51,15 +53,10 @@ public class AuthProvider implements AuthProviderInterface {
     }
 
     @Override
-    public char[] getPEMAsCharArray() {
-
-        InputStream is = getClass().getResourceAsStream("/RSA.pk");
-        try {
-            return IOUtils.toCharArray(is);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return null;
+    public char[] getPEMAsCharArray() throws Exception {
+        char [] PEM  = IOUtils.toCharArray(privateKeyFileInputStream);
+        privateKeyFileInputStream.close();
+        return PEM;
     }
 
     @Override
index 71f1cc350fda1d5d829cb101798d208eaf1bc906..8e40578a0e47c001676b8fb28809a9cf306364e2 100644 (file)
@@ -13,7 +13,7 @@ import org.opendaylight.controller.usermanager.IUserManager;
 public interface AuthProviderInterface {
 
     public boolean authenticated(String username, String password) throws Exception;
-    public char[] getPEMAsCharArray();
+    public char[] getPEMAsCharArray() throws Exception;
     public void removeUserManagerService();
     public void addUserManagerService(IUserManager userManagerService);
 }
index e5da03b4cf4c9d97765ce098a8c2761b0eda8e39..d159f59f1a2cedcefeca01bf24b93854c4fa269b 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.netconf.ssh.threads;
 
 
@@ -59,8 +66,8 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser
         conn = new ServerConnection(socket);
         try {
             conn.setPEMHostKey(authProvider.getPEMAsCharArray(),"netconf");
-        } catch (IOException e) {
-            e.printStackTrace();
+        } catch (Exception e) {
+            logger.debug("Server authentication setup failed.");
         }
         conn.setAuthenticationCallback(this);
         conn.setServerConnectionCallback(this);
@@ -108,6 +115,7 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser
                                         netconf_ssh_input.join();
                                     }
                                 } catch (InterruptedException e) {
+                                    Thread.currentThread().interrupt();
                                    logger.error("netconf_ssh_input join error ",e);
                                 }
 
@@ -116,6 +124,7 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser
                                         netconf_ssh_output.join();
                                     }
                                 } catch (InterruptedException e) {
+                                    Thread.currentThread().interrupt();
                                     logger.error("netconf_ssh_output join error ",e);
                                 }
 
index 62396ed87ac1f4db3dcaa7942f676012ab35ade8..91783ff755b5e934af8359c47f25b51d9ed5cd23 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.netconf;
 
 import ch.ethz.ssh2.Connection;
+import java.io.InputStream;
 import java.net.InetSocketAddress;
 import junit.framework.Assert;
 import org.junit.Test;
@@ -33,7 +34,8 @@ public class SSHServerTest {
     public void startSSHServer() throws Exception{
         logger.info("Creating SSH server");
         StubUserManager um = new StubUserManager(USER,PASSWORD);
-        AuthProvider ap = new AuthProvider(um);
+        InputStream is = getClass().getResourceAsStream("/RSA.pk");
+        AuthProvider ap = new AuthProvider(um, is);
         NetconfSSHServer server = NetconfSSHServer.start(PORT,tcpAddress,ap);
         sshServerThread = new Thread(server);
         sshServerThread.setDaemon(true);
diff --git a/opendaylight/netconf/netconf-ssh/src/test/resources/RSA.pk b/opendaylight/netconf/netconf-ssh/src/test/resources/RSA.pk
new file mode 100644 (file)
index 0000000..c0266c7
--- /dev/null
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAuC9hbEacpewvylI0mwFwjy3Wou2hpr/ncN9BBiFDSaG5yW2k
+3Oy+SCAcFCL+ZKWb6cc6Ch4gUeCwyEHRojZguuhliKtak9YQf6qbvpPLe00842Lx
+iqNAGurMpzizCDsGFq8ChaAkBZQI3TvcHuPoSUWSMJ+K8xHpRyUdVr6g2yEjezKJ
+sTXBtWaeCCh6YUafFujuDJk7fvYcPW7Je5KRBBStIKvxcMW0zB+7eq04deTHwGbJ
+gGjKWilQ72hsDDP3Hbp5CJMAYg1r4GlCmFx3KyHRGztgWgNgaD7nNpKCkTLjtmA6
+b4x7TA+jrzZ6Af2z5TMrI4dv5w1SrxHaZ+ziLQIDAQABAoIBAHTndeGgq/rQf8De
+Do+4CTaHtK0zQSAyu/azbXUzlZ7drKuCEVs8VMY4wzmwwGEnkF+A2YDkgEUX5X0l
+8aYQ97KKoS9u+43MGCrAIhyDeGrpqlT1TzRcy+qJz53v6gq2U/X/3QztiQ+VV078
+mIluxNgE9XYxPaNsYfGLSCTv1+9c8y/hjGVX2kwFK+u4ut0ZZETggNa8UxfaHVDS
+fIJQX9Gm3J3GSUV30fDGMBIUW6ESLc2L8b7u8Mp9TRP39ZeQSuEUjBe8MYKv0Rel
+oEpjZvcnniMTpFbLpndBYn7/AoIiEBvtCN8faVTuRRcvvLcsRm09IctzKQYnMh6M
+6PLKV+ECgYEA8HFRYaKHUzxpzE/fyon82GQbzqFFY0/bbWrfWICMfNbIgshJUie6
+FmH5iUFMfeqaT7v557HFM0GB9FeIeSbvd88YmiBAcRopZ3DfMkDH+DT73yJ+/TKG
+2nrQtdhyuTIs4bwHqeS2BBJYs7PK9R2rratF3l34Tf7mjlvyOgygHdUCgYEAxBo2
+8hEBlAVNcNb1hTYUxe1w1B6675/mFlmw98Xmj9dRYfICXNhahs8tX3/lsBEd+vBu
+fI0oyHaff8m5bPgGzD1ZMybfeROujNrgxaKVk7Ef0FDRRCop4bm18OroFlFAt9l8
+wMp++ToACbdvQvL/mjWMPYlIxhB/YxHswICZZvkCgYAexxKYwdo6sGAGlC7cWT9x
+X5cjowcjyEQZRHXkeUgCbufpvcOM7aLnXJE5nY8yCwbHsBM0MlBA2GDPKylAANjk
+aDEJAZneIHAuWodngl1Wi0m2bU7+ECqs6s2uiU9eH2sZVh1RBQK7kLGkBx6ys6KX
+L3ZZGYRAT6GplWFzRsx0JQKBgCeVlxPD5QqpC1nEumi6YvUVGdpnnZpzL3HBhxxs
+wT612wKnZFyze4qM1X7ahVXGDsQxtkvD/sCAWW/lG13orw6ZL6FIroF1PJ3ILOkY
+CZN3hJF7TtKwpCWhZB2OfWzL2AGEkE8mUP0j/Q/5DCd6f6f0OSvOw3bfq6cm3iB5
+lP2ZAoGAXsRN5TZTX4AQ2xTlrDQ8A5XgcvyWQpJOmEXMTyHV7VaJVzmNWFVAvndK
+5UIq8ALDwB2t7vjmMUW6euvIwqtXiop7G79UOb3e3NhzeyWFGQyBLqCRznGaXQTT
+dlFy73xhukZMhFnj006bjKCYvOPnwuGl3+0fuWil5Rq3jOuY5c8=
+-----END RSA PRIVATE KEY-----
index 4fee930eff7db3c3ecfe5beb0bd113c9acfd5366..26ea7ceb79d4b78d98ecf42af34d7be87364ffcb 100644 (file)
@@ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit;
 public abstract class AbstractNetconfSessionNegotiator<P extends NetconfSessionPreferences, S extends NetconfSession>
         extends AbstractSessionNegotiator<NetconfMessage, S> {
 
-    // TODO what time ?
+    // TODO Adjust wait time for negotiation, now is 1 minute ?
     private static final long INITIAL_HOLDTIMER = 1;
 
     private static final Logger logger = LoggerFactory.getLogger(AbstractNetconfSessionNegotiator.class);
index 12d1129daff5c6b3c4a7aa4324e4de14385a9347..8636e5ecb5fe55f22ce01cf9a19fb537397c9b0e 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.netconf.util.handler.ssh.client;
 
 import java.io.IOException;
index 07c81b0ccb7127aad1a5ffc14a3e6d6412dd1446..4b9bfbf5f826ee13c34127d902c2ad583d5f8eb4 100644 (file)
@@ -57,6 +57,7 @@ public class ChannelInputStream extends InputStream implements ChannelInboundHan
                 try {
                     lock.wait();
                 } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
                     throw new RuntimeException(e);
                 }
             }
index 987708d67ed03db1276a6459ad47c75f7eabf0bf..55ed7e074423968dd7e7626e45a181893cdfd4a1 100644 (file)
@@ -23,6 +23,7 @@ public class NetconfConfigUtil {
     private static final String PORT_SUFFIX_PROP = ".port";
     private static final String ADDRESS_SUFFIX_PROP = ".address";
     private static final String CLIENT_PROP = ".client";
+    private static final String PRIVATE_KEY_PATH_PROP = ".pk.path";
 
     public static InetSocketAddress extractTCPNetconfAddress(BundleContext context, String exceptionMessageIfNotFound, boolean forClient) {
 
@@ -38,6 +39,16 @@ public class NetconfConfigUtil {
         return extractSomeNetconfAddress(context, InfixProp.ssh, exceptionMessage, false);
     }
 
+    public static String getPrivateKeyPath(BundleContext context){
+        return getPropertyValue(context,PREFIX_PROP + InfixProp.ssh +PRIVATE_KEY_PATH_PROP);
+    }
+    private static String getPropertyValue(BundleContext context, String propertyName){
+        String propertyValue = context.getProperty(propertyName);
+        if (propertyValue == null){
+            throw new IllegalStateException("Cannot find initial property with name '"+propertyName+"'");
+        }
+        return propertyValue;
+    }
     /**
      * @param context
      *            from which properties are being read.
index 63dfcde0c6f49e5685dbfcfb6adff4b8350c5668..7109971b5d56625f57d35b607d831b21433986e3 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.controller.netconf.util.xml;\r
 \r
 import com.siemens.ct.exi.CodingMode;\r
index 8baa68e494272ebda3658527525ff09c95df9398..82bbb66c02a74c0f13a022511d6f08b9b6643819 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.controller.netconf.util.xml;\r
 \r
 import io.netty.buffer.ByteBuf;\r
diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml
new file mode 100644 (file)
index 0000000..6e68326
--- /dev/null
@@ -0,0 +1,38 @@
+<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <edit-config>
+        <target>
+            <candidate/>
+        </target>
+        <test-option>
+            test-only
+        </test-option>
+        <default-operation>merge</default-operation>
+        <config>
+            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+
+                <module>
+                    <name>instance-from-code_dep</name>
+                    <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
+                        test-impl:impl-dep
+                    </type>
+                </module>
+            </modules>
+
+            <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <service>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
+                    <instance>
+                        <name>ref_dep_user_another_test1</name>
+                        <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
+                        </provider>
+                    </instance>
+                    <instance>
+                        <name>ref_dep_user_another_test2</name>
+                        <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
+                        </provider>
+                    </instance>
+                </service>
+            </services>
+        </config>
+    </edit-config>
+</rpc>
index 7f884dc43c605af7537a95ed7d0bce71e93d577a..36f79a50bcceaaed5649492b69dff79ff08ee157 100644 (file)
@@ -1,19 +1,6 @@
 <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" id="a" message-id="101" xmlnx="a:b:c:d">
     <data>
-        <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-            <!--<module>
-            <type>impl</type>
-            </module>
-            -->
-            <!--<module>
-            <type>impl-dep</type>
-            </module>
-            -->
-            <!--<module>
-            <type>impl-netconf</type>
-            </module>
-            -->
-        </modules>
+        <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config"/>
         <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config"/>
     </data>
 </rpc-reply>
index a7f1c863910f4b24b421531b82ffb9cb68499452..ade40f6a49c94f2a682b7e55e1ec1a3d79e03ecc 100644 (file)
                     </type>
                 </module>
 
-
                 <module>
                     <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
                         test-impl:impl-netconf
                     </type>
-                    <name>test1</name>
+                    <name>instance-from-code</name>
                     <simple-long-2>44</simple-long-2>
                     <binaryLeaf>8ad1</binaryLeaf>
                     <dto_d>
@@ -72,7 +71,7 @@
                     <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
                         test-impl:impl-netconf
                     </type>
-                    <name>test2</name>
+                    <name>test3</name>
                 </module>
             </modules>
 
index c4b146722004d6792303b0f0a3a423d2d89f91e6..21a1ffe81dab64f9fab54bdf316b03631937ed6c 100644 (file)
@@ -48,7 +48,7 @@
 
     <properties>
         <osgi.version>5.0.0</osgi.version>
-        <maven.bundle.version>2.3.7</maven.bundle.version>
+        <maven.bundle.version>2.4.0</maven.bundle.version>
         <slf4j.version>1.7.2</slf4j.version>
         <netconf.netty.version>4.0.10.Final</netconf.netty.version>
         <ct.exi.version>0.9.2</ct.exi.version>
index 3b335463d97b34c8faf0f69825c5fa814f9fb4e4..150f6028022e01e38f5a3558237e9c2281ccc20f 100644 (file)
@@ -50,6 +50,7 @@
           <instructions>
             <Import-Package>
               org.opendaylight.controller.clustering.services,
+              org.opendaylight.controller.configuration,
               org.opendaylight.controller.sal.core,
               org.opendaylight.controller.sal.utils,
               org.apache.felix.dm,
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>configuration</artifactId>
       <version>0.4.1-SNAPSHOT</version>
     </dependency>
     <dependency>
@@ -86,7 +92,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
   </dependencies>
 </project>
index 4202856774b81a19403a0de2f193c8aa24bf185e..351496abb3052c406260191bc80cf77f8db32266 100644 (file)
@@ -10,11 +10,12 @@ package org.opendaylight.controller.networkconfig.neutron.implementation;
 
 import java.util.Hashtable;
 import java.util.Dictionary;
+
 import org.apache.felix.dm.Component;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
 import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
@@ -32,6 +33,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * ComponentActivatorAbstractBase.
      *
      */
+    @Override
     public void init() {
 
     }
@@ -41,6 +43,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * cleanup done by ComponentActivatorAbstractBase
      *
      */
+    @Override
     public void destroy() {
 
     }
@@ -54,6 +57,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * instantiated in order to get an fully working implementation
      * Object
      */
+    @Override
     public Object[] getImplementations() {
         Object[] res = { NeutronFloatingIPInterface.class,
                 NeutronRouterInterface.class,
@@ -76,11 +80,13 @@ public class Activator extends ComponentActivatorAbstractBase {
      * also optional per-container different behavior if needed, usually
      * should not be the case though.
      */
+    @Override
     public void configureInstance(Component c, Object imp, String containerName) {
         if (imp.equals(NeutronFloatingIPInterface.class)) {
             // export the service
             c.setInterface(
-                    new String[] { INeutronFloatingIPCRUD.class.getName() }, null);
+                    new String[] { INeutronFloatingIPCRUD.class.getName(),
+                                   IConfigurationContainerAware.class.getName()}, null);
             Dictionary<String, String> props = new Hashtable<String, String>();
             props.put("salListenerName", "neutron");
             c.add(createContainerServiceDependency(containerName)
@@ -91,7 +97,8 @@ public class Activator extends ComponentActivatorAbstractBase {
         if (imp.equals(NeutronRouterInterface.class)) {
             // export the service
             c.setInterface(
-                    new String[] { INeutronRouterCRUD.class.getName() }, null);
+                    new String[] { INeutronRouterCRUD.class.getName(),
+                                   IConfigurationContainerAware.class.getName()}, null);
             Dictionary<String, String> props = new Hashtable<String, String>();
             props.put("salListenerName", "neutron");
             c.add(createContainerServiceDependency(containerName)
@@ -102,7 +109,8 @@ public class Activator extends ComponentActivatorAbstractBase {
         if (imp.equals(NeutronPortInterface.class)) {
             // export the service
             c.setInterface(
-                    new String[] { INeutronPortCRUD.class.getName() }, null);
+                    new String[] { INeutronPortCRUD.class.getName(),
+                                   IConfigurationContainerAware.class.getName()}, null);
             Dictionary<String, String> props = new Hashtable<String, String>();
             props.put("salListenerName", "neutron");
             c.add(createContainerServiceDependency(containerName)
@@ -113,7 +121,8 @@ public class Activator extends ComponentActivatorAbstractBase {
         if (imp.equals(NeutronSubnetInterface.class)) {
             // export the service
             c.setInterface(
-                    new String[] { INeutronSubnetCRUD.class.getName() }, null);
+                    new String[] { INeutronSubnetCRUD.class.getName(),
+                                   IConfigurationContainerAware.class.getName()}, null);
             Dictionary<String, String> props = new Hashtable<String, String>();
             props.put("salListenerName", "neutron");
             c.add(createContainerServiceDependency(containerName)
@@ -124,7 +133,8 @@ public class Activator extends ComponentActivatorAbstractBase {
         if (imp.equals(NeutronNetworkInterface.class)) {
             // export the service
             c.setInterface(
-                    new String[] { INeutronNetworkCRUD.class.getName() }, null);
+                    new String[] { INeutronNetworkCRUD.class.getName(),
+                                   IConfigurationContainerAware.class.getName()}, null);
             Dictionary<String, String> props = new Hashtable<String, String>();
             props.put("salListenerName", "neutron");
             c.add(createContainerServiceDependency(containerName)
index 7d9a2e657675e767d78a774c484e07a39f81d7d9..ceb009bf2c142006f44c069eae06beb81526a317 100644 (file)
@@ -8,6 +8,9 @@
 
 package org.opendaylight.controller.networkconfig.neutron.implementation;
 
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Dictionary;
@@ -16,6 +19,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
 import org.apache.felix.dm.Component;
@@ -23,6 +27,7 @@ import org.opendaylight.controller.clustering.services.CacheConfigException;
 import org.opendaylight.controller.clustering.services.CacheExistException;
 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
 import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
 import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
@@ -31,11 +36,20 @@ import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
 import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;
 import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
 import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {
+public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD, IConfigurationContainerAware,
+                                                   IObjectReader {
     private static final Logger logger = LoggerFactory.getLogger(NeutronFloatingIPInterface.class);
+    private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+    private static final String FILENAME ="neutron.floatingip";
+    private static String fileName;
     private String containerName = null;
 
     private IClusterContainerServices clusterContainerService = null;
@@ -103,6 +117,9 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {
     private void startUp() {
         allocateCache();
         retrieveCache();
+        if (floatingIPDB.isEmpty()) {
+            loadConfiguration();
+        }
     }
 
     /**
@@ -119,6 +136,7 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {
             // In the Global instance case the containerName is empty
             this.containerName = "";
         }
+        fileName = ROOT + FILENAME + "_" + containerName + ".conf";
         startUp();
     }
 
@@ -178,16 +196,19 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {
 
     // IfNBFloatingIPCRUD interface methods
 
+    @Override
     public boolean floatingIPExists(String uuid) {
         return floatingIPDB.containsKey(uuid);
     }
 
+    @Override
     public NeutronFloatingIP getFloatingIP(String uuid) {
         if (!floatingIPExists(uuid))
             return null;
         return floatingIPDB.get(uuid);
     }
 
+    @Override
     public List<NeutronFloatingIP> getAllFloatingIPs() {
         Set<NeutronFloatingIP> allIPs = new HashSet<NeutronFloatingIP>();
         for (Entry<String, NeutronFloatingIP> entry : floatingIPDB.entrySet()) {
@@ -200,6 +221,7 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {
         return ans;
     }
 
+    @Override
     public boolean addFloatingIP(NeutronFloatingIP input) {
         INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
         INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
@@ -223,6 +245,7 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {
         return true;
     }
 
+    @Override
     public boolean removeFloatingIP(String uuid) {
         INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
         INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
@@ -242,6 +265,7 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {
         return true;
     }
 
+    @Override
     public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta) {
         INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
 
@@ -263,4 +287,30 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {
         target.setFixedIPAddress(delta.getFixedIPAddress());
         return true;
     }
+
+    @SuppressWarnings("unchecked")
+    private void loadConfiguration() {
+        ObjectReader objReader = new ObjectReader();
+        ConcurrentMap<String, NeutronFloatingIP> confList = (ConcurrentMap<String, NeutronFloatingIP>)
+                                                            objReader.read(this, fileName);
+
+        if (confList == null) {
+            return;
+        }
+
+        for (String key : confList.keySet()) {
+            floatingIPDB.put(key, confList.get(key));
+        }
+    }
+
+    @Override
+    public Status saveConfiguration() {
+        ObjectWriter objWriter = new ObjectWriter();
+        return objWriter.write(new ConcurrentHashMap<String, NeutronFloatingIP>(floatingIPDB), fileName);
+    }
+
+    @Override
+    public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+        return ois.readObject();
+    }
 }
index b1e382107adcb5e52b58da3e41a5f4b91e9881bf..de9b9d1bc4fdd9d77fb29d342cf24512c4dd5b06 100644 (file)
@@ -8,6 +8,9 @@
 
 package org.opendaylight.controller.networkconfig.neutron.implementation;
 
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Dictionary;
@@ -16,6 +19,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
 import org.apache.felix.dm.Component;
@@ -23,13 +27,23 @@ import org.opendaylight.controller.clustering.services.CacheConfigException;
 import org.opendaylight.controller.clustering.services.CacheExistException;
 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
 import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
 import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class NeutronNetworkInterface implements INeutronNetworkCRUD {
+public class NeutronNetworkInterface implements INeutronNetworkCRUD, IConfigurationContainerAware,
+                                                IObjectReader {
     private static final Logger logger = LoggerFactory.getLogger(NeutronNetworkInterface.class);
+    private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+    private static final String FILENAME ="neutron.network";
+    private static String fileName;
     private String containerName = null;
 
     private ConcurrentMap<String, NeutronNetwork> networkDB;
@@ -85,6 +99,9 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD {
     private void startUp() {
         allocateCache();
         retrieveCache();
+        if (networkDB.isEmpty()) {
+            loadConfiguration();
+        }
     }
 
     /**
@@ -101,6 +118,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD {
             // In the Global instance case the containerName is empty
             this.containerName = "";
         }
+        fileName = ROOT + FILENAME + "_" + containerName + ".conf";
         startUp();
     }
 
@@ -170,16 +188,19 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD {
 
     // IfNBNetworkCRUD methods
 
+    @Override
     public boolean networkExists(String uuid) {
         return networkDB.containsKey(uuid);
     }
 
+    @Override
     public NeutronNetwork getNetwork(String uuid) {
         if (!networkExists(uuid))
             return null;
         return networkDB.get(uuid);
     }
 
+    @Override
     public List<NeutronNetwork> getAllNetworks() {
         Set<NeutronNetwork> allNetworks = new HashSet<NeutronNetwork>();
         for (Entry<String, NeutronNetwork> entry : networkDB.entrySet()) {
@@ -192,6 +213,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD {
         return ans;
     }
 
+    @Override
     public boolean addNetwork(NeutronNetwork input) {
         if (networkExists(input.getID()))
             return false;
@@ -200,6 +222,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD {
         return true;
     }
 
+    @Override
     public boolean removeNetwork(String uuid) {
         if (!networkExists(uuid))
             return false;
@@ -208,6 +231,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD {
         return true;
     }
 
+    @Override
     public boolean updateNetwork(String uuid, NeutronNetwork delta) {
         if (!networkExists(uuid))
             return false;
@@ -215,6 +239,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD {
         return overwrite(target, delta);
     }
 
+    @Override
     public boolean networkInUse(String netUUID) {
         if (!networkExists(netUUID))
             return true;
@@ -223,4 +248,31 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD {
             return true;
         return false;
     }
+
+    @SuppressWarnings("unchecked")
+    private void loadConfiguration() {
+        ObjectReader objReader = new ObjectReader();
+        ConcurrentMap<String, NeutronNetwork> confList = (ConcurrentMap<String, NeutronNetwork>)
+                                                            objReader.read(this, fileName);
+
+        if (confList == null) {
+            return;
+        }
+
+        for (String key : confList.keySet()) {
+            networkDB.put(key, confList.get(key));
+        }
+    }
+
+    @Override
+    public Status saveConfiguration() {
+        ObjectWriter objWriter = new ObjectWriter();
+        return objWriter.write(new ConcurrentHashMap<String, NeutronNetwork>(networkDB), fileName);
+    }
+
+    @Override
+    public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+        return ois.readObject();
+    }
+
 }
index fd030e178bd021cb8ec4ccfcb14c1877d89b172a..ec439bb92782b9f8b7b9f1dd865666c1d3ae8286 100644 (file)
@@ -8,6 +8,9 @@
 
 package org.opendaylight.controller.networkconfig.neutron.implementation;
 
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Dictionary;
@@ -17,6 +20,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
 import org.apache.felix.dm.Component;
@@ -24,6 +28,7 @@ import org.opendaylight.controller.clustering.services.CacheConfigException;
 import org.opendaylight.controller.clustering.services.CacheExistException;
 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
 import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
 import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
@@ -32,11 +37,20 @@ import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
 import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
 import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
 import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class NeutronPortInterface implements INeutronPortCRUD {
+public class NeutronPortInterface implements INeutronPortCRUD, IConfigurationContainerAware,
+                                             IObjectReader {
     private static final Logger logger = LoggerFactory.getLogger(NeutronPortInterface.class);
+    private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+    private static final String FILENAME ="neutron.port";
+    private static String fileName;
     private String containerName = null;
 
     private IClusterContainerServices clusterContainerService = null;
@@ -104,6 +118,10 @@ public class NeutronPortInterface implements INeutronPortCRUD {
     private void startUp() {
         allocateCache();
         retrieveCache();
+        if (portDB.isEmpty()) {
+            loadConfiguration();
+        }
+
     }
 
     /**
@@ -120,6 +138,7 @@ public class NeutronPortInterface implements INeutronPortCRUD {
             // In the Global instance case the containerName is empty
             containerName = "";
         }
+        fileName = ROOT + FILENAME + "_" + containerName + ".conf";
         startUp();
     }
 
@@ -329,4 +348,30 @@ public class NeutronPortInterface implements INeutronPortCRUD {
         return null;
     }
 
+    @SuppressWarnings("unchecked")
+    private void loadConfiguration() {
+        ObjectReader objReader = new ObjectReader();
+        ConcurrentMap<String, NeutronPort> confList = (ConcurrentMap<String, NeutronPort>)
+                                                            objReader.read(this, fileName);
+
+        if (confList == null) {
+            return;
+        }
+
+        for (String key : confList.keySet()) {
+            portDB.put(key, confList.get(key));
+        }
+    }
+
+    @Override
+    public Status saveConfiguration() {
+        ObjectWriter objWriter = new ObjectWriter();
+        return objWriter.write(new ConcurrentHashMap<String, NeutronPort>(portDB), fileName);
+    }
+
+    @Override
+    public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+        return ois.readObject();
+    }
+
 }
index 0e64dc5a098284640bb9d242a68e3649e100cf5e..850cc02163bd7965a2aefd936e39149e607bf26f 100644 (file)
@@ -8,6 +8,9 @@
 
 package org.opendaylight.controller.networkconfig.neutron.implementation;
 
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Dictionary;
@@ -16,6 +19,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
 import org.apache.felix.dm.Component;
@@ -23,13 +27,23 @@ import org.opendaylight.controller.clustering.services.CacheConfigException;
 import org.opendaylight.controller.clustering.services.CacheExistException;
 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
 import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
 import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;
 import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class NeutronRouterInterface implements INeutronRouterCRUD {
+public class NeutronRouterInterface implements INeutronRouterCRUD, IConfigurationContainerAware,
+                                               IObjectReader {
     private static final Logger logger = LoggerFactory.getLogger(NeutronRouterInterface.class);
+    private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+    private static final String FILENAME ="neutron.router";
+    private static String fileName;
     private String containerName = null;
 
     private IClusterContainerServices clusterContainerService = null;
@@ -96,6 +110,10 @@ public class NeutronRouterInterface implements INeutronRouterCRUD {
     private void startUp() {
         allocateCache();
         retrieveCache();
+        if (routerDB.isEmpty()) {
+            loadConfiguration();
+        }
+
     }
 
     /**
@@ -112,6 +130,7 @@ public class NeutronRouterInterface implements INeutronRouterCRUD {
             // In the Global instance case the containerName is empty
             this.containerName = "";
         }
+        fileName = ROOT + FILENAME + "_" + containerName + ".conf";
         startUp();
     }
 
@@ -172,16 +191,19 @@ public class NeutronRouterInterface implements INeutronRouterCRUD {
 
     // IfNBRouterCRUD Interface methods
 
+    @Override
     public boolean routerExists(String uuid) {
         return routerDB.containsKey(uuid);
     }
 
+    @Override
     public NeutronRouter getRouter(String uuid) {
         if (!routerExists(uuid))
             return null;
         return routerDB.get(uuid);
     }
 
+    @Override
     public List<NeutronRouter> getAllRouters() {
         Set<NeutronRouter> allRouters = new HashSet<NeutronRouter>();
         for (Entry<String, NeutronRouter> entry : routerDB.entrySet()) {
@@ -194,6 +216,7 @@ public class NeutronRouterInterface implements INeutronRouterCRUD {
         return ans;
     }
 
+    @Override
     public boolean addRouter(NeutronRouter input) {
         if (routerExists(input.getID()))
             return false;
@@ -201,6 +224,7 @@ public class NeutronRouterInterface implements INeutronRouterCRUD {
         return true;
     }
 
+    @Override
     public boolean removeRouter(String uuid) {
         if (!routerExists(uuid))
             return false;
@@ -208,6 +232,7 @@ public class NeutronRouterInterface implements INeutronRouterCRUD {
         return true;
     }
 
+    @Override
     public boolean updateRouter(String uuid, NeutronRouter delta) {
         if (!routerExists(uuid))
             return false;
@@ -215,10 +240,38 @@ public class NeutronRouterInterface implements INeutronRouterCRUD {
         return overwrite(target, delta);
     }
 
+    @Override
     public boolean routerInUse(String routerUUID) {
         if (!routerExists(routerUUID))
             return true;
         NeutronRouter target = routerDB.get(routerUUID);
         return (target.getInterfaces().size() > 0);
     }
+
+    @SuppressWarnings("unchecked")
+    private void loadConfiguration() {
+        ObjectReader objReader = new ObjectReader();
+        ConcurrentMap<String, NeutronRouter> confList = (ConcurrentMap<String, NeutronRouter>)
+                                                            objReader.read(this, fileName);
+
+        if (confList == null) {
+            return;
+        }
+
+        for (String key : confList.keySet()) {
+            routerDB.put(key, confList.get(key));
+        }
+    }
+
+    @Override
+    public Status saveConfiguration() {
+        ObjectWriter objWriter = new ObjectWriter();
+        return objWriter.write(new ConcurrentHashMap<String, NeutronRouter>(routerDB), fileName);
+    }
+
+    @Override
+    public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+        return ois.readObject();
+    }
+
 }
index 62ef64c74c705fe8d0fb0f92c913d750157ece9c..f908a95c313390e25b340f862d4f63e65999c07c 100644 (file)
@@ -8,6 +8,9 @@
 
 package org.opendaylight.controller.networkconfig.neutron.implementation;
 
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Dictionary;
@@ -16,6 +19,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
 import org.apache.felix.dm.Component;
@@ -23,16 +27,27 @@ import org.opendaylight.controller.clustering.services.CacheConfigException;
 import org.opendaylight.controller.clustering.services.CacheExistException;
 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
 import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
 import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
 import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
 import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class NeutronSubnetInterface implements INeutronSubnetCRUD {
+public class NeutronSubnetInterface implements INeutronSubnetCRUD, IConfigurationContainerAware,
+                                               IObjectReader {
     private static final Logger logger = LoggerFactory.getLogger(NeutronSubnetInterface.class);
+    private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+    private static final String FILENAME ="neutron.subnet";
+    private static String fileName;
+
     private String containerName = null;
 
     private IClusterContainerServices clusterContainerService = null;
@@ -100,6 +115,10 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD {
     private void startUp() {
         allocateCache();
         retrieveCache();
+        if (subnetDB.isEmpty()) {
+            loadConfiguration();
+        }
+
     }
 
     /**
@@ -116,6 +135,7 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD {
             // In the Global instance case the containerName is empty
             this.containerName = "";
         }
+        fileName = ROOT + FILENAME + "_" + containerName + ".conf";
         startUp();
     }
 
@@ -176,16 +196,19 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD {
 
     // IfNBSubnetCRUD methods
 
+    @Override
     public boolean subnetExists(String uuid) {
         return subnetDB.containsKey(uuid);
     }
 
+    @Override
     public NeutronSubnet getSubnet(String uuid) {
         if (!subnetExists(uuid))
             return null;
         return subnetDB.get(uuid);
     }
 
+    @Override
     public List<NeutronSubnet> getAllSubnets() {
         Set<NeutronSubnet> allSubnets = new HashSet<NeutronSubnet>();
         for (Entry<String, NeutronSubnet> entry : subnetDB.entrySet()) {
@@ -198,6 +221,7 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD {
         return ans;
     }
 
+    @Override
     public boolean addSubnet(NeutronSubnet input) {
         String id = input.getID();
         if (subnetExists(id))
@@ -210,6 +234,7 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD {
         return true;
     }
 
+    @Override
     public boolean removeSubnet(String uuid) {
         if (!subnetExists(uuid))
             return false;
@@ -222,6 +247,7 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD {
         return true;
     }
 
+    @Override
     public boolean updateSubnet(String uuid, NeutronSubnet delta) {
         if (!subnetExists(uuid))
             return false;
@@ -229,10 +255,38 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD {
         return overwrite(target, delta);
     }
 
+    @Override
     public boolean subnetInUse(String subnetUUID) {
         if (!subnetExists(subnetUUID))
             return true;
         NeutronSubnet target = subnetDB.get(subnetUUID);
         return (target.getPortsInSubnet().size() > 0);
     }
+
+    @SuppressWarnings("unchecked")
+    private void loadConfiguration() {
+        ObjectReader objReader = new ObjectReader();
+        ConcurrentMap<String, NeutronSubnet> confList = (ConcurrentMap<String, NeutronSubnet>)
+                                                            objReader.read(this, fileName);
+
+        if (confList == null) {
+            return;
+        }
+
+        for (String key : confList.keySet()) {
+            subnetDB.put(key, confList.get(key));
+        }
+    }
+
+    @Override
+    public Status saveConfiguration() {
+        ObjectWriter objWriter = new ObjectWriter();
+        return objWriter.write(new ConcurrentHashMap<String, NeutronSubnet>(subnetDB), fileName);
+    }
+
+    @Override
+    public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+        return ois.readObject();
+    }
+
 }
index 588a61653ab6bfac66c0886d01aa69746ecd7e64..b6cdd2512bf7d0d314ba39344f2db9931fe06a70 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>commons-net</groupId>
index 4d029dccf31c642a7fd8ca790570e8764bcbebb2..9c8c91b284f0914a16011429306de380fb7f2399 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.networkconfig.neutron;
 
+import java.io.Serializable;
 import java.util.Iterator;
 import java.util.List;
 
@@ -19,7 +20,9 @@ import javax.xml.bind.annotation.XmlRootElement;
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
 
-public class NeutronFloatingIP {
+public class NeutronFloatingIP implements Serializable {
+    private static final long serialVersionUID = 1L;
+
     // See OpenStack Network API v2.0 Reference for description of
     // annotated attributes
 
index 9d7ba5d58a8535dec530c37e4e29c2c821031fec..1277436e236fa375467d3ec07e6dda12a62f70c0 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.networkconfig.neutron;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -20,10 +21,12 @@ import javax.xml.bind.annotation.XmlRootElement;
 @XmlRootElement(name = "network")
 @XmlAccessorType(XmlAccessType.NONE)
 
-public class NeutronNetwork {
+public class NeutronNetwork implements Serializable {
     // See OpenStack Network API v2.0 Reference for description of
     // annotated attributes
 
+    private static final long serialVersionUID = 1L;
+
     @XmlElement (name="id")
     String networkUUID;              // network UUID
 
index 536fc3fd6e5ac1f2594cd8850afe8f9bd5538297..bcadba202a049f9948d48270964beb94b9d7ea9b 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.networkconfig.neutron;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -22,7 +23,9 @@ import javax.xml.bind.annotation.XmlRootElement;
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
 
-public class NeutronPort {
+public class NeutronPort implements Serializable {
+    private static final long serialVersionUID = 1L;
+
     // See OpenStack Network API v2.0 Reference for description of
     // annotated attributes
 
index 1ef48bd95bfe2f4a378f497371f38db11b307e91..ed65c5c91b9b8d16b86c1d96499ce135c1b91e52 100644 (file)
@@ -8,9 +8,11 @@
 
 package org.opendaylight.controller.networkconfig.neutron;
 
+import java.io.Serializable;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
@@ -19,7 +21,9 @@ import javax.xml.bind.annotation.XmlRootElement;
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
 
-public class NeutronRouter {
+public class NeutronRouter implements Serializable {
+    private static final long serialVersionUID = 1L;
+
     // See OpenStack Network API v2.0 Reference for description of
     // annotated attributes
     @XmlElement (name="id")
index 5b5e0ce9cc61de995360bb0172b14b7f13475676..e2df13b9aa859d739114b72b89cb1072e891bd9f 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.controller.networkconfig.neutron;
 
+import java.io.Serializable;
+
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
@@ -15,7 +17,9 @@ import javax.xml.bind.annotation.XmlRootElement;
 
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
-public class NeutronRouter_Interface {
+public class NeutronRouter_Interface implements Serializable {
+    private static final long serialVersionUID = 1L;
+
     // See OpenStack Network API v2.0 Reference for description of
     // annotated attributes
 
index 07f165dc7e16b661c0f9c9e052af89c63c43cf2a..8583d44531ec5387b1ea7b1d8b884fc98ffe2564 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.controller.networkconfig.neutron;
 
+import java.io.Serializable;
+
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
@@ -16,7 +18,9 @@ import javax.xml.bind.annotation.XmlRootElement;
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
 
-public class NeutronRouter_NetworkReference {
+public class NeutronRouter_NetworkReference implements Serializable {
+    private static final long serialVersionUID = 1L;
+
     // See OpenStack Network API v2.0 Reference for description of
     // annotated attributes
 
index 1dbe253a5815ce75e4cea142ed2903a42cc31bdd..fbaa63a14800f163659b8fe1616cfca271598879 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.networkconfig.neutron;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -23,7 +24,9 @@ import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
 
-public class NeutronSubnet {
+public class NeutronSubnet implements Serializable {
+    private static final long serialVersionUID = 1L;
+
     // See OpenStack Network API v2.0 Reference for description of
     // annotated attributes
 
index 75238c1ad97956de49a0d77ab1b0f2ac76d255d8..07744061e66b4eba3fbd18c20455e4ef1b7ba9fa 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.controller.networkconfig.neutron;
 
+import java.io.Serializable;
+
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
@@ -15,7 +17,9 @@ import javax.xml.bind.annotation.XmlRootElement;
 
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
-public class NeutronSubnet_HostRoute {
+public class NeutronSubnet_HostRoute implements Serializable {
+    private static final long serialVersionUID = 1L;
+
     // See OpenStack Network API v2.0 Reference for description of
     // annotated attributes
 
index 7829ba2199aac43b5e7ac99c2fa730d656436562..15ff548a532c1a14f6ec5e963c1734ca40278aab 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.networkconfig.neutron;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -18,7 +19,9 @@ import javax.xml.bind.annotation.XmlRootElement;
 
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
-public class NeutronSubnet_IPAllocationPool {
+public class NeutronSubnet_IPAllocationPool implements Serializable {
+    private static final long serialVersionUID = 1L;
+
     // See OpenStack Network API v2.0 Reference for description of
     // annotated attributes
 
@@ -28,7 +31,8 @@ public class NeutronSubnet_IPAllocationPool {
     @XmlElement(name="end")
     String poolEnd;
 
-    public NeutronSubnet_IPAllocationPool() { }
+    public NeutronSubnet_IPAllocationPool() {
+    }
 
     public NeutronSubnet_IPAllocationPool(String lowAddress, String highAddress) {
         poolStart = lowAddress;
index 6fe7c529942f1cf524320b923282d3b0b60315cc..e862a59e8a7bef2772645d9567661be9716a49fd 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.controller.networkconfig.neutron;
 
+import java.io.Serializable;
+
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
@@ -15,7 +17,9 @@ import javax.xml.bind.annotation.XmlRootElement;
 
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
-public class Neutron_IPs {
+public class Neutron_IPs implements Serializable {
+    private static final long serialVersionUID = 1L;
+
     // See OpenStack Network API v2.0 Reference for description of
     // annotated attributes
 
index baa0755dc9314f2ead370bad01acc804dc1d7a44..03cb9c20de7f4d504b5dacc60197281d0a482bf0 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>bundlescanner</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${bundlescanner.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${sal.version}</version>
     </dependency>
   </dependencies>
 </project>
index 8e769a23499edacd822f4b6a6a2375ecc3a401a3..2169f3f3e7c679670f24c94516217fe9bbceaf9b 100644 (file)
               org.osgi.service.packageadmin,
               org.osgi.util.tracker,
               javax.servlet.http,
-              org.codehaus.jackson,
-              org.codehaus.jackson.jaxrs,
-              org.codehaus.jackson.map,
+              com.fasterxml.jackson.core,
+              com.fasterxml.jackson.databind,
+              com.fasterxml.jackson.jaxrs.base,
+              com.fasterxml.jackson.jaxrs.json,
               org.slf4j
             </Import-Package>
           </instructions>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${sal.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>usermanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${usermanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>bundlescanner</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${bundlescanner.version}</version>
     </dependency>
+
     <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-core-asl</artifactId>
+       <groupId>com.fasterxml.jackson.core</groupId>
+       <artifactId>jackson-annotations</artifactId>
     </dependency>
+
     <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-mapper-asl</artifactId>
+       <groupId>com.fasterxml.jackson.core</groupId>
+       <artifactId>jackson-core</artifactId>
     </dependency>
+
     <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-jaxrs</artifactId>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
     </dependency>
+
+    <dependency>
+       <groupId>com.fasterxml.jackson.jaxrs</groupId>
+       <artifactId>jackson-jaxrs-json-provider</artifactId>
+    </dependency>
+
+      <dependency>
+         <groupId>com.fasterxml.jackson.jaxrs</groupId>
+         <artifactId>jackson-jaxrs-base</artifactId>
+      </dependency>
+
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <artifactId>jersey-client</artifactId>
       <version>${jersey.version}</version>
     </dependency>
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-json</artifactId>
-      <version>${jersey.version}</version>
-    </dependency>
+
   </dependencies>
 </project>
index 5e5dee3279a2642b2719316b110804bed0c716fb..eb43920826c18f052e6749fb223646dafe5e5a47 100644 (file)
@@ -15,7 +15,8 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.ExceptionMapper;
 import javax.ws.rs.ext.Provider;
 
-import org.codehaus.jackson.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonProcessingException;
+
 
 /**
  * A custom exception mapper for handling Jackson JsonProcessingException types
index e164abaf95c0ccd3adb07e3bb55d32b8f9f22ec8..47bb3ffd7c72df59e0804527412a5a897dc922db 100644 (file)
@@ -12,15 +12,14 @@ import java.util.Dictionary;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-
 import javax.ws.rs.core.Application;
 import javax.ws.rs.ext.ContextResolver;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.annotation.XmlRootElement;
 
-import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
-import org.codehaus.jackson.map.DeserializationConfig;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
 import org.opendaylight.controller.northbound.bundlescanner.IBundleScanService;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -78,7 +77,7 @@ public class NorthboundApplication extends Application {
 
     private static final JacksonJaxbJsonProvider getJsonProvider() {
         JacksonJaxbJsonProvider jsonProvider = new JacksonJaxbJsonProvider();
-        jsonProvider.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,
+        jsonProvider.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
                 false);
         return jsonProvider;
     }
index 65790ad17ca1383b7e6ae387aa4666dfbd283d3b..0a282b9b28b8c3c68ca31e3419a39b0f607105c2 100644 (file)
@@ -23,7 +23,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new InternalServerErrorException("Internal Server Exception");
         } catch (InternalServerErrorException e) {
-            Assert.assertTrue(e instanceof InternalServerErrorException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Internal Server Exception"));
         }
@@ -34,7 +33,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new MethodNotAllowedException("Method Not Allowed Exception");
         } catch (MethodNotAllowedException e) {
-            Assert.assertTrue(e instanceof MethodNotAllowedException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Method Not Allowed Exception"));
         }
@@ -45,7 +43,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new NotAcceptableException("Not Acceptable Exception");
         } catch (NotAcceptableException e) {
-            Assert.assertTrue(e instanceof NotAcceptableException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Not Acceptable Exception"));
         }
@@ -56,7 +53,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new ResourceConflictException("Resource Conflict Exception");
         } catch (ResourceConflictException e) {
-            Assert.assertTrue(e instanceof ResourceConflictException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Resource Conflict Exception"));
         }
@@ -67,7 +63,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new ResourceForbiddenException("Resource Forbidden Exception");
         } catch (ResourceForbiddenException e) {
-            Assert.assertTrue(e instanceof ResourceForbiddenException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Resource Forbidden Exception"));
         }
@@ -78,7 +73,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new ResourceGoneException("Resource Gone Exception");
         } catch (ResourceGoneException e) {
-            Assert.assertTrue(e instanceof ResourceGoneException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Resource Gone Exception"));
         }
@@ -89,7 +83,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new ResourceNotFoundException("Resource Not Found Exception");
         } catch (ResourceNotFoundException e) {
-            Assert.assertTrue(e instanceof ResourceNotFoundException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Resource Not Found Exception"));
         }
@@ -101,7 +94,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
             throw new ServiceUnavailableException(
                     "Service Unavailable Exception");
         } catch (ServiceUnavailableException e) {
-            Assert.assertTrue(e instanceof ServiceUnavailableException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Service Unavailable Exception"));
         }
@@ -112,7 +104,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new UnauthorizedException("Unauthorized Exception");
         } catch (UnauthorizedException e) {
-            Assert.assertTrue(e instanceof UnauthorizedException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Unauthorized Exception"));
         }
@@ -124,7 +115,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
             throw new UnsupportedMediaTypeException(
                     "Unsupported Media Type Exception");
         } catch (UnsupportedMediaTypeException e) {
-            Assert.assertTrue(e instanceof UnsupportedMediaTypeException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Unsupported Media Type Exception"));
         }
index 0ddfcdb3e19f730cb5768cd1da1bdaabdb3bd5f0..8ade6134e6b3a715d223288d9e0719098aa5b4df 100644 (file)
@@ -27,7 +27,7 @@
           <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>${sal.version}</version>
           </dependency>
         </dependencies>
       </plugin>
@@ -58,7 +58,8 @@
               javax.xml.bind.annotation,
               javax.xml.bind,
               org.apache.catalina.filters,
-              org.codehaus.jackson.jaxrs,
+              com.fasterxml.jackson.jaxrs.base,
+              com.fasterxml.jackson.jaxrs.json,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Export-Package>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${sal.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal.connection</artifactId>
-      <version>0.1.1-SNAPSHOT</version>
+      <version>${sal.connection.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>connectionmanager</artifactId>
-      <version>0.1.1-SNAPSHOT</version>
+      <version>${connectionmanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>containermanager</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${containermanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.codehaus.enunciate</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>commons.northbound</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${commons.northbound.version}</version>
     </dependency>
   </dependencies>
 </project>
index 517f2e76a35b443a6f2afd0091278d6ecc43c346..a8b8f2a5d0e4ae44cc6ca3183dadadbd1586edf3 100644 (file)
@@ -52,7 +52,8 @@
               javax.xml.bind,
               org.slf4j,
               org.apache.catalina.filters,
-              org.codehaus.jackson.jaxrs,
+              com.fasterxml.jackson.jaxrs.base,
+              com.fasterxml.jackson.jaxrs.json,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Web-ContextPath>/controller/nb/v2/containermanager</Web-ContextPath>
@@ -66,7 +67,7 @@
   <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>containermanager</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${containermanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
@@ -81,7 +82,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${sal.version}</version>
     </dependency>
     <dependency>
       <groupId>org.codehaus.enunciate</groupId>
@@ -91,7 +92,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>commons.northbound</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${commons.northbound.version}</version>
     </dependency>
   </dependencies>
 </project>
index 10559a2bbda3e1dd96cc25b6b9ddaeefb86a957e..b9d2200180dbd858c17624dbaa7b2bd8e0c97038 100644 (file)
@@ -13,7 +13,7 @@ import java.util.HashSet;
 import java.util.Set;
 import javax.ws.rs.core.Application;
 
-import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
+import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
 
 /**
  * Instance of javax.ws.rs.core.Application used to return the classes
index d1299a2559830b3ce10ddb3437cacad9765b39de..5baaeb0dccc64d358ce960d224cd578dc17f52f1 100644 (file)
@@ -27,7 +27,7 @@
           <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>${sal.version}</version>
           </dependency>
         </dependencies>
       </plugin>
@@ -43,6 +43,7 @@
             <Import-Package>
               org.opendaylight.controller.sal.core,
               org.opendaylight.controller.sal.utils,
+              org.opendaylight.controller.configuration,
               org.opendaylight.controller.containermanager,
               org.opendaylight.controller.switchmanager,
               org.opendaylight.controller.usermanager,
@@ -59,8 +60,9 @@
               javax.xml.bind,
               org.slf4j,
               org.apache.catalina.filters,
-              org.codehaus.jackson.jaxrs,
-              org.codehaus.jackson.annotate,
+              com.fasterxml.jackson.annotation,
+              com.fasterxml.jackson.jaxrs.base,
+              com.fasterxml.jackson.jaxrs.json,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Web-ContextPath>/controller/nb/v2/controllermanager</Web-ContextPath>
     <dependency>
       <groupId>org.opendaylight.controller.thirdparty</groupId>
       <artifactId>com.sun.jersey.jersey-servlet</artifactId>
-      <version>1.18-SNAPSHOT</version>
+      <version>${jersey-servlet.version}</version>
     </dependency>
 
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>containermanager</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${containermanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>switchmanager</artifactId>
-      <version>0.6.1-SNAPSHOT</version>
+      <version>${switchmanager.api.version}</version>
     </dependency>
 
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${sal.version}</version>
     </dependency>
 
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>commons.northbound</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${commons.northbound.version}</version>
     </dependency>
 
     <dependency>
     <dependency>
       <groupId>org.opendaylight.controller.thirdparty</groupId>
       <artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
-      <version>7.0.43-SNAPSHOT</version>
+      <version>${corsfilter.version}</version>
     </dependency>
   </dependencies>
 </project>
index c5153962125445ead7ce27411f4bc87ea0b989f8..003f8b3b95df37b465ad04caf487181614511ddc 100644 (file)
@@ -29,6 +29,7 @@ import javax.ws.rs.core.UriInfo;
 import org.codehaus.enunciate.jaxrs.ResponseCode;
 import org.codehaus.enunciate.jaxrs.StatusCodes;
 import org.codehaus.enunciate.jaxrs.TypeHint;
+import org.opendaylight.controller.configuration.IConfigurationService;
 import org.opendaylight.controller.containermanager.IContainerManager;
 import org.opendaylight.controller.northbound.commons.RestMessages;
 import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
@@ -254,6 +255,44 @@ public class ControllerManagerNorthbound {
         return NorthboundUtils.getResponse(status);
     }
 
+    /**
+     * Save controller configuration
+     *
+     * Request URL:
+     *  http://localhost:8080/controller/nb/v2/controllermanager/configuration
+     *
+     * Request body is empty
+     */
+    @Path("/configuration")
+    @PUT
+    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+    @StatusCodes({
+            @ResponseCode(code = 204, condition = "Operation successful"),
+            @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
+            @ResponseCode(code = 503, condition = "Configuration service is unavailable.")
+    })
+    public Response saveConfiguration() {
+
+        if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
+            throw new UnauthorizedException("User is not authorized to perform this operation");
+        }
+
+        IConfigurationService configService = (IConfigurationService)
+                ServiceHelper.getGlobalInstance(IConfigurationService.class, this);
+
+        if (configService == null) {
+            throw new ServiceUnavailableException("Configuration Service " +
+                    RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        Status status = configService.saveConfigurations();
+        if (status.isSuccess()) {
+            NorthboundUtils.auditlog("Controller Configuration", username,
+                    "save", "configuration");
+            return Response.noContent().build();
+        }
+        return NorthboundUtils.getResponse(status);
+    }
+
     private boolean isValidContainer(String containerName) {
         if (containerName.equals(GlobalConstants.DEFAULT.toString())) {
             return true;
index ac0d0397464b53a6bbbd32afcbbc8421a94784ac..1560f96072e438f5665784aabc59ba2d6bdd89bb 100644 (file)
@@ -4,15 +4,14 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElementRef;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 
-import org.codehaus.jackson.annotate.JsonIgnore;
-import org.codehaus.jackson.annotate.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import org.opendaylight.controller.sal.core.Property;
 
 /**
index 1b81ccb450f71a9050739830c3e57758e0a43fc4..565bd5f6aa1961452041069baa57f5fd5b997615 100644 (file)
@@ -28,7 +28,7 @@
           <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>${sal.version}</version>
           </dependency>
         </dependencies>
       </plugin>
@@ -57,7 +57,8 @@
               javax.xml.bind.annotation,
               javax.xml.bind,
               org.slf4j,
-              org.codehaus.jackson.jaxrs,
+              com.fasterxml.jackson.jaxrs.base,
+              com.fasterxml.jackson.jaxrs.json,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Export-Package>
@@ -74,7 +75,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>containermanager</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${containermanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${forwardingrulesmanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.7.0-SNAPSHOT</version>
+      <version>${sal.version}</version>
     </dependency>
     <dependency>
       <groupId>org.codehaus.enunciate</groupId>
@@ -98,7 +99,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>commons.northbound</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${commons.northbound.version}</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index 541dfcfe2d9b20919995332dafa7d8098e2cfac5..aab519e5f682746f9478a311bdf4966fe29243ab 100644 (file)
@@ -27,7 +27,7 @@
           <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>${sal.version}</version>
           </dependency>
         </dependencies>
       </plugin>
@@ -59,7 +59,8 @@
               javax.xml.bind,
               org.slf4j,
               org.apache.catalina.filters,
-              org.codehaus.jackson.jaxrs,
+              com.fasterxml.jackson.jaxrs.base,
+              com.fasterxml.jackson.jaxrs.json,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Web-ContextPath>/controller/nb/v2/hosttracker</Web-ContextPath>
@@ -74,7 +75,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>containermanager</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${containermanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${sal.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>commons.northbound</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${commons.northbound.version}</version>
     </dependency>
     <dependency>
       <groupId>org.codehaus.enunciate</groupId>
index 793af2f5d779379f1f92227c80d584b231a6b361..d1815bbf8c80b0ca4f8eaec2f520061609805bc2 100644 (file)
       <artifactId>logback-classic</artifactId>
       <version>${logback.version}</version>
     </dependency>
+
     <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-mapper-asl</artifactId>
-      <version>${jackson.version}</version>
+       <groupId>com.fasterxml.jackson.core</groupId>
+       <artifactId>jackson-databind</artifactId>
     </dependency>
+
     <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-core-asl</artifactId>
-      <version>${jackson.version}</version>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-annotations</artifactId>
     </dependency>
+
     <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-jaxrs</artifactId>
-      <version>${jackson.version}</version>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-core</artifactId>
     </dependency>
+
     <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-xc</artifactId>
-      <version>${jackson.version}</version>
+      <groupId>com.fasterxml.jackson.jaxrs</groupId>
+      <artifactId>jackson-jaxrs-json-provider</artifactId>
     </dependency>
+
+    <dependency>
+       <groupId>com.fasterxml.jackson.module</groupId>
+       <artifactId>jackson-module-jaxb-annotations</artifactId>
+    </dependency>
+
     <dependency>
       <groupId>org.codehaus.jettison</groupId>
       <artifactId>jettison</artifactId>
       <artifactId>jersey-client</artifactId>
       <version>${jersey.version}</version>
     </dependency>
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-json</artifactId>
-      <version>${jersey.version}</version>
-    </dependency>
+
     <dependency>
       <groupId>eclipselink</groupId>
       <artifactId>javax.resource</artifactId>
index 602de9a1c6f28f8e195ed0aa00c78bd82f3da434..cabfb0ee5a1e98e27194cb244f445ca8ba3ca40d 100644 (file)
@@ -15,7 +15,6 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
 import javax.inject.Inject;
 
 import org.apache.commons.codec.binary.Base64;
@@ -44,8 +43,8 @@ import org.opendaylight.controller.sal.topology.IListenTopoUpdates;
 import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
 import org.opendaylight.controller.switchmanager.IInventoryListener;
 import org.opendaylight.controller.usermanager.IUserManager;
-import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.junit.PaxExam;
 import org.ops4j.pax.exam.util.PathUtils;
 import org.osgi.framework.Bundle;
@@ -63,7 +62,7 @@ public class NorthboundIT {
     private IUserManager userManager = null;
     private IInventoryListener invtoryListener = null;
     private IListenTopoUpdates topoUpdates = null;
-
+    private static final String baseUrlPrefix = "http://127.0.0.1:8080/controller/nb/v2/";
     private final Boolean debugMsg = false;
 
     private String stateToString(int state) {
@@ -187,7 +186,6 @@ public class NorthboundIT {
                 System.out.println("HTTP response code: " + response.getStatus());
                 System.out.println("HTTP response message: " + response.getEntity());
             }
-
             return response.getEntity();
         } catch (Exception e) {
             if (debugMsg) {
@@ -269,7 +267,7 @@ public class NorthboundIT {
     @Test
     public void testSubnetsNorthbound() throws JSONException, ConstructionException {
         System.out.println("Starting Subnets JAXB client.");
-        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/subnetservice/";
+        String baseURL = baseUrlPrefix + "subnetservice/";
 
         String name1 = "testSubnet1";
         String subnet1 = "1.1.1.1/24";
@@ -412,7 +410,7 @@ public class NorthboundIT {
     @Test
     public void testStaticRoutingNorthbound() throws JSONException {
         System.out.println("Starting StaticRouting JAXB client.");
-        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/staticroute/";
+        String baseURL = baseUrlPrefix + "staticroute/";
 
         String name1 = "testRoute1";
         String prefix1 = "192.168.1.1/24";
@@ -493,7 +491,7 @@ public class NorthboundIT {
     @Test
     public void testSwitchManager() throws JSONException {
         System.out.println("Starting SwitchManager JAXB client.");
-        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/switchmanager/default/";
+        String baseURL = baseUrlPrefix + "switchmanager/default/";
 
         // define Node/NodeConnector attributes for test
         int nodeId_1 = 51966;
@@ -644,7 +642,7 @@ public class NorthboundIT {
                 "SET_NW_SRC", "SET_NW_DST", "SET_NW_TOS", "SET_TP_SRC", "SET_TP_DST" };
         System.out.println("Starting Statistics JAXB client.");
 
-        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/statistics/default/";
+        String baseURL = baseUrlPrefix + "statistics/default/";
 
         String result = getJsonResult(baseURL + "flow");
         JSONTokener jt = new JSONTokener(result);
@@ -835,7 +833,7 @@ public class NorthboundIT {
     @Test
     public void testFlowProgrammer() throws JSONException {
         System.out.println("Starting FlowProgrammer JAXB client.");
-        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/flowprogrammer/default/";
+        String baseURL = baseUrlPrefix + "flowprogrammer/default/";
         // Attempt to get a flow that doesn't exit. Should return 404
         // status.
         String result = getJsonResult(baseURL + "node/STUB/51966/staticFlow/test1", "GET");
@@ -863,7 +861,7 @@ public class NorthboundIT {
         // code
         fc = "{\"name\":\"test1\", \"node\":{\"id\":\"51966\",\"type\":\"STUB\"}, \"actions\":[\"LOOPBACK\"]}";
         result = getJsonResult(baseURL + "node/STUB/51966/staticFlow/test1", "PUT", fc);
-        Assert.assertTrue(result.equals("Success"));
+        Assert.assertTrue(result.contains("Success"));
 
         fc = "{\"name\":\"test2\", \"node\":{\"id\":\"51966\",\"type\":\"STUB\"}, \"actions\":[\"DROP\"]}";
         result = getJsonResult(baseURL + "node/STUB/51966/staticFlow/test2", "PUT", fc);
@@ -974,7 +972,7 @@ public class NorthboundIT {
         Integer nodeConnectorId_2 = 34;
         String vlan_2 = "123";
 
-        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/hosttracker/default";
+        String baseURL = baseUrlPrefix + "hosttracker/default";
 
         // test PUT method: addHost()
         JSONObject fc_json = new JSONObject();
@@ -1128,14 +1126,14 @@ public class NorthboundIT {
         } else {
             JSONObject ja = json.getJSONObject("hostConfig");
             String na = ja.getString("networkAddress");
-            return (na.equalsIgnoreCase(hostIp)) ? true : false;
+            return na.equalsIgnoreCase(hostIp);
         }
     }
 
     @Test
     public void testTopology() throws JSONException, ConstructionException {
         System.out.println("Starting Topology JAXB client.");
-        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/topology/default";
+        String baseURL = baseUrlPrefix + "topology/default";
 
         // === test GET method for getTopology()
         short state_1 = State.EDGE_UP, state_2 = State.EDGE_DOWN;
@@ -1391,10 +1389,13 @@ public class NorthboundIT {
                 mavenBundle("org.opendaylight.controller", "flowprogrammer.northbound").versionAsInProject(),
                 mavenBundle("org.opendaylight.controller", "subnets.northbound").versionAsInProject(),
 
-                mavenBundle("org.codehaus.jackson", "jackson-mapper-asl").versionAsInProject(),
-                mavenBundle("org.codehaus.jackson", "jackson-core-asl").versionAsInProject(),
-                mavenBundle("org.codehaus.jackson", "jackson-jaxrs").versionAsInProject(),
-                mavenBundle("org.codehaus.jackson", "jackson-xc").versionAsInProject(),
+                mavenBundle("com.fasterxml.jackson.core", "jackson-annotations").versionAsInProject(),
+                mavenBundle("com.fasterxml.jackson.core", "jackson-core").versionAsInProject(),
+                mavenBundle("com.fasterxml.jackson.core", "jackson-databind").versionAsInProject(),
+                mavenBundle("com.fasterxml.jackson.jaxrs", "jackson-jaxrs-json-provider").versionAsInProject(),
+                mavenBundle("com.fasterxml.jackson.jaxrs", "jackson-jaxrs-base").versionAsInProject(),
+                mavenBundle("com.fasterxml.jackson.module", "jackson-module-jaxb-annotations").versionAsInProject(),
+
                 mavenBundle("org.codehaus.jettison", "jettison").versionAsInProject(),
 
                 mavenBundle("commons-io", "commons-io").versionAsInProject(),
@@ -1493,7 +1494,7 @@ public class NorthboundIT {
                 mavenBundle("com.sun.jersey", "jersey-client").versionAsInProject(),
                 mavenBundle("com.sun.jersey", "jersey-server").versionAsInProject().startLevel(2),
                 mavenBundle("com.sun.jersey", "jersey-core").versionAsInProject().startLevel(2),
-                mavenBundle("com.sun.jersey", "jersey-json").versionAsInProject().startLevel(2), junitBundles());
+                junitBundles());
     }
 
 }
index aa9fea5467ecbe1e0793ed44fd15c2616f2a2547..483d993d04a0e872034fae5f1a926846d4639b9b 100644 (file)
@@ -27,7 +27,7 @@
           <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>${sal.version}</version>
           </dependency>
         </dependencies>
       </plugin>
@@ -59,7 +59,8 @@
               javax.xml.bind.annotation,
               javax.xml.bind,
               org.apache.catalina.filters,
-              org.codehaus.jackson.jaxrs,
+              com.fasterxml.jackson.jaxrs.base,
+              com.fasterxml.jackson.jaxrs.json,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Export-Package>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${sal.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal.connection</artifactId>
-      <version>0.1.1-SNAPSHOT</version>
+      <version>${sal.connection.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal.networkconfiguration</artifactId>
-      <version>0.0.2-SNAPSHOT</version>
+      <version>${sal.networkconfiguration.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>connectionmanager</artifactId>
-      <version>0.1.1-SNAPSHOT</version>
+      <version>${connectionmanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>containermanager</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${containermanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.codehaus.enunciate</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>commons.northbound</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${commons.northbound.version}</version>
     </dependency>
   </dependencies>
 </project>
index f8342f935c9124568e652356028093cad7b12036..d54f2c5b2860ca6f2514ea1ca4420b2280132c84 100644 (file)
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>containermanager</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>${containermanager.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>${sal.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>commons.northbound</artifactId>
-            <version>0.4.1-SNAPSHOT</version>
+            <version>${commons.northbound.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
index d3c262f222f7f62bd612193944b0b0d919a50271..642b3bb197c1e0e9416967cbc71760ef79c64ecf 100644 (file)
@@ -30,7 +30,6 @@ import org.codehaus.enunciate.jaxrs.StatusCodes;
 import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronPortAware;
 import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;
 import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
 import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
 import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
@@ -268,7 +267,7 @@ public class NeutronPortsNorthbound {
             List<NeutronPort> bulk = input.getBulk();
             Iterator<NeutronPort> i = bulk.iterator();
             HashMap<String, NeutronPort> testMap = new HashMap<String, NeutronPort>();
-            Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);
             while (i.hasNext()) {
                 NeutronPort test = i.next();
 
index d169de9f2af44372d4099adb6015c82b14d8d85e..c020e6b2a24e32226c96b4892a5530a2257feb2e 100644 (file)
@@ -27,7 +27,7 @@
           <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>${sal.version}</version>
           </dependency>
         </dependencies>
       </plugin>
@@ -57,7 +57,8 @@
               javax.xml.bind.annotation,
               javax.xml.bind,
               org.apache.catalina.filters,
-              org.codehaus.jackson.jaxrs,
+              com.fasterxml.jackson.jaxrs.base,
+              com.fasterxml.jackson.jaxrs.json,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Export-Package>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${sal.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>containermanager</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${containermanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
@@ -94,7 +95,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>commons.northbound</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${commons.northbound.version}</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index 8df02c976b63db49ed411fc962a79593c82f3a4b..95410b0d3a34a4a879e0fde3f3ed00561c495992 100644 (file)
@@ -27,7 +27,7 @@
           <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>${sal.version}</version>
           </dependency>
         </dependencies>
       </plugin>
@@ -65,7 +65,8 @@
                 javax.xml.bind,
                 org.slf4j,
                 org.apache.catalina.filters,
-                org.codehaus.jackson.jaxrs,
+                com.fasterxml.jackson.jaxrs.base,
+                com.fasterxml.jackson.jaxrs.json,
                 !org.codehaus.enunciate.jaxrs
               </Import-Package>
             <Export-Package>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>containermanager</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${containermanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>statisticsmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${statisticsmanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${sal.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>commons.northbound</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${commons.northbound.version}</version>
     </dependency>
     <dependency>
       <groupId>org.codehaus.enunciate</groupId>
index bdf0b988f815a88c85e0f593b4ed1d2405cdd23d..c7108b2efaa9ec375d9597afa8ccceb62835fa92 100644 (file)
           <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>${sal.version}</version>
           </dependency>
           <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>clustering.services</artifactId>
-            <version>0.4.1-SNAPSHOT</version>
+            <version>${clustering.services.version}</version>
           </dependency>
           <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>configuration</artifactId>
-            <version>0.4.1-SNAPSHOT</version>
+            <version>${configuration.version}</version>
           </dependency>
           <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>switchmanager</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>${switchmanager.api.version}</version>
           </dependency>
         </dependencies>
       </plugin>
@@ -72,7 +72,8 @@
               javax.xml.bind.annotation,
               org.slf4j,
               org.apache.catalina.filters,
-              org.codehaus.jackson.jaxrs,
+              com.fasterxml.jackson.jaxrs.base,
+              com.fasterxml.jackson.jaxrs.json,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Export-Package>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${sal.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>containermanager</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${containermanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>commons.northbound</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${commons.northbound.version}</version>
     </dependency>
     <dependency>
       <groupId>org.codehaus.enunciate</groupId>
index e4447fee2d8528e75dbe0819b4a3a20303e56c92..a1932f521bcec302e30e4b77fb5d2cdfaa5afb8d 100644 (file)
@@ -28,7 +28,7 @@
           <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>${sal.version}</version>
           </dependency>
         </dependencies>
       </plugin>
@@ -59,8 +59,8 @@
               javax.xml.bind,
               org.slf4j,
               org.apache.catalina.filters,
-              org.codehaus.jackson.jaxrs,
-              org.codehaus.jackson.annotate,
+              com.fasterxml.jackson.annotation,
+              com.fasterxml.jackson.databind,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Web-ContextPath>/controller/nb/v2/switchmanager</Web-ContextPath>
@@ -75,7 +75,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>containermanager</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${containermanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${sal.version}</version>
     </dependency>
 
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>commons.northbound</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${commons.northbound.version}</version>
     </dependency>
 
     <dependency>
index 43d3aae57c71f33f735f5ad35e1f887e7ad52f1c..00f0d4b0544fd7c474efae06550e0961ef08025c 100644 (file)
@@ -13,15 +13,15 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlElementRef;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementRef;
 import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
 
-import org.codehaus.jackson.annotate.JsonIgnore;
-import org.codehaus.jackson.annotate.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.core.Property;
 
index 58a024c928d17be3f8060ed5fc812ce10d66f839..51e96c49eaf4cd7ac39803c1bde77abe96c821cc 100644 (file)
@@ -13,15 +13,15 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlElementRef;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementRef;
 import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
 
-import org.codehaus.jackson.annotate.JsonIgnore;
-import org.codehaus.jackson.annotate.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.Property;
 
index 3b3abc34368f7937e01bf736770a08c20078576c..4cdfb02d58ee81d77fb29e938fb6f64a95c1951a 100644 (file)
@@ -29,7 +29,7 @@
           <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>${sal.version}</version>
           </dependency>
         </dependencies>
       </plugin>
               org.opendaylight.controller.usermanager,
               org.opendaylight.controller.topologymanager,
               com.sun.jersey.spi.container.servlet,
-              org.codehaus.jackson.annotate,
+              com.fasterxml.jackson.annotation,
               javax.ws.rs,
               javax.ws.rs.core,
               javax.xml.bind,
               javax.xml.bind.annotation,
               org.slf4j,
               org.apache.catalina.filters,
-              org.codehaus.jackson.jaxrs,
+              com.fasterxml.jackson.jaxrs.base,
+              com.fasterxml.jackson.jaxrs.json,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Web-ContextPath>/controller/nb/v2/topology</Web-ContextPath>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>containermanager</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${containermanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>commons.northbound</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${commons.northbound.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${sal.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>topologymanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${topologymanager.version}</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index 6614bbe640d804030c5aa8fd49fb9e26a2ccc45f..1d4a8a66eec478c963cd76f5cc14dffca76b8ddb 100644 (file)
@@ -13,7 +13,6 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
@@ -21,8 +20,8 @@ import javax.xml.bind.annotation.XmlElementRef;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 
-import org.codehaus.jackson.annotate.JsonIgnore;
-import org.codehaus.jackson.annotate.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import org.opendaylight.controller.sal.core.Edge;
 import org.opendaylight.controller.sal.core.Property;
 
index 8a85dbb62202de158261e466beb20a997461808c..b48d67252e1bac2165f8d7a8bdec5c25b952ea91 100644 (file)
@@ -47,7 +47,8 @@
               javax.xml.bind.annotation,
               org.slf4j,
               org.apache.catalina.filters,
-              org.codehaus.jackson.jaxrs,
+              com.fasterxml.jackson.jaxrs.base,
+              com.fasterxml.jackson.jaxrs.json,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Export-Package>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>${sal.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>usermanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${usermanager.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>commons.northbound</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>${commons.northbound.version}</version>
     </dependency>
     <dependency>
       <groupId>org.codehaus.enunciate</groupId>
index 8a86d2f256fee58addddffaa9b998071b99c58ac..27a7ae6ffb125ebb42d8af542ca27348fa926bb0 100644 (file)
@@ -748,7 +748,7 @@ public class OFStatisticsManager implements IOFStatisticsManager, IInventoryShim
             for (OFStatistics stats : targetList) {
                 V6StatsReply v6Stats = (V6StatsReply) stats;
                 V6Match v6Match = v6Stats.getMatch();
-                if (v6Stats.getPriority() == priority && v6Match.equals(targetMatch)) {
+                if (v6Stats.getPriority() == priority && targetMatch.equals(v6Match)) {
                     List<OFStatistics> list = new ArrayList<OFStatistics>();
                     list.add(stats);
                     return list;
@@ -757,7 +757,7 @@ public class OFStatisticsManager implements IOFStatisticsManager, IInventoryShim
         } else {
             for (OFStatistics stats : statsList) {
                 OFFlowStatisticsReply flowStats = (OFFlowStatisticsReply) stats;
-                if (flowStats.getPriority() == priority && flowStats.getMatch().equals(ofMatch)) {
+                if (flowStats.getPriority() == priority && ofMatch.equals(flowStats.getMatch())) {
                     List<OFStatistics> list = new ArrayList<OFStatistics>();
                     list.add(stats);
                     return list;
index 2457ddeb67d779fbb171553371a341e1e5617c8d..b7d7b05b608cf821a75076d93b53c3df2341ebf6 100644 (file)
@@ -57,7 +57,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index ec050fa305d17123fcada432873e747dd2273944..9f2454bbffa9d6ace80c29fafaf6e8ea770f460c 100644 (file)
@@ -65,6 +65,12 @@ public class InventoryService implements IPluginInInventoryService {
         }
     }
 
+    @Override
+    public Set<Node> getConfiguredNotConnectedNodes() {
+        // TODO
+        return null;
+    }
+
     /**
      * Function called by the dependency manager when all the required
      * dependencies are satisfied
index eeea5d91d7e773cea232420f40c0462428358c7e..aa3f6259396d78434a2c87e83d9284f090dda053 100644 (file)
@@ -59,7 +59,7 @@
    <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 969aa630a1519f712e24af8ef0e0cd0025022635..0cd1612808b4a67e8c0eb38c0dec013e4090dee3 100644 (file)
@@ -45,8 +45,8 @@ abstract public class ComponentActivatorAbstractBase implements
     Logger logger = LoggerFactory
             .getLogger(ComponentActivatorAbstractBase.class);
     private DependencyManager dm;
-    private ConcurrentMap<ImmutablePair<String, Object>, Component> dbInstances = (ConcurrentMap<ImmutablePair<String, Object>, Component>) new ConcurrentHashMap<ImmutablePair<String, Object>, Component>();
-    private ConcurrentMap<Object, Component> dbGlobalInstances = (ConcurrentMap<Object, Component>) new ConcurrentHashMap<Object, Component>();
+    private ConcurrentMap<ImmutablePair<String, Object>, Component> dbInstances = new ConcurrentHashMap<ImmutablePair<String, Object>, Component>();
+    private ConcurrentMap<Object, Component> dbGlobalInstances = new ConcurrentHashMap<Object, Component>();
 
     /**
      * Method that should be overriden by the derived class for customization
@@ -253,6 +253,11 @@ abstract public class ComponentActivatorAbstractBase implements
                             containerName, imps[i]);
                     Component c = this.dbInstances.get(key);
                     if (c != null) {
+                        if (c.getService() != null) {
+                            c.invokeCallbackMethod(new Object[] { c.getService() }, "containerStop",
+                                                   new Class[][] {{ Component.class}, {} },
+                                                   new Object[][] { {c}, {} });
+                        }
                         // Now remove the component from dependency manager,
                         // which will implicitely stop it first
                         this.dm.remove(c);
index 0df6d4cec47a778cf4645f9fd342f63250ce9855..a823864a67ad07f9ed055633e5c2ed7b1c9f48c7 100644 (file)
@@ -8,17 +8,6 @@
 
 package org.opendaylight.controller.sal.flowprogrammer;
 
-import java.io.Serializable;
-import java.net.Inet6Address;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-
 import org.opendaylight.controller.sal.action.Action;
 import org.opendaylight.controller.sal.action.ActionType;
 import org.opendaylight.controller.sal.action.SetDlType;
@@ -29,6 +18,16 @@ import org.opendaylight.controller.sal.utils.EtherTypes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.net.Inet6Address;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
 /**
  * Represent a flow: match + actions + flow specific properties
  */
@@ -305,4 +304,5 @@ public class Flow implements Cloneable, Serializable {
         }
         return true;
     }
+
 }
index d60e7abe70874e75f582aa9b672c0fa23758415c..006334edfeb7567742bb679f8fa04c50e5a9d364 100644 (file)
@@ -50,7 +50,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index e171a8de59ad275cc7ea2253bba098b6aadcd30a..4a7e70b836aa06146b89a67b19aaa38f2fbc87c3 100644 (file)
@@ -58,7 +58,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 79707cbc572d0b8856f31aafd7e27fc4f060ff31..3c08b439aeea04b9d37d8ebc1c4d6dccb1b24f26 100644 (file)
@@ -47,7 +47,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
   </dependencies>
 </project>
index 9d7b84ac79bedcedf8f277dba6f88c9563abc37a..c25ce0fa4f11cfd691b04cb56aaea523b5917ad0 100644 (file)
@@ -50,7 +50,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index cf7a18ea659e6d126f43b868d8cf996cee6253dc..6f951ca2f6c6c9e4edb55ce0e714dfce4813c9ff 100644 (file)
@@ -85,7 +85,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
@@ -95,7 +95,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index 45d041c3e1e02533251ff672da2f0908a4da46a9..4fd3f4a32de5964fe7f2b0df20c4125497e71eb6 100644 (file)
@@ -29,7 +29,6 @@ public class LoadBalancerTest extends TestCase {
     public void testRoundRobinPolicy() {\r
         ConfigManager cm = null;\r
         cm = new ConfigManager();\r
-        Assert.assertFalse(cm== null);\r
 \r
         Pool pool = cm.createPool("TestPool","roundrobin");\r
         VIP vip = cm.createVIP("TestVIP","10.0.0.9","TCP",(short)5550,"TestPool");\r
index 543aa8ca54be34ed6bdd1f120b11235267801757..3b054b6339514595ffce28642792bff675763ff6 100644 (file)
@@ -28,7 +28,7 @@
           <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
+            <version>0.7.0-SNAPSHOT</version>
           </dependency>
         </dependencies>
       </plugin>
@@ -59,7 +59,8 @@
               javax.xml.bind,
               org.slf4j,
               org.apache.catalina.filters,
-              org.codehaus.jackson.jaxrs,
+              com.fasterxml.jackson.jaxrs.base,
+              com.fasterxml.jackson.jaxrs.json,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Web-ContextPath>/one/nb/v2/lb</Web-ContextPath>
@@ -89,7 +90,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index edd146e61572fd49ff025c1d732b510fca3353e0..a4bb76d5ab5d780774c23225d4a2f4687038389c 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>hosttracker</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
@@ -86,7 +86,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
   </dependencies>
 </project>
index a34cbb5db80f8f7232bf8dac7c2c41e7aba42c01..7a3625a229ef5ae04f76de4a6eabe28feef657b7 100644 (file)
@@ -800,8 +800,7 @@ public class SimpleForwardingImpl implements IfNewHostNotify,
         log.debug("Host Facing Port in a container came up, install the rules for all hosts from this port !");
         Set<HostNodeConnector> allHosts = this.hostTracker.getAllHosts();
         for (HostNodeConnector host : allHosts) {
-            if (node.equals(host.getnodeconnectorNode())
-                    && swPort.equals(host.getnodeConnector())) {
+            if (node.equals(host.getnodeconnectorNode())) {
                 /*
                  * This host resides behind the same switch and port for which a port up
                  * message is received. Ideally this should not happen, but if it does,
index 2e7466daf000255e915fca10252e9295bbb5349c..ef45e768337a621f4ffa7ffd259bfdcbd271ee90 100644 (file)
@@ -58,7 +58,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
         <groupId>orbit</groupId>
index 0dca7396e71ead84841bee31b4c9f2db8708aaab..3a1367901be031e85de8d9014022c11aa447ca56 100644 (file)
@@ -47,7 +47,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
   </dependencies>
 </project>
index 54ba4865b2231d9e2b15b299e1b76094285a8c85..c69e752549dfe4b2f12f0fbfbdcc3feab411600d 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index d04371461f371e1e11ba0254a57fb92763f793c3..026811f75b6f92476bbc146132df141ed5f26db6 100644 (file)
@@ -45,7 +45,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index b9cac8f2f86ac286f07bebeea3982e3aa75c5ec4..a4e96dd6a03d0339b46c97a0b2759d17b2b71e07 100644 (file)
@@ -92,7 +92,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index 16c09fe3f6a4ddfe62623293b055b53eabde15c0..56df8e26bd094b82bdd8d6ddb89cec4ab249e7a9 100644 (file)
@@ -161,15 +161,11 @@ public class Subnet implements Cloneable, Serializable {
         }
         InetAddress thisPrefix = getPrefixForAddress(this.networkAddress);
         InetAddress otherPrefix = getPrefixForAddress(ip);
-        if ((thisPrefix == null) || (otherPrefix == null)) {
-            return false;
-        }
-        if (thisPrefix.equals(otherPrefix)) {
-            return true;
-        }
-        else {
-            return false;
+        boolean isSubnetOf = true;
+        if (((thisPrefix == null) || (otherPrefix == null)) || (!thisPrefix.equals(otherPrefix)) ) {
+            isSubnetOf = false;
         }
+        return isSubnetOf;
     }
 
     public short getVlan() {
@@ -248,17 +244,7 @@ public class Subnet implements Cloneable, Serializable {
     }
 
     public boolean isMutualExclusive(Subnet otherSubnet) {
-        if (this.networkAddress.getClass() != otherSubnet.networkAddress
-                .getClass()) {
-            return true;
-        }
-        if (this.isSubnetOf(otherSubnet.getNetworkAddress())) {
-            return false;
-        }
-        if (otherSubnet.isSubnetOf(this.getNetworkAddress())) {
-            return false;
-        }
-        return true;
+        return !(isSubnetOf(otherSubnet.getNetworkAddress()) || otherSubnet.isSubnetOf(getNetworkAddress()));
     }
 
     /**
index 189476a5d1bb1c1420c683bf4ea6a6c2a07b3d7b..4f06b79f490c55ddd530924cab3f75705255c8bc 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
@@ -35,8 +34,8 @@ import org.opendaylight.controller.sal.utils.StatusCode;
 @XmlAccessorType(XmlAccessType.NONE)
 public class SubnetConfig implements Cloneable, Serializable {
     private static final long serialVersionUID = 1L;
-    private static final String prettyFields[] = { GUIField.NAME.toString(),
-            GUIField.GATEWAYIP.toString(), GUIField.NODEPORTS.toString() };
+    private static final String prettyFields[] = { GUIField.NAME.toString(), GUIField.GATEWAYIP.toString(),
+            GUIField.NODEPORTS.toString() };
 
     /**
      * Name of the subnet
@@ -44,14 +43,13 @@ public class SubnetConfig implements Cloneable, Serializable {
     @XmlElement
     private String name;
     /**
-     * A.B.C.D/MM  Where A.B.C.D is the Default
-     * Gateway IP (L3) or ARP Querier IP (L2)
+     * A.B.C.D/MM Where A.B.C.D is the Default Gateway IP (L3) or ARP Querier IP
+     * (L2)
      */
     @XmlElement
     private String subnet;
     /**
-     * Set of node connectors in the format:
-     * Port Type|Port Id@Node Type|Node Id
+     * Set of node connectors in the format: Port Type|Port Id@Node Type|Node Id
      */
     @XmlElement
     private List<String> nodeConnectors;
@@ -68,7 +66,8 @@ public class SubnetConfig implements Cloneable, Serializable {
     public SubnetConfig(SubnetConfig subnetConfig) {
         name = subnetConfig.name;
         subnet = subnetConfig.subnet;
-        nodeConnectors = (subnetConfig.nodeConnectors == null) ? null : new ArrayList<String>(subnetConfig.nodeConnectors);
+        nodeConnectors = (subnetConfig.nodeConnectors == null) ? null : new ArrayList<String>(
+                subnetConfig.nodeConnectors);
     }
 
     public String getName() {
@@ -96,22 +95,43 @@ public class SubnetConfig implements Cloneable, Serializable {
     public Short getIPMaskLen() {
         Short maskLen = 0;
         String[] s = subnet.split("/");
-        maskLen = (s.length == 2) ? Short.valueOf(s[1]) : 32;
+
+        try {
+            maskLen = (s.length == 2) ? Short.valueOf(s[1]) : 32;
+        } catch (NumberFormatException e) {
+            maskLen = 32;
+        }
         return maskLen;
     }
 
     private Status validateSubnetAddress() {
         if (!NetUtils.isIPAddressValid(subnet)) {
-            return new Status(StatusCode.BADREQUEST, String.format("Invalid Subnet configuration: Invalid address: %s", subnet));
+            return new Status(StatusCode.BADREQUEST, String.format("Invalid Subnet configuration: Invalid address: %s",
+                    subnet));
+        }
+        if ((this.getIPMaskLen() == 0) || (this.getIPMaskLen() == 32)) {
+            return new Status(StatusCode.BADREQUEST, String.format("Invalid Subnet configuration: Invalid mask: /%s",
+                    this.getIPMaskLen()));
         }
-        if((this.getIPMaskLen() == 0) || (this.getIPMaskLen() == 32)) {
-            return new Status(StatusCode.BADREQUEST, String.format("Invalid Subnet configuration: Invalid mask: /%s", this.getIPMaskLen()));
+
+        //checks that address doesn't start with 0 or 255
+        String address = subnet.split("/")[0];
+        if (address.startsWith("0.") || address.startsWith("255.")) {
+            return  new Status(StatusCode.BADREQUEST, String.format("Invalid Subnet configuration: Invalid address: %s", address));
         }
+
         byte[] bytePrefix = NetUtils.getSubnetPrefix(this.getIPAddress(), this.getIPMaskLen()).getAddress();
         long prefix = BitBufferHelper.getLong(bytePrefix);
         if (prefix == 0) {
             return new Status(StatusCode.BADREQUEST, "Invalid network source address: subnet zero");
         }
+
+        //check that host is not set to all 0's or 1's
+        long hostAddress = BitBufferHelper.getLong(this.getIPAddress().getAddress()) - prefix;
+        if (hostAddress == 0 || hostAddress == Math.pow(2, 32-this.getIPMaskLen()) - 1) {
+            return new Status(StatusCode.BADREQUEST, String.format("Invalid subnet gateway address: /%s", subnet));
+        }
+
         return new Status(StatusCode.SUCCESS);
     }
 
@@ -158,7 +178,8 @@ public class SubnetConfig implements Cloneable, Serializable {
     }
 
     public boolean isGlobal() {
-        // If no ports are specified to be part of the domain, then it's a global domain IP
+        // If no ports are specified to be part of the domain, then it's a
+        // global domain IP
         return (nodeConnectors == null || nodeConnectors.isEmpty());
     }
 
@@ -180,8 +201,7 @@ public class SubnetConfig implements Cloneable, Serializable {
 
     @Override
     public String toString() {
-        return ("SubnetConfig [Name=" + name + ", Subnet=" + subnet
-                + ", NodeConnectors=" + nodeConnectors + "]");
+        return ("SubnetConfig [Name=" + name + ", Subnet=" + subnet + ", NodeConnectors=" + nodeConnectors + "]");
     }
 
     /**
index 41a1f1ab06d978a350002d7e52c5d0e5c755bbfd..8b6a149917602992c8f4360cceed2cc1c70cb54a 100644 (file)
@@ -8,8 +8,13 @@
 
 package org.opendaylight.controller.switchmanager;
 
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
 import java.net.Inet6Address;
 import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -26,19 +31,19 @@ public class SubnetTest {
     public void testSubnet() throws Exception {
         InetAddress ipaddr = InetAddress.getByName("100.0.0.1");
         Subnet subnet = new Subnet(ipaddr, (short) 24, (short) 5);
-        Assert.assertTrue(subnet.equals(subnet));
-        Assert.assertFalse(subnet.equals(null));
-        Assert.assertFalse(subnet.equals(ipaddr));
+        assertTrue(subnet.equals(subnet));
+        assertFalse(subnet.equals(null));
+        assertFalse(subnet.equals(ipaddr));
         Subnet subnet2 = new Subnet(ipaddr, (short) 24, (short) 5);
         Inet6Address ipv6 = (Inet6Address) Inet6Address
                 .getByName("1111::2222:3333:4444:5555:6666");
         Subnet subnet3 = new Subnet(ipv6, (short) 24, (short) 5);
-        Assert.assertTrue(subnet.equals(subnet2));
-        Assert.assertFalse(subnet.isMutualExclusive(subnet2));
-        Assert.assertTrue(subnet.isMutualExclusive(subnet3));
+        assertTrue(subnet.equals(subnet2));
+        assertFalse(subnet.isMutualExclusive(subnet2));
+        assertTrue(subnet.isMutualExclusive(subnet3));
         InetAddress subnetAddr = InetAddress.getByName("200.0.0.100");
 
-        Assert.assertTrue(subnet.isFlatLayer2() == true);
+        assertTrue(subnet.isFlatLayer2() == true);
 
         Set<NodeConnector> ncSet = new HashSet<NodeConnector>();
         Node node = NodeCreator.createOFNode(((long) 10));
@@ -53,10 +58,10 @@ public class SubnetTest {
         ncSet.add(nc1);
         ncSet.add(nc2);
 
-        Assert.assertTrue(subnet.hasNodeConnector(nc0));
-        Assert.assertFalse(subnet.hasNodeConnector(null));
+        assertTrue(subnet.hasNodeConnector(nc0));
+        assertFalse(subnet.hasNodeConnector(null));
         subnet.addNodeConnectors(ncSet);
-        Assert.assertTrue(subnet.hasNodeConnector(nc0));
+        assertTrue(subnet.hasNodeConnector(nc0));
 
         Set<NodeConnector> resultncSet = subnet.getNodeConnectors();
         Assert.assertEquals(resultncSet, ncSet);
@@ -69,24 +74,61 @@ public class SubnetTest {
         Set<NodeConnector> ncSet2 = new HashSet<NodeConnector>();
         ncSet2.add(nc0);
         subnet.deleteNodeConnectors(ncSet2);
-        Assert.assertFalse(subnet.getNodeConnectors().contains(nc0));
-        Assert.assertFalse(subnet.hasNodeConnector(nc0));
-        Assert.assertTrue(subnet.getNodeConnectors().contains(nc1));
-        Assert.assertTrue(subnet.getNodeConnectors().contains(nc2));
+        assertFalse(subnet.getNodeConnectors().contains(nc0));
+        assertFalse(subnet.hasNodeConnector(nc0));
+        assertTrue(subnet.getNodeConnectors().contains(nc1));
+        assertTrue(subnet.getNodeConnectors().contains(nc2));
 
         subnet.deleteNodeConnectors(ncSet2);
 
         subnet.setNetworkAddress(subnetAddr);
-        Assert.assertTrue(subnet.isMutualExclusive(subnet2));
-        Assert.assertTrue(subnet.getNetworkAddress().equals(subnetAddr));
+        assertTrue(subnet.isMutualExclusive(subnet2));
+        assertTrue(subnet.getNetworkAddress().equals(subnetAddr));
 
         subnet.setSubnetMaskLength((short) 16);
-        Assert.assertTrue(subnet.getSubnetMaskLength() == 16);
+        assertTrue(subnet.getSubnetMaskLength() == 16);
 
         subnet.setVlan((short) 100);
-        Assert.assertTrue(subnet.getVlan() == 100);
+        assertTrue(subnet.getVlan() == 100);
+
+        assertTrue(subnet.isFlatLayer2() == false);
+    }
+
+    @Test
+    public void checkIsSubnetOfComparisonMatch() {
+        String host = "10.0.0.1";
+        InetAddress ipAddrForSubnetComparison = null;
+        try {
+            ipAddrForSubnetComparison = InetAddress.getByName(host);
+        } catch (UnknownHostException e) {
+            fail("Failed to create InetAddress object for" + host);
+        }
+        SubnetConfig subnetConf = new SubnetConfig("subnet", "10.0.0.254/24",null);
+        Subnet subnet = new Subnet(subnetConf);
+        assertTrue(subnet.isSubnetOf(ipAddrForSubnetComparison));
+    }
 
-        Assert.assertTrue(subnet.isFlatLayer2() == false);
+    @Test
+    public void checkIsSubnetOfComparisonNoMatch() {
+        String host = "100.0.0.1";
+        InetAddress ipAddrForSubnetComparison = null;
+        try {
+            ipAddrForSubnetComparison = InetAddress.getByName(host);
+        } catch (UnknownHostException e) {
+            fail("Failed to create InetAddress object for" + host);
+        }
+        SubnetConfig subnetConf = new SubnetConfig("subnet", "10.0.0.254/24",null);
+        Subnet subnet = new Subnet(subnetConf);
+        assertFalse(subnet.isSubnetOf(ipAddrForSubnetComparison));
+    }
+
+    @Test
+    public void checkIsSubnetOfComparisonIpEmpty() {
+        SubnetConfig subnetConf = new SubnetConfig("subnet", "10.0.0.254/24",null);
+        Subnet subnet = new Subnet(subnetConf);
+        assertFalse(subnet.isSubnetOf(null));
     }
 
+
+
 }
index 76bfd56c2913cf9f89625e3db71fcf2cc9cc9e48..93c076dcba084ddd81616c691c8282ff9521378e 100644 (file)
@@ -97,7 +97,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>statisticsmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index a91e7275ba6ac5403ac4dee11baa363cbe80c694..10b1a7243bdbe2f76cb81915a5014b3d1c025743 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 97966255a03db0b91b60a899764cd1de3b8e432b..fa01fa6a6025f1dc4da35e0bda80b43f77a0388a 100644 (file)
@@ -35,10 +35,10 @@ import org.opendaylight.controller.sal.core.State;
 import org.opendaylight.controller.sal.core.UpdateType;
 import org.opendaylight.controller.sal.packet.address.EthernetAddress;
 import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
 import org.opendaylight.controller.sal.utils.NodeCreator;
+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.SpanConfig;
 import org.opendaylight.controller.switchmanager.Subnet;
@@ -55,7 +55,7 @@ public class TopologyManagerImplTest {
     private final class TestSwitchManager implements ISwitchManager {
         private final Set<Node>  nodeSet = new HashSet<Node>();
         private final Set<NodeConnector> nodeConnectorSet =
-            new HashSet<NodeConnector>();
+                new HashSet<NodeConnector>();
 
         private void addNodeConnectors(NodeConnector ... connectors) {
             for (NodeConnector nc: connectors) {
@@ -69,9 +69,9 @@ public class TopologyManagerImplTest {
         private void addNodeConnectors(TopologyUserLinkConfig ... links) {
             for (TopologyUserLinkConfig link: links) {
                 NodeConnector src =
-                    NodeConnector.fromString(link.getSrcNodeConnector());
+                        NodeConnector.fromString(link.getSrcNodeConnector());
                 NodeConnector dst =
-                    NodeConnector.fromString(link.getDstNodeConnector());
+                        NodeConnector.fromString(link.getDstNodeConnector());
                 addNodeConnectors(src, dst);
             }
         }
@@ -292,6 +292,35 @@ public class TopologyManagerImplTest {
         public String getNodeDescription(Node node) {
             return null;
         }
+
+        @Override
+        public Status removeControllerProperty(String propertyName){
+            return null;
+        }
+
+        @Override
+        public Set<Switch> getConfiguredNotConnectedSwitches() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Map<String, Property> getControllerProperties() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Property getControllerProperty(String propertyName) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Status setControllerProperty(Property property) {
+            // TODO Auto-generated method stub
+            return null;
+        }
     }
 
     /*
@@ -485,13 +514,13 @@ public class TopologyManagerImplTest {
         Assert.assertTrue(topoManagerImpl.getUserLinks().isEmpty());
 
         TopologyUserLinkConfig badlink1 =
-            new TopologyUserLinkConfig("bad1", "OF|1@OF|4", "OF|1@OF|5");
+                new TopologyUserLinkConfig("bad1", "OF|1@OF|4", "OF|1@OF|5");
         TopologyUserLinkConfig badlink2 =
-            new TopologyUserLinkConfig("bad2", "OF|10@OF|7", "OF|7@OF|13");
+                new TopologyUserLinkConfig("bad2", "OF|10@OF|7", "OF|7@OF|13");
         Assert.assertEquals(StatusCode.NOTFOUND,
-                            topoManagerImpl.addUserLink(badlink1).getCode());
+                topoManagerImpl.addUserLink(badlink1).getCode());
         Assert.assertEquals(StatusCode.NOTFOUND,
-                            topoManagerImpl.addUserLink(badlink2).getCode());
+                topoManagerImpl.addUserLink(badlink2).getCode());
     }
 
     @Test
@@ -559,7 +588,7 @@ public class TopologyManagerImplTest {
             reverseLink[i] = new TopologyUserLinkConfig(name, dstNodeConnector, srcNodeConnector);
 
             Assert.assertEquals(StatusCode.NOTFOUND,
-                                topoManagerImpl.addUserLink(link[i]).getCode());
+                    topoManagerImpl.addUserLink(link[i]).getCode());
             swMgr.addNodeConnectors(link[i]);
             Assert.assertTrue(topoManagerImpl.addUserLink(link[i]).isSuccess());
         }
index 5dfa1632f74c4d323cb87e8cbe8bb8885ada9e35..93e8dcc89f3bec602c04762ded8ea0619819cba5 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.0-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
      <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal.implementation</artifactId>
-      <version>0.4.0-SNAPSHOT</version>
+      <version>0.4.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>containermanager</artifactId>
-      <version>0.5.0-SNAPSHOT</version>
+      <version>0.5.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>containermanager.it.implementation</artifactId>
-      <version>0.5.0-SNAPSHOT</version>
+      <version>0.5.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.4.0-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.0-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.stub</artifactId>
-      <version>0.4.0-SNAPSHOT</version>
+      <version>0.4.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>statisticsmanager</artifactId>
-      <version>0.4.0-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>statisticsmanager.implementation</artifactId>
-      <version>0.4.0-SNAPSHOT</version>
+      <version>0.4.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>switchmanager.implementation</artifactId>
-      <version>0.4.0-SNAPSHOT</version>
+      <version>0.4.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>configuration</artifactId>
-      <version>0.4.0-SNAPSHOT</version>
+      <version>0.4.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>configuration.implementation</artifactId>
-      <version>0.4.0-SNAPSHOT</version>
+      <version>0.4.1-SNAPSHOT</version>
     </dependency>
       <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>topologymanager</artifactId>
-      <version>0.4.0-SNAPSHOT</version>
+      <version>0.4.1-SNAPSHOT</version>
     </dependency>
   </dependencies>
   <properties>
index 5d9e6c70ce622415a190ed1f4438407103e5a924..f7064a3c6dee8ee5bd9b01b599ed4858bbcc9372 100644 (file)
@@ -76,7 +76,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
@@ -86,7 +86,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index dcdc2f6d50447e942fe868c22bc69bc732bfe248..dbf71fec6866b9cfb2ab1c368378495294b02948 100644 (file)
@@ -79,7 +79,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
@@ -89,7 +89,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.springframework.security</groupId>
index d66381f6ce737321c384f15c57aa9d64e19cf0bd..82abfbadb091e13cb30595c6fafd9df5dd1bea78 100644 (file)
               org.apache.taglibs.standard.tag.rt.fmt,
               org.apache.taglibs.standard.tei,
               org.apache.taglibs.standard.tlv,
-              org.codehaus.jackson,
-              org.codehaus.jackson.annotate,
-              org.codehaus.jackson.map,
-              org.codehaus.jackson.map.annotate,
+              com.fasterxml.jackson.databind,
+              com.fasterxml.jackson.annotation,
               org.osgi.framework,
               org.slf4j,
               org.springframework.beans,
@@ -95,7 +93,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwarding.staticrouting</artifactId>
       <version>${forwarding.staticrouting}</version>
     </dependency>
+
     <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-mapper-asl</artifactId>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-databind</artifactId>
     </dependency>
   </dependencies>
 </project>
index 3d33edcbf2272c308cdb2236c574aaa42cd95ed9..a118ccfbba70658fd4e2c817ea5a9e60bce7b500 100644 (file)
@@ -23,7 +23,7 @@ import java.util.concurrent.ConcurrentMap;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.codehaus.jackson.map.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.opendaylight.controller.connectionmanager.IConnectionManager;
 import org.opendaylight.controller.forwarding.staticrouting.IForwardingStaticRouting;
 import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig;
index cc142bf9672f136686a952e88c5c99395f6c2d8e..855dc90aa9023208b41168c384806db16d86dae5 100644 (file)
@@ -37,11 +37,11 @@ one.f.dashlet = {
 one.f.menu = {
   left : {
     top : [
-      one.f.dashlet.nodesLearnt,
-      one.f.dashlet.connection
+      one.f.dashlet.nodesLearnt
       ],
     bottom : [
-      one.f.dashlet.staticRouteConfig
+      one.f.dashlet.staticRouteConfig,
+      one.f.dashlet.connection
       ]
   },
   right : {
@@ -1361,7 +1361,7 @@ one.f.switchmanager.spanPortConfig = {
 
       $fieldset.append($label).append($select);
       // input port
-      var $label = one.lib.form.label("Input Port");
+      var $label = one.lib.form.label("Port");
       var $select = one.lib.form.select.create();
       one.lib.form.select.prepend($select, {'':'None'});
       $select.attr('id', one.f.switchmanager.spanPortConfig.id.modal.form.port);
index f0393c19cb0a04eb0fffae836840bff46441411f..5812c0e861700d3b04ff44a2f663465fd9694508 100644 (file)
               org.apache.taglibs.standard.tag.rt.fmt,
               org.apache.taglibs.standard.tei,
               org.apache.taglibs.standard.tlv,
-              org.codehaus.jackson,
-              org.codehaus.jackson.annotate,
-              org.codehaus.jackson.map,
-              org.codehaus.jackson.map.annotate,
+              com.fasterxml.jackson.core,
+              com.fasterxml.jackson.annotation,
+              com.fasterxml.jackson.databind,
               org.osgi.framework,
               org.slf4j,
               org.springframework.beans,
@@ -92,7 +91,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 6b4cfa00253ef4f36026a51f639fba6af02ed4b6..094562fac07252b182e601774e79209d0a473e20 100644 (file)
@@ -390,8 +390,8 @@ one.f.flows = {
                     $tr = $(tr);
                     $span = $("td span", $tr);
                     var flowstatus = $span.data("flowstatus");
-                    if($span.data("installInHw") != null) {
-                        var installInHw = $span.data("installInHw").toString();
+                    if($span.data("installinhw") != null) {
+                        var installInHw = $span.data("installinhw").toString();
                         if(installInHw == "true" && flowstatus == "Success") {
                             $tr.addClass("success");
                         } else {
index 85388d9b05f70587f6ba5006590411fac1363a25..1a801a2fe41517b907cbae2662973e993b2589f9 100644 (file)
               org.apache.taglibs.standard.tag.rt.fmt,
               org.apache.taglibs.standard.tei,
               org.apache.taglibs.standard.tlv,
-              org.codehaus.jackson,
-              org.codehaus.jackson.annotate,
-              org.codehaus.jackson.map,
-              org.codehaus.jackson.map.annotate,
+              com.fasterxml.jackson.core,
+              com.fasterxml.jackson.databind,
+              com.fasterxml.jackson.annotation,
               org.osgi.framework,
               org.slf4j,
               org.springframework.beans,
@@ -98,7 +97,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 1d4211a9267e25a1399f48d99c145cdb6bf5b6fa..ca37f4b7c19658ca14facf9af29d6d83d2cd07cb 100644 (file)
@@ -8,8 +8,10 @@
 
 package org.opendaylight.controller.web;
 
+import java.io.FileInputStream;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 
 import javax.servlet.http.HttpServletRequest;
@@ -28,6 +30,7 @@ import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.usermanager.IUserManager;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.ResponseBody;
@@ -52,6 +55,23 @@ public class DaylightWeb {
         return "main";
     }
 
+    /**
+     * Read the version.properties file for the property
+     *
+     * @param request
+     * @return String value configured in the version.properties file
+     */
+    @RequestMapping(value="/versionProperty/{property}", method = RequestMethod.GET)
+    @ResponseBody
+    public String getVersion(HttpServletRequest request, @PathVariable("property") String property) {
+        Properties prop = new Properties();
+        try {
+            prop.load(new FileInputStream("version.properties"));
+            return prop.getProperty(property+".version");
+        } catch (Exception e) {
+            return null;
+        }
+    }
     @RequestMapping(value = "web.json")
     @ResponseBody
     public Map<String, Map<String, Object>> bundles(HttpServletRequest request) {
index 89812af53df5447ef4426dd49ce312aff6f87a43..072f08f581eadb4b6b9290c92e93776f7b560c87 100644 (file)
@@ -46,6 +46,7 @@
              <url-pattern>/images/*</url-pattern>
              <url-pattern>/css/*</url-pattern>
              <url-pattern>/favicon.ico</url-pattern>
+             <url-pattern>/versionProperty/*</url-pattern>
           </web-resource-collection>
         </security-constraint>
 
index 226dcc87b7fb8bf34fa94937ec5e79b86eb8d577..358ea21ad9948d0b371bece2ae27abd1f9935a13 100644 (file)
               org.apache.taglibs.standard.tag.rt.fmt,
               org.apache.taglibs.standard.tei,
               org.apache.taglibs.standard.tlv,
-              org.codehaus.jackson,
-              org.codehaus.jackson.annotate,
-              org.codehaus.jackson.map,
-              org.codehaus.jackson.map.annotate,
+              com.fasterxml.jackson.core,
+              com.fasterxml.jackson.databind,
+              com.fasterxml.jackson.annotation,
               org.osgi.framework,
               org.slf4j,
               org.springframework.beans,
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index bb5e9f1f18f1ac3682485e34f82088ee7e17ff3c..033cc6d9e976e214400d0c56db229bcb3b822495 100644 (file)
               org.apache.taglibs.standard.tag.rt.fmt,
               org.apache.taglibs.standard.tei,
               org.apache.taglibs.standard.tlv,
-              org.codehaus.jackson,
-              org.codehaus.jackson.annotate,
-              org.codehaus.jackson.map,
-              org.codehaus.jackson.map.annotate,
+              com.fasterxml.jackson.core,
+              com.fasterxml.jackson.databind,
+              com.fasterxml.jackson.annotation,
               org.osgi.framework,
               org.slf4j,
               org.springframework.beans,
@@ -94,7 +93,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>statisticsmanager</artifactId>
-      <version>0.4.1-SNAPSHOT</version>
+      <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>web</artifactId>
       <version>0.4.1-SNAPSHOT</version>
     </dependency>
-    <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-mapper-asl</artifactId>
-    </dependency>
+
+   <dependency>
+         <groupId>com.fasterxml.jackson.core</groupId>
+         <artifactId>jackson-databind</artifactId>
+   </dependency>
   </dependencies>
 </project>