Merge "Fixed for bug 1197"
authorEd Warnicke <eaw@cisco.com>
Fri, 1 Aug 2014 02:31:30 +0000 (02:31 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Fri, 1 Aug 2014 02:31:30 +0000 (02:31 +0000)
1018 files changed:
features/adsal/pom.xml [new file with mode: 0644]
features/adsal/src/main/resources/features.xml [new file with mode: 0644]
features/base/src/main/resources/features.xml
features/config-netty/pom.xml [new file with mode: 0644]
features/config-netty/src/main/resources/features.xml [new file with mode: 0644]
features/config-persister/pom.xml [new file with mode: 0644]
features/config-persister/src/main/resources/features.xml [new file with mode: 0644]
features/config/pom.xml [moved from opendaylight/config/feature/pom.xml with 85% similarity]
features/config/src/main/resources/features.xml [new file with mode: 0644]
features/extras/pom.xml [new file with mode: 0644]
features/extras/src/main/resources/features.xml [new file with mode: 0644]
features/mdsal/pom.xml [moved from opendaylight/md-sal/feature/pom.xml with 97% similarity]
features/mdsal/src/main/resources/features.xml [moved from opendaylight/md-sal/feature/src/main/resources/features.xml with 56% similarity]
features/netconf/pom.xml [new file with mode: 0644]
features/netconf/src/main/resources/features.xml [new file with mode: 0644]
features/nsf/pom.xml [new file with mode: 0644]
features/nsf/src/main/resources/features.xml [new file with mode: 0644]
features/pom.xml [new file with mode: 0644]
features/protocol-framework/pom.xml [new file with mode: 0644]
features/protocol-framework/src/main/resources/features.xml [new file with mode: 0644]
opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/ArpHandler.java
opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/jaxb/Context.java
opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/model/FilterProcessor.java
opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/model/UrlMatcher.java
opendaylight/commons/opendaylight/pom.xml
opendaylight/commons/protocol-framework/src/main/java/org/opendaylight/controller/config/yang/protocol/framework/ReconnectImmediatelyStrategyFactoryModule.java
opendaylight/commons/protocol-framework/src/main/java/org/opendaylight/controller/config/yang/protocol/framework/TimedReconnectStrategyFactoryModule.java
opendaylight/commons/protocol-framework/src/main/java/org/opendaylight/protocol/framework/AbstractDispatcher.java
opendaylight/commons/protocol-framework/src/main/yang/odl-protocol-framework-cfg.yang
opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/ReconnectImmediatelyStrategyModuleTest.java
opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/TimedReconnectStrategyModuleTest.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/jmx/ServiceReferenceMXBean.java [moved from opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceMXBean.java with 87% similarity]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/DynamicWritableWrapper.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceMXBeanImpl.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtensibleBundleTracker.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImplTest.java
opendaylight/config/config-module-archetype/src/main/resources/archetype-resources/pom.xml
opendaylight/config/config-module-archetype/src/main/resources/archetype-resources/src/main/yang/__module-name__-impl.yang
opendaylight/config/config-module-archetype/src/main/resources/archetype-resources/src/main/yang/__module-name__.yang
opendaylight/config/config-util/pom.xml
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigRegistryJMXClient.java
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionClient.java
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionJMXClient.java
opendaylight/config/feature/src/main/resources/features.xml [deleted file]
opendaylight/config/pom.xml
opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/threadpool/util/FlexibleThreadPoolWrapper.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/yang/threadpool-impl-flexible.yang
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.java
opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ConfigConstants.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleUtil.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.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/ServiceInterfaceEntryTest.java
opendaylight/config/yang-jmx-generator/src/test/resources/test-config-threads-java.yang
opendaylight/config/yang-test/.gitignore [deleted file]
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/.gitignore [new file with mode: 0644]
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java [deleted file]
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java [deleted file]
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java [deleted file]
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java [deleted file]
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/MultipleDependenciesModuleStub.txt [new file with mode: 0644]
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java [deleted file]
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java [deleted file]
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleStub.txt
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java [deleted file]
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java [deleted file]
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/util/NetconfTestImplModuleUtil.java [moved from opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleUtil.java with 69% similarity]
opendaylight/config/yang-test/src/main/yang/config-test-impl.yang
opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/MultipleDependenciesModuleTest.java [new file with mode: 0644]
opendaylight/distribution/opendaylight-karaf/pom.xml
opendaylight/distribution/opendaylight-karaf/src/main/resources/configuration/initial/02-clustering.xml [deleted file]
opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/instance [new file with mode: 0755]
opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/instance.bat [new file with mode: 0644]
opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/karaf [new file with mode: 0755]
opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/karaf.bat [new file with mode: 0644]
opendaylight/distribution/opendaylight/pom.xml
opendaylight/distribution/opendaylight/src/assemble/bin.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini
opendaylight/distribution/opendaylight/src/main/resources/configuration/cors-config.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-netconf.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml
opendaylight/distribution/opendaylight/src/main/resources/functions.sh [new file with mode: 0644]
opendaylight/distribution/opendaylight/src/main/resources/run.bat
opendaylight/distribution/opendaylight/src/main/resources/run.sh
opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java
opendaylight/forwardingrulesmanager/api/src/test/java/org/opendaylight/controller/forwardingrulesmanager/frmTest.java
opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.java
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.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.java
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/FlowServiceAdapter.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/test/java/org/opendaylight/controller/sal/compatibility/test/NodeMappingTest.java
opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestFromSalConversionsUtils.java
opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestToSalConversionsUtils.java
opendaylight/md-sal/forwardingrules-manager/pom.xml
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.java
opendaylight/md-sal/model/model-flow-base/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/flow/types/port/rev130925/PortNumberBuilder.java [new file with mode: 0644]
opendaylight/md-sal/model/model-flow-management/pom.xml [deleted file]
opendaylight/md-sal/model/model-flow-management/src/main/yang/flow-management.yang [deleted file]
opendaylight/md-sal/model/model-flow-management/src/main/yang/group-management.yang [deleted file]
opendaylight/md-sal/model/model-flow-management/src/main/yang/meter-management.yang [deleted file]
opendaylight/md-sal/model/model-flow-management/src/main/yang/port-management.yang [deleted file]
opendaylight/md-sal/model/model-flow-management/src/main/yang/queue-management.yang [deleted file]
opendaylight/md-sal/model/model-flow-management/src/main/yang/table-management.yang [deleted file]
opendaylight/md-sal/model/model-flow-service/src/main/yang/node-errors.yang
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-flow-statistics.yang
opendaylight/md-sal/model/model-inventory/src/main/yang/opendaylight-inventory.yang
opendaylight/md-sal/model/pom.xml
opendaylight/md-sal/pom.xml
opendaylight/md-sal/sal-akka-raft/README-FIRST [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/pom.xml [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/run.sh [new file with mode: 0755]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/ClientActor.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/ExampleActor.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/LogGenerator.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/Main.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/TestDriver.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/messages/KeyValue.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/messages/KeyValueSaved.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/messages/PrintRole.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/messages/PrintState.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/protobuff/messages/KeyValueMessages.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ClientRequestTracker.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ClientRequestTrackerImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ElectionTerm.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/FollowerLogInformation.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/FollowerLogInformationImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorContext.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorContextImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftState.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLog.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLogEntry.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLogImplEntry.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/SerializationUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/ApplySnapshot.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/ApplyState.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/CommitEntry.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/ElectionTimeout.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/PersistEntry.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/Replicate.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/SaveSnapshot.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/SendHeartBeat.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/SendInstallSnapshot.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/AbstractRaftActorBehavior.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Candidate.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Follower.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Leader.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/RaftActorBehavior.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/AddRaftPeer.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/FindLeader.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CompositeNodeUtils.java with 76% similarity]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/FindLeaderReply.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/RemoveRaftPeer.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AbstractRaftRPC.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AppendEntries.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AppendEntriesReply.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/InstallSnapshot.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/InstallSnapshotReply.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/RaftRPC.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/RequestVote.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/RequestVoteReply.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/protobuff/client/messages/Payload.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/protobuff/messages/AppendEntriesMessages.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/protobuff/messages/VotingMessages.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/resources/AppendEntriesMessages.proto [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/resources/KeyValueMessages.proto [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/resources/VotingMessages.proto [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/main/resources/application.conf [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/AbstractActorTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActorContext.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/AbstractRaftActorBehaviorTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/FollowerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/LeaderTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/protobuff/messages/MockPayloadMessages.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/utils/DoNothingActor.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/test/resources/MockPayload.proto [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/test/resources/application.conf [new file with mode: 0644]
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/BindingTransactionChain.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataBroker.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/MountPoint.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/MountPointService.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/ReadTransaction.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/TransactionFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/WriteTransaction.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareBroker.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareConsumer.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareProvider.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationListener.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationProviderService.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationService.java
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/data/DataBrokerService.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/DataChangeListener.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/DataModificationTransaction.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/DataProviderService.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/DataRefresher.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/RuntimeDataProvider.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/SynchronizedTransaction.java
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/BindingAsyncDataBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingAsyncDataBrokerImplModuleFactory.java
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/BindingBrokerImplModuleFactory.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/DataBrokerImplModuleFactory.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/ForwardedCompatibleDataBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/ForwardedCompatibleDataBrokerImplModuleFactory.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedDataBroker.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractReadWriteTransaction.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractWriteTransaction.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDataReadTransactionImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDataReadWriteTransactionImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDataWriteTransactionImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingTranslatedTransactionChain.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBackwardsCompatibleDataBroker.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBindingDataBroker.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RpcIsNotRoutedException.java [new file with mode: 0644]
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/AbstractRuntimeCodeGenerator.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/BrokerImplClassLoader.java [deleted file]
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/RuntimeCodeGenerator.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java
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/BindingToDomCommitHandler.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingToDomTransaction.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DataModificationTracker.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingCommitHandler.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingNotificationForwarder.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingRpcForwarder.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingRpcForwardingManager.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingTransaction.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategy.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/package-info.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/MapUtils.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/DelegateProxy.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/remote/RouteChangeListener.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/md/sal/binding/impl/test/BindingNormalizedCodecTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1125RegressionTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ListInsertionDataChangeListenerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/RpcProviderRegistryTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/WriteTransactionTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataBrokerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataChangeListenerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractSchemaAwareTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AssertCollections.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestCustomizer.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategyTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/AbstractDataServiceTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/compat/MultipleAugmentationPutsTest.java [moved from opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPutsTest.java with 97% similarity]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/compat/UnionSerializationTest.java [moved from opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/UnionSerializationTest.java with 97% similarity]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/compat/package-info.java [moved from opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/RpcRegistrationNullPointer.java with 72% similarity]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingBrokerTestFactory.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/pom.xml
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/md/sal/binding/data/ConcurrentImplicitCreateTest.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/md/sal/binding/data/ListProcessingAndOrderingTest.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/md/sal/binding/data/WildcardedDataChangeListenerTest.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug01Test.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug02Test.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug03Test.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DeleteNestedAugmentationListenParentTest.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/bugfix/WriteParentListenAugmentTest.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/WriteParentReadChildTest.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/package-info.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.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
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerRpcTest.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/DOMRpcServiceTestBugfix560.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/NotificationTest.java
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/RegistrationListener.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/AsyncDataChangeEvent.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/AsyncDataChangeListener.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/AsyncReadOnlyTransaction.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/AsyncReadTransaction.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/AsyncWriteTransaction.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataChangeEvent.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataChangeListener.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataChangePublisher.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataCommitHandler.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataCommitHandlerRegistration.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataModification.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataModificationTransactionFactory.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataProvider.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataProvisionService.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataReader.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataStore.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataValidationFailedException.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/OptimisticLockFailedException.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/TransactionCommitFailedException.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/notify/NotificationPublishService.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/notify/NotificationSubscriptionService.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/routing/RouteChange.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/routing/RouteChangeListener.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/routing/RouteChangePublisher.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/routing/RoutedRegistration.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/routing/AbstractDataReadRouter.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataTransaction.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/TwoPhaseCommit.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java
opendaylight/md-sal/sal-common-impl/src/test/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizerTest.java
opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/CommitHandlerTransactions.java
opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/RpcErrors.java
opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Rpcs.java
opendaylight/md-sal/sal-compability/src/main/java/org/opendaylight/controller/sal/compability/ToSalPropertyClassUtils.java [deleted file]
opendaylight/md-sal/sal-connector-api/src/main/java/org/opendaylight/controller/sal/connector/api/Connector.java
opendaylight/md-sal/sal-connector-api/src/main/java/org/opendaylight/controller/sal/connector/api/ConnectorListener.java
opendaylight/md-sal/sal-distributed-datastore/pom.xml
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/AbstractUntypedActor.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ActorSystemFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ClusterWrapper.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ClusterWrapperImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/CompositeModificationPayload.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Configuration.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ConfigurationImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListener.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxy.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistration.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationProxy.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStore.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ListenerProxy.java [deleted file]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ListenerRegistration.java [deleted file]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ListenerRegistrationProxy.java [deleted file]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/NoOpCohort.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardManager.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardTransactionChain.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TerminationMonitor.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ThreePhaseCommitCohort.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ThreePhaseCommitCohortProxy.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TransactionChainProxy.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TransactionProxy.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/exceptions/PrimaryNotFoundException.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/Constants.java with 59% similarity]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/exceptions/TimeoutException.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/AbstractBaseMBean.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardMBeanFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStats.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStatsMBean.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/AbortTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/AbortTransactionReply.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CanCommitTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CanCommitTransactionReply.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CloseDataChangeListenerRegistration.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CloseDataChangeListenerRegistrationReply.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CloseTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CloseTransactionChain.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CloseTransactionChainReply.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CloseTransactionReply.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CommitTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CommitTransactionReply.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CreateTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CreateTransactionChain.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CreateTransactionChainReply.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CreateTransactionReply.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/DataChanged.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/DataChangedReply.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/DeleteData.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/DeleteDataReply.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/FindPrimary.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/MergeData.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/MergeDataReply.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/ModifyData.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/Monitor.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/NonPersistent.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/PeerAddressResolved.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/PreCommitTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/PreCommitTransactionReply.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/PrimaryFound.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/PrimaryNotFound.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/ReadData.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/ReadDataReply.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/ReadyTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/ReadyTransactionReply.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/RegisterChangeListener.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/RegisterChangeListenerReply.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/SerializableMessage.java [moved from opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CloseListenerRegistrationReply.java with 84% similarity]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/WriteData.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/WriteDataReply.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/AbstractModification.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/DeleteModification.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/ImmutableCompositeModification.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/MergeModification.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/Modification.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/MutableCompositeModification.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/modification/WriteModification.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardstrategy/DefaultShardStrategy.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ModuleShardStrategy.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ShardStrategy.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ShardStrategyFactory.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/utils/ActorContext.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/utils/InstanceIdentifierUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModuleFactory.java [moved from opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedDataStoreProviderModuleFactory.java with 52% similarity]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedDataStoreProviderModule.java [deleted file]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/resources/application.conf [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/resources/module-shards.conf [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/resources/modules.conf [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/yang/distributed-datastore-provider.yang
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/AbstractActorTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/BasicIntegrationTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ConfigurationImplTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxyTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationProxyTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationTest.java [moved from opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ListenerRegistrationTest.java with 68% similarity]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreIntegrationTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardManagerTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionChainTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ThreePhaseCommitCohortProxyTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/TransactionProxyTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStatsTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/messages/MergeDataTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/AbstractModificationTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/DeleteModificationTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/MergeModificationTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/MutableCompositeModificationTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/modification/WriteModificationTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ModuleShardStrategyTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ShardStrategyFactoryTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/utils/ActorContextTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/utils/MockActorContext.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/utils/MockClusterWrapper.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/utils/MockConfiguration.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/utils/TestUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/CarsModel.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/CompositeModel.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/PeopleModel.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/SampleModelsTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/SchemaContextHelper.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/TestModel.java
opendaylight/md-sal/sal-distributed-datastore/src/test/resources/application.conf
opendaylight/md-sal/sal-distributed-datastore/src/test/resources/cars.yang [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/resources/module-shards.conf [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/resources/modules.conf [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/resources/odl-datastore-augmentation.yang [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/resources/odl-datastore-test-notification.yang [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/resources/people.yang [new file with mode: 0644]
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataBroker.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataChangeListener.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataReadOnlyTransaction.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataReadTransaction.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataReadWriteTransaction.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataWriteTransaction.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMMountPoint.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMMountPointService.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMService.java [moved from opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CloseListenerRegistration.java with 74% similarity]
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMTransactionChain.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/Broker.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/Consumer.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/Provider.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RoutedRpcDefaultImplementation.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/data/DataBrokerService.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataChangeListener.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataModificationTransaction.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataProviderService.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataStore.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/data/DataValidator.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/MountProvisionListener.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionService.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountService.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/NotificationPublishService.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/NotificationService.java
opendaylight/md-sal/sal-dom-broker/pom.xml
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomBrokerImplModule.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomBrokerImplModuleFactory.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomInmemoryDataBrokerModule.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomInmemoryDataBrokerModuleFactory.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/AbstractDOMForwardedCompositeTransaction.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/AbstractDOMForwardedTransactionFactory.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMDataBrokerImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMDataBrokerTransactionChainImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMDataCommitCoordinatorImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMDataCommitErrorInvoker.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMDataCommitExecutor.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMDataCommitImplementation.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMForwardedReadOnlyTransaction.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMForwardedReadWriteTransaction.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMForwardedWriteTransaction.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleDataBroker.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleTransaction.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingListenerInvoker.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/mount/DOMMountPointServiceImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPoint.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPointManager.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.java [deleted file]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ConsumerContextImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataTransactionImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/GlobalBundleScanningSchemaServiceImpl.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.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/NotificationModule.java [deleted file]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ProviderContextImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataStoreStatsWrapper.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/GlobalRpcRegistration.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/HashMapDataStore.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/HashMapDataStoreTransaction.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/NotificationRouterImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/RoutedRpcRegImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/RoutedRpcSelector.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareRpcBroker.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/AbstractBrokerServiceProxy.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/DOMDataBrokerProxy.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/DOMMountPointServiceProxy.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/DataBrokerServiceProxy.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/DataProviderServiceProxy.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/MountProviderServiceProxy.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/NotificationPublishServiceProxy.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/NotificationServiceProxy.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/ProxyFactory.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/RpcProvisionRegistryProxy.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/SchemaServiceActivator.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/spi/NotificationRouter.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/spi/RoutedRpcProcessor.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/ProxySchemaContext.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/YangDataOperations.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/YangSchemaUtils.java
opendaylight/md-sal/sal-dom-broker/src/main/yang/opendaylight-dom-broker-impl.yang
opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMBrokerPerformanceTest.java
opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMBrokerTest.java
opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMTransactionChainTest.java
opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/broker/impl/MountPointServiceTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/TestModel.java
opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPointManagerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPointTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/md/sal/dom/broker/spi/mount/SimpleDOMMountPoint.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/md/sal/dom/broker/spi/rpc/RpcRoutingStrategy.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStore.java
opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStoreReadTransaction.java
opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStoreWriteTransaction.java
opendaylight/md-sal/sal-dom-xsql/.checkstyle [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/.gitignore [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/pom.xml [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/TablesResultSet.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLAdapter.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLBluePrint.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLBluePrintNode.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLBluePrintRelation.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLColumn.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLCriteria.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLODLUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLThreadPool.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCCommand.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCConnection.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCDriver.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCResultSet.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCServer.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCStatement.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/xsql/XSQLProvider.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/yang/gen/v1/http/netconfcentral/org/ns/xsql/rev140626/XSQLModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/yang/gen/v1/http/netconfcentral/org/ns/xsql/rev140626/XSQLModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/resources/04-xsql.xml [new file with mode: 0644]
opendaylight/md-sal/sal-dom-xsql/src/main/yang/XSQL.yang [new file with mode: 0644]
opendaylight/md-sal/sal-inmemory-datastore/pom.xml
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryConfigDataStoreProviderModule.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryOperationalDataStoreProviderModule.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ChangeListenerNotifyTask.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DOMImmutableDataChangeEvent.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataChangeListenerRegistration.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedReadTransaction.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedReadWriteTransaction.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedWriteTransaction.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ListenerTree.java
opendaylight/md-sal/sal-inmemory-datastore/src/main/yang/opendaylight-inmemory-datastore-provider.yang
opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/AbstractDataChangeListenerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/DatastoreTestTask.java [new file with mode: 0644]
opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/DefaultDataChangeListenerTestSuite.java [new file with mode: 0644]
opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDataStoreTest.java
opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/RootScopeSubtreeTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaUpdateForTransactionTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/TestModel.java
opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/WildcardedScopeBaseTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/WildcardedScopeOneTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/WildcardedScopeSubtreeTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/pom.xml
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfSessionCapabilities.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceCommitHandler.java [deleted file]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataBroker.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataReader.java [deleted file]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDatastoreAdapter.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceRpc.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalFacade.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalProvider.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTwoPhaseCommitTransaction.java [deleted file]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadOnlyTx.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadWriteTx.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceWriteOnlyTx.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfMessageTransformUtil.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NodeContainerProxy.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/FailedRpcResult.java [deleted file]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/RemoteDeviceId.java
opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java
opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToNotificationTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToRpcRequestTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/test/resources/notification-payload.xml [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/test/resources/schemas/rpc-notification-subscription.yang [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/test/resources/schemas/user-notification.yang [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/README-FIRST
opendaylight/md-sal/sal-protocolbuffer-encoding/pom.xml
opendaylight/md-sal/sal-protocolbuffer-encoding/run.sh
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NodeToNormalizedNodeBuilder.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NodeValueCodec.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NormalizedNodeToNodeCodec.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NormalizedNodeToProtocolBufferNode.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/AugmentationIdentifierGenerator.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierGenerator.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierWithPredicatesGenerator.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierWithValueGenerator.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NormalizedNodeGetter.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NormalizedNodeNavigator.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NormalizedNodePrinter.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NormalizedNodeVisitor.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/PathUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/QNameFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/registration/ListenerRegistrationMessages.java [deleted file]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/transaction/ShardTransactionMessages.java [deleted file]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/util/EncoderDecoderUtil.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/util/InstanceIdentifierUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/mdsal/CompositeModificationPayload.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/cohort3pc/ThreePhaseCommitCohortMessages.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/common/NormalizedNodeMessages.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/common/SimpleNormalizedNodeMessage.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/datachange/notification/DataChangeListenerMessages.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/persistent/PersistentMessages.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/registration/ListenerRegistrationMessages.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/shard/ShardManagerMessages.java [moved from opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/shard/ShardManagerMessages.java with 59% similarity]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/transaction/ShardTransactionChainMessages.java [moved from opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/transaction/ShardTransactionChainMessages.java with 70% similarity]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/transaction/ShardTransactionMessages.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/Cohort.proto [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/Common.proto [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/CompositeModificationPayload.proto [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/DataChangeListener.proto [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/ListenerRegistration.proto
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/Persistent.proto [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/ShardManager.proto
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/ShardTransaction.proto
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/ShardTransactionChain.proto
opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/SimpleNormalizedNode.proto [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/messages/ShardManagerMessagesTest.java [deleted file]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/node/NormalizedNodeToNodeCodecTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierFactoryTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/util/InstanceIdentifierUtilsTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/util/NormalizedNodeXmlConverterTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/util/TestModel.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/protobuff/messages/ShardManagerMessagesTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/protobuff/messages/transaction/ShardTransactionMessagesTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/application.conf [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/augment_choice.xml [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/augment_choice.yang [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/odl-datastore-augmentation.yang [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/odl-datastore-test-notification.yang [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/odl-datastore-test.yang [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/simple_xml_with_attributes.xml [new file with mode: 0644]
opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/test.yang [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/pom.xml [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/config/yang/config/remote_rpc_connector/RemoteRPCBrokerModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/config/yang/config/remote_rpc_connector/RemoteRPCBrokerModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/AbstractUntypedActor.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/ActorSystemFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RemoteRpcImplementation.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RemoteRpcProvider.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RemoteRpcProviderFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RouteIdentifierImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RoutedRpcListener.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcBroker.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcListener.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcManager.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/TerminationMonitor.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/AddRoutedRpc.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/AddRpc.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/ErrorResponse.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/ExecuteRpc.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/GetRoutedRpc.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/GetRoutedRpcReply.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/GetRpc.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/GetRpcReply.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/InvokeRoutedRpc.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/InvokeRpc.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/Monitor.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/remote/RemoteRpcRouter.java with 52% similarity]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/RemoveRoutedRpc.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/RemoveRpc.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/RoutingTableData.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/RpcResponse.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/UpdateSchemaContext.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/ClusterWrapper.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/ClusterWrapperImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RoutingTable.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RpcRegistry.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/ActorUtil.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/InstanceIdentifierForXmlCodec.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/RandomPrefix.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/XmlDocumentUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/XmlStreamUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/XmlUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/resources/application.conf [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/main/yang/remote-rpc-connector.yang [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/RpcBrokerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/registry/RoutingTableTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/registry/RpcRegistryTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/utils/XmlUtilsTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/src/test/resources/org/opendaylight/controller/remote/rpc/utils/rpcTest.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector-config/pom.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector-config/src/main/resources/initial/10-rest-connector.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/pom.xml
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/rest/connector/RestConnectorModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/rest/connector/RestConnectorModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft02.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestConnector.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/package-info.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/gson/JsonParser.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonToCompositeNodeProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonToCompositeNodeReader.java [moved from opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonReader.java with 52% similarity]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestUtil.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfApplication.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfDocumentedExceptionMapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProviderImpl.java [moved from opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java with 56% similarity]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToJsonProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToXmlProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToCompositeNodeProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToCompositeNodeReader.java [moved from opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlReader.java with 88% similarity]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/package-info.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.java
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.java
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/IdentityValuesDTO.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/RestconfDocumentedException.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfError.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/SimpleNodeWrapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/StructuredData.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/package-info.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/rpc/impl/AbstractRpcExecutor.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/rpc/impl/BrokerRpcExecutor.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/rpc/impl/MountPointRpcExecutor.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/rpc/impl/RpcExecutor.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/streams/listeners/ListenerAdapter.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/streams/listeners/Notificator.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/streams/websockets/WebSocketServer.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/streams/websockets/WebSocketServerHandler.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/streams/websockets/WebSocketServerInitializer.java
opendaylight/md-sal/sal-rest-connector/src/main/yang/opendaylight-rest-connector.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonChoiceCaseTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonBasicDataTypesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnInstanceIdentifierToXmlTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java
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
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithDataFromSeveralModulesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/input/to/cnsn/test/RestPutListDataTest.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
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java
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/BrokerFacadeTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CodecsExceptionsCatchingTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyFuture.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyRpcResult.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java
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
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MultipleEqualNamesForDataNodesTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/NormalizeNodeTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestDeleteOperationTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetAugmentedElementWhenEqualNamesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPostOperationTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPutOperationTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfDocumentedExceptionMapperTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfErrorTest.java
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/URITest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnInstanceIdentifierTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnLeafRefTest.java
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/test/structures/LstItem.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/websockets/client/WebSocketClient.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/websockets/client/WebSocketClientHandler.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/websockets/test/RestStream.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlAugmentedElementToCnSnTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java
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/equal-data-node-names/equal-name-data-for-container.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/equal-data-node-names/equal-name-data-for-container.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/equal-data-node-names/equal-name-data-for-leaf.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/equal-data-node-names/equal-name-data-for-leaf.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/equal-data-node-names/yang/equal-data-node-names.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/test-module/test-module
opendaylight/md-sal/sal-rest-connector/src/test/resources/invoke-rpc/invoke-rpc-module.yang
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/empty-data1.json
opendaylight/md-sal/sal-rest-connector/src/test/resources/multiple-nodes/multiple-nodes.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/DocProvider.java
opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/BaseYangSwaggerGenerator.java
opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/ModelGenerator.java
opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/mountpoints/MountPointSwagger.java
opendaylight/md-sal/sal-rest-docgen/src/main/resources/explorer/index.html
opendaylight/md-sal/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGeneratorTest.java
opendaylight/md-sal/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/MountPointSwaggerTest.java
opendaylight/md-sal/sal-test-model/pom.xml [new file with mode: 0644]
opendaylight/md-sal/sal-test-model/src/main/java/org/opendaylight/controller/md/sal/test/model/util/ListsBindingUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-test-model/src/main/yang/opendaylight-mdsal-augment-test.yang [new file with mode: 0644]
opendaylight/md-sal/sal-test-model/src/main/yang/opendaylight-mdsal-list-test.yang [new file with mode: 0644]
opendaylight/md-sal/sal-test-model/src/main/yang/opendaylight-sal-test-store.yang [moved from opendaylight/md-sal/sal-binding-dom-it/src/main/yang/opendaylight-sal-test-store.yang with 100% similarity]
opendaylight/md-sal/sal-test-model/src/main/yang/opendaylight-test-routed-rpc.yang [new file with mode: 0644]
opendaylight/md-sal/sal-test-model/src/main/yang/opendaylight-test-rpc-service.yang [new file with mode: 0644]
opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/L2SwitchProvider.java
opendaylight/md-sal/samples/toaster-consumer/pom.xml
opendaylight/md-sal/samples/toaster-consumer/src/main/java/org/opendaylight/controller/config/yang/config/kitchen_service/impl/KitchenServiceModule.java
opendaylight/md-sal/samples/toaster-consumer/src/main/java/org/opendaylight/controller/sample/kitchen/api/KitchenService.java
opendaylight/md-sal/samples/toaster-consumer/src/main/java/org/opendaylight/controller/sample/kitchen/impl/KitchenServiceImpl.java
opendaylight/md-sal/samples/toaster-it/src/test/java/org/opendaylight/controller/sample/toaster/it/ToasterTest.java
opendaylight/md-sal/samples/toaster-it/src/test/resources/logback.xml
opendaylight/md-sal/samples/toaster-provider/src/main/java/org/opendaylight/controller/sample/toaster/provider/OpendaylightToaster.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowComparator.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsRequestScheduler.java
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.java
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.java
opendaylight/netconf/config-netconf-connector/pom.xml
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreServiceImpl.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreSnapshotImpl.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategyTest.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImplTest.java
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/TestingExceptionHandler.java
opendaylight/netconf/netconf-cli/.gitignore [new file with mode: 0644]
opendaylight/netconf/netconf-cli/README [new file with mode: 0644]
opendaylight/netconf/netconf-cli/README_ODL [new file with mode: 0644]
opendaylight/netconf/netconf-cli/pom.xml [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Cli.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/CommandArgHandlerRegistry.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Main.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionHandler.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionManager.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/SchemaContextRegistry.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/AbstractCommand.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/Command.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandConstants.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandDispatcher.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandInvocationException.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/Input.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/InputDefinition.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Close.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Connect.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Disconnect.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Help.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/Output.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/OutputDefinition.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/remote/RemoteCommand.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/BaseConsoleContext.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleContext.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIO.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIOImpl.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/IOUtil.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/AbstractReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/GenericListEntryReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/Reader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/ReadingException.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/ConfigReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/EditContentReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/FilterReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/PasswordReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/AnyXmlReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/BasicDataHolderReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ChoiceReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ContainerReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/DecisionReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericListReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafListEntryReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ListEntryReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/SeparatedNodes.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/UnionTypeReader.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/OutFormatter.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/WriteException.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/Writer.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/custom/DataWriter.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AbstractWriter.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AugmentationNodeCliSerializer.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ChoiceNodeCliSerializer.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/CliOutputFromNormalizedNodeSerializerFactory.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/CompositeNodeWriter.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ContainerNodeCliSerializer.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafNodeCliSerializer.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetEntryNodeCliSerializer.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetNodeCliSerializer.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapEntryNodeCliSerializer.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapNodeCliSerializer.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NodeCliSerializerDispatcher.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NormalizedNodeWriter.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/resources/logback.xml [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/resources/schema/common/ietf-inet-types.yang [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/resources/schema/common/netconf-cli-ext.yang [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/resources/schema/local/netconf-cli.yang [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/main/resources/schema/remote/ietf-netconf.yang [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ConsoleIOTestImpl.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/NetconfCliTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ValueForMessages.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/io/IOUtilTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/test/resources/schema-context/ietf-inet-types.yang [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/test/resources/schema-context/ietf-netconf.yang [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/test/resources/schema-context/model1.yang [new file with mode: 0644]
opendaylight/netconf/netconf-cli/src/test/resources/schema-context/model2.yang [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SshClientChannelInitializer.java
opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/test/TestingNetconfClient.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/SSLUtil.java
opendaylight/netconf/netconf-it/src/test/resources/logback-test.xml [moved from opendaylight/netconf/netconf-it/src/test/resources/logback.xml with 83% similarity]
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/AbstractNetconfSessionNegotiator.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfEOMAggregator.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfMessageToXMLEncoder.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/EXIParameters.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/NetconfStartExiMessage.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/authentication/LoginPassword.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/Invoker.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshClient.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshClientAdapter.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshHandler.java [moved from opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/SshHandler.java with 83% similarity]
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/SshSession.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/virtualsocket/VirtualSocket.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/virtualsocket/VirtualSocketException.java [deleted file]
opendaylight/netconf/netconf-ssh/pom.xml
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/Handshaker.java
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/netty/EchoClient.java
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/netty/EchoClientHandler.java
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/netty/SSHTest.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_merge_multiple-deps1.xml [new file with mode: 0644]
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_merge_multiple-deps2.xml [new file with mode: 0644]
opendaylight/netconf/pom.xml
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronObject.java [new file with mode: 0644]
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/NeutronSubnet.java
opendaylight/northbound/commons/pom.xml
opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java
opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/exception/GenericExceptionMapper.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/INeutronRequest.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworkRequest.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworksNorthbound.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortRequest.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetRequest.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetsNorthbound.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/PaginatedNeutronNetworkRequest.java [deleted file]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/PaginatedRequestFactory.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IEEE8021Q.java
pom.xml

diff --git a/features/adsal/pom.xml b/features/adsal/pom.xml
new file mode 100644 (file)
index 0000000..0ccb17a
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.2-SNAPSHOT</version>
+    <relativePath>../../opendaylight/commons/opendaylight</relativePath>
+  </parent>
+  <artifactId>features-adsal</artifactId>
+  <version>${sal.version}</version>
+  <packaging>pom</packaging>
+  <name>Features :: AD-SAL Features</name>
+  <description>AD-SAL Features POM</description>
+  <properties>
+    <features.file>features.xml</features.file>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>base-features</artifactId>
+      <version>${project.parent.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <resources>
+      <resource>
+        <filtering>true</filtering>
+        <directory>src/main/resources</directory>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>filter</id>
+            <goals>
+              <goal>resources</goal>
+            </goals>
+            <phase>generate-resources</phase>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <phase>package</phase>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>${project.build.directory}/classes/${features.file}</file>
+                  <type>xml</type>
+                  <classifier>features</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/features/adsal/src/main/resources/features.xml b/features/adsal/src/main/resources/features.xml
new file mode 100644 (file)
index 0000000..f955315
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<features name="adsal-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+   <feature name="odl-adsal-all" description="OpenDaylight AD-SAL All Features" version="${sal.version}">
+      <feature version="${sal.version}">odl-adsal-core</feature>
+      <feature version="${sal.networkconfiguration.version}">odl-adsal-networkconfiguration</feature>
+      <feature version="${sal.connection.version}">odl-adsal-connection</feature>
+      <feature version="${clustering.services.version}">odl-adsal-clustering</feature>
+      <feature version="${configuration.version}">odl-adsal-configuration</feature>
+   </feature>
+   <feature name="odl-adsal-core" description="OpenDaylight :: AD-SAL :: Core" version="${sal.version}">
+      <feature>base-felix-dm</feature>
+      <feature>base-dummy-console</feature>
+      <feature version="${project.version}">odl-adsal-thirdparty</feature>
+      <bundle start="true" start-level="35">mvn:org.apache.commons/commons-lang3/${commons.lang3.version}</bundle>
+  <!--    <bundle>mvn:org.osgi/org.osgi.compendium/${osgi.compendium.version}</bundle> -->
+      <bundle>mvn:org.opendaylight.controller/sal/${sal.version}</bundle>
+      <bundle>mvn:org.opendaylight.controller/sal.implementation/${sal.implementation.version}</bundle>
+   </feature>
+   <feature name="odl-adsal-networkconfiguration" description="OpenDaylight :: AD-SAL :: Network Configuration" version="${sal.networkconfiguration.version}">
+      <bundle>mvn:org.opendaylight.controller/sal.networkconfiguration/${sal.networkconfiguration.version}</bundle>
+      <bundle>mvn:org.opendaylight.controller/sal.networkconfiguration.implementation/${sal.networkconfiguration.version}</bundle>
+   </feature>
+   <feature name="odl-adsal-connection" description="OpenDaylight :: AD-SAL :: Connection" version="${sal.connection.version}">
+      <feature>odl-adsal-core</feature>
+      <bundle>mvn:org.opendaylight.controller/sal.connection/${sal.connection.version}</bundle>
+      <bundle>mvn:org.opendaylight.controller/sal.connection.implementation/${sal.connection.version}</bundle>
+   </feature>
+   <feature name="odl-adsal-clustering" description="OpenDaylight :: AD-SAL :: Clustering" version="${clustering.services.version}">
+      <feature>transaction</feature>
+      <feature>base-felix-dm</feature>
+      <feature>base-eclipselink-persistence</feature>
+      <feature version="${sal.version}">odl-adsal-core</feature>
+      <bundle>mvn:org.opendaylight.controller/clustering.services/${clustering.services.version}</bundle>
+      <bundle>mvn:org.opendaylight.controller/clustering.services-implementation/${clustering.services_implementation.version}</bundle>
+      <bundle>mvn:org.opendaylight.controller/clustering.stub/${clustering.stub.version}</bundle>
+   </feature>
+   <feature name="odl-adsal-configuration" description="OpenDaylight :: AD-SAL :: Configuration" version="${configuration.version}">
+      <feature version="${sal.version}">odl-adsal-core</feature>
+      <feature version="${clustering.services.version}">odl-adsal-clustering</feature>
+      <bundle>mvn:org.opendaylight.controller/configuration/${configuration.version}</bundle>
+      <bundle>mvn:org.opendaylight.controller/configuration.implementation/${configuration.implementation.version}</bundle>
+   </feature>
+   <feature name="odl-adsal-thirdparty" description="OpenDaylight :: AD-SAL :: Third-Party Depenencies" version="${project.version}">
+      <bundle>mvn:org.opendaylight.controller/logging.bridge/${logging.bridge.version}</bundle>
+   </feature>
+</features>
index 60286175c18e0a6455dedcc19f23018216b406dd..b9107b9f62881d1fc2799ddbecc238559add943a 100644 (file)
@@ -79,6 +79,8 @@
    <feature name="base-eclipselink-persistence" description="EclipseLink Persistence API" version="2.0.4.v201112161009">
       <bundle start="true" start-level="35">mvn:eclipselink/javax.persistence/2.0.4.v201112161009</bundle>
       <bundle start="true" start-level="35">mvn:eclipselink/javax.resource/1.5.0.v200906010428</bundle>
+      <bundle start="true" start-level="35">mvn:org.eclipse.persistence/org.eclipse.persistence.moxy/2.5.0</bundle>
+      <bundle start="true" start-level="35">mvn:org.eclipse.persistence/org.eclipse.persistence.core/2.5.0</bundle>
    </feature>
    <feature name="base-gemini-web" description="Gemini Web" version="${geminiweb.version}">
       <feature>http</feature>
diff --git a/features/config-netty/pom.xml b/features/config-netty/pom.xml
new file mode 100644 (file)
index 0000000..98b97d1
--- /dev/null
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>config-subsystem</artifactId>
+    <version>0.2.5-SNAPSHOT</version>
+    <relativePath>../../opendaylight/config/</relativePath>
+  </parent>
+  <artifactId>config-netty-features</artifactId>
+
+  <packaging>pom</packaging>
+
+  <properties>
+    <features.file>features.xml</features.file>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>config-persister-features</artifactId>
+      <version>${config.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <resources>
+      <resource>
+        <filtering>true</filtering>
+        <directory>src/main/resources</directory>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>filter</id>
+            <goals>
+              <goal>resources</goal>
+            </goals>
+            <phase>generate-resources</phase>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <phase>package</phase>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>${project.build.directory}/classes/${features.file}</file>
+                  <type>xml</type>
+                  <classifier>features</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+    <tag>HEAD</tag>
+    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+  </scm>
+</project>
diff --git a/features/config-netty/src/main/resources/features.xml b/features/config-netty/src/main/resources/features.xml
new file mode 100644 (file)
index 0000000..3121ca0
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<features name="odl-config-persister-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+  <repository>mvn:org.opendaylight.controller/config-persister-features/${config.version}/xml/features</repository>
+  <feature name='odl-config-netty' version='${project.version}'>
+    <feature version='${project.version}'>odl-config-netty-config-api</feature>
+    <bundle>mvn:org.opendaylight.controller/netty-event-executor-config/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/netty-threadgroup-config/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/netty-timer-config/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/threadpool-config-api/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/threadpool-config-impl/${project.version}</bundle>
+    <feature version='${project.version}'>odl-config-startup</feature>
+  </feature>
+</features>
\ No newline at end of file
diff --git a/features/config-persister/pom.xml b/features/config-persister/pom.xml
new file mode 100644 (file)
index 0000000..969d0c8
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>config-subsystem</artifactId>
+    <version>0.2.5-SNAPSHOT</version>
+    <relativePath>../../opendaylight/config/</relativePath>
+  </parent>
+  <artifactId>config-persister-features</artifactId>
+
+  <packaging>pom</packaging>
+
+  <properties>
+    <features.file>features.xml</features.file>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>features-yangtools</artifactId>
+      <version>${yangtools.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-features</artifactId>
+      <version>${netconf.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>config-features</artifactId>
+      <version>${config.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <resources>
+      <resource>
+        <filtering>true</filtering>
+        <directory>src/main/resources</directory>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>filter</id>
+            <goals>
+              <goal>resources</goal>
+            </goals>
+            <phase>generate-resources</phase>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <phase>package</phase>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>${project.build.directory}/classes/${features.file}</file>
+                  <type>xml</type>
+                  <classifier>features</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+    <tag>HEAD</tag>
+    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+  </scm>
+</project>
diff --git a/features/config-persister/src/main/resources/features.xml b/features/config-persister/src/main/resources/features.xml
new file mode 100644 (file)
index 0000000..2273a4a
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<features name="odl-config-persister-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+  <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.controller/netconf-features/${netconf.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.controller/config-features/${config.version}/xml/features</repository>
+  <feature name='odl-config-startup' version='${project.version}'>
+    <feature version='${project.version}'>odl-config-netconf-connector</feature>
+    <feature version='${project.version}'>odl-config-persister</feature>
+    <feature version='${project.version}'>odl-netconf-impl</feature>
+  </feature>
+  <feature name='odl-config-persister' version='${project.version}'>
+    <feature version='${netconf.version}'>odl-netconf-api</feature>
+    <feature version='${project.version}'>odl-config-api</feature>
+    <feature version='${yangtools.version}'>yangtools-binding-generator</feature>
+    <bundle>mvn:org.opendaylight.controller/config-persister-api/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/config-persister-file-xml-adapter/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/config-persister-directory-xml-adapter/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/config-persister-impl/${project.version}</bundle>
+
+    <bundle>mvn:org.opendaylight.controller/netconf-util/${netconf.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/netconf-mapping-api/${netconf.version}</bundle>
+
+    <bundle>mvn:com.google.guava/guava/${guava.version}</bundle>
+    <bundle>mvn:commons-io/commons-io/${commons.io.version}</bundle>
+    <bundle>mvn:org.apache.commons/commons-lang3/${commons.lang3.version}</bundle>
+    <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.core/${eclipse.persistence.version}</bundle>
+    <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.moxy/${eclipse.persistence.version}</bundle>
+  </feature>
+</features>
\ No newline at end of file
similarity index 85%
rename from opendaylight/config/feature/pom.xml
rename to features/config/pom.xml
index aaf33ccc0fdfb64639ef6feb2c15256443dbca56..7e5dd6472bc7320a6b7c20953c811fb41982cb26 100644 (file)
@@ -5,6 +5,7 @@
     <groupId>org.opendaylight.controller</groupId>
     <artifactId>config-subsystem</artifactId>
     <version>0.2.5-SNAPSHOT</version>
+    <relativePath>../../opendaylight/config/</relativePath>
   </parent>
   <artifactId>config-features</artifactId>
 
     <features.file>features.xml</features.file>
   </properties>
 
-  <dependencies></dependencies>
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>features-yangtools</artifactId>
+      <version>${yangtools.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+  </dependencies>
 
   <build>
     <resources>
diff --git a/features/config/src/main/resources/features.xml b/features/config/src/main/resources/features.xml
new file mode 100644 (file)
index 0000000..de5b198
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<features name="odl-config-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+  <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
+
+  <feature name='odl-config-core' version='${project.version}'>
+    <feature version='${yangtools.version}'>yangtools-concepts</feature>
+    <feature version='${yangtools.version}'>yangtools-binding</feature>
+    <feature version='${yangtools.version}'>yangtools-binding-generator</feature>
+    <feature version='${mdsal.version}'>odl-mdsal-commons</feature>
+    <feature version='${project.version}'>odl-config-api</feature>
+    <bundle>mvn:org.opendaylight.controller/config-util/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/yang-jmx-generator/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/shutdown-api/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/shutdown-impl/${project.version}</bundle>
+    <bundle>mvn:org.osgi/org.osgi.core/${osgi.core.version}</bundle>
+    <bundle>mvn:com.google.guava/guava/${guava.version}</bundle>
+    <bundle>mvn:org.javassist/javassist/${javassist.version}</bundle>
+  </feature>
+  <feature name='odl-config-manager' version='${project.version}'>
+    <feature version='${project.version}'>odl-config-core</feature>
+    <bundle>mvn:org.opendaylight.controller/config-manager/${project.version}</bundle>
+  </feature>
+
+  <feature name='odl-config-api' version='${project.version}'>
+    <bundle>mvn:org.opendaylight.controller/config-api/${project.version}</bundle>
+
+    <!-- yangtools features -->
+    <feature version='${yangtools.version}'>yangtools-concepts</feature>
+    <feature version='${yangtools.version}'>yangtools-binding</feature>
+  </feature>
+
+  <feature name='odl-config-netty-config-api' version='${project.version}'>
+    <bundle>mvn:org.opendaylight.controller/netty-config-api/${project.version}</bundle>
+
+    <!-- netty bundles -->
+    <bundle>mvn:io.netty/netty-transport/${netty.version}</bundle>
+    <bundle>mvn:io.netty/netty-common/${netty.version}</bundle>
+    <bundle>mvn:io.netty/netty-buffer/${netty.version}</bundle>
+
+    <feature version='${project.version}'>odl-config-api</feature>
+  </feature>
+  <feature name='odl-config-dispatcher' version='${project.version}'>
+      <bundle>mvn:org.opendaylight.controller/netconf-config-dispatcher/${project.version}</bundle>
+  </feature>
+
+</features>
\ No newline at end of file
diff --git a/features/extras/pom.xml b/features/extras/pom.xml
new file mode 100644 (file)
index 0000000..4563190
--- /dev/null
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.2-SNAPSHOT</version>
+    <relativePath>../../opendaylight/commons/opendaylight</relativePath>
+  </parent>
+  <artifactId>extras-features</artifactId>
+  <packaging>kar</packaging>
+  <name>${project.artifactId}</name>
+  <description>Base Features POM</description>
+  <properties>
+    <features.file>features.xml</features.file>
+    <netty3.version>3.9.2.Final</netty3.version>
+  </properties>
+  <build>
+    <resources>
+      <resource>
+        <filtering>true</filtering>
+        <directory>src/main/resources</directory>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.karaf.tooling</groupId>
+        <artifactId>karaf-maven-plugin</artifactId>
+        <version>${karaf.version}</version>
+        <extensions>true</extensions>
+        <executions>
+          <execution>
+            <id>features-create-kar</id>
+            <goals>
+              <goal>features-create-kar</goal>
+            </goals>
+            <configuration>
+              <featuresFile>${project.build.directory}/classes/${features.file}</featuresFile>
+            </configuration>
+          </execution>
+        </executions>
+        <!-- There is no useful configuration for the kar mojo. The features-generate-descriptor mojo configuration may be useful -->
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>filter</id>
+            <goals>
+              <goal>resources</goal>
+            </goals>
+            <phase>generate-resources</phase>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <phase>package</phase>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>${project.build.directory}/classes/${features.file}</file>
+                  <type>xml</type>
+                  <classifier>features</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/features/extras/src/main/resources/features.xml b/features/extras/src/main/resources/features.xml
new file mode 100644 (file)
index 0000000..3be66d9
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<features name="extras-features-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
+
+   <feature name="osgi-compendium" description="OSGi compendium feature" version="${osgi.version}" resolver="(obr)">
+      <bundle start-level="10">mvn:org.osgi/org.osgi.compendium/${osgi.compendium.version}</bundle>
+   </feature>
+
+   <feature name="odl-extras-scala" description="Scala Runtime for OpenDaylight" version="${scala.version}" resolver="(obr)" start-level="10">
+      <bundle>mvn:org.scala-lang/scala-library/${scala.version}.${scala.micro.version}</bundle>
+      <bundle>mvn:org.scala-lang/scala-reflect/${scala.version}.${scala.micro.version}</bundle>
+   </feature>
+
+   <feature name="odl-extras-akka-system" description="Akka Actor Framework System Bundles" version="${akka.version}" resolver="(obr)" start-level="15">
+      <feature version="${scala.version}">odl-extras-scala</feature>
+      <bundle dependency="true">mvn:com.typesafe/config/${typesafe.config.version}</bundle>
+      <bundle dependency="true">mvn:com.typesafe.akka/akka-actor_${scala.version}/${akka.version}</bundle>
+      <bundle dependency="true">mvn:com.typesafe.akka/akka-slf4j_${scala.version}/${akka.version}</bundle>
+      <bundle>mvn:com.typesafe.akka/akka-osgi_${scala.version}/${akka.version}</bundle>
+   </feature>
+
+   <feature name="odl-extras-akka-clustering" description="Akka Clustering Support" version="${akka.version}" resolver="(obr)" start-level="20">
+      <feature version="${akka.version}">odl-extras-akka-system</feature>
+      <bundle dependency="true">wrap:mvn:org.uncommons.maths/uncommons-maths/${uncommons.maths.version}</bundle>
+      <bundle dependency="true">mvn:com.google.protobuf/protobuf-java/${protobuf.version}</bundle>
+      <bundle dependency="true">wrap:mvn:io.netty/netty/${netty3.version}</bundle>
+      <bundle>mvn:com.typesafe.akka/akka-remote_${scala.version}/${akka.version}</bundle>
+      <bundle>mvn:com.typesafe.akka/akka-cluster_${scala.version}/${akka.version}</bundle>
+   </feature>
+
+   <feature name='odl-extras-leveldb' description='LevelDB feature' version='0.7' resolver='(obr)'>
+      <bundle start-level="20">wrap:mvn:org.iq80.leveldb/leveldb/${leveldb.version}</bundle>
+      <bundle start-level="20">wrap:mvn:org.fusesource.leveldbjni/leveldbjni-all/${leveldbjni.version}</bundle>
+   </feature>
+</features>
similarity index 97%
rename from opendaylight/md-sal/feature/pom.xml
rename to features/mdsal/pom.xml
index c08c3e5606023bcc9cbd4c6780287135a7dd32ab..2983c5efab8fb21031991fe6af248032eb842365 100644 (file)
@@ -5,6 +5,7 @@
     <groupId>org.opendaylight.controller</groupId>
     <artifactId>sal-parent</artifactId>
     <version>1.1-SNAPSHOT</version>
+    <relativePath>../../opendaylight/md-sal</relativePath>
   </parent>
   <artifactId>mdsal-features</artifactId>
 
similarity index 56%
rename from opendaylight/md-sal/feature/src/main/resources/features.xml
rename to features/mdsal/src/main/resources/features.xml
index 16b457403740b7cac4f3fc137e1a1a9d00db4521..7d393bc64cdc7aab9056043d8b1f852260dcfe27 100644 (file)
@@ -9,20 +9,20 @@
         <feature version='${project.version}'>odl-mdsal-restconf</feature>
     </feature>
     <feature name='odl-mdsal-commons' version='${project.version}'>
-        <feature version='${yangtools.version}'>yangtools-concepts</feature>
-        <feature version='${yangtools.version}'>yangtools-binding</feature>
+        <feature version='${yangtools.version}'>yangtools-data-binding</feature>
         <bundle>mvn:org.opendaylight.controller/sal-common/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-common-api/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-common-impl/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-common-util/${project.version}</bundle>
-        <bundle>wrap:mvn:com.google.guava/guava/${guava.version}</bundle>
-        <bundle>wrap:mvn:org.eclipse.xtend/org.eclipse.xtend.lib/${xtend.version}</bundle>
     </feature>
     <feature name='odl-mdsal-broker' version='${project.version}'>
         <feature version='${yangtools.version}'>yangtools-concepts</feature>
         <feature version='${yangtools.version}'>yangtools-binding</feature>
         <feature version='${mdsal.version}'>odl-mdsal-commons</feature>
-        <feature version='${config.version}'>odl-config-subsystem</feature>
+        <feature version='${config.version}'>odl-config-core</feature>
+        <feature version='${config.version}'>odl-config-manager</feature>
+        <feature version='${config.version}'>odl-config-api</feature>
+        <feature version='${config.version}'>odl-config-persister</feature>
         <bundle>mvn:org.opendaylight.controller/sal-core-api/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-core-spi/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-broker-impl/${project.version}</bundle>
@@ -31,6 +31,7 @@
         <bundle>mvn:org.opendaylight.controller/sal-binding-broker-impl/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-binding-util/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-connector-api/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/sal-inmemory-datastore/${project.version}</bundle>
     </feature>
     <feature name='odl-mdsal-restconf' version='${project.version}'>
         <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
         <bundle>wrap:mvn:io.netty/netty-handler/${netty.version}</bundle>
         <bundle>wrap:mvn:io.netty/netty-transport/${netty.version}</bundle>
     </feature>
+    <feature name='odl-mdsal-model' version='${project.version}'>
+        <bundle>mvn:org.opendaylight.controller.model/model-flow-base/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller.model/model-flow-management/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller.model/model-flow-service/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller.model/model-flow-statistics/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller.model/model-inventory/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller.model/model-topology/${project.version}</bundle>
+    </feature>
+    <feature name='odl-mdsal-toaster' version='${project.version}'>
+        <feature version='${yangtools.version}'>yangtools-concepts</feature>
+        <feature version='${yangtools.version}'>yangtools-binding</feature>
+        <feature version='${project.version}'>odl-mdsal-broker</feature>
+        <feature version='${project.version}'>odl-mdsal-all</feature>
+        <bundle>mvn:org.opendaylight.controller.samples/sample-toaster/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller.samples/sample-toaster-consumer/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller.samples/sample-toaster-provider/${project.version}</bundle>
+    </feature>
+    <feature name='odl-mdsal-misc' version='${project.version}'>
+        <bundle>mvn:org.opendaylight.controller/sal-netconf-connector/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/sal-restconf-broker/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/sal-remote/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller.md/topology-manager/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller.md/topology-lldp-discovery/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller.md/statistics-manager/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller.md/inventory-manager/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller.md/forwardingrules-manager/${project.version}</bundle>
+    </feature>
+
 </features>
diff --git a/features/netconf/pom.xml b/features/netconf/pom.xml
new file mode 100644 (file)
index 0000000..90c088e
--- /dev/null
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>netconf-subsystem</artifactId>
+    <version>0.2.5-SNAPSHOT</version>
+    <relativePath>../../opendaylight/netconf</relativePath>
+  </parent>
+  <artifactId>netconf-features</artifactId>
+
+  <packaging>pom</packaging>
+
+  <properties>
+    <features.file>features.xml</features.file>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>config-features</artifactId>
+      <version>${config.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>features-odl-protocol-framework</artifactId>
+      <version>${protocol-framework.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <resources>
+      <resource>
+        <filtering>true</filtering>
+        <directory>src/main/resources</directory>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>filter</id>
+            <goals>
+              <goal>resources</goal>
+            </goals>
+            <phase>generate-resources</phase>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <phase>package</phase>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>${project.build.directory}/classes/${features.file}</file>
+                  <type>xml</type>
+                  <classifier>features</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+    <tag>HEAD</tag>
+    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+  </scm>
+</project>
diff --git a/features/netconf/src/main/resources/features.xml b/features/netconf/src/main/resources/features.xml
new file mode 100644 (file)
index 0000000..50a537b
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<features name="odl-netconf-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+  <repository>mvn:org.opendaylight.controller/features-odl-protocol-framework/${protocol-framework.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.controller/config-features/${config.version}/xml/features</repository>
+
+  <feature name='odl-netconf-api' version='${project.version}'>
+    <bundle>mvn:org.opendaylight.controller/netconf-api/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/ietf-netconf-monitoring/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/ietf-netconf-monitoring-extension/${project.version}</bundle>
+    <feature version='${protocol-framework.version}'>odl-protocol-framework</feature>
+    <bundle>mvn:org.opendaylight.yangtools.model/ietf-inet-types/${ietf-inet-types.version}</bundle>
+    <bundle>mvn:org.opendaylight.yangtools.model/ietf-yang-types/${ietf-yang-types.version}</bundle>
+  </feature>
+  <feature name='odl-netconf-mapping-api' version='${project.version}'>
+    <feature version='${project.version}'>odl-netconf-api</feature>
+    <bundle>mvn:org.opendaylight.controller/netconf-mapping-api/${project.version}</bundle>
+  </feature>
+  <feature name='odl-netconf-util' version='${project.version}'>
+    <feature version='${project.version}'>odl-netconf-mapping-api</feature>
+    <bundle>mvn:org.opendaylight.controller/netconf-util/${project.version}</bundle>
+  </feature>
+  <feature name='odl-config-netconf-connector' version='${project.version}'>
+    <feature version='${config.version}'>odl-config-manager</feature>
+    <bundle>mvn:org.opendaylight.controller/config-netconf-connector/${project.version}</bundle>
+    <feature version='${project.version}'>odl-netconf-api</feature>
+    <feature version='${project.version}'>odl-netconf-mapping-api</feature>
+    <feature version='${project.version}'>odl-netconf-util</feature>
+  </feature>
+
+  <feature name='odl-netconf-impl' version='${project.version}'>
+    <bundle>mvn:org.opendaylight.controller/netconf-impl/${project.version}</bundle>
+    <feature version='${project.version}'>odl-netconf-api</feature>
+    <feature version='${project.version}'>odl-netconf-mapping-api</feature>
+    <feature version='${project.version}'>odl-netconf-util</feature>
+    <feature version='${project.version}'>odl-netconf-netty-util</feature>
+  </feature>
+  <feature name='odl-netconf-netty-util' version='${project.version}'>
+    <bundle>mvn:org.opendaylight.controller/netconf-netty-util/${project.version}</bundle>
+    <feature version='${project.version}'>odl-netconf-api</feature>
+    <feature version='${project.version}'>odl-netconf-mapping-api</feature>
+    <feature version='${project.version}'>odl-netconf-util</feature>
+    <bundle>mvn:org.opendaylight.controller.thirdparty/ganymed/${ganymed.version}</bundle>
+    <bundle>mvn:org.openexi/nagasena/${exi.nagasena.version}</bundle>
+    <bundle>mvn:io.netty/netty-codec/${netty.version}</bundle>
+    <bundle>mvn:io.netty/netty-handler/${netty.version}</bundle>
+    <bundle>mvn:io.netty/netty-common/${netty.version}</bundle>
+    <bundle>mvn:io.netty/netty-buffer/${netty.version}</bundle>
+    <bundle>mvn:io.netty/netty-transport/${netty.version}</bundle>
+  </feature>
+  <feature name='odl-netconf-misc' version='${project.version}'>
+    <bundle>mvn:org.opendaylight.controller/netconf-client/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/netconf-monitoring/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/netconf-tcp/${project.version}</bundle>
+  </feature>
+
+</features>
\ No newline at end of file
diff --git a/features/nsf/pom.xml b/features/nsf/pom.xml
new file mode 100644 (file)
index 0000000..224aef1
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.2-SNAPSHOT</version>
+    <relativePath>../../opendaylight/commons/opendaylight</relativePath>
+  </parent>
+  <artifactId>features-nsf</artifactId>
+  <packaging>pom</packaging>
+  <name>OpenDaylight :: Features :: Network Service Functions</name>
+  <description>Feature for Network Service Functions</description>
+  <properties>
+    <features.file>features.xml</features.file>
+  </properties>
+  <build>
+    <resources>
+      <resource>
+        <filtering>true</filtering>
+        <directory>src/main/resources</directory>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>filter</id>
+            <goals>
+              <goal>resources</goal>
+            </goals>
+            <phase>generate-resources</phase>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <phase>package</phase>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>${project.build.directory}/classes/${features.file}</file>
+                  <type>xml</type>
+                  <classifier>features</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/features/nsf/src/main/resources/features.xml b/features/nsf/src/main/resources/features.xml
new file mode 100644 (file)
index 0000000..fb61f33
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<features name="nsf-${project.version}"  xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+    <feature name="odl-nsf-all" description="OpenDaylight :: NSF :: All Network Service Functions" version="${project.version}">
+        <feature version="${sal.version}">odl-adsal-all</feature>
+        <feature version="${project.version}">odl-nsf-managers</feature>
+        <feature version="${project.version}">odl-adsal-northbound</feature>
+        <!--
+         TODO : Resolve this in a follow-up commit
+            <feature>odl-controller-web</feature>
+        -->
+    </feature>
+
+    <feature name="odl-nsf-managers" description="OpenDaylight :: AD-SAL :: Network Service Functions" version="${project.version}">
+        <feature version="${project.version}">base-all</feature>
+        <feature version="${sal.version}">odl-adsal-all</feature>
+        <bundle>mvn:org.opendaylight.controller/usermanager/${usermanager.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/usermanager.implementation/${usermanager.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/appauth/${appauth.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/connectionmanager/${connectionmanager.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/connectionmanager.implementation/${connectionmanager.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/containermanager/${containermanager.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/containermanager.implementation/${containermanager.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/statisticsmanager/${statisticsmanager.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/statisticsmanager.implementation/${statisticsmanager.implementation.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/switchmanager/${switchmanager.api.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/switchmanager.implementation/${switchmanager.implementation.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/forwardingrulesmanager/${forwardingrulesmanager.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/forwardingrulesmanager.implementation/${forwardingrulesmanager.implementation.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/topologymanager/${topologymanager.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/networkconfig.neutron/${networkconfig.neutron.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/networkconfig.neutron.implementation/${networkconfig.neutron.implementation.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/hosttracker/${hosttracker.api.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/hosttracker.implementation/${hosttracker.implementation.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/forwarding.staticrouting</bundle>
+
+        <bundle>mvn:org.opendaylight.controller.thirdparty/net.sf.jung2/2.0.1</bundle>
+        <bundle>mvn:org.opendaylight.controller/routing.dijkstra_implementation</bundle>
+    </feature>
+
+    <feature name="odl-adsal-northbound" description="OpenDaylight :: AD-SAL :: Northbound APIs" version="${project.version}">
+        <feature version="${project.version}">base-all</feature>
+        <feature version="${project.version}">odl-nsf-managers</feature>
+        <bundle start-level="35">mvn:org.ow2.asm/asm-all/${asm.version}</bundle>
+        <!--
+            TODO : Resolve these in a follow-up commit
+            <bundle>mvn:org.opendaylight.controller/httpservice-bridge/${httpservice-bridge.northbound.version}</bundle>
+            <bundle>mvn:org.opendaylight.controller/jolokia-bridge/${jolokia-bridge.version}</bundle>
+        -->
+        <bundle>mvn:org.opendaylight.controller/bundlescanner/${bundlescanner.api.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/bundlescanner.implementation/${bundlescanner.implementation.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/commons.northbound/${northbound.commons.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/flowprogrammer.northbound/${flowprogrammer.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/hosttracker.northbound/${hosttracker.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/networkconfig.bridgedomain.northbound/${networkconfig.bridgedomain.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/networkconfig.neutron.northbound/${networkconfig.neutron.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/forwarding.staticrouting.northbound/${forwarding.staticrouting.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/statistics.northbound/${statistics.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/subnets.northbound/${subnets.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/switchmanager.northbound/${switchmanager.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/topology.northbound/${topology.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/usermanager.northbound/${usermanager.northbound.version}</bundle>
+    </feature>
+</features>
\ No newline at end of file
diff --git a/features/pom.xml b/features/pom.xml
new file mode 100644 (file)
index 0000000..f69190c
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.2-SNAPSHOT</version>
+    <relativePath>../opendaylight/commons/opendaylight</relativePath>
+  </parent>
+  <artifactId>features-controller</artifactId>
+  <packaging>pom</packaging>
+  <prerequisites>
+    <maven>3.0</maven>
+  </prerequisites>
+  <modules>
+    <module>base</module>
+    <module>controller</module>
+    <module>adsal</module>
+    <module>nsf</module>
+    <module>extras</module>
+    <module>config</module>
+    <module>config-persister</module>
+    <module>config-netty</module>
+    <module>mdsal</module>
+    <module>netconf</module>
+    <module>protocol-framework</module>
+  </modules>
+</project>
diff --git a/features/protocol-framework/pom.xml b/features/protocol-framework/pom.xml
new file mode 100644 (file)
index 0000000..045ac2d
--- /dev/null
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.2-SNAPSHOT</version>
+    <relativePath>../../opendaylight/commons/opendaylight</relativePath>
+  </parent>
+  <artifactId>features-odl-protocol-framework</artifactId>
+  <version>${protocol-framework.version}</version>
+  <packaging>pom</packaging>
+
+  <properties>
+    <features.file>features.xml</features.file>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>config-features</artifactId>
+      <version>${config.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <resources>
+      <resource>
+        <filtering>true</filtering>
+        <directory>src/main/resources</directory>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>filter</id>
+            <goals>
+              <goal>resources</goal>
+            </goals>
+            <phase>generate-resources</phase>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <phase>package</phase>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>${project.build.directory}/classes/${features.file}</file>
+                  <type>xml</type>
+                  <classifier>features</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+    <tag>HEAD</tag>
+    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+  </scm>
+</project>
diff --git a/features/protocol-framework/src/main/resources/features.xml b/features/protocol-framework/src/main/resources/features.xml
new file mode 100644 (file)
index 0000000..d2560f5
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<features name="odl-protocol-framework-${protocol-framework.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+  <repository>mvn:org.opendaylight.controller/config-features/${config.version}/xml/features</repository>
+  <feature name='odl-protocol-framework' version='${project.version}'>
+    <bundle>mvn:org.opendaylight.controller/protocol-framework/${protocol-framework.version}</bundle>
+    <feature version='${config.version}'>odl-config-api</feature> <!-- needed by netty-config-api -->
+    <feature version='${config.version}'>odl-config-netty-config-api</feature> <!-- needed by netty-config-api -->
+  </feature>
+</features>
\ No newline at end of file
index fe456f3f8ebe6f6237352cb09f5b6a7dc8056398..4efcada2f8ed9ef7fd0d2774c5b41cfb6e265ba1 100644 (file)
@@ -695,6 +695,8 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
             dot1q.setVid(vlan);
             dot1q.setEtherType(EtherTypes.ARP.shortValue());
             dot1q.setPayload(arp);
+            dot1q.setCfi((byte)0);
+            dot1q.setPcp((byte)0);
             ethernet.setEtherType(EtherTypes.VLANTAGGED.shortValue());
             ethernet.setPayload(dot1q);
         }
index dbe0745725eba376b5fe6102bb12c9750401fa6a..cec780c9ecafc0f4486299b7f24cc056aaa43f70 100644 (file)
@@ -69,9 +69,10 @@ public class Context {
         initialized = true;
     }
 
-    public List<Filter> findMatchingFilters(String pathInfo) {
+    public List<Filter> findMatchingFilters(String path) {
+        logger.trace("findMatchingFilters({})", path);
         checkState(initialized, "Not initialized");
-        return urlMatcher.findMatchingFilters(pathInfo);
+        return urlMatcher.findMatchingFilters(path);
     }
 
     @XmlAttribute(name = "path")
index dc3e9dcd49201654866f6603dc0201cd38359bdd..ae9d79a63df8d24f72ac7adf916d03c5f7708741 100644 (file)
@@ -37,14 +37,14 @@ public class FilterProcessor {
             throws IOException, ServletException {
 
         String contextPath = request.getContext().getPath();
-        String pathInfo = request.getPathInfo();
+        String path = request.getDecodedRequestURI();
 
         Optional<Context> maybeContext = host.findContext(contextPath);
-        logger.trace("Processing context {} path {}, found {}", contextPath, pathInfo, maybeContext);
+        logger.trace("Processing context {} path {}, found {}", contextPath, path, maybeContext);
         if (maybeContext.isPresent()) {
             // process filters
             Context context = maybeContext.get();
-            List<Filter> matchingFilters = context.findMatchingFilters(pathInfo);
+            List<Filter> matchingFilters = context.findMatchingFilters(path);
             FilterChain fromLast = nextValveFilterChain;
             ListIterator<Filter> it = matchingFilters.listIterator(matchingFilters.size());
             final boolean trace = logger.isTraceEnabled();
index 9535fb1f70f5a51323339c02107a8ebe102f459e..210326f5d109b896ee397db321769fc7aca29544 100644 (file)
@@ -62,31 +62,31 @@ public class UrlMatcher<FILTER> {
     /**
      * Find filters matching path
      *
-     * @param pathInfo as returned by request.getPathInfo()
+     * @param path relative and decoded path to resource
      * @return list of matching filters
      */
-    public List<FILTER> findMatchingFilters(String pathInfo) {
-        checkNotNull(pathInfo);
+    public List<FILTER> findMatchingFilters(String path) {
+        checkNotNull(path);
         TreeMap<Integer, FILTER> sortedMap = new TreeMap<>();
         // add matching prefixes
         for (Entry<String, Entry<FILTER, Integer>> prefixEntry : prefixMap.entrySet()) {
-            if (pathInfo.startsWith(prefixEntry.getKey())) {
+            if (path.startsWith(prefixEntry.getKey())) {
                 put(sortedMap, prefixEntry.getValue());
             }
         }
         // add matching suffixes
         for (Entry<String, Entry<FILTER, Integer>> suffixEntry : suffixMap.entrySet()) {
-            if (pathInfo.endsWith(suffixEntry.getKey())) {
+            if (path.endsWith(suffixEntry.getKey())) {
                 put(sortedMap, suffixEntry.getValue());
             }
         }
         // add exact match
-        Entry<FILTER, Integer> exactMatch = exactMatchMap.get(pathInfo);
+        Entry<FILTER, Integer> exactMatch = exactMatchMap.get(path);
         if (exactMatch != null) {
             put(sortedMap, exactMatch);
         }
         ArrayList<FILTER> filters = new ArrayList<>(sortedMap.values());
-        logger.trace("Matching filters for path {} are {}", pathInfo, filters);
+        logger.trace("Matching filters for path {} are {}", path, filters);
         return filters;
     }
 
index de8caa0e6747179c4f893c64a9c508ed7b80247d..be88e4a5059c335147a2ebacdb4f09851bbbc0e9 100644 (file)
@@ -18,7 +18,7 @@
 
   <properties>
 
-    <akka.version>2.3.2</akka.version>
+    <akka.version>2.3.4</akka.version>
     <aopalliance.version>1.0.0</aopalliance.version>
     <appauth.version>0.4.2-SNAPSHOT</appauth.version>
     <archetype-app-northbound>0.0.1-SNAPSHOT</archetype-app-northbound>
@@ -43,7 +43,6 @@
     <commons.catalina.ha>7.0.32.v201211201952</commons.catalina.ha>
     <commons.catalina.tribes>7.0.32.v201211201952</commons.catalina.tribes>
     <commons.checkstyle.version>0.0.3-SNAPSHOT</commons.checkstyle.version>
-    <commons.codec.version>1.7</commons.codec.version>
     <commons.coyote>7.0.32.v201211201952</commons.coyote>
     <commons.el>7.0.32.v201211081135</commons.el>
     <commons.fileupload.version>1.2.2</commons.fileupload.version>
@@ -63,6 +62,7 @@
     <compiler.version>2.3.2</compiler.version>
     <commons.httpclient.version>0.1.2-SNAPSHOT</commons.httpclient.version>
     <concepts.version>0.5.2-SNAPSHOT</concepts.version>
+    <concurrentlinkedhashmap.version>1.4</concurrentlinkedhashmap.version>
     <config.version>0.2.5-SNAPSHOT</config.version>
     <configuration.implementation.version>0.4.3-SNAPSHOT</configuration.implementation.version>
     <configuration.version>0.4.3-SNAPSHOT</configuration.version>
@@ -91,6 +91,7 @@
     <forwarding.staticrouting.northbound.version>0.4.2-SNAPSHOT</forwarding.staticrouting.northbound.version>
     <forwardingrulesmanager.implementation.version>0.4.2-SNAPSHOT</forwardingrulesmanager.implementation.version>
     <forwardingrulesmanager.version>0.6.0-SNAPSHOT</forwardingrulesmanager.version>
+    <ganymed.version>1.1-SNAPSHOT</ganymed.version>
     <hosttracker.api.version>0.5.2-SNAPSHOT</hosttracker.api.version>
     <hosttracker.implementation.version>0.5.2-SNAPSHOT</hosttracker.implementation.version>
     <hosttracker.northbound.version>0.4.2-SNAPSHOT</hosttracker.northbound.version>
     <karaf.branding.version>1.0.0-SNAPSHOT</karaf.branding.version>
     <karaf.shell.version>3.0.0</karaf.shell.version>
     <karaf.version>3.0.1</karaf.version>
+    <leveldb.version>0.7</leveldb.version>
+    <leveldbjni.version>1.8</leveldbjni.version>
     <lifecycle.mapping.version>1.0.0</lifecycle.mapping.version>
     <logback.version>1.0.9</logback.version>
     <logging.bridge.version>0.4.2-SNAPSHOT</logging.bridge.version>
     <maven.plugin.api.version>3.0.5</maven.plugin.api.version>
+    <mimepull.version>1.9.4</mimepull.version>
     <mdsal.version>1.1-SNAPSHOT</mdsal.version>
     <netconf.version>0.2.5-SNAPSHOT</netconf.version>
     <networkconfig.bridgedomain.northbound.version>0.0.3-SNAPSHOT</networkconfig.bridgedomain.northbound.version>
     <northbound.jolokia.version>1.4.2-SNAPSHOT</northbound.jolokia.version>
     <opendaylight-l2-types.version>2013.08.27.4-SNAPSHOT</opendaylight-l2-types.version>
     <osgi-brandfragment.web.version>0.0.2-SNAPSHOT</osgi-brandfragment.web.version>
+    <parboiled.version>1.1.6</parboiled.version>
+    <parboiled.scala.version>1.1.6</parboiled.scala.version>
     <propertymavenplugin.version>1.0-alpha-2</propertymavenplugin.version>
+    <protobuf.version>2.5.0</protobuf.version>
     <protocol-framework.version>0.5.0-SNAPSHOT</protocol-framework.version>
     <protocol_plugins.openflow.version>0.4.2-SNAPSHOT</protocol_plugins.openflow.version>
     <protocol_plugins.stub.version>0.4.2-SNAPSHOT</protocol_plugins.stub.version>
     <samples.loadbalancer.northbound.version>0.4.2-SNAPSHOT</samples.loadbalancer.northbound.version>
     <samples.simpleforwarding.version>0.4.2-SNAPSHOT</samples.simpleforwarding.version>
     <sanitytest.version>0.4.2-SNAPSHOT</sanitytest.version>
-    <scala.version>2.11</scala.version>
+    <scala.version>2.10</scala.version>
+    <scala.micro.version>4</scala.micro.version>
     <security.version>0.4.2-SNAPSHOT</security.version>
+    <shapeless.version>1.2.4</shapeless.version>
     <sitedeploy>dav:http://nexus.opendaylight.org/content/sites/site</sitedeploy>
     <sonar.branch>${user.name}-private-view</sonar.branch>
     <sonar.host.url>https://sonar.opendaylight.org/</sonar.host.url>
     <!-- Sonar properties using jacoco to retrieve integration test results -->
     <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
     <sonar.language>java</sonar.language>
+    <sonar.skippedModules>org.openflow.openflowj,net.sf.jung2,org.opendaylight.controller.protobuff.messages</sonar.skippedModules>
+    <spifly.version>1.0.0</spifly.version>
+    <spring-osgi.version>1.2.1</spring-osgi.version>
+    <spring-security-karaf.version>3.1.4.RELEASE</spring-security-karaf.version>
+    <spring-security.version>3.1.3.RELEASE</spring-security.version>
+    <spring.version>3.1.3.RELEASE</spring.version>
     <sonar.skippedModules>org.openflow.openflowj,net.sf.jung2</sonar.skippedModules>
     <statistics.northbound.version>0.4.2-SNAPSHOT</statistics.northbound.version>
     <statisticsmanager.implementation.version>0.4.2-SNAPSHOT</statisticsmanager.implementation.version>
     <topology.web.version>0.4.2-SNAPSHOT</topology.web.version>
     <topologymanager.version>0.4.2-SNAPSHOT</topologymanager.version>
     <troubleshoot.web.version>0.4.2-SNAPSHOT</troubleshoot.web.version>
+    <typesafe.config.version>1.2.0</typesafe.config.version>
+    <uncommons.maths.version>1.2.2</uncommons.maths.version>
     <usermanager.implementation.version>0.4.2-SNAPSHOT</usermanager.implementation.version>
     <usermanager.northbound.version>0.0.2-SNAPSHOT</usermanager.northbound.version>
     <usermanager.version>0.4.2-SNAPSHOT</usermanager.version>
         <artifactId>sal-rest-connector</artifactId>
         <version>${mdsal.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>sal-rest-connector-config</artifactId>
+        <version>${mdsal.version}</version>
+      </dependency>
       <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>sal-rest-docgen</artifactId>
         <artifactId>sal-restconf-broker</artifactId>
         <version>${mdsal.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>sal-test-model</artifactId>
+        <version>${mdsal.version}</version>
+      </dependency>
 
       <!-- SAL Extension bundles -->
       <dependency>
       <dependency>
         <groupId>org.opendaylight.controller.thirdparty</groupId>
         <artifactId>ganymed</artifactId>
-        <version>1.1-SNAPSHOT</version>
+        <version>${ganymed.version}</version>
       </dependency>
       <!-- Third parties from opendaylight released -->
       <dependency>
           <includeTestSourceDirectory>true</includeTestSourceDirectory>
           <sourceDirectory>${project.basedir}</sourceDirectory>
           <includes>**\/*.java,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat</includes>
-          <excludes>**\/target\/,**\/bin\/,**\/target-ide\/,**\/${jmxGeneratorPath}\/,**\/${salGeneratorPath}\/,**\/xtend-gen\/</excludes>
+          <excludes>**\/target\/,**\/bin\/,**\/target-ide\/,**\/${jmxGeneratorPath}\/,**\/${salGeneratorPath}\/,**\/xtend-gen\/,**\/protobuff\/</excludes>
         </configuration>
         <dependencies>
           <dependency>
index 580a53be94c57ad08ce7b69352994eb028486311..12b771df808ccf49b2a57ab1b4411f17f298fb65 100644 (file)
@@ -32,14 +32,14 @@ public final class ReconnectImmediatelyStrategyFactoryModule extends org.openday
 
     @Override
     protected void customValidation(){
-        JmxAttributeValidationException.checkNotNull(getTimeout(), "value is not set.", timeoutJmxAttribute);
-        JmxAttributeValidationException.checkCondition(getTimeout() >= 0, "value " + getTimeout() + " is less than 0",
-                timeoutJmxAttribute);
+        JmxAttributeValidationException.checkNotNull(getReconnectTimeout(), "value is not set.", reconnectTimeoutJmxAttribute);
+        JmxAttributeValidationException.checkCondition(getReconnectTimeout() >= 0, "value " + getReconnectTimeout() + " is less than 0",
+                reconnectTimeoutJmxAttribute);
     }
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        return new ReconnectImmediatelyStrategyFactoryCloseable(getExecutorDependency(), getTimeout());
+        return new ReconnectImmediatelyStrategyFactoryCloseable(getReconnectExecutorDependency(), getReconnectTimeout());
     }
 
     private static final class ReconnectImmediatelyStrategyFactoryCloseable implements ReconnectStrategyFactory, AutoCloseable {
index b8849c7a1d7c8b42db885274f3f8311b2c6626e3..0b4a7baf6fb43737b3d673723d5a3da7ad29a08c 100644 (file)
@@ -49,7 +49,7 @@ public final class TimedReconnectStrategyFactoryModule extends org.opendaylight.
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        return new TimedReconnectStrategyFactoryCloseable(getExecutorDependency(),
+        return new TimedReconnectStrategyFactoryCloseable(getTimedReconnectExecutorDependency(),
                 getConnectTime(), getMinSleep(), getSleepFactor().doubleValue(), getMaxSleep(), getMaxAttempts(),
                 getDeadline());
     }
index fef2c7196948c007705b4444a5c9445065618648..a62bd7da06501b355c41f36230dbf30a982d61fa 100644 (file)
@@ -8,9 +8,11 @@
 package org.opendaylight.protocol.framework;
 
 import com.google.common.base.Preconditions;
+
 import io.netty.bootstrap.Bootstrap;
 import io.netty.bootstrap.ServerBootstrap;
 import io.netty.channel.Channel;
+import io.netty.buffer.PooledByteBufAllocator;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelInitializer;
 import io.netty.channel.ChannelOption;
@@ -25,9 +27,11 @@ import io.netty.util.concurrent.EventExecutor;
 import io.netty.util.concurrent.Future;
 import io.netty.util.concurrent.GlobalEventExecutor;
 import io.netty.util.concurrent.Promise;
+
 import java.io.Closeable;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -94,8 +98,8 @@ public abstract class AbstractDispatcher<S extends ProtocolSession<?>, L extends
      *
      * @return ChannelFuture representing the binding process
      */
-    protected <CH extends Channel> ChannelFuture createServer(SocketAddress address, Class<? extends ServerChannel> channelClass,
-                                                              final ChannelPipelineInitializer<CH, S> initializer) {
+    protected <CH extends Channel> ChannelFuture createServer(final SocketAddress address, final Class<? extends ServerChannel> channelClass,
+            final ChannelPipelineInitializer<CH, S> initializer) {
         final ServerBootstrap b = new ServerBootstrap();
         b.childHandler(new ChannelInitializer<CH>() {
 
@@ -110,6 +114,7 @@ public abstract class AbstractDispatcher<S extends ProtocolSession<?>, L extends
             // makes no sense for LocalServer and produces warning
             b.childOption(ChannelOption.SO_KEEPALIVE, true);
         }
+        b.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
         customizeBootstrap(b);
 
         if (b.group() == null) {
@@ -151,9 +156,8 @@ public abstract class AbstractDispatcher<S extends ProtocolSession<?>, L extends
     protected Future<S> createClient(final InetSocketAddress address, final ReconnectStrategy strategy, final PipelineInitializer<S> initializer) {
         final Bootstrap b = new Bootstrap();
         final ProtocolSessionPromise<S> p = new ProtocolSessionPromise<S>(executor, address, strategy, b);
-        b.group(this.workerGroup).channel(NioSocketChannel.class).option(ChannelOption.SO_KEEPALIVE, true).handler(
+        b.option(ChannelOption.SO_KEEPALIVE, true).handler(
                 new ChannelInitializer<SocketChannel>() {
-
                     @Override
                     protected void initChannel(final SocketChannel ch) {
                         initializer.initializeChannel(ch, p);
@@ -162,6 +166,18 @@ public abstract class AbstractDispatcher<S extends ProtocolSession<?>, L extends
 
         customizeBootstrap(b);
 
+        if (b.group() == null) {
+            b.group(workerGroup);
+        }
+
+        // There is no way to detect if this was already set by
+        // customizeBootstrap()
+        try {
+            b.channel(NioSocketChannel.class);
+        } catch (IllegalStateException e) {
+            LOG.trace("Not overriding channelFactory on bootstrap {}", b, e);
+        }
+
         p.connect();
         LOG.debug("Client created.");
         return p;
index 1856369178c0c2230db2eca3e24288ce5ca2f0b3..cd84d4a95e24156453d9d56b0b02ee072f2d036a 100644 (file)
@@ -77,12 +77,12 @@ module protocol-framework {
         case reconnect-immediately-strategy-factory {
             when "/config:modules/config:module/config:type = 'reconnect-immediately-strategy-factory'";
 
-            leaf timeout {
+            leaf reconnect-timeout {
                 mandatory true;
                 type int32;
             }
 
-            container executor {
+            container reconnect-executor {
                 uses config:service-ref {
                     refine type {
                         mandatory true;
@@ -138,7 +138,7 @@ module protocol-framework {
                 units "milliseconds";
             }
 
-            container executor {
+            container timed-reconnect-executor {
                 uses config:service-ref {
                     refine type {
                         mandatory true;
index 9beadc4dbb2b7f8aa34a0390e9aa65614168d666..cfdf3bff28729e5f80a4c9811316eb04e2b1bcc6 100644 (file)
@@ -78,7 +78,7 @@ public class ReconnectImmediatelyStrategyModuleTest extends AbstractConfigTest {
         final ReconnectImmediatelyStrategyFactoryModuleMXBean mxBean = transaction.newMBeanProxy(
                 transaction.lookupConfigBean(FACTORY_NAME, INSTANCE_NAME),
                 ReconnectImmediatelyStrategyFactoryModuleMXBean.class);
-        mxBean.setTimeout(200);
+        mxBean.setReconnectTimeout(200);
         final CommitStatus status = transaction.commit();
         assertBeanCount(1, FACTORY_NAME);
         assertStatus(status, 0, 1, 1);
@@ -99,8 +99,8 @@ public class ReconnectImmediatelyStrategyModuleTest extends AbstractConfigTest {
         final ObjectName nameCreated = transaction.createModule(FACTORY_NAME, INSTANCE_NAME);
         final ReconnectImmediatelyStrategyFactoryModuleMXBean mxBean = transaction.newMBeanProxy(nameCreated,
                 ReconnectImmediatelyStrategyFactoryModuleMXBean.class);
-        mxBean.setTimeout(timeout);
-        mxBean.setExecutor(GlobalEventExecutorUtil.create(transaction));
+        mxBean.setReconnectTimeout(timeout);
+        mxBean.setReconnectExecutor(GlobalEventExecutorUtil.create(transaction));
         return nameCreated;
     }
 
index a8cdff711905ead55193384baed9362d1f7df909..1c068a98e748e76e0404fc5b71c87d97e839f75d 100644 (file)
@@ -7,6 +7,13 @@
  */
 package org.opendaylight.controller.config.yang.protocol.framework;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.math.BigDecimal;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.api.ConflictingVersionException;
@@ -17,14 +24,6 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hardcod
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
 
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-import java.math.BigDecimal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
 public class TimedReconnectStrategyModuleTest extends AbstractConfigTest {
 
     private static final String INSTANCE_NAME = "timed-reconect-stategy-facotry-impl";
@@ -158,7 +157,7 @@ public class TimedReconnectStrategyModuleTest extends AbstractConfigTest {
         mxBean.setMaxSleep(maxSleep);
         mxBean.setMinSleep(minSleep);
         mxBean.setSleepFactor(sleepFactor);
-        mxBean.setExecutor(GlobalEventExecutorUtil.create(transaction));
+        mxBean.setTimedReconnectExecutor(GlobalEventExecutorUtil.create(transaction));
         return nameCreated;
     }
 
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.controller.config.manager.impl.jmx;
+package org.opendaylight.controller.config.api.jmx;
 
 import javax.management.ObjectName;
 
index 335acc81fe67859386b3369269c15f3101d7e2f4..07bd63b7c7be8c78397b227ae40db7e53cb8da91 100644 (file)
@@ -53,12 +53,12 @@ public class DynamicWritableWrapper extends AbstractDynamicWrapper {
     private final ReadOnlyAtomicBoolean configBeanModificationDisabled;
 
     public DynamicWritableWrapper(Module module,
-            ModuleIdentifier moduleIdentifier,
-            TransactionIdentifier transactionIdentifier,
-            ReadOnlyAtomicBoolean configBeanModificationDisabled,
-            MBeanServer internalServer, MBeanServer configMBeanServer) {
+                                  ModuleIdentifier moduleIdentifier,
+                                  TransactionIdentifier transactionIdentifier,
+                                  ReadOnlyAtomicBoolean configBeanModificationDisabled,
+                                  MBeanServer internalServer, MBeanServer configMBeanServer) {
         super(module, true, moduleIdentifier, ObjectNameUtil
-                .createTransactionModuleON(transactionIdentifier.getName(), moduleIdentifier), getOperations(moduleIdentifier),
+                        .createTransactionModuleON(transactionIdentifier.getName(), moduleIdentifier), getOperations(moduleIdentifier),
                 internalServer, configMBeanServer);
         this.configBeanModificationDisabled = configBeanModificationDisabled;
     }
@@ -67,22 +67,19 @@ public class DynamicWritableWrapper extends AbstractDynamicWrapper {
             ModuleIdentifier moduleIdentifier) {
         Method validationMethod;
         try {
-            validationMethod = DynamicWritableWrapper.class.getMethod(
-                    "validate", new Class<?>[0]);
+            validationMethod = DynamicWritableWrapper.class.getMethod("validate");
         } catch (NoSuchMethodException e) {
-            throw new IllegalStateException("No such method exception on "
-                    + moduleIdentifier, e);
+            throw new IllegalStateException("No such method exception on " + moduleIdentifier, e);
         }
-        return new MBeanOperationInfo[] { new MBeanOperationInfo("Validation",
-                validationMethod) };
+        return new MBeanOperationInfo[]{new MBeanOperationInfo("Validation", validationMethod)};
     }
 
     @Override
     public synchronized void setAttribute(Attribute attribute)
-            throws AttributeNotFoundException, InvalidAttributeValueException,
-            MBeanException, ReflectionException {
-        if (configBeanModificationDisabled.get() == true)
+            throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
+        if (configBeanModificationDisabled.get() == true) {
             throw new IllegalStateException("Operation is not allowed now");
+        }
 
         if (attribute.getName().equals("Attribute")) {
             setAttribute((Attribute) attribute.getValue());
@@ -92,7 +89,7 @@ public class DynamicWritableWrapper extends AbstractDynamicWrapper {
         try {
             if (attribute.getValue() instanceof ObjectName) {
                 attribute = fixDependencyAttribute(attribute);
-            } else if(attribute.getValue() instanceof ObjectName[]) {
+            } else if (attribute.getValue() instanceof ObjectName[]) {
                 attribute = fixDependencyListAttribute(attribute);
             }
 
@@ -104,24 +101,19 @@ public class DynamicWritableWrapper extends AbstractDynamicWrapper {
     }
 
     private Attribute fixDependencyListAttribute(Attribute attribute) {
-        AttributeHolder attributeHolder = attributeHolderMap
-                .get(attribute.getName());
+        AttributeHolder attributeHolder = attributeHolderMap.get(attribute.getName());
         if (attributeHolder.getRequireInterfaceOrNull() != null) {
-            attribute = new Attribute(attribute.getName(),
-                    fixObjectNames((ObjectName[]) attribute.getValue()));
+            attribute = new Attribute(attribute.getName(), fixObjectNames((ObjectName[]) attribute.getValue()));
         }
         return attribute;
     }
 
     private Attribute fixDependencyAttribute(Attribute attribute) {
-        AttributeHolder attributeHolder = attributeHolderMap
-                .get(attribute.getName());
+        AttributeHolder attributeHolder = attributeHolderMap.get(attribute.getName());
         if (attributeHolder.getRequireInterfaceOrNull() != null) {
-            attribute = new Attribute(attribute.getName(),
-                    fixObjectName((ObjectName) attribute.getValue()));
+            attribute = new Attribute(attribute.getName(), fixObjectName((ObjectName) attribute.getValue()));
         } else {
-            attribute = new Attribute(attribute.getName(),
-                    attribute.getValue());
+            attribute = new Attribute(attribute.getName(), attribute.getValue());
         }
         return attribute;
     }
@@ -145,8 +137,7 @@ public class DynamicWritableWrapper extends AbstractDynamicWrapper {
                 setAttribute(attribute);
                 result.add(attribute);
             } catch (Exception e) {
-                logger.warn("Setting attribute {} failed on {}",
-                        attribute.getName(), moduleIdentifier, e);
+                logger.warn("Setting attribute {} failed on {}", attribute.getName(), moduleIdentifier, e);
                 throw new IllegalArgumentException(
                         "Setting attribute failed - " + attribute.getName()
                                 + " on " + moduleIdentifier, e);
index dedeeed789f5e8b9ec030f2c349beec19f1c2872..ba6676b927bb554d296b2ebaa9efd3205bdebc4c 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.config.manager.impl.jmx;
 
 import javax.management.ObjectName;
+import org.opendaylight.controller.config.api.jmx.ServiceReferenceMXBean;
 
 public class ServiceReferenceMXBeanImpl implements ServiceReferenceMXBean {
     private ObjectName currentImplementation;
index c1ebba78817fb36c1a34f256ee81bdcb8c86d85f..eff267ad1319c90c1ce9e06de2ff7bcaddc86c67 100644 (file)
@@ -7,6 +7,13 @@
  */
 package org.opendaylight.controller.config.manager.impl.osgi;
 
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadFactory;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
@@ -15,74 +22,114 @@ import org.osgi.util.tracker.BundleTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
 /**
  *
- * Extensible bundle tracker. Takes several BundleTrackerCustomizers and propagates bundle events to all of them.
- * Primary customizer
+ * Extensible bundle tracker. Takes several BundleTrackerCustomizers and
+ * propagates bundle events to all of them.
+ *
+ * Primary customizer may return tracking object,
+ * which will be passed to it during invocation of
+ * {@link BundleTrackerCustomizer#removedBundle(Bundle, BundleEvent, Future)}
+ *
+ *
+ * This extender modifies behaviour to not leak platform thread
+ * in {@link BundleTrackerCustomizer#addingBundle(Bundle, BundleEvent)}
+ * but deliver this event from its own single threaded executor.
+ *
+ * If bundle is removed before event for adding bundle was executed,
+ * that event is cancelled. If addingBundle event is currently in progress
+ * or was already executed, platform thread is block untill addingBundle
+ * finishes so bundle could be removed correctly in platform thread.
+ *
+ *
+ * Method {@link BundleTrackerCustomizer#removedBundle(Bundle, BundleEvent, Object)}
+ * is never invoked on registered trackers.
  *
  * @param <T>
  */
-public final class ExtensibleBundleTracker<T> extends BundleTracker<T> {
+public final class ExtensibleBundleTracker<T> extends BundleTracker<Future<T>> {
 
+    private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder()
+        .setNameFormat("config-bundle-tracker-%d")
+        .build();
+    private final ExecutorService eventExecutor;
     private final BundleTrackerCustomizer<T> primaryTracker;
     private final BundleTrackerCustomizer<?>[] additionalTrackers;
 
-    private static final Logger logger = LoggerFactory.getLogger(ExtensibleBundleTracker.class);
+    private static final Logger LOG = LoggerFactory.getLogger(ExtensibleBundleTracker.class);
 
-    public ExtensibleBundleTracker(BundleContext context, BundleTrackerCustomizer<T> primaryBundleTrackerCustomizer,
-                                   BundleTrackerCustomizer<?>... additionalBundleTrackerCustomizers) {
+    public ExtensibleBundleTracker(final BundleContext context, final BundleTrackerCustomizer<T> primaryBundleTrackerCustomizer,
+                                   final BundleTrackerCustomizer<?>... additionalBundleTrackerCustomizers) {
         this(context, Bundle.ACTIVE, primaryBundleTrackerCustomizer, additionalBundleTrackerCustomizers);
     }
 
-    public ExtensibleBundleTracker(BundleContext context, int bundleState,
-                                   BundleTrackerCustomizer<T> primaryBundleTrackerCustomizer,
-                                   BundleTrackerCustomizer<?>... additionalBundleTrackerCustomizers) {
+    public ExtensibleBundleTracker(final BundleContext context, final int bundleState,
+                                   final BundleTrackerCustomizer<T> primaryBundleTrackerCustomizer,
+                                   final BundleTrackerCustomizer<?>... additionalBundleTrackerCustomizers) {
         super(context, bundleState, null);
         this.primaryTracker = primaryBundleTrackerCustomizer;
         this.additionalTrackers = additionalBundleTrackerCustomizers;
-        logger.trace("Registered as extender with context {} and bundle state {}", context, bundleState);
+        eventExecutor = Executors.newSingleThreadExecutor(THREAD_FACTORY);
+        LOG.trace("Registered as extender with context {} and bundle state {}", context, bundleState);
     }
 
     @Override
-    public T addingBundle(final Bundle bundle, final BundleEvent event) {
-        T primaryTrackerRetVal = primaryTracker.addingBundle(bundle, event);
-
-        forEachAdditionalBundle(new BundleStrategy() {
+    public Future<T> addingBundle(final Bundle bundle, final BundleEvent event) {
+        LOG.trace("Submiting AddingBundle for bundle {} and event {} to be processed asynchronously",bundle,event);
+        Future<T> future = eventExecutor.submit(new Callable<T>() {
             @Override
-            public void execute(BundleTrackerCustomizer<?> tracker) {
-                tracker.addingBundle(bundle, event);
+            public T call() throws Exception {
+                try {
+                    T primaryTrackerRetVal = primaryTracker.addingBundle(bundle, event);
+
+                    forEachAdditionalBundle(new BundleStrategy() {
+                        @Override
+                        public void execute(final BundleTrackerCustomizer<?> tracker) {
+                            tracker.addingBundle(bundle, event);
+                        }
+                    });
+                    LOG.trace("AddingBundle for {} and event {} finished successfully",bundle,event);
+                    return primaryTrackerRetVal;
+                } catch (Exception e) {
+                    LOG.error("Failed to add bundle {}",e);
+                    throw e;
+                }
             }
         });
-
-        return primaryTrackerRetVal;
+        return future;
     }
 
     @Override
-    public void modifiedBundle(final Bundle bundle, final BundleEvent event, final T object) {
-        primaryTracker.modifiedBundle(bundle, event, object);
-
-        forEachAdditionalBundle(new BundleStrategy() {
-            @Override
-            public void execute(BundleTrackerCustomizer<?> tracker) {
-                tracker.modifiedBundle(bundle, event, null);
-            }
-        });
+    public void modifiedBundle(final Bundle bundle, final BundleEvent event, final Future<T> object) {
+        // Intentionally NOOP
 
     }
 
     @Override
-    public void removedBundle(final Bundle bundle, final BundleEvent event, final T object) {
-        primaryTracker.removedBundle(bundle, event, object);
-
-        forEachAdditionalBundle(new BundleStrategy() {
-            @Override
-            public void execute(BundleTrackerCustomizer<?> tracker) {
-                tracker.removedBundle(bundle, event, null);
-            }
-        });
+    public void removedBundle(final Bundle bundle, final BundleEvent event, final Future<T> object) {
+        if(!object.isDone() && object.cancel(false)) {
+            // We canceled adding event before it was processed
+            // so it is safe to return
+            LOG.trace("Adding Bundle event for {} was cancelled. No additional work required.",bundle);
+            return;
+        }
+        try {
+            LOG.trace("Invoking removedBundle event for {}",bundle);
+            primaryTracker.removedBundle(bundle, event, object.get());
+            forEachAdditionalBundle(new BundleStrategy() {
+                @Override
+                public void execute(final BundleTrackerCustomizer<?> tracker) {
+                    tracker.removedBundle(bundle, event, null);
+                }
+            });
+            LOG.trace("Removed bundle event for {} finished successfully.",bundle);
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Addition of bundle failed, ", e);
+        }
     }
 
-    private void forEachAdditionalBundle(BundleStrategy lambda) {
+    private void forEachAdditionalBundle(final BundleStrategy lambda) {
         for (BundleTrackerCustomizer<?> trac : additionalTrackers) {
             lambda.execute(trac);
         }
index 3e7b65e1bdcf8f25cfe6c255e43072edc2382f6a..8c132c93b298dee714f3efa063f329efc70a7878 100644 (file)
@@ -13,7 +13,7 @@ import org.junit.Test;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest.RecordingBundleContextServiceRegistrationHandler.RegistrationHolder;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
-import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceMXBean;
+import org.opendaylight.controller.config.api.jmx.ServiceReferenceMXBean;
 import org.opendaylight.controller.config.manager.testingservices.parallelapsp.TestingParallelAPSPModuleFactory;
 import org.opendaylight.controller.config.manager.testingservices.parallelapsp.test.AbstractParallelAPSPTest;
 import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolModuleFactory;
index 6ddb1306c559633193b2d6e897ad09d9499ee7f1..ae041f45852fd484e2f3a51cf80059211bc36294 100644 (file)
@@ -20,6 +20,7 @@
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-api</artifactId>
+            <version>${config.version}</version>
         </dependency>
     </dependencies>
 
index b6e2efcd457653f6414ac381eb80018b0e4249f8..7429f4d57431c9922d9a33ef5e8053ef1cfd174f 100644 (file)
@@ -8,7 +8,7 @@
     <relativePath>..</relativePath>
   </parent>
   <artifactId>config-util</artifactId>
-  <packaging>jar</packaging>
+  <packaging>bundle</packaging>
   <name>${project.artifactId}</name>
 
   <dependencies>
           <threadCount>1</threadCount>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Export-Package>org.opendaylight.controller.config.util</Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
 
index 549ff9ffcfdb9254a4115349d1cbd65520875809..559993f2648ec013791bdcf7167e412fe9a69102 100644 (file)
@@ -26,6 +26,7 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import org.opendaylight.controller.config.api.jmx.ServiceReferenceMXBean;
 
 public class ConfigRegistryJMXClient implements ConfigRegistryClient {
     private final ConfigRegistryMXBean configRegistryMXBeanProxy;
@@ -65,10 +66,27 @@ public class ConfigRegistryJMXClient implements ConfigRegistryClient {
                 configMBeanServer);
     }
 
+    /**
+     * Usage of this method indicates error as config JMX uses solely MXBeans.
+     * Use {@link #newMXBeanProxy(javax.management.ObjectName, Class)}
+     * or {@link JMX#newMBeanProxy(javax.management.MBeanServerConnection, javax.management.ObjectName, Class)}
+     * This method will be removed soon.
+     */
+    @Deprecated
     public <T> T newMBeanProxy(ObjectName on, Class<T> clazz) {
+        on = translateServiceRefIfPossible(on, clazz, configMBeanServer);
         return JMX.newMBeanProxy(configMBeanServer, on, clazz);
     }
 
+    static  ObjectName translateServiceRefIfPossible(ObjectName on, Class<?> clazz, MBeanServer configMBeanServer) {
+        if (ObjectNameUtil.isServiceReference(on) && clazz.equals(ServiceReferenceMXBean.class) == false) {
+            ServiceReferenceMXBean proxy = JMX.newMXBeanProxy(configMBeanServer, on, ServiceReferenceMXBean.class);
+            on = proxy.getCurrentImplementation();
+        }
+        return on;
+    }
+
+
     public <T> T newMXBeanProxy(ObjectName on, Class<T> clazz) {
         return JMX.newMXBeanProxy(configMBeanServer, on, clazz);
     }
@@ -211,5 +229,4 @@ public class ConfigRegistryJMXClient implements ConfigRegistryClient {
     public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
         configRegistryMXBeanProxy.checkServiceReferenceExists(objectName);
     }
-
 }
index 4f02db5a3807095c0302ee1446eb765a2858ea77..f5381424de8c217414a326212c69b25879c52fe8 100644 (file)
@@ -41,4 +41,14 @@ public interface ConfigTransactionClient extends
     void destroyModule(String moduleName, String instanceName) throws InstanceNotFoundException;
 
     void setAttribute(ObjectName on, String jmxName, Attribute attribute);
+
+    /*
+     * Get the attribute named jmxName from the Object with ObjectName on
+     *
+     * @param on - ObjectName of the Object from which the attribute should be read
+     * @param jmxName - name of the attribute to be read
+     *
+     * @return Attribute of Object on with attribute name jmxName
+     */
+    Attribute getAttribute(ObjectName on, String jmxName);
 }
index 4adc0d9364e3392969c0c771edc4fd5ae41cdaf1..bc188515538485f9a13f87366a281a893a5984ae 100644 (file)
@@ -7,12 +7,8 @@
  */
 package org.opendaylight.controller.config.util;
 
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.jmx.CommitStatus;
-import org.opendaylight.controller.config.api.jmx.ConfigRegistryMXBean;
-import org.opendaylight.controller.config.api.jmx.ConfigTransactionControllerMXBean;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import java.util.Map;
+import java.util.Set;
 
 import javax.management.Attribute;
 import javax.management.InstanceAlreadyExistsException;
@@ -22,8 +18,13 @@ import javax.management.JMX;
 import javax.management.MBeanException;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
-import java.util.Map;
-import java.util.Set;
+
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.jmx.CommitStatus;
+import org.opendaylight.controller.config.api.jmx.ConfigRegistryMXBean;
+import org.opendaylight.controller.config.api.jmx.ConfigTransactionControllerMXBean;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 
 public class ConfigTransactionJMXClient implements ConfigTransactionClient {
     private final ConfigRegistryMXBean configRegistryMXBeanProxy;
@@ -44,9 +45,21 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
     }
 
     public <T> T newMXBeanProxy(ObjectName on, Class<T> clazz) {
+        // if on is without transaction, add it. Reason is that when using getters on MXBeans the transaction name is stripped
+        on = ObjectNameUtil.withTransactionName(on, getTransactionName());
+        // if this is service reference and user requests for implementation, look it up
+        on = ConfigRegistryJMXClient.translateServiceRefIfPossible(on, clazz, configMBeanServer);
+        on = ObjectNameUtil.withTransactionName(on, getTransactionName());
         return JMX.newMXBeanProxy(configMBeanServer, on, clazz);
     }
 
+    /**
+     * Usage of this method indicates error as config JMX uses solely MXBeans.
+     * Use {@link #newMXBeanProxy(javax.management.ObjectName, Class)}
+     * or {@link JMX#newMBeanProxy(javax.management.MBeanServerConnection, javax.management.ObjectName, Class)}
+     * This method will be removed soon.
+     */
+    @Deprecated
     public <T> T newMBeanProxy(ObjectName on, Class<T> clazz) {
         return JMX.newMBeanProxy(configMBeanServer, on, clazz);
     }
@@ -259,6 +272,20 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
         }
     }
 
+    @Override
+    public Attribute getAttribute(ObjectName on, String attrName) {
+        if (ObjectNameUtil.getTransactionName(on) == null)
+            throw new IllegalArgumentException("Not in transaction instance "
+                    + on + ", no transaction name present");
+
+        try {
+            return new Attribute(attrName, configMBeanServer.getAttribute(on,attrName));
+        } catch (JMException e) {
+            throw new IllegalStateException("Unable to get attribute "
+                    + attrName + " for " + on, e);
+        }
+    }
+
     @Override
     public Set<String> getAvailableModuleFactoryQNames() {
         return configTransactionControllerMXBeanProxy.getAvailableModuleFactoryQNames();
diff --git a/opendaylight/config/feature/src/main/resources/features.xml b/opendaylight/config/feature/src/main/resources/features.xml
deleted file mode 100644 (file)
index 81972c3..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<features name="config-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
-   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-   xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
-    <feature name='config-all' version='${project.version}'>
-        <feature version='${project.version}'>odl-config-subsystem</feature>
-    </feature>
-
-    <feature name='odl-config-subsystem' version='${project.version}'>
-        <feature version='${yangtools.version}'>yangtools-concepts</feature>
-        <feature version='${yangtools.version}'>yangtools-binding</feature>
-        <feature version='${yangtools.version}'>yangtools-binding-generator</feature>
-        <feature version='${mdsal.version}'>odl-mdsal-commons</feature>
-        <bundle>mvn:org.opendaylight.controller/config-api/${project.version}</bundle>
-        <bundle>mvn:org.opendaylight.controller/config-manager/${project.version}</bundle>
-        <bundle>mvn:org.opendaylight.controller/yang-jmx-generator/${project.version}</bundle>
-        <bundle>mvn:org.opendaylight.controller/config-persister-api/${project.version}</bundle>
-        <bundle>mvn:org.opendaylight.controller/config-persister-file-xml-adapter/${project.version}</bundle>
-        <bundle>mvn:org.opendaylight.controller/config-persister-directory-xml-adapter/${project.version}</bundle>
-        <bundle>mvn:org.opendaylight.controller/shutdown-api/${project.version}</bundle>
-        <bundle>mvn:org.opendaylight.controller/shutdown-impl/${project.version}</bundle>
-        <bundle>mvn:org.osgi/org.osgi.core/${osgi.core.version}</bundle>
-        <bundle>wrap:mvn:com.google.guava/guava/${guava.version}</bundle>
-        <bundle>mvn:org.javassist/javassist/${javassist.version}</bundle>
-    </feature>
-</features>
\ No newline at end of file
index 76fbd7f6e55c057e6248fed354da9c8f801da2bb..66bb01f051fa1042e9fc08d4019a236f1e07bb04 100644 (file)
@@ -1,5 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
 <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>
 
@@ -40,7 +39,6 @@
     <module>shutdown-impl</module>
     <module>netconf-config-dispatcher</module>
     <module>config-module-archetype</module>
-    <module>feature</module>
   </modules>
 
   <dependencies>
index 3dfa6e2bc756419b18f3224b32b127255e00d35d..5036399828a539e5ec5deb451881f3e4e9218b68 100644 (file)
@@ -10,15 +10,20 @@ package org.opendaylight.controller.config.threadpool.util;
 
 import java.io.Closeable;
 import java.io.IOException;
+import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.RejectedExecutionHandler;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
 import org.opendaylight.controller.config.threadpool.ThreadPool;
 
+import com.google.common.base.Optional;
+
 /**
  * Implementation of {@link ThreadPool} using flexible number of threads wraps
  * {@link ExecutorService}.
@@ -28,12 +33,33 @@ public class FlexibleThreadPoolWrapper implements ThreadPool, Closeable {
 
     public FlexibleThreadPoolWrapper(int minThreadCount, int maxThreadCount, long keepAlive, TimeUnit timeUnit,
             ThreadFactory threadFactory) {
+        this(minThreadCount, maxThreadCount, keepAlive, timeUnit, threadFactory, getQueue(Optional.<Integer>absent()));
+    }
+
+    public FlexibleThreadPoolWrapper(int minThreadCount, int maxThreadCount, long keepAlive, TimeUnit timeUnit,
+            ThreadFactory threadFactory, Optional<Integer> queueCapacity) {
+        this(minThreadCount, maxThreadCount, keepAlive, timeUnit, threadFactory, getQueue(queueCapacity));
+    }
+
+    private FlexibleThreadPoolWrapper(int minThreadCount, int maxThreadCount, long keepAlive, TimeUnit timeUnit,
+            ThreadFactory threadFactory, BlockingQueue<Runnable> queue) {
 
         executor = new ThreadPoolExecutor(minThreadCount, maxThreadCount, keepAlive, timeUnit,
-                new SynchronousQueue<Runnable>(), threadFactory);
+                queue, threadFactory, new FlexibleRejectionHandler());
         executor.prestartAllCoreThreads();
     }
 
+    /**
+     * Overriding the queue:
+     * ThreadPoolExecutor would not create new threads if the queue is not full, thus adding
+     * occurs in RejectedExecutionHandler.
+     * This impl saturates threadpool first, then queue. When both are full caller will get blocked.
+     */
+    private static ForwardingBlockingQueue getQueue(Optional<Integer> capacity) {
+        final BlockingQueue<Runnable> delegate = capacity.isPresent() ? new LinkedBlockingQueue<Runnable>(capacity.get()) : new LinkedBlockingQueue<Runnable>();
+        return new ForwardingBlockingQueue(delegate);
+    }
+
     @Override
     public ExecutorService getExecutor() {
         return Executors.unconfigurableExecutorService(executor);
@@ -77,4 +103,37 @@ public class FlexibleThreadPoolWrapper implements ThreadPool, Closeable {
         executor.shutdown();
     }
 
+    /**
+     * if the max threads are met, then it will raise a rejectedExecution. We then push to the queue.
+     */
+    private static class FlexibleRejectionHandler implements RejectedExecutionHandler {
+        @Override
+        public void rejectedExecution(final Runnable r, final ThreadPoolExecutor executor) {
+            try {
+                executor.getQueue().put(r);
+            } catch (InterruptedException e) {
+                throw new RejectedExecutionException("Interrupted while waiting on the queue", e);
+            }
+        }
+    }
+
+    private static class ForwardingBlockingQueue extends com.google.common.util.concurrent.ForwardingBlockingQueue<Runnable> {
+        private final BlockingQueue<Runnable> delegate;
+
+        public ForwardingBlockingQueue(BlockingQueue<Runnable> delegate) {
+            this.delegate = delegate;
+        }
+
+        @Override
+        protected BlockingQueue<Runnable> delegate() {
+            return delegate;
+        }
+
+        @Override
+        public boolean offer(final Runnable r) {
+            // ThreadPoolExecutor will spawn a new thread after core size is reached only
+            // if the queue.offer returns false.
+            return false;
+        }
+    }
 }
index 94639d43c0248787c736a2d7df7738597a4ef975..d6abe168fbedfa9a7d2db6fc16d1151e621ca874 100644 (file)
@@ -17,6 +17,7 @@
 */
 package org.opendaylight.controller.config.yang.threadpool.impl.flexible;
 
+import com.google.common.base.Optional;
 import java.util.concurrent.TimeUnit;
 
 import org.opendaylight.controller.config.api.JmxAttributeValidationException;
@@ -50,11 +51,15 @@ public final class FlexibleThreadPoolModule extends org.opendaylight.controller.
         JmxAttributeValidationException.checkNotNull(getMaxThreadCount(), maxThreadCountJmxAttribute);
         JmxAttributeValidationException.checkCondition(getMaxThreadCount() > 0, "must be greater than zero",
                 maxThreadCountJmxAttribute);
+
+        if(getQueueCapacity() != null) {
+            JmxAttributeValidationException.checkCondition(getQueueCapacity() > 0, "Queue capacity cannot be < 1", queueCapacityJmxAttribute);
+        }
     }
 
     @Override
     public java.lang.AutoCloseable createInstance() {
         return new FlexibleThreadPoolWrapper(getMinThreadCount(), getMaxThreadCount(), getKeepAliveMillis(),
-                TimeUnit.MILLISECONDS, getThreadFactoryDependency());
+                TimeUnit.MILLISECONDS, getThreadFactoryDependency(), Optional.fromNullable(getQueueCapacity()));
     }
 }
index be275ef4870b3797e5195d61380a8c5935f3ff83..c124f6388fb2f5f41b1c48a86f55231ea4c023b4 100644 (file)
@@ -46,6 +46,12 @@ module threadpool-impl-flexible {
                 type uint32;
             }
 
+            leaf queueCapacity {
+                type uint16;
+                mandatory false;
+                description "Capacity of queue that holds waiting tasks";
+            }
+
             container threadFactory {
                 uses config:service-ref {
                     refine type {
index 6eda364af0d05860196bca23b7433e47f961d1a6..33546b1e2ae6a4d6ede0dfaddfc307495f13a325 100644 (file)
@@ -286,7 +286,7 @@ public class AbsModuleGeneratedObjectFactory {
             format("private final %s oldModule;\n", abstractFQN.getTypeName())+
             format("private final %s oldInstance;\n", AutoCloseable.class.getCanonicalName())+
             format("private %s instance;\n", AutoCloseable.class.getCanonicalName())+
-            format("private final %s dependencyResolver;\n", DependencyResolver.class.getCanonicalName())+
+            format("protected final %s dependencyResolver;\n", DependencyResolver.class.getCanonicalName())+
             format("private final %s identifier;\n", ModuleIdentifier.class.getCanonicalName())+
             "@Override\n"+
             format("public %s getIdentifier() {\n", ModuleIdentifier.class.getCanonicalName())+
index 0fd9720f79be60b0abab01dd60c651e1ed865ba6..864ebdf95468173f79070e9fa8c4c3165a8a2bec 100644 (file)
@@ -7,12 +7,40 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator.plugin;
 
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.matchers.JUnitMatchers.containsString;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.google.common.io.Files;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
 import org.apache.commons.io.FileUtils;
 import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.project.MavenProject;
@@ -46,35 +74,6 @@ import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.fail;
-import static org.junit.matchers.JUnitMatchers.containsString;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-
 //TODO: refactor
 public class JMXGeneratorTest extends AbstractGeneratorTest {
 
@@ -85,7 +84,7 @@ public class JMXGeneratorTest extends AbstractGeneratorTest {
     File generatedResourcesDir;
 
     private static final List<String> expectedModuleFileNames = ServiceInterfaceEntryTest
-            .toFileNames("[AbstractAsyncEventBusModule.java, AbstractAsyncEventBusModuleFactory.java, AbstractDynamicThreadPoolModule.java, AbstractDynamicThreadPoolModuleFactory.java, AbstractEventBusModule.java, AbstractEventBusModuleFactory.java, AbstractNamingThreadFactoryModule.java, AbstractNamingThreadFactoryModuleFactory.java, AbstractThreadPoolRegistryImplModule.java, AbstractThreadPoolRegistryImplModuleFactory.java, AsyncEventBusModule.java, AsyncEventBusModuleFactory.java, AsyncEventBusModuleMXBean.java, AsyncEventBusRuntimeMXBean.java, AsyncEventBusRuntimeRegistration.java, AsyncEventBusRuntimeRegistrator.java, DynamicThreadPoolModule.java, DynamicThreadPoolModuleFactory.java, DynamicThreadPoolModuleMXBean.java, DynamicThreadPoolRuntimeMXBean.java, DynamicThreadPoolRuntimeRegistration.java, DynamicThreadPoolRuntimeRegistrator.java, EventBusModule.java, EventBusModuleFactory.java, EventBusModuleMXBean.java, EventRuntimeMXBean.java, EventRuntimeRegistration.java, InnerStreamList.java, NamingThreadFactoryModule.java, NamingThreadFactoryModuleFactory.java, NamingThreadFactoryModuleMXBean.java, NamingThreadFactoryRuntimeMXBean.java, NamingThreadFactoryRuntimeRegistration.java, NamingThreadFactoryRuntimeRegistrator.java, Peer.java, StreamRuntimeMXBean.java, StreamRuntimeRegistration.java, ThreadPoolRegistryImplModule.java, ThreadPoolRegistryImplModuleFactory.java, ThreadPoolRegistryImplModuleMXBean.java, ThreadRuntimeMXBean.java, ThreadRuntimeRegistration.java, ThreadStreamRuntimeMXBean.java, ThreadStreamRuntimeRegistration.java]");
+            .toFileNames("[AbstractAsyncEventBusModule.java, AbstractAsyncEventBusModuleFactory.java, AbstractDynamicThreadPoolModule.java, AbstractDynamicThreadPoolModuleFactory.java, AbstractEventBusModule.java, AbstractEventBusModuleFactory.java, AbstractNamingThreadFactoryModule.java, AbstractNamingThreadFactoryModuleFactory.java, AbstractThreadPoolRegistryImplModule.java, AbstractThreadPoolRegistryImplModuleFactory.java, AsyncEventBusModule.java, AsyncEventBusModuleFactory.java, AsyncEventBusModuleMXBean.java, AsyncEventBusRuntimeMXBean.java, AsyncEventBusRuntimeRegistration.java, AsyncEventBusRuntimeRegistrator.java, DynamicThreadPoolModule.java, DynamicThreadPoolModuleFactory.java, DynamicThreadPoolModuleMXBean.java, DynamicThreadPoolRuntimeMXBean.java, DynamicThreadPoolRuntimeRegistration.java, DynamicThreadPoolRuntimeRegistrator.java, EventBusModule.java, EventBusModuleFactory.java, EventBusModuleMXBean.java, EventRuntimeMXBean.java, EventRuntimeRegistration.java, FromGrouping.java, InnerStreamList.java, NamingThreadFactoryModule.java, NamingThreadFactoryModuleFactory.java, NamingThreadFactoryModuleMXBean.java, NamingThreadFactoryRuntimeMXBean.java, NamingThreadFactoryRuntimeRegistration.java, NamingThreadFactoryRuntimeRegistrator.java, Peer.java, StreamRuntimeMXBean.java, StreamRuntimeRegistration.java, ThreadPoolRegistryImplModule.java, ThreadPoolRegistryImplModuleFactory.java, ThreadPoolRegistryImplModuleMXBean.java, ThreadRuntimeMXBean.java, ThreadRuntimeRegistration.java, ThreadStreamRuntimeMXBean.java, ThreadStreamRuntimeRegistration.java]");
 
     private static final List<String> expectedBGPNames = ServiceInterfaceEntryTest
             .toFileNames("[AbstractBgpListenerImplModule.java, " + "AbstractBgpListenerImplModuleFactory.java, " +
@@ -108,7 +107,7 @@ public class JMXGeneratorTest extends AbstractGeneratorTest {
                     "NetconfTestFiles1ImplModuleMXBean.java, NetconfTestFiles1ImplRuntimeMXBean.java, " +
                     "NetconfTestFiles1ImplRuntimeRegistration.java, NetconfTestFiles1ImplRuntimeRegistrator.java, TestFileImplModule.java, TestFileImplModuleFactory.java, TestFileImplModuleMXBean.java, TestFileImplRuntimeMXBean.java, TestFileImplRuntimeRegistration.java, TestFileImplRuntimeRegistrator.java, TestFiles1ImplModule.java, TestFiles1ImplModuleFactory.java, TestFiles1ImplModuleMXBean.java, TestFiles1ImplRuntimeMXBean.java, TestFiles1ImplRuntimeRegistration.java, TestFiles1ImplRuntimeRegistrator.java]");
     private static final List<String> expectedAllFileNames = ServiceInterfaceEntryTest
-            .toFileNames("[AbstractAsyncEventBusModule.java, AbstractAsyncEventBusModuleFactory.java, AbstractBgpListenerImplModule.java, AbstractBgpListenerImplModuleFactory.java, AbstractDynamicThreadPoolModule.java, AbstractDynamicThreadPoolModuleFactory.java, AbstractEventBusModule.java, AbstractEventBusModuleFactory.java, AbstractNamingThreadFactoryModule.java, AbstractNamingThreadFactoryModuleFactory.java, AbstractNetconfTestFileImplModule.java, AbstractNetconfTestFileImplModuleFactory.java, AbstractNetconfTestFiles1ImplModule.java, AbstractNetconfTestFiles1ImplModuleFactory.java, AbstractNetconfTestImplModule.java, AbstractNetconfTestImplModuleFactory.java, AbstractTestFileImplModule.java, AbstractTestFileImplModuleFactory.java, AbstractTestFiles1ImplModule.java, AbstractTestFiles1ImplModuleFactory.java, AbstractTestImplModule.java, AbstractTestImplModuleFactory.java, AbstractThreadPoolRegistryImplModule.java, AbstractThreadPoolRegistryImplModuleFactory.java, AsyncEventBusModule.java, AsyncEventBusModuleFactory.java, AsyncEventBusModuleMXBean.java, AsyncEventBusRuntimeMXBean.java, AsyncEventBusRuntimeRegistration.java, AsyncEventBusRuntimeRegistrator.java, AutoCloseableServiceInterface.java, BgpListenerImplModule.java, BgpListenerImplModuleFactory.java, BgpListenerImplModuleMXBean.java, BgpListenerImplRuntimeMXBean.java, BgpListenerImplRuntimeRegistration.java, BgpListenerImplRuntimeRegistrator.java, ComplexDtoBInner.java, ComplexList.java, Deep.java, DtoA.java, DtoA.java, DtoA.java, DtoA1.java, DtoAInner.java, DtoAInnerInner.java, DtoB.java, DtoC.java, DynamicThreadPoolModule.java, DynamicThreadPoolModuleFactory.java, DynamicThreadPoolModuleMXBean.java, DynamicThreadPoolRuntimeMXBean.java, DynamicThreadPoolRuntimeRegistration.java, DynamicThreadPoolRuntimeRegistrator.java, EventBusModule.java, EventBusModuleFactory.java, EventBusModuleMXBean.java, EventBusServiceInterface.java, EventRuntimeMXBean.java, EventRuntimeRegistration.java, InnerStreamList.java, NamingThreadFactoryModule.java, NamingThreadFactoryModuleFactory.java, NamingThreadFactoryModuleMXBean.java, NamingThreadFactoryRuntimeMXBean.java, NamingThreadFactoryRuntimeRegistration.java, NamingThreadFactoryRuntimeRegistrator.java, NetconfTestFileImplModule.java, NetconfTestFileImplModuleFactory.java, NetconfTestFileImplModuleMXBean.java, NetconfTestFileImplRuntimeMXBean.java, NetconfTestFileImplRuntimeRegistration.java, NetconfTestFileImplRuntimeRegistrator.java, NetconfTestFiles1ImplModule.java, NetconfTestFiles1ImplModuleFactory.java, NetconfTestFiles1ImplModuleMXBean.java, NetconfTestFiles1ImplRuntimeMXBean.java, NetconfTestFiles1ImplRuntimeRegistration.java, NetconfTestFiles1ImplRuntimeRegistrator.java, NetconfTestImplModule.java, NetconfTestImplModuleFactory.java, NetconfTestImplModuleMXBean.java, NetconfTestImplRuntimeMXBean.java, NetconfTestImplRuntimeRegistration.java, NetconfTestImplRuntimeRegistrator.java, Peer.java, Peer.java, PeersRuntimeMXBean.java, PeersRuntimeRegistration.java, ScheduledThreadPoolServiceInterface.java, SimpleList.java, StreamRuntimeMXBean.java, StreamRuntimeRegistration.java, TestFileImplModule.java, TestFileImplModuleFactory.java, TestFileImplModuleMXBean.java, TestFileImplRuntimeMXBean.java, TestFileImplRuntimeRegistration.java, TestFileImplRuntimeRegistrator.java, TestFiles1ImplModule.java, TestFiles1ImplModuleFactory.java, TestFiles1ImplModuleMXBean.java, TestFiles1ImplRuntimeMXBean.java, TestFiles1ImplRuntimeRegistration.java, TestFiles1ImplRuntimeRegistrator.java, TestImplModule.java, TestImplModuleFactory.java, TestImplModuleMXBean.java, TestImplRuntimeMXBean.java, TestImplRuntimeRegistration.java, TestImplRuntimeRegistrator.java, ThreadFactoryServiceInterface.java, ThreadPoolRegistryImplModule.java, ThreadPoolRegistryImplModuleFactory.java, ThreadPoolRegistryImplModuleMXBean.java, ThreadPoolServiceInterface.java, ThreadRuntimeMXBean.java, ThreadRuntimeRegistration.java, ThreadStreamRuntimeMXBean.java, ThreadStreamRuntimeRegistration.java]");
+            .toFileNames("[AbstractAsyncEventBusModule.java, AbstractAsyncEventBusModuleFactory.java, AbstractBgpListenerImplModule.java, AbstractBgpListenerImplModuleFactory.java, AbstractDynamicThreadPoolModule.java, AbstractDynamicThreadPoolModuleFactory.java, AbstractEventBusModule.java, AbstractEventBusModuleFactory.java, AbstractNamingThreadFactoryModule.java, AbstractNamingThreadFactoryModuleFactory.java, AbstractNetconfTestFileImplModule.java, AbstractNetconfTestFileImplModuleFactory.java, AbstractNetconfTestFiles1ImplModule.java, AbstractNetconfTestFiles1ImplModuleFactory.java, AbstractNetconfTestImplModule.java, AbstractNetconfTestImplModuleFactory.java, AbstractTestFileImplModule.java, AbstractTestFileImplModuleFactory.java, AbstractTestFiles1ImplModule.java, AbstractTestFiles1ImplModuleFactory.java, AbstractTestImplModule.java, AbstractTestImplModuleFactory.java, AbstractThreadPoolRegistryImplModule.java, AbstractThreadPoolRegistryImplModuleFactory.java, AsyncEventBusModule.java, AsyncEventBusModuleFactory.java, AsyncEventBusModuleMXBean.java, AsyncEventBusRuntimeMXBean.java, AsyncEventBusRuntimeRegistration.java, AsyncEventBusRuntimeRegistrator.java, AutoCloseableServiceInterface.java, BgpListenerImplModule.java, BgpListenerImplModuleFactory.java, BgpListenerImplModuleMXBean.java, BgpListenerImplRuntimeMXBean.java, BgpListenerImplRuntimeRegistration.java, BgpListenerImplRuntimeRegistrator.java, ComplexDtoBInner.java, ComplexList.java, Deep.java, DtoA.java, DtoA.java, DtoA.java, DtoA1.java, DtoAInner.java, DtoAInnerInner.java, DtoB.java, DtoC.java, DynamicThreadPoolModule.java, DynamicThreadPoolModuleFactory.java, DynamicThreadPoolModuleMXBean.java, DynamicThreadPoolRuntimeMXBean.java, DynamicThreadPoolRuntimeRegistration.java, DynamicThreadPoolRuntimeRegistrator.java, EventBusModule.java, EventBusModuleFactory.java, EventBusModuleMXBean.java, EventBusServiceInterface.java, EventRuntimeMXBean.java, EventRuntimeRegistration.java, FromGrouping.java, InnerStreamList.java, NamingThreadFactoryModule.java, NamingThreadFactoryModuleFactory.java, NamingThreadFactoryModuleMXBean.java, NamingThreadFactoryRuntimeMXBean.java, NamingThreadFactoryRuntimeRegistration.java, NamingThreadFactoryRuntimeRegistrator.java, NetconfTestFileImplModule.java, NetconfTestFileImplModuleFactory.java, NetconfTestFileImplModuleMXBean.java, NetconfTestFileImplRuntimeMXBean.java, NetconfTestFileImplRuntimeRegistration.java, NetconfTestFileImplRuntimeRegistrator.java, NetconfTestFiles1ImplModule.java, NetconfTestFiles1ImplModuleFactory.java, NetconfTestFiles1ImplModuleMXBean.java, NetconfTestFiles1ImplRuntimeMXBean.java, NetconfTestFiles1ImplRuntimeRegistration.java, NetconfTestFiles1ImplRuntimeRegistrator.java, NetconfTestImplModule.java, NetconfTestImplModuleFactory.java, NetconfTestImplModuleMXBean.java, NetconfTestImplRuntimeMXBean.java, NetconfTestImplRuntimeRegistration.java, NetconfTestImplRuntimeRegistrator.java, Peer.java, Peer.java, PeersRuntimeMXBean.java, PeersRuntimeRegistration.java, ScheduledThreadPoolServiceInterface.java, SimpleList.java, StreamRuntimeMXBean.java, StreamRuntimeRegistration.java, TestFileImplModule.java, TestFileImplModuleFactory.java, TestFileImplModuleMXBean.java, TestFileImplRuntimeMXBean.java, TestFileImplRuntimeRegistration.java, TestFileImplRuntimeRegistrator.java, TestFiles1ImplModule.java, TestFiles1ImplModuleFactory.java, TestFiles1ImplModuleMXBean.java, TestFiles1ImplRuntimeMXBean.java, TestFiles1ImplRuntimeRegistration.java, TestFiles1ImplRuntimeRegistrator.java, TestImplModule.java, TestImplModuleFactory.java, TestImplModuleMXBean.java, TestImplRuntimeMXBean.java, TestImplRuntimeRegistration.java, TestImplRuntimeRegistrator.java, ThreadFactoryServiceInterface.java, ThreadPoolRegistryImplModule.java, ThreadPoolRegistryImplModuleFactory.java, ThreadPoolRegistryImplModuleMXBean.java, ThreadPoolServiceInterface.java, ThreadRuntimeMXBean.java, ThreadRuntimeRegistration.java, ThreadStreamRuntimeMXBean.java, ThreadStreamRuntimeRegistration.java]");
     private static final List<String> expectedGenerateMBEsListNames = ServiceInterfaceEntryTest
             .toFileNames("[AbstractBgpListenerImplModule.java, AbstractBgpListenerImplModuleFactory.java, BgpListenerImplModule.java, BgpListenerImplModuleFactory.java, BgpListenerImplModuleMXBean.java, BgpListenerImplRuntimeMXBean.java, BgpListenerImplRuntimeRegistration.java, BgpListenerImplRuntimeRegistrator.java, PeersRuntimeMXBean.java, PeersRuntimeRegistration.java]");
 
@@ -506,8 +505,9 @@ public class JMXGeneratorTest extends AbstractGeneratorTest {
                 + ".threads.java", visitor.packageName);
         assertEquals("AsyncEventBusModuleMXBean", visitor.type);
 
-        assertEquals("Incorrenct number of generated methods", 2,
+        assertEquals("Incorrenct number of generated methods", 4,
                 visitor.methods.size());
+
     }
 
     private void assertAbstractDynamicThreadPoolModule(MbeASTVisitor visitor) {
index ae064001956b9217fcfc1e950309ff514d17ddf6..775fa9fc20d97b10a48859703a4572f03b65d2ca 100644 (file)
@@ -7,11 +7,6 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator;
 
-import java.net.URI;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
 import org.opendaylight.yangtools.yang.common.QName;
 
 public class ConfigConstants {
@@ -33,33 +28,14 @@ public class ConfigConstants {
     public static final QName RPC_CONTEXT_REF_GROUPING_LEAF = createRpcXQName("context-instance");
     public static final QName RPC_CONTEXT_INSTANCE_EXTENSION_QNAME = createRpcXQName("rpc-context-instance");
 
-    public static QName createConfigQName(String localName) {
-        return createQName(CONFIG_NAMESPACE, "2013-04-05", localName);
+    public static QName createConfigQName(final String localName) {
+        // FIXME: pre-construct QNameModule
+        return QName.create(CONFIG_NAMESPACE, "2013-04-05", localName);
     }
 
-    public static QName createRpcXQName(String localName) {
-        return createQName("urn:ietf:params:xml:ns:yang:rpc-context",
+    public static QName createRpcXQName(final String localName) {
+        // FIXME: pre-construct QNameModule
+        return QName.create("urn:ietf:params:xml:ns:yang:rpc-context",
                 "2013-06-17", localName);
     }
-
-    /**
-     *
-     * @param uri
-     * @param revisionDate
-     *            in format yyyy-MM-dd
-     * @param localName
-     * @return
-     */
-    private static QName createQName(String uri, String revisionDate,
-            String localName) {
-        SimpleDateFormat revisionFormat = new SimpleDateFormat("yyyy-MM-dd");
-        Date revision;
-        try {
-            revision = revisionFormat.parse(revisionDate);
-        } catch (ParseException e) {
-            throw new RuntimeException(e);
-        }
-        return new QName(URI.create(uri), revision, localName);
-    }
-
 }
index 89f3a4a51923a3f126f09b50af7e0d14b7af62a3..e9f0ac817675d90a9c9257456d0f9c03c7106719 100644 (file)
@@ -18,6 +18,7 @@ import com.google.common.base.Optional;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
+
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -26,7 +27,9 @@ import java.util.Objects;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+
 import javax.annotation.Nullable;
+
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute;
@@ -35,6 +38,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.config.yangjmxgenerator.plugin.util.NameConflictException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.ServiceRef;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
@@ -64,27 +68,27 @@ final class ModuleMXBeanEntryBuilder {
     private TypeProviderWrapper typeProviderWrapper;
     private String packageName;
 
-    public ModuleMXBeanEntryBuilder setModule(Module module) {
+    public ModuleMXBeanEntryBuilder setModule(final Module module) {
         this.currentModule = module;
         return this;
     }
 
-    public ModuleMXBeanEntryBuilder setqNamesToSIEs(Map<QName, ServiceInterfaceEntry> qNamesToSIEs) {
+    public ModuleMXBeanEntryBuilder setqNamesToSIEs(final Map<QName, ServiceInterfaceEntry> qNamesToSIEs) {
         this.qNamesToSIEs = qNamesToSIEs;
         return this;
     }
 
-    public ModuleMXBeanEntryBuilder setSchemaContext(SchemaContext schemaContext) {
+    public ModuleMXBeanEntryBuilder setSchemaContext(final SchemaContext schemaContext) {
         this.schemaContext = schemaContext;
         return this;
     }
 
-    public ModuleMXBeanEntryBuilder setTypeProviderWrapper(TypeProviderWrapper typeProviderWrapper) {
+    public ModuleMXBeanEntryBuilder setTypeProviderWrapper(final TypeProviderWrapper typeProviderWrapper) {
         this.typeProviderWrapper = typeProviderWrapper;
         return this;
     }
 
-    public ModuleMXBeanEntryBuilder setPackageName(String packageName) {
+    public ModuleMXBeanEntryBuilder setPackageName(final String packageName) {
         this.packageName = packageName;
         return this;
     }
@@ -127,7 +131,7 @@ final class ModuleMXBeanEntryBuilder {
         Map<String, ModuleMXBeanEntry> result = new HashMap<>();
 
         for (AugmentationSchema augmentation : currentModule.getAugmentations()) {
-            Set<DataSchemaNode> childNodes = augmentation.getChildNodes();
+            Collection<DataSchemaNode> childNodes = augmentation.getChildNodes();
             if (areAllChildrenChoiceCaseNodes(childNodes)) {
                 for (ChoiceCaseNode childCase : castChildNodesToChoiceCases(childNodes)) {
                     // TODO refactor, extract to standalone builder class
@@ -147,7 +151,7 @@ final class ModuleMXBeanEntryBuilder {
         return result;
     }
 
-    private static void cleanUpNulls(Map<String, ModuleMXBeanEntry> result) {
+    private static void cleanUpNulls(final Map<String, ModuleMXBeanEntry> result) {
         for (Map.Entry<String, ModuleMXBeanEntry> entry : result.entrySet()) {
             ModuleMXBeanEntry module = entry.getValue();
             if (module.getAttributes() == null) {
@@ -160,14 +164,14 @@ final class ModuleMXBeanEntryBuilder {
         }
     }
 
-    private static void checkUnaugumentedIdentities(Map<String, IdentitySchemaNode> unaugmentedModuleIdentities) {
+    private static void checkUnaugumentedIdentities(final Map<String, IdentitySchemaNode> unaugmentedModuleIdentities) {
         if (unaugmentedModuleIdentities.size() > 0) {
             logger.warn("Augmentation not found for all currentModule identities: {}",
                     unaugmentedModuleIdentities.keySet());
         }
     }
 
-    private static void checkAttributeNamesUniqueness(Map<String, QName> uniqueGeneratedClassesNames, Map<String, ModuleMXBeanEntry> result) {
+    private static void checkAttributeNamesUniqueness(final Map<String, QName> uniqueGeneratedClassesNames, final Map<String, ModuleMXBeanEntry> result) {
         for (Map.Entry<String, ModuleMXBeanEntry> entry : result.entrySet()) {
             checkUniqueRuntimeBeanAttributesName(entry.getValue(),
                     uniqueGeneratedClassesNames);
@@ -212,29 +216,30 @@ final class ModuleMXBeanEntryBuilder {
         return moduleIdentities;
     }
 
-    private Collection<ChoiceCaseNode> castChildNodesToChoiceCases(Set<DataSchemaNode> childNodes) {
+    private Collection<ChoiceCaseNode> castChildNodesToChoiceCases(final Collection<DataSchemaNode> childNodes) {
         return Collections2.transform(childNodes, new Function<DataSchemaNode, ChoiceCaseNode>() {
             @Nullable
             @Override
-            public ChoiceCaseNode apply(@Nullable DataSchemaNode input) {
+            public ChoiceCaseNode apply(@Nullable final DataSchemaNode input) {
                 return (ChoiceCaseNode) input;
             }
         });
     }
 
-    private boolean areAllChildrenChoiceCaseNodes(Set<DataSchemaNode> childNodes) {
+    private boolean areAllChildrenChoiceCaseNodes(final Iterable<DataSchemaNode> childNodes) {
         for (DataSchemaNode childNode : childNodes) {
-            if (childNode instanceof ChoiceCaseNode == false)
+            if (childNode instanceof ChoiceCaseNode == false) {
                 return false;
+            }
         }
         return true;
     }
 
-    private <HAS_CHILDREN_AND_QNAME extends DataNodeContainer & SchemaNode> void processChoiceCaseNode(Map<String, ModuleMXBeanEntry> result,
-            Map<String, QName> uniqueGeneratedClassesNames, String configModulePrefix,
-            Map<String, IdentitySchemaNode> moduleIdentities,
-            Map<String, IdentitySchemaNode> unaugmentedModuleIdentities, AugmentationSchema augmentation,
-            DataSchemaNode when) {
+    private <HAS_CHILDREN_AND_QNAME extends DataNodeContainer & SchemaNode> void processChoiceCaseNode(final Map<String, ModuleMXBeanEntry> result,
+            final Map<String, QName> uniqueGeneratedClassesNames, final String configModulePrefix,
+            final Map<String, IdentitySchemaNode> moduleIdentities,
+            final Map<String, IdentitySchemaNode> unaugmentedModuleIdentities, final AugmentationSchema augmentation,
+            final DataSchemaNode when) {
 
         ChoiceCaseNode choiceCaseNode = (ChoiceCaseNode) when;
         if (choiceCaseNode.getConstraints() == null || choiceCaseNode.getConstraints().getWhenCondition() == null) {
@@ -301,12 +306,12 @@ final class ModuleMXBeanEntryBuilder {
             }
             checkState(Objects.equals(nullableDummyContainerName, moduleMXBeanEntry.getNullableDummyContainerName()),
                     "Mismatch in module " + moduleMXBeanEntry.toString() + " - dummy container must be present/missing in" +
-                            " both state and configuration");
+                    " both state and configuration");
         } else {
             ModuleMXBeanEntry.ModuleMXBeanEntryInitial initial = new ModuleMXBeanEntry.ModuleMXBeanEntryInitialBuilder()
-                    .setIdSchemaNode(moduleIdentity).setPackageName(packageName).setJavaNamePrefix(javaNamePrefix)
-                    .setNamespace(currentModule.getNamespace().toString()).setqName(ModuleUtil.getQName(currentModule))
-                    .build();
+            .setIdSchemaNode(moduleIdentity).setPackageName(packageName).setJavaNamePrefix(javaNamePrefix)
+            .setNamespace(currentModule.getNamespace().toString()).setqName(ModuleUtil.getQName(currentModule))
+            .build();
 
             // construct ModuleMXBeanEntry
             ModuleMXBeanEntry moduleMXBeanEntry = new ModuleMXBeanEntry(initial, yangToAttributes, providedServices,
@@ -319,8 +324,8 @@ final class ModuleMXBeanEntryBuilder {
         }
     }
 
-    private void checkUniqueRuntimeBeansGeneratedClasses(Map<String, QName> uniqueGeneratedClassesNames,
-            DataSchemaNode when, Collection<RuntimeBeanEntry> runtimeBeans) {
+    private void checkUniqueRuntimeBeansGeneratedClasses(final Map<String, QName> uniqueGeneratedClassesNames,
+            final DataSchemaNode when, final Collection<RuntimeBeanEntry> runtimeBeans) {
         for (RuntimeBeanEntry runtimeBean : runtimeBeans) {
             final String javaNameOfRuntimeMXBean = runtimeBean.getJavaNameOfRuntimeMXBean();
             if (uniqueGeneratedClassesNames.containsKey(javaNameOfRuntimeMXBean)) {
@@ -331,8 +336,8 @@ final class ModuleMXBeanEntryBuilder {
         }
     }
 
-    private static void checkUniqueRuntimeBeanAttributesName(ModuleMXBeanEntry mxBeanEntry,
-            Map<String, QName> uniqueGeneratedClassesNames) {
+    private static void checkUniqueRuntimeBeanAttributesName(final ModuleMXBeanEntry mxBeanEntry,
+            final Map<String, QName> uniqueGeneratedClassesNames) {
         for (RuntimeBeanEntry runtimeBeanEntry : mxBeanEntry.getRuntimeBeans()) {
             for (String runtimeAttName : runtimeBeanEntry.getYangPropertiesToTypesMap().keySet()) {
                 if (mxBeanEntry.getAttributes().keySet().contains(runtimeAttName)) {
@@ -344,8 +349,8 @@ final class ModuleMXBeanEntryBuilder {
         }
     }
 
-    private void checkUniqueAttributesWithGeneratedClass(Map<String, QName> uniqueGeneratedClassNames,
-            QName parentQName, Map<String, AttributeIfc> yangToAttributes) {
+    private void checkUniqueAttributesWithGeneratedClass(final Map<String, QName> uniqueGeneratedClassNames,
+            final QName parentQName, final Map<String, AttributeIfc> yangToAttributes) {
         for (Map.Entry<String, AttributeIfc> attr : yangToAttributes.entrySet()) {
             if (attr.getValue() instanceof TOAttribute) {
                 checkUniqueTOAttr(uniqueGeneratedClassNames, parentQName, (TOAttribute) attr.getValue());
@@ -357,7 +362,7 @@ final class ModuleMXBeanEntryBuilder {
         }
     }
 
-    private void checkUniqueTOAttr(Map<String, QName> uniqueGeneratedClassNames, QName parentQName, TOAttribute attr) {
+    private void checkUniqueTOAttr(final Map<String, QName> uniqueGeneratedClassNames, final QName parentQName, final TOAttribute attr) {
         final String upperCaseCamelCase = attr.getUpperCaseCammelCase();
         if (uniqueGeneratedClassNames.containsKey(upperCaseCamelCase)) {
             QName firstDefinedQName = uniqueGeneratedClassNames.get(upperCaseCamelCase);
@@ -367,9 +372,9 @@ final class ModuleMXBeanEntryBuilder {
         }
     }
 
-    private Collection<RuntimeBeanEntry> fillRuntimeBeans(DataNodeContainer dataNodeContainer, Module currentModule,
-            TypeProviderWrapper typeProviderWrapper, String packageName, String moduleLocalNameFromXPath,
-            String javaNamePrefix) {
+    private Collection<RuntimeBeanEntry> fillRuntimeBeans(final DataNodeContainer dataNodeContainer, final Module currentModule,
+            final TypeProviderWrapper typeProviderWrapper, final String packageName, final String moduleLocalNameFromXPath,
+            final String javaNamePrefix) {
 
         return RuntimeBeanEntry.extractClassNameToRuntimeBeanMap(packageName, dataNodeContainer, moduleLocalNameFromXPath,
                 typeProviderWrapper, javaNamePrefix, currentModule).values();
@@ -383,8 +388,8 @@ final class ModuleMXBeanEntryBuilder {
      * @param choiceCaseNode state or configuration case statement
      * @return either choiceCaseNode or its only child container
      */
-    private <HAS_CHILDREN_AND_QNAME extends DataNodeContainer & SchemaNode> HAS_CHILDREN_AND_QNAME getDataNodeContainer(ChoiceCaseNode choiceCaseNode) {
-        Set<DataSchemaNode> childNodes = choiceCaseNode.getChildNodes();
+    private <HAS_CHILDREN_AND_QNAME extends DataNodeContainer & SchemaNode> HAS_CHILDREN_AND_QNAME getDataNodeContainer(final ChoiceCaseNode choiceCaseNode) {
+        Collection<DataSchemaNode> childNodes = choiceCaseNode.getChildNodes();
         if (childNodes.size() == 1) {
             DataSchemaNode onlyChild = childNodes.iterator().next();
             if (onlyChild instanceof ContainerSchemaNode) {
@@ -398,12 +403,11 @@ final class ModuleMXBeanEntryBuilder {
         return (HAS_CHILDREN_AND_QNAME) choiceCaseNode;
     }
 
-    private Map<String, AttributeIfc> fillConfiguration(DataNodeContainer dataNodeContainer, Module currentModule,
-            TypeProviderWrapper typeProviderWrapper, Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
-            SchemaContext schemaContext, String packageName) {
+    private Map<String, AttributeIfc> fillConfiguration(final DataNodeContainer dataNodeContainer, final Module currentModule,
+            final TypeProviderWrapper typeProviderWrapper, final Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
+            final SchemaContext schemaContext, final String packageName) {
         Map<String, AttributeIfc> yangToAttributes = new HashMap<>();
-        Set<DataSchemaNode> childNodes = dataNodeContainer.getChildNodes();
-        for (DataSchemaNode attrNode : childNodes) {
+        for (DataSchemaNode attrNode : dataNodeContainer.getChildNodes()) {
             AttributeIfc attributeValue = getAttributeValue(attrNode, currentModule, qNamesToSIEs, typeProviderWrapper,
                     schemaContext, packageName);
             yangToAttributes.put(attributeValue.getAttributeYangName(), attributeValue);
@@ -411,8 +415,8 @@ final class ModuleMXBeanEntryBuilder {
         return yangToAttributes;
     }
 
-    private Map<String, QName> findProvidedServices(IdentitySchemaNode moduleIdentity, Module currentModule,
-            Map<QName, ServiceInterfaceEntry> qNamesToSIEs, SchemaContext schemaContext) {
+    private Map<String, QName> findProvidedServices(final IdentitySchemaNode moduleIdentity, final Module currentModule,
+            final Map<QName, ServiceInterfaceEntry> qNamesToSIEs, final SchemaContext schemaContext) {
         Map<String, QName> result = new HashMap<>();
         for (UnknownSchemaNode unknownNode : moduleIdentity.getUnknownSchemaNodes()) {
             if (ConfigConstants.PROVIDED_SERVICE_EXTENSION_QNAME.equals(unknownNode.getNodeType())) {
@@ -425,9 +429,9 @@ final class ModuleMXBeanEntryBuilder {
         return result;
     }
 
-    private AttributeIfc getAttributeValue(DataSchemaNode attrNode, Module currentModule,
-            Map<QName, ServiceInterfaceEntry> qNamesToSIEs, TypeProviderWrapper typeProviderWrapper,
-            SchemaContext schemaContext, String packageName) {
+    private AttributeIfc getAttributeValue(final DataSchemaNode attrNode, final Module currentModule,
+            final Map<QName, ServiceInterfaceEntry> qNamesToSIEs, final TypeProviderWrapper typeProviderWrapper,
+            final SchemaContext schemaContext, final String packageName) {
 
         if (attrNode instanceof LeafSchemaNode) {
             // simple type
@@ -460,10 +464,10 @@ final class ModuleMXBeanEntryBuilder {
         }
     }
 
-    private Optional<? extends AbstractDependencyAttribute> extractDependency(DataNodeContainer dataNodeContainer,
-            DataSchemaNode attrNode, Module currentModule, Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
-            SchemaContext schemaContext) {
-        if (dataNodeContainer.getUses().size() == 1 && getChildNodeSizeWithoutUses(dataNodeContainer) == 0) {
+    private Optional<? extends AbstractDependencyAttribute> extractDependency(final DataNodeContainer dataNodeContainer,
+            final DataSchemaNode attrNode, final Module currentModule, final Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
+            final SchemaContext schemaContext) {
+        if (isDependencyContainer(dataNodeContainer)) {
             // reference
             UsesNode usesNode = dataNodeContainer.getUses().iterator().next();
             checkState(usesNode.getRefines().size() == 1, "Unexpected 'refine' child node size of " + dataNodeContainer);
@@ -490,7 +494,19 @@ final class ModuleMXBeanEntryBuilder {
         return Optional.absent();
     }
 
-    private int getChildNodeSizeWithoutUses(DataNodeContainer csn) {
+    private boolean isDependencyContainer(final DataNodeContainer dataNodeContainer) {
+        if(dataNodeContainer.getUses().size() != 1) {
+            return false;
+        }
+        UsesNode onlyUses = dataNodeContainer.getUses().iterator().next();
+        if(onlyUses.getGroupingPath().getLastComponent().equals(ServiceRef.QNAME) == false) {
+            return false;
+        }
+
+        return getChildNodeSizeWithoutUses(dataNodeContainer) == 0;
+    }
+
+    private int getChildNodeSizeWithoutUses(final DataNodeContainer csn) {
         int result = 0;
         for (DataSchemaNode dsn : csn.getChildNodes()) {
             if (dsn.isAddedByUses() == false) {
@@ -500,8 +516,8 @@ final class ModuleMXBeanEntryBuilder {
         return result;
     }
 
-    private ServiceInterfaceEntry findSIE(String prefixAndIdentityLocalName, Module currentModule,
-            Map<QName, ServiceInterfaceEntry> qNamesToSIEs, SchemaContext schemaContext) {
+    private ServiceInterfaceEntry findSIE(final String prefixAndIdentityLocalName, final Module currentModule,
+            final Map<QName, ServiceInterfaceEntry> qNamesToSIEs, final SchemaContext schemaContext) {
 
         Matcher m = PREFIX_COLON_LOCAL_NAME.matcher(prefixAndIdentityLocalName);
         Module foundModule;
@@ -518,13 +534,13 @@ final class ModuleMXBeanEntryBuilder {
             foundModule = currentModule; // no prefix => SIE is in currentModule
             localSIName = prefixAndIdentityLocalName;
         }
-        QName siQName = new QName(foundModule.getNamespace(), foundModule.getRevision(), localSIName);
+        QName siQName = QName.create(foundModule.getNamespace(), foundModule.getRevision(), localSIName);
         ServiceInterfaceEntry sie = qNamesToSIEs.get(siQName);
         checkState(sie != null, "Cannot find referenced Service Interface by " + prefixAndIdentityLocalName);
         return sie;
     }
 
-    private ModuleImport findModuleImport(Module module, String prefix) {
+    private ModuleImport findModuleImport(final Module module, final String prefix) {
         for (ModuleImport moduleImport : module.getImports()) {
             if (moduleImport.getPrefix().equals(prefix)) {
                 return moduleImport;
@@ -534,13 +550,13 @@ final class ModuleMXBeanEntryBuilder {
     }
 
     @VisibleForTesting
-    static Matcher getWhenConditionMatcher(String prefix, RevisionAwareXPath whenConstraint) {
+    static Matcher getWhenConditionMatcher(final String prefix, final RevisionAwareXPath whenConstraint) {
         String xpathRegex = MODULE_CONDITION_XPATH_TEMPLATE.replace(MAGIC_STRING, prefix);
         Pattern pattern = Pattern.compile(xpathRegex);
         return pattern.matcher(whenConstraint.toString());
     }
 
-    String getConfigModulePrefixFromImport(Module currentModule) {
+    String getConfigModulePrefixFromImport(final Module currentModule) {
         for (ModuleImport currentImport : currentModule.getImports()) {
             if (currentImport.getModuleName().equals(ConfigConstants.CONFIG_MODULE)) {
                 return currentImport.getPrefix();
index 5fea8fd078dfbbd95ead79b2610eb16e7bf0a4fe..ccd701d1fb36a2bba58093999a21aa23c7ac5c08 100644 (file)
@@ -12,7 +12,7 @@ import org.opendaylight.yangtools.yang.model.api.Module;
 
 public class ModuleUtil {
 
-    public static QName getQName(Module currentModule){
-        return new QName(currentModule.getNamespace(), currentModule.getRevision(), currentModule.getName());
+    public static QName getQName(final Module currentModule) {
+        return QName.create(currentModule.getNamespace(), currentModule.getRevision(), currentModule.getName());
     }
 }
index c941d1504ddae409a9fdfa0c14ec4da957d1038e..67f624175b00aacff88369aa8fce5fe00ce5a961 100644 (file)
@@ -13,6 +13,7 @@ import static com.google.common.base.Preconditions.checkState;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -25,6 +26,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
+
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
@@ -65,11 +67,11 @@ public class RuntimeBeanEntry {
     private final Set<Rpc> rpcs;
 
     @VisibleForTesting
-    RuntimeBeanEntry(String packageName,
-            DataNodeContainer nodeForReporting, String yangName,
-            String javaNamePrefix, boolean isRoot,
-            Optional<String> keyYangName, List<AttributeIfc> attributes,
-            List<RuntimeBeanEntry> children, Set<Rpc> rpcs) {
+    RuntimeBeanEntry(final String packageName,
+            final DataNodeContainer nodeForReporting, final String yangName,
+            final String javaNamePrefix, final boolean isRoot,
+            final Optional<String> keyYangName, final List<AttributeIfc> attributes,
+            final List<RuntimeBeanEntry> children, final Set<Rpc> rpcs) {
 
         checkArgument(isRoot == false || keyYangName.isPresent() == false,
                 "Root RuntimeBeanEntry must not have key " + "set");
@@ -86,7 +88,7 @@ public class RuntimeBeanEntry {
         for (AttributeIfc a : attributes) {
             checkState(map.containsKey(a.getAttributeYangName()) == false,
                     "Attribute already defined: " + a.getAttributeYangName()
-                            + " in " + nodeForReporting);
+                    + " in " + nodeForReporting);
             map.put(a.getAttributeYangName(), a);
         }
 
@@ -110,9 +112,9 @@ public class RuntimeBeanEntry {
      *         not contain special configuration for it.
      */
     public static Map<String, RuntimeBeanEntry> extractClassNameToRuntimeBeanMap(
-            String packageName, DataNodeContainer container,
-            String moduleYangName, TypeProviderWrapper typeProviderWrapper,
-            String javaNamePrefix, Module currentModule) {
+            final String packageName, final DataNodeContainer container,
+            final String moduleYangName, final TypeProviderWrapper typeProviderWrapper,
+            final String javaNamePrefix, final Module currentModule) {
 
         Map<QName, Set<RpcDefinition>> identitiesToRpcs = getIdentitiesToRpcs(currentModule);
 
@@ -151,7 +153,7 @@ public class RuntimeBeanEntry {
     }
 
     private static Map<QName/* of identity */, Set<RpcDefinition>> getIdentitiesToRpcs(
-            Module currentModule) {
+            final Module currentModule) {
         // currently only looks for local identities (found in currentModule)
         Map<QName, Set<RpcDefinition>> result = new HashMap<>();
         for (IdentitySchemaNode identity : currentModule.getIdentities()) {
@@ -164,14 +166,16 @@ public class RuntimeBeanEntry {
             if (input != null) {
                 for (UsesNode uses : input.getUses()) {
 
-                    if (uses.getGroupingPath().getPath().size() != 1)
+                    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))
+                            .equals(ConfigConstants.RPC_CONTEXT_REF_GROUPING_QNAME)) {
                         continue;
+                    }
 
                     for (SchemaNode refinedNode : uses.getRefines().values()) {
 
@@ -181,7 +185,7 @@ public class RuntimeBeanEntry {
                                     .equals(unknownSchemaNode.getNodeType())) {
                                 String localIdentityName = unknownSchemaNode
                                         .getNodeParameter();
-                                QName identityQName = new QName(
+                                QName identityQName = QName.create(
                                         currentModule.getNamespace(),
                                         currentModule.getRevision(),
                                         localIdentityName);
@@ -208,9 +212,9 @@ public class RuntimeBeanEntry {
      * in subtree.
      */
     private static AttributesRpcsAndRuntimeBeans extractSubtree(
-            String packageName, DataNodeContainer subtree,
-            TypeProviderWrapper typeProviderWrapper, Module currentModule,
-            Map<QName, Set<RpcDefinition>> identitiesToRpcs) {
+            final String packageName, final DataNodeContainer subtree,
+            final TypeProviderWrapper typeProviderWrapper, final Module currentModule,
+            final Map<QName, Set<RpcDefinition>> identitiesToRpcs) {
 
         List<AttributeIfc> attributes = Lists.newArrayList();
         // List<JavaAttribute> javaAttributes = new ArrayList<>();
@@ -258,7 +262,7 @@ public class RuntimeBeanEntry {
             if (ConfigConstants.RPC_CONTEXT_INSTANCE_EXTENSION_QNAME
                     .equals(unknownSchemaNode.getNodeType())) {
                 String localIdentityName = unknownSchemaNode.getNodeParameter();
-                QName identityQName = new QName(currentModule.getNamespace(),
+                QName identityQName = QName.create(currentModule.getNamespace(),
                         currentModule.getRevision(), localIdentityName);
                 Set<RpcDefinition> rpcDefinitions = identitiesToRpcs
                         .get(identityQName);
@@ -290,8 +294,8 @@ public class RuntimeBeanEntry {
                     for (DataSchemaNode childNode : sortAttributes(rpcDefinition.getInput()
                             .getChildNodes())) {
                         if (childNode.isAddedByUses() == false) { // skip
-                                                                  // refined
-                                                                  // context-instance
+                            // refined
+                            // context-instance
                             checkArgument(childNode instanceof LeafSchemaNode, "Unexpected type of rpc input type. "
                                     + "Currently only leafs and empty output nodes are supported, got " + childNode);
                             JavaAttribute javaAttribute = new JavaAttribute(
@@ -310,8 +314,8 @@ public class RuntimeBeanEntry {
                 attributes, rpcs);
     }
 
-    private static AttributeIfc getReturnTypeAttribute(DataSchemaNode child, TypeProviderWrapper typeProviderWrapper,
-                                                       String packageName) {
+    private static AttributeIfc getReturnTypeAttribute(final DataSchemaNode child, final TypeProviderWrapper typeProviderWrapper,
+            final String packageName) {
         if (child instanceof LeafSchemaNode) {
             LeafSchemaNode leaf = (LeafSchemaNode) child;
             return new JavaAttribute(leaf, typeProviderWrapper);
@@ -328,10 +332,10 @@ public class RuntimeBeanEntry {
         }
     }
 
-    private static Collection<DataSchemaNode> sortAttributes(Set<DataSchemaNode> childNodes) {
+    private static Collection<DataSchemaNode> sortAttributes(final Collection<DataSchemaNode> childNodes) {
         final TreeSet<DataSchemaNode> dataSchemaNodes = new TreeSet<>(new Comparator<DataSchemaNode>() {
             @Override
-            public int compare(DataSchemaNode o1, DataSchemaNode o2) {
+            public int compare(final DataSchemaNode o1, final DataSchemaNode o2) {
                 return o1.getQName().getLocalName().compareTo(o2.getQName().getLocalName());
             }
         });
@@ -339,20 +343,21 @@ public class RuntimeBeanEntry {
         return dataSchemaNodes;
     }
 
-    private static boolean isInnerStateBean(DataSchemaNode child) {
+    private static boolean isInnerStateBean(final DataSchemaNode child) {
         for (UnknownSchemaNode unknownSchemaNode : child
                 .getUnknownSchemaNodes()) {
             if (unknownSchemaNode.getNodeType().equals(
-                    ConfigConstants.INNER_STATE_BEAN_EXTENSION_QNAME))
+                    ConfigConstants.INNER_STATE_BEAN_EXTENSION_QNAME)) {
                 return true;
+            }
         }
         return false;
     }
 
-    private static RuntimeBeanEntry createHierarchical(String packageName,
-            ListSchemaNode listSchemaNode,
-            TypeProviderWrapper typeProviderWrapper, Module currentModule,
-            Map<QName, Set<RpcDefinition>> identitiesToRpcs) {
+    private static RuntimeBeanEntry createHierarchical(final String packageName,
+            final ListSchemaNode listSchemaNode,
+            final TypeProviderWrapper typeProviderWrapper, final Module currentModule,
+            final Map<QName, Set<RpcDefinition>> identitiesToRpcs) {
 
         // supported are numeric types, strings, enums
         // get all attributes
@@ -387,10 +392,10 @@ public class RuntimeBeanEntry {
         return rbFromAttributes;
     }
 
-    private static RuntimeBeanEntry createRoot(String packageName,
-            DataNodeContainer nodeForReporting, String attributeYangName,
-            List<AttributeIfc> attributes, String javaNamePrefix,
-            List<RuntimeBeanEntry> children, Set<Rpc> rpcs) {
+    private static RuntimeBeanEntry createRoot(final String packageName,
+            final DataNodeContainer nodeForReporting, final String attributeYangName,
+            final List<AttributeIfc> attributes, final String javaNamePrefix,
+            final List<RuntimeBeanEntry> children, final Set<Rpc> rpcs) {
         return new RuntimeBeanEntry(packageName, nodeForReporting,
                 attributeYangName, javaNamePrefix, true,
                 Optional.<String> absent(), attributes, children, rpcs);
@@ -442,8 +447,8 @@ public class RuntimeBeanEntry {
         private final Set<Rpc> rpcs;
 
         public AttributesRpcsAndRuntimeBeans(
-                List<RuntimeBeanEntry> runtimeBeanEntries,
-                List<AttributeIfc> attributes, Set<Rpc> rpcs) {
+                final List<RuntimeBeanEntry> runtimeBeanEntries,
+                final List<AttributeIfc> attributes, final Set<Rpc> rpcs) {
             this.runtimeBeanEntries = runtimeBeanEntries;
             this.attributes = attributes;
             this.rpcs = rpcs;
@@ -472,8 +477,8 @@ public class RuntimeBeanEntry {
         private final AttributeIfc returnType;
         private final String yangName;
 
-        Rpc(AttributeIfc returnType, String name, String yangName,
-                List<JavaAttribute> parameters) {
+        Rpc(final AttributeIfc returnType, final String name, final String yangName,
+                final List<JavaAttribute> parameters) {
             this.returnType = returnType;
             this.name = name;
             this.parameters = parameters;
@@ -503,12 +508,12 @@ public class RuntimeBeanEntry {
         return getJavaNameOfRuntimeMXBean(javaNamePrefix);
     }
 
-    public String getFullyQualifiedName(String typeName) {
+    public String getFullyQualifiedName(final String typeName) {
         return FullyQualifiedNameHelper.getFullyQualifiedName(packageName,
                 typeName);
     }
 
-    private static String getJavaNameOfRuntimeMXBean(String javaNamePrefix) {
+    private static String getJavaNameOfRuntimeMXBean(final String javaNamePrefix) {
         return javaNamePrefix + MXBEAN_SUFFIX;
     }
 
index dd44246867abb9af1e51bfe1bc5dbd8ea8c63f91..fab273c60093b529931e5f0ce4f02f9198327ff7 100644 (file)
@@ -7,7 +7,35 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator;
 
+import static org.hamcrest.CoreMatchers.is;
+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.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
 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.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+
+import javax.management.openmbean.ArrayType;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.SimpleType;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
@@ -25,32 +53,6 @@ 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;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.SimpleType;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-
-import static org.hamcrest.CoreMatchers.is;
-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.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
 public class ModuleMXBeanEntryTest extends AbstractYangTest {
 
     public static final String PACKAGE_NAME = "pack2";
@@ -95,7 +97,7 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
                 PACKAGE_NAME,identitiesToSIs));
         Map<String /* identity local name */, ModuleMXBeanEntry> namesToMBEs = ModuleMXBeanEntry
                 .create(jmxImplModule, modulesToSIEs, context, new TypeProviderWrapper(new TypeProviderImpl(context))
-                        , PACKAGE_NAME);
+                , PACKAGE_NAME);
         Map<String, AttributeIfc> attributes = namesToMBEs.get("impl-netconf")
                 .getAttributes();
 
@@ -120,7 +122,7 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
         assertThat(threadFactoryAttribute.getType().getName(), is("ObjectName"));
     }
 
-    private void assertCorrectAttributesSize(Map<String, ModuleMXBeanEntry> namesToMBEs, Map<String, AttributeIfc> attributes) {
+    private void assertCorrectAttributesSize(final Map<String, ModuleMXBeanEntry> namesToMBEs, final Map<String, AttributeIfc> attributes) {
         assertEquals(14, attributes.size());
         assertEquals(1, namesToMBEs.get("impl-netconf").getRuntimeBeans().size());
         assertEquals(2, namesToMBEs.get("impl-netconf").getRuntimeBeans().iterator().next().getAttributes().size());
@@ -131,10 +133,11 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
     }
 
     protected RuntimeBeanEntry findFirstByYangName(
-            Collection<RuntimeBeanEntry> runtimeBeans, String yangName) {
+            final Collection<RuntimeBeanEntry> runtimeBeans, final String yangName) {
         for (RuntimeBeanEntry rb : runtimeBeans) {
-            if (yangName.equals(rb.getYangName()))
+            if (yangName.equals(rb.getYangName())) {
                 return rb;
+            }
         }
         throw new IllegalArgumentException("Yang name not found:" + yangName
                 + " in " + runtimeBeans);
@@ -150,7 +153,7 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
                 "/config:modules/config:module/config:type=\"threadpool-dynamic\"");
     }
 
-    private void assertMatches(String prefix, String input) {
+    private void assertMatches(final String prefix, final String input) {
         RevisionAwareXPath whenConstraint = mock(RevisionAwareXPath.class);
         doReturn(input).when(whenConstraint).toString();
         Matcher output = ModuleMXBeanEntryBuilder.getWhenConditionMatcher(prefix,
@@ -181,7 +184,7 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
                         is((Type) Types.typeForClass(Long.class)));
             }
             // check dependency on thread factory
-            QName threadfactoryQName = new QName(THREADS_NAMESPACE,
+            QName threadfactoryQName = QName.create(THREADS_NAMESPACE,
                     THREADS_REVISION_DATE, "threadfactory");
             ServiceInterfaceEntry threadFactorySIEntry = modulesToSIEs
                     .get(threadfactoryQName);
@@ -192,7 +195,7 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
 
             DataSchemaNode mockedDataSchemaNode = mock(DataSchemaNode.class);
             doReturn(Collections.emptyList()).when(mockedDataSchemaNode)
-                    .getUnknownSchemaNodes();
+            .getUnknownSchemaNodes();
             doReturn(threadfactoryQName).when(mockedDataSchemaNode).getQName();
             AttributeIfc expectedDependencyAttribute = new DependencyAttribute(
                     mockedDataSchemaNode, threadFactorySIEntry,
@@ -200,7 +203,7 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
             assertThat(actualThreadFactory, is(expectedDependencyAttribute));
             assertThat(
                     dynamicThreadPool
-                            .getFullyQualifiedName("DynamicThreadPoolModuleMXBean"),
+                    .getFullyQualifiedName("DynamicThreadPoolModuleMXBean"),
                     is(PACKAGE_NAME + ".DynamicThreadPoolModuleMXBean"));
             assertThat(dynamicThreadPool.getNullableDescription(),
                     is("threadpool-dynamic description"));
index eed86951033bc5ec2aa5251e4f187ea0f0f3c1a9..f22edbf948f0ba93b77346cc0b55786fcc032ab5 100644 (file)
@@ -7,7 +7,12 @@
  */
 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;
@@ -20,13 +25,11 @@ 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 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";
@@ -53,15 +56,15 @@ public class ServiceInterfaceEntryTest extends AbstractYangTest {
         }
     }
 
-    public static final QName EVENTBUS_QNAME = new QName(THREADS_NAMESPACE,
+    public static final QName EVENTBUS_QNAME = QName.create(THREADS_NAMESPACE,
             THREADS_REVISION_DATE, "eventbus");
-    public static final QName THREADFACTORY_QNAME = new QName(
+    public static final QName THREADFACTORY_QNAME = QName.create(
             THREADS_NAMESPACE, THREADS_REVISION_DATE, "threadfactory");
-    public static final QName THREADPOOL_QNAME = new QName(THREADS_NAMESPACE,
+    public static final QName THREADPOOL_QNAME = QName.create(THREADS_NAMESPACE,
             THREADS_REVISION_DATE, "threadpool");
-    public static final QName SCHEDULED_THREADPOOL_QNAME = new QName(
+    public static final QName SCHEDULED_THREADPOOL_QNAME = QName.create(
             THREADS_NAMESPACE, THREADS_REVISION_DATE, "scheduled-threadpool");
-    public static final QName SCHEDULED_EXECUTOR_SERVICE_QNAME = new QName(
+    public static final QName SCHEDULED_EXECUTOR_SERVICE_QNAME = QName.create(
             THREADS_NAMESPACE, THREADS_REVISION_DATE,
             "scheduled-executor-service");
     public static final String SCHEDULED_THREADPOOL_INTERFACE_NAME = "ScheduledThreadPoolServiceInterface";
@@ -133,9 +136,10 @@ public class ServiceInterfaceEntryTest extends AbstractYangTest {
                 + SCHEDULED_THREADPOOL_INTERFACE_NAME));
     }
 
-    static String trimInnerSpacesOrNull(String input) {
-        if (input == null)
+    static String trimInnerSpacesOrNull(final String input) {
+        if (input == null) {
             return null;
+        }
         return input.replaceAll("\\s{2,}", " ");
     }
 }
index e189ef7d66c65b8bdfe9f905889797d84dbb5e36..a6d2feaf044bb2f9865ec322612eb624b4594ea1 100644 (file)
@@ -56,6 +56,12 @@ module config-threads-java {
         }
     }
 
+    grouping async-eventbus-config-attrs {
+        leaf cfg-attr {
+            type string;
+        }
+    }
+
     augment "/config:modules/config:module/config:configuration" {
         case async-eventbus {
             when "/config:modules/config:module/config:type = 'async-eventbus'";
@@ -66,6 +72,10 @@ module config-threads-java {
                     }
                 }
             }
+
+            container from-grouping {
+                uses async-eventbus-config-attrs;
+            }
         }
     }
     augment "/config:modules/config:module/config:state" {
diff --git a/opendaylight/config/yang-test/.gitignore b/opendaylight/config/yang-test/.gitignore
deleted file mode 100644 (file)
index 1439354..0000000
+++ /dev/null
@@ -1 +0,0 @@
-src/main/java/org/opendaylight/controller/config/yang/test/impl/*
diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/.gitignore b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/.gitignore
new file mode 100644 (file)
index 0000000..27d1535
--- /dev/null
@@ -0,0 +1 @@
+*.java
diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java
deleted file mode 100644 (file)
index 6046665..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.opendaylight.controller.config.yang.test.impl;
-public class DepTestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModule {
-    public DepTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
-        super(identifier, dependencyResolver);
-    }
-
-    public DepTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.test.impl.DepTestImplModule oldModule, java.lang.AutoCloseable oldInstance) {
-        super(identifier, dependencyResolver, oldModule, oldInstance);
-    }
-
-    @Override
-    public void customValidation() {
-        // add custom validation form module attributes here.
-    }
-
-    @Override
-    public java.lang.AutoCloseable createInstance() {
-        return new AutoCloseable() {
-            @Override
-            public void close() throws Exception {
-            }
-        };
-
-    }
-
-}
diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java
deleted file mode 100644 (file)
index 026dd9a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-package org.opendaylight.controller.config.yang.test.impl;
-public class DepTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModuleFactory {
-
-}
diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java
deleted file mode 100644 (file)
index bda3548..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.opendaylight.controller.config.yang.test.impl;
-public class IdentityTestModule extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModule {
-    public IdentityTestModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
-        super(identifier, dependencyResolver);
-    }
-
-    public IdentityTestModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.test.impl.IdentityTestModule oldModule, java.lang.AutoCloseable oldInstance) {
-        super(identifier, dependencyResolver, oldModule, oldInstance);
-    }
-
-    @Override
-    public void customValidation() {
-        // add custom validation form module attributes here.
-    }
-
-    @Override
-    public java.lang.AutoCloseable createInstance() {
-        org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(getClass());
-        logger.info("Afi: {}", getAfi());
-        logger.info("Afi class: {}", getAfiIdentity());
-
-        for (Identities identities : getIdentities()) {
-            logger.info("Identities Afi class: {}", identities.resolveAfi());
-            logger.info("Identities Safi class: {}", identities.resolveSafi());
-
-        }
-        logger.info("IdentityContainer Afi class: {}", getIdentitiesContainer().resolveAfi());
-
-        return new AutoCloseable() {
-            @Override
-            public void close() throws Exception {
-            }
-        };
-
-    }
-
-}
diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java
deleted file mode 100644 (file)
index 3a4348d..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-package org.opendaylight.controller.config.yang.test.impl;
-public class IdentityTestModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModuleFactory {
-
-}
diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/MultipleDependenciesModuleStub.txt b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/MultipleDependenciesModuleStub.txt
new file mode 100644 (file)
index 0000000..80c1e54
--- /dev/null
@@ -0,0 +1,5 @@
+        return new AutoCloseable() {
+            @Override
+            public void close() throws Exception {
+            }
+        };
diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java
deleted file mode 100644 (file)
index ab43dea..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.opendaylight.controller.config.yang.test.impl;
-public class NetconfTestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModule {
-    public NetconfTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
-        super(identifier, dependencyResolver);
-    }
-
-    public NetconfTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModule oldModule, java.lang.AutoCloseable oldInstance) {
-        super(identifier, dependencyResolver, oldModule, oldInstance);
-    }
-
-    @Override
-    public void customValidation() {
-        // add custom validation form module attributes here.
-    }
-
-    @Override
-    public java.lang.AutoCloseable createInstance() {
-return NetconfTestImplModuleUtil.registerRuntimeBeans(this);
-
-    }
-
-}
diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java
deleted file mode 100644 (file)
index 587089b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-package org.opendaylight.controller.config.yang.test.impl;
-public class NetconfTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModuleFactory {
-
-}
diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java
deleted file mode 100644 (file)
index 2880b46..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.opendaylight.controller.config.yang.test.impl;
-public class TestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModule {
-    public TestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
-        super(identifier, dependencyResolver);
-    }
-
-    public TestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.test.impl.TestImplModule oldModule, java.lang.AutoCloseable oldInstance) {
-        super(identifier, dependencyResolver, oldModule, oldInstance);
-    }
-
-    @Override
-    public void customValidation() {
-        // add custom validation form module attributes here.
-    }
-
-    @Override
-    public java.lang.AutoCloseable createInstance() {
-        return new AutoCloseable() {
-            @Override
-            public void close() throws Exception {
-            }
-        };
-
-    }
-
-}
diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java
deleted file mode 100644 (file)
index de9ac2f..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-package org.opendaylight.controller.config.yang.test.impl;
-public class TestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModuleFactory {
-
-}
@@ -1,13 +1,34 @@
 
 
-package org.opendaylight.controller.config.yang.test.impl;
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 
-import com.google.common.collect.Lists;
+package org.opendaylight.controller.config.yang.test.util;
 
+import com.google.common.collect.Lists;
 import java.util.List;
+import org.opendaylight.controller.config.yang.test.impl.Asdf;
+import org.opendaylight.controller.config.yang.test.impl.Deep2;
+import org.opendaylight.controller.config.yang.test.impl.Deep3;
+import org.opendaylight.controller.config.yang.test.impl.Deep4;
+import org.opendaylight.controller.config.yang.test.impl.InnerInnerRunningDataRuntimeMXBean;
+import org.opendaylight.controller.config.yang.test.impl.InnerRunningDataAdditionalRuntimeMXBean;
+import org.opendaylight.controller.config.yang.test.impl.InnerRunningDataRuntimeMXBean;
+import org.opendaylight.controller.config.yang.test.impl.InnerRunningDataRuntimeRegistration;
+import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModule;
+import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplRuntimeMXBean;
+import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplRuntimeRegistration;
+import org.opendaylight.controller.config.yang.test.impl.NotStateBean;
+import org.opendaylight.controller.config.yang.test.impl.RetValContainer;
+import org.opendaylight.controller.config.yang.test.impl.RetValList;
 
 public class NetconfTestImplModuleUtil {
-    static NetconfTestImplRuntimeRegistration registerRuntimeBeans(final NetconfTestImplModule module) {
+    public static NetconfTestImplRuntimeRegistration registerRuntimeBeans(final NetconfTestImplModule module) {
         NetconfTestImplRuntimeRegistration reg = module.getRootRuntimeBeanRegistratorWrapper().register(new NetconfTestImplRuntimeMXBean() {
 
             @Override
index 4b006bc72e52c3026130db4b556e62fd340523da..e7aa64d7a621cc5ecdfa4781c6389e576b7865c1 100644 (file)
@@ -41,6 +41,12 @@ module config-test-impl {
         config:java-name-prefix IdentityTest;
     }
 
+    identity multiple-dependencies {
+        base config:module-type;
+        config:provided-service test:testing;
+        config:java-name-prefix MultipleDependencies;
+    }
+
     augment "/config:modules/config:module/config:configuration" {
             case impl-identity-test {
                 when "/config:modules/config:module/config:type = 'impl-identity-test'";
@@ -444,6 +450,24 @@ module config-test-impl {
         }
     }
 
+
+    augment "/config:modules/config:module/config:configuration" {
+        case multiple-dependencies {
+            when "/config:modules/config:module/config:type = 'multiple-dependencies'";
+            container multiple-dependencies {
+                list testing-deps {
+                    uses config:service-ref {
+                        refine type {
+                            mandatory true;
+                            config:required-identity test:testing;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+
     identity test-rpc;
     identity inner-test-rpc;
     identity inner-inner-test-rpc;
diff --git a/opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/MultipleDependenciesModuleTest.java b/opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/MultipleDependenciesModuleTest.java
new file mode 100644 (file)
index 0000000..2df15d0
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yang.test.impl;
+
+import static java.util.Arrays.asList;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.opendaylight.controller.config.api.jmx.ObjectNameUtil.getInstanceName;
+import static org.opendaylight.controller.config.api.jmx.ObjectNameUtil.getTransactionName;
+
+import java.util.List;
+import javax.management.ObjectName;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+
+public class MultipleDependenciesModuleTest extends AbstractConfigTest {
+    private static final MultipleDependenciesModuleFactory factory = new MultipleDependenciesModuleFactory();
+
+    @Before
+    public void setUp() throws Exception {
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory));
+    }
+
+    @Test
+    public void testMultipleDependencies() throws Exception {
+        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+        ObjectName d1 = transaction.createModule(factory.getImplementationName(), "d1");
+        ObjectName d2 = transaction.createModule(factory.getImplementationName(), "d2");
+
+        assertEquals(transaction.getTransactionName(), getTransactionName(d1));
+
+        ObjectName parent = transaction.createModule(factory.getImplementationName(), "parent");
+        MultipleDependenciesModuleMXBean multipleDependenciesModuleMXBean = transaction.newMXBeanProxy(parent, MultipleDependenciesModuleMXBean.class);
+        multipleDependenciesModuleMXBean.setTestingDeps(asList(d1, d2));
+        List<ObjectName> found = multipleDependenciesModuleMXBean.getTestingDeps();
+        ObjectName d1WithoutTxName = found.get(0);
+        assertEquals(getInstanceName(d1), getInstanceName(d1WithoutTxName));
+        // check that transaction name gets stripped automatically from attribute.
+        // d1,2 contained tx name, found doesn't
+        assertNull(getTransactionName(d1WithoutTxName));
+        transaction.commit();
+    }
+}
index 8a23a6b5e60e64a6baaf20fd9d7d9712894f57dd..977fab1334ae48791f9901aedbc1420eabb1e2e7 100644 (file)
       <version>${karaf.version}</version>
       <type>kar</type>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>base-features</artifactId>
+      <version>${project.version}</version>
+      <type>kar</type>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>karaf.branding</artifactId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>base-features</artifactId>
+      <version>${project.parent.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <!-- scope is compile so all features (there is only one) are installed
+            into startup.properties and the feature repo itself is not installed -->
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>extras-features</artifactId>
       <version>${project.version}</version>
       <type>kar</type>
       <scope>runtime</scope>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
-      <artifactId>config-features</artifactId>
+      <artifactId>config-netty-features</artifactId>
       <version>${config.version}</version>
       <classifier>features</classifier>
       <type>xml</type>
       <scope>runtime</scope>
     </dependency>
-    <!--<dependency>
+
+    <!-- AD-SAL Related Features -->
+    <dependency>
       <groupId>org.opendaylight.controller</groupId>
-      <artifactId>base-features</artifactId>
-      <version>${project.version}</version>
+      <artifactId>features-adsal</artifactId>
+      <version>${sal.version}</version>
       <classifier>features</classifier>
       <type>xml</type>
       <scope>runtime</scope>
-    </dependency>-->
-    <!-- <dependency>
+    </dependency>
+    <dependency>
       <groupId>org.opendaylight.controller</groupId>
-      <artifactId>controller-features</artifactId>
+      <artifactId>features-nsf</artifactId>
       <version>${project.version}</version>
       <classifier>features</classifier>
       <type>xml</type>
       <scope>runtime</scope>
     </dependency>
-  -->
+
+    <!-- MD-SAL Related Features -->
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>mdsal-features</artifactId>
       <type>xml</type>
       <scope>runtime</scope>
     </dependency>
-    <dependency>
-      <groupId>org.opendaylight.yangtools</groupId>
-      <artifactId>features-yangtools</artifactId>
-      <version>${yangtools.version}</version>
-      <classifier>features</classifier>
-      <type>xml</type>
-      <scope>runtime</scope>
-    </dependency>
   </dependencies>
 
   <build>
           </execution>
         </executions>
       </plugin>
+        <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-antrun-plugin</artifactId>
+            <executions>
+                <execution>
+                    <phase>prepare-package</phase>
+                    <goals>
+                        <goal>run</goal>
+                    </goals>
+                    <configuration>
+                        <tasks>
+                            <copy todir="${project.build.directory}/assembly/bin" overwrite="true">
+                                <fileset dir="${basedir}/src/main/resources/karaf/" includes="karaf,karaf.bat,instance,instance.bat"/>
+                            </copy>
+                        </tasks>
+                    </configuration>
+                </execution>
+            </executions>
+        </plugin>
     </plugins>
   </build>
   <scm>
diff --git a/opendaylight/distribution/opendaylight-karaf/src/main/resources/configuration/initial/02-clustering.xml b/opendaylight/distribution/opendaylight-karaf/src/main/resources/configuration/initial/02-clustering.xml
deleted file mode 100644 (file)
index 7853b86..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<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:remote:rpc">prefix:remote-zeromq-rpc-server</type>
-                   <name>remoter</name>
-                   <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">5666</port>
-                   <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">
-                       <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
-                       <name>dom-broker</name>
-                   </dom-broker>
-               </module>
-            </modules>
-            <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-            </services>
-        </data>
-    </configuration>
-
-    <required-capabilities>
-       <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:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&amp;revision=2013-10-28</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:controller:md:sal:remote:rpc?module=odl-sal-dom-rpc-remote-cfg&amp;revision=2013-10-28</capability>
-    </required-capabilities>
-</snapshot>
-
diff --git a/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/instance b/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/instance
new file mode 100755 (executable)
index 0000000..7288042
--- /dev/null
@@ -0,0 +1,349 @@
+#!/bin/sh
+#
+#    Licensed to the Apache Software Foundation (ASF) under one or more
+#    contributor license agreements.  See the NOTICE file distributed with
+#    this work for additional information regarding copyright ownership.
+#    The ASF licenses this file to You under the Apache License, Version 2.0
+#    (the "License"); you may not use this file except in compliance with
+#    the License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+#
+
+DIRNAME=`dirname "$0"`
+PROGNAME=`basename "$0"`
+
+#
+# Sourcing environment settings for karaf similar to tomcats setenv
+#
+KARAF_SCRIPT="instance"
+export KARAF_SCRIPT
+if [ -f "$DIRNAME/setenv" ]; then
+  . "$DIRNAME/setenv"
+fi
+
+#
+# Check/Set up some easily accessible MIN/MAX params for JVM mem usage
+#
+if [ "x$JAVA_MIN_MEM" = "x" ]; then
+    JAVA_MIN_MEM=128M
+    export JAVA_MIN_MEM
+fi
+if [ "x$JAVA_MAX_MEM" = "x" ]; then
+    JAVA_MAX_MEM=512M
+    export JAVA_MAX_MEM
+fi
+
+warn() {
+    echo "${PROGNAME}: $*"
+}
+
+die() {
+    warn "$*"
+    exit 1
+}
+
+detectOS() {
+    # OS specific support (must be 'true' or 'false').
+    cygwin=false;
+    darwin=false;
+    aix=false;
+    os400=false;
+    case "`uname`" in
+        CYGWIN*)
+            cygwin=true
+            ;;
+        Darwin*)
+            darwin=true
+            ;;
+        AIX*)
+            aix=true
+            ;;
+        OS400*)
+            os400=true
+            ;;
+    esac
+    # For AIX, set an environment variable
+    if $aix; then
+         export LDR_CNTRL=MAXDATA=0xB0000000@DSA
+         echo $LDR_CNTRL
+    fi
+}
+
+unlimitFD() {
+    # Use the maximum available, or set MAX_FD != -1 to use that
+    if [ "x$MAX_FD" = "x" ]; then
+        MAX_FD="maximum"
+    fi
+
+    # Increase the maximum file descriptors if we can
+    if [ "$os400" = "false" ] && [ "$cygwin" = "false" ]; then
+        MAX_FD_LIMIT=`ulimit -H -n`
+        if [ "$MAX_FD_LIMIT" != 'unlimited' ]; then 
+            if [ $? -eq 0 ]; then
+                if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then
+                    # use the system max
+                    MAX_FD="$MAX_FD_LIMIT"
+                fi
+
+                ulimit -n $MAX_FD > /dev/null
+                # echo "ulimit -n" `ulimit -n`
+                if [ $? -ne 0 ]; then
+                    warn "Could not set maximum file descriptor limit: $MAX_FD"
+                fi
+            else
+                warn "Could not query system maximum file descriptor limit: $MAX_FD_LIMIT"
+            fi
+        fi
+    fi
+}
+
+locateHome() {
+    if [ "x$KARAF_HOME" != "x" ]; then
+        warn "Ignoring predefined value for KARAF_HOME"
+    fi
+
+    # In POSIX shells, CDPATH may cause cd to write to stdout
+    (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+    KARAF_HOME=`cd "$DIRNAME/.."; pwd`
+    if [ ! -d "$KARAF_HOME" ]; then
+        die "KARAF_HOME is not valid: $KARAF_HOME"
+    fi
+}
+
+locateBase() {
+    if [ "x$KARAF_BASE" != "x" ]; then
+        if [ ! -d "$KARAF_BASE" ]; then
+            die "KARAF_BASE is not valid: $KARAF_BASE"
+        fi
+    else
+        KARAF_BASE=$KARAF_HOME
+    fi
+}
+
+locateData() {
+    if [ "x$KARAF_DATA" != "x" ]; then
+        if [ ! -d "$KARAF_DATA" ]; then
+            die "KARAF_DATA is not valid: $KARAF_DATA"
+        fi
+    else
+        KARAF_DATA=$KARAF_BASE/data
+    fi
+}
+
+locateEtc() {
+    if [ "x$KARAF_ETC" != "x" ]; then
+        if [ ! -d "$KARAF_ETC" ]; then
+            die "KARAF_ETC is not valid: $KARAF_ETC"
+        fi
+    else
+        KARAF_ETC=$KARAF_BASE/etc
+    fi
+}
+
+setupNativePath() {
+    # Support for loading native libraries
+    LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:$KARAF_BASE/lib:$KARAF_HOME/lib"
+
+    # For Cygwin, set PATH from LD_LIBRARY_PATH
+    if $cygwin; then
+        LD_LIBRARY_PATH=`cygpath --path --windows "$LD_LIBRARY_PATH"`
+        PATH="$PATH;$LD_LIBRARY_PATH"
+        export PATH
+    fi
+    export LD_LIBRARY_PATH
+}
+
+pathCanonical() {
+    local dst="${1}"
+    while [ -h "${dst}" ] ; do
+        ls=`ls -ld "${dst}"`
+        link=`expr "$ls" : '.*-> \(.*\)$'`
+        if expr "$link" : '/.*' > /dev/null; then
+            dst="$link"
+        else
+            dst="`dirname "${dst}"`/$link"
+        fi
+    done
+    local bas=`basename "${dst}"`
+    local dir=`dirname "${dst}"`
+    if [ "$bas" != "$dir" ]; then
+        dst="`pathCanonical "$dir"`/$bas"
+    fi
+    echo "${dst}" | sed -e 's#//#/#g' -e 's#/./#/#g' -e 's#/[^/]*/../#/#g'
+}
+
+locateJava() {
+    # Setup the Java Virtual Machine
+    if $cygwin ; then
+        [ -n "$JAVA" ] && JAVA=`cygpath --unix "$JAVA"`
+        [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+    fi
+
+    if [ "x$JAVA_HOME" = "x" ] && [ "$darwin" = "true" ]; then
+        JAVA_HOME="$(/usr/libexec/java_home)"
+    fi
+    if [ "x$JAVA" = "x" ] && [ -r /etc/gentoo-release ] ; then
+        JAVA_HOME=`java-config --jre-home`
+    fi
+    if [ "x$JAVA" = "x" ]; then
+        if [ "x$JAVA_HOME" != "x" ]; then
+            if [ ! -d "$JAVA_HOME" ]; then
+                die "JAVA_HOME is not valid: $JAVA_HOME"
+            fi
+            JAVA="$JAVA_HOME/bin/java"
+        else
+            warn "JAVA_HOME not set; results may vary"
+            JAVA=`type java`
+            JAVA=`expr "$JAVA" : '.*is \(.*\)$'`
+            if [ "x$JAVA" = "x" ]; then
+                die "java command not found"
+            fi
+        fi
+    fi
+    if [ "x$JAVA_HOME" = "x" ]; then
+        JAVA_HOME="$(dirname $(dirname $(pathCanonical "$JAVA")))"
+    fi
+}
+
+detectJVM() {
+   #echo "`$JAVA -version`"
+   # This service should call `java -version`,
+   # read stdout, and look for hints
+   if $JAVA -version 2>&1 | grep "^IBM" ; then
+       JVM_VENDOR="IBM"
+   # on OS/400, java -version does not contain IBM explicitly
+   elif $os400; then
+       JVM_VENDOR="IBM"
+   else
+       JVM_VENDOR="SUN"
+   fi
+   # echo "JVM vendor is $JVM_VENDOR"
+}
+
+setupDebugOptions() {
+    if [ "x$JAVA_OPTS" = "x" ]; then
+        JAVA_OPTS="$DEFAULT_JAVA_OPTS"
+    fi
+    export JAVA_OPTS
+
+    # Set Debug options if enabled
+    if [ "x$KARAF_DEBUG" != "x" ]; then
+        # Use the defaults if JAVA_DEBUG_OPTS was not set
+        if [ "x$JAVA_DEBUG_OPTS" = "x" ]; then
+            JAVA_DEBUG_OPTS="$DEFAULT_JAVA_DEBUG_OPTS"
+        fi
+
+        JAVA_OPTS="$JAVA_DEBUG_OPTS $JAVA_OPTS"
+        warn "Enabling Java debug options: $JAVA_DEBUG_OPTS"
+    fi
+}
+
+setupDefaults() {
+    DEFAULT_JAVA_OPTS="-Xms$JAVA_MIN_MEM -Xmx$JAVA_MAX_MEM "
+
+    #Set the JVM_VENDOR specific JVM flags
+    if [ "$JVM_VENDOR" = "SUN" ]; then
+        #
+        # Check some easily accessible MIN/MAX params for JVM mem usage
+        #
+        if [ "x$JAVA_PERM_MEM" != "x" ]; then
+            DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS -XX:PermSize=$JAVA_PERM_MEM"
+        fi
+        if [ "x$JAVA_MAX_PERM_MEM" != "x" ]; then
+            DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS -XX:MaxPermSize=$JAVA_MAX_PERM_MEM"
+        fi
+        DEFAULT_JAVA_OPTS="-server $DEFAULT_JAVA_OPTS -Dcom.sun.management.jmxremote"
+    elif [ "$JVM_VENDOR" = "IBM" ]; then
+        if $os400; then
+            DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS"
+        elif $aix; then
+            DEFAULT_JAVA_OPTS="-Xverify:none -Xdump:heap -Xlp $DEFAULT_JAVA_OPTS"
+        else
+            DEFAULT_JAVA_OPTS="-Xverify:none $DEFAULT_JAVA_OPTS"
+        fi
+    fi
+
+    # Add the jars in the lib dir
+    for file in "$KARAF_HOME"/lib/*.jar
+    do
+        if [ -z "$CLASSPATH" ]; then
+            CLASSPATH="$file"
+        else
+            CLASSPATH="$CLASSPATH:$file"
+        fi
+    done
+    DEFAULT_JAVA_DEBUG_OPTS="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"
+
+    ##
+    ## TODO: Move to conf/profiler/yourkit.{sh|cmd}
+    ##
+    # Uncomment to enable YourKit profiling
+    #DEFAULT_JAVA_DEBUG_OPTS="-Xrunyjpagent"
+}
+
+init() {
+    # Determine if there is special OS handling we must perform
+    detectOS
+
+    # Unlimit the number of file descriptors if possible
+    unlimitFD
+
+    # Locate the Karaf home directory
+    locateHome
+
+    # Locate the Karaf base directory
+    locateBase
+
+    # Locate the Karaf data directory
+    locateData
+
+    # Locate the Karaf etc directory
+    locateEtc
+
+    # Setup the native library path
+    setupNativePath
+
+    # Locate the Java VM to execute
+    locateJava
+
+    # Determine the JVM vendor
+    detectJVM
+
+    # Setup default options
+    setupDefaults
+
+    # Install debug options
+    setupDebugOptions
+
+}
+
+run() {
+
+    CLASSPATH="${KARAF_HOME}/system/org/apache/karaf/instance/org.apache.karaf.instance.command/3.0.1/org.apache.karaf.instance.command-3.0.1.jar:${KARAF_HOME}/system/org/apache/karaf/instance/org.apache.karaf.instance.core/3.0.1/org.apache.karaf.instance.core-3.0.1.jar:${KARAF_HOME}/system/org/apache/karaf/shell/org.apache.karaf.shell.console/3.0.1/org.apache.karaf.shell.console-3.0.1.jar:${KARAF_HOME}/system/org/apache/karaf/shell/org.apache.karaf.shell.table/3.0.1/org.apache.karaf.shell.table-3.0.1.jar:${KARAF_HOME}/system/org/apache/aries/blueprint/org.apache.aries.blueprint.api/1.0.0/org.apache.aries.blueprint.api-1.0.0.jar:${KARAF_HOME}/system/org/apache/aries/blueprint/org.apache.aries.blueprint.core/1.4.0/org.apache.aries.blueprint.core-1.4.0.jar:${KARAF_HOME}/system/org/apache/aries/blueprint/org.apache.aries.blueprint.cm/1.0.3/org.apache.aries.blueprint.cm-1.0.3.jar:${KARAF_HOME}/system/org/ops4j/pax/logging/pax-logging-api/1.7.2/pax-logging-api-1.7.2.jar:${KARAF_HOME}/system/org/apache/felix/org.apache.felix.framework/4.2.1/org.apache.felix.framework-4.2.1.jar:${KARAF_HOME}/system/jline/jline/2.11/jline-2.11.jar:$CLASSPATH"
+
+    if $cygwin; then
+        KARAF_HOME=`cygpath --path --windows "$KARAF_HOME"`
+        KARAF_BASE=`cygpath --path --windows "$KARAF_BASE"`
+        KARAF_DATA=`cygpath --path --windows "$KARAF_DATA"`
+        KARAF_ETC=`cygpath --path --windows "$KARAF_ETC"`
+        CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+    fi
+
+    exec "$JAVA" $JAVA_OPTS -Dkaraf.instances="${KARAF_HOME}/instances" -Dkaraf.home="$KARAF_HOME" -Dkaraf.base="$KARAF_BASE" -Dkaraf.etc="$KARAF_ETC" -Djava.io.tmpdir="$KARAF_DATA/tmp" -Djava.util.logging.config.file="$KARAF_BASE/etc/java.util.logging.properties" $KARAF_OPTS $OPTS -classpath "$CLASSPATH" org.apache.karaf.instance.main.Execute "$@"
+}
+
+main() {
+    init
+    run "$@"
+}
+
+main "$@"
+
diff --git a/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/instance.bat b/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/instance.bat
new file mode 100644 (file)
index 0000000..49c2c0f
--- /dev/null
@@ -0,0 +1,151 @@
+@echo off\r
+rem\r
+rem\r
+rem    Licensed to the Apache Software Foundation (ASF) under one or more\r
+rem    contributor license agreements.  See the NOTICE file distributed with\r
+rem    this work for additional information regarding copyright ownership.\r
+rem    The ASF licenses this file to You under the Apache License, Version 2.0\r
+rem    (the "License"); you may not use this file except in compliance with\r
+rem    the License.  You may obtain a copy of the License at\r
+rem\r
+rem       http://www.apache.org/licenses/LICENSE-2.0\r
+rem\r
+rem    Unless required by applicable law or agreed to in writing, software\r
+rem    distributed under the License is distributed on an "AS IS" BASIS,\r
+rem    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+rem    See the License for the specific language governing permissions and\r
+rem    limitations under the License.\r
+rem\r
+\r
+if not "%ECHO%" == "" echo %ECHO%\r
+\r
+setlocal\r
+set DIRNAME=%~dp0%\r
+set PROGNAME=%~nx0%\r
+set ARGS=%*\r
+\r
+rem Sourcing environment settings for karaf similar to tomcats setenv\r
+SET KARAF_SCRIPT="instance.bat"\r
+if exist "%DIRNAME%setenv.bat" (\r
+  call "%DIRNAME%setenv.bat"\r
+)\r
+\r
+rem Check console window title. Set to Karaf by default\r
+if not "%KARAF_TITLE%" == "" (\r
+    title %KARAF_TITLE%\r
+) else (\r
+    title Karaf\r
+)\r
+\r
+rem Check/Set up some easily accessible MIN/MAX params for JVM mem usage\r
+if "%JAVA_MIN_MEM%" == "" (\r
+    set JAVA_MIN_MEM=128M\r
+)\r
+if "%JAVA_MAX_MEM%" == "" (\r
+    set JAVA_MAX_MEM=512M\r
+)\r
+\r
+goto BEGIN\r
+\r
+:warn\r
+    echo %PROGNAME%: %*\r
+goto :EOF\r
+\r
+:BEGIN\r
+\r
+rem # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\r
+\r
+if not "%KARAF_HOME%" == "" (\r
+    call :warn Ignoring predefined value for KARAF_HOME\r
+)\r
+set KARAF_HOME=%DIRNAME%..\r
+if not exist "%KARAF_HOME%" (\r
+    call :warn KARAF_HOME is not valid: "%KARAF_HOME%"\r
+    goto END\r
+)\r
+\r
+if not "%KARAF_BASE%" == "" (\r
+    if not exist "%KARAF_BASE%" (\r
+       call :warn KARAF_BASE is not valid: "%KARAF_BASE%"\r
+       goto END\r
+    )\r
+)\r
+if "%KARAF_BASE%" == "" (\r
+  set "KARAF_BASE=%KARAF_HOME%"\r
+)\r
+\r
+if not "%KARAF_DATA%" == "" (\r
+    if not exist "%KARAF_DATA%" (\r
+        call :warn KARAF_DATA is not valid: "%KARAF_DATA%"\r
+        goto END\r
+    )\r
+)\r
+if "%KARAF_DATA%" == "" (\r
+    set "KARAF_DATA=%KARAF_BASE%\data"\r
+)\r
+\r
+if not "%KARAF_ETC%" == "" (\r
+    if not exist "%KARAF_ETC%" (\r
+        call :warn KARAF_ETC is not valid: "%KARAF_ETC%"\r
+        goto END\r
+    )\r
+)\r
+if "%KARAF_ETC%" == "" (\r
+    set "KARAF_ETC=%KARAF_BASE%\etc"\r
+)\r
+\r
+set DEFAULT_JAVA_OPTS=\r
+set DEFAULT_JAVA_DEBUG_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005\r
+\r
+rem Support for loading native libraries\r
+set PATH=%PATH%;%KARAF_BASE%\lib;%KARAF_HOME%\lib\r
+\r
+rem Setup the Java Virtual Machine\r
+if not "%JAVA%" == "" goto :Check_JAVA_END\r
+    set JAVA=java\r
+    if "%JAVA_HOME%" == "" call :warn JAVA_HOME not set; results may vary\r
+    if not "%JAVA_HOME%" == "" set JAVA=%JAVA_HOME%\bin\java\r
+    if not exist "%JAVA_HOME%" (\r
+        call :warn JAVA_HOME is not valid: "%JAVA_HOME%"\r
+        goto END\r
+    )\r
+:Check_JAVA_END\r
+\r
+if "%JAVA_OPTS%" == "" set JAVA_OPTS=%DEFAULT_JAVA_OPTS%\r
+\r
+if "%KARAF_DEBUG%" == "" goto :KARAF_DEBUG_END\r
+    rem Use the defaults if JAVA_DEBUG_OPTS was not set\r
+    if "%JAVA_DEBUG_OPTS%" == "" set JAVA_DEBUG_OPTS=%DEFAULT_JAVA_DEBUG_OPTS%\r
+\r
+    set "JAVA_OPTS=%JAVA_DEBUG_OPTS% %JAVA_OPTS%"\r
+    call :warn Enabling Java debug options: %JAVA_DEBUG_OPTS%\r
+:KARAF_DEBUG_END\r
+\r
+rem Setup the classpath\r
+pushd "%KARAF_HOME%\lib"\r
+for %%G in (karaf*.jar) do call:APPEND_TO_CLASSPATH %%G\r
+popd\r
+goto CLASSPATH_END\r
+\r
+: APPEND_TO_CLASSPATH\r
+set filename=%~1\r
+set suffix=%filename:~-4%\r
+if %suffix% equ .jar set CLASSPATH=%CLASSPATH%;%KARAF_HOME%\lib\%filename%\r
+goto :EOF\r
+\r
+:CLASSPATH_END\r
+\r
+set CLASSPATH=%KARAF_HOME%\system\org\apache\karaf\instance\org.apache.karaf.instance.command\3.0.1\org.apache.karaf.instance.command-3.0.1.jar;%KARAF_HOME%\system\org\apache\karaf\instance\org.apache.karaf.instance.core\3.0.1\org.apache.karaf.instance.core-3.0.1.jar;%KARAF_HOME%\system\org\apache\karaf\shell\org.apache.karaf.shell.console\3.0.1\org.apache.karaf.shell.console-3.0.1.jar;%KARAF_HOME%\system\org\apache\karaf\shell\org.apache.karaf.shell.table\3.0.1\org.apache.karaf.shell.table-3.0.1.jar;%KARAF_HOME%\system\org\apache\aries\blueprint\org.apache.aries.blueprint.api\1.0.0\org.apache.aries.blueprint.api-1.0.0.jar;%KARAF_HOME%\system\org\apache\aries\blueprint\org.apache.aries.blueprint.core\1.4.0\org.apache.aries.blueprint.core-1.4.0.jar;%KARAF_HOME%\system\org\apache\aries\blueprint\org.apache.aries.blueprint.cm\1.0.3\org.apache.aries.blueprint.cm-1.0.3.jar;%KARAF_HOME%\system\org\ops4j\pax\logging\pax-logging-api\1.7.2\pax-logging-api-1.7.2.jar;%KARAF_HOME%\system\org\apache\felix\org.apache.felix.framework\4.2.1\org.apache.felix.framework-4.2.1.jar;%KARAF_HOME%\system\jline\jline\2.11\jline-2.11.jar;%CLASSPATH%\r
+\r
+:EXECUTE\r
+    if "%SHIFT%" == "true" SET ARGS=%2 %3 %4 %5 %6 %7 %8\r
+    if not "%SHIFT%" == "true" SET ARGS=%1 %2 %3 %4 %5 %6 %7 %8\r
+    rem Execute the Java Virtual Machine\r
+    "%JAVA%" %JAVA_OPTS% %OPTS% -classpath "%CLASSPATH%" -Dkaraf.instances="%KARAF_HOME%\instances" -Dkaraf.home="%KARAF_HOME%" -Dkaraf.base="%KARAF_BASE%" -Dkaraf.etc="%KARAF_ETC%" -Djava.io.tmpdir="%KARAF_DATA%\tmp" -Djava.util.logging.config.file="%KARAF_BASE%\etc\java.util.logging.properties" %KARAF_OPTS% org.apache.karaf.instance.main.Execute %ARGS%\r
+\r
+rem # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\r
+\r
+:END\r
+\r
+endlocal\r
+\r
diff --git a/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/karaf b/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/karaf
new file mode 100755 (executable)
index 0000000..cad052a
--- /dev/null
@@ -0,0 +1,418 @@
+#!/bin/sh
+#
+#    Licensed to the Apache Software Foundation (ASF) under one or more
+#    contributor license agreements.  See the NOTICE file distributed with
+#    this work for additional information regarding copyright ownership.
+#    The ASF licenses this file to You under the Apache License, Version 2.0
+#    (the "License"); you may not use this file except in compliance with
+#    the License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+#
+
+DIRNAME=`dirname $0`
+PROGNAME=`basename $0`
+
+#
+# Sourcing environment settings for karaf similar to tomcats setenv
+#
+KARAF_SCRIPT="karaf"
+export KARAF_SCRIPT
+if [ -f "$DIRNAME/setenv" ]; then
+  . "$DIRNAME/setenv"
+fi
+
+#
+# Set up some easily accessible MIN/MAX params for JVM mem usage
+#
+if [ "x$JAVA_MIN_MEM" = "x" ]; then
+    JAVA_MIN_MEM=128M
+    export JAVA_MIN_MEM
+fi
+if [ "x$JAVA_MAX_MEM" = "x" ]; then
+    JAVA_MAX_MEM=512M
+    export JAVA_MAX_MEM
+fi
+
+#
+# Check the mode that initiated the script
+#
+if [ "x$1" != "x" ]; then
+    MODE=$1
+fi
+
+warn() {
+    echo "${PROGNAME}: $*"
+}
+
+die() {
+    warn "$*"
+    exit 1
+}
+
+detectOS() {
+    # OS specific support (must be 'true' or 'false').
+    cygwin=false;
+    darwin=false;
+    aix=false;
+    os400=false;
+    case "`uname`" in
+        CYGWIN*)
+            cygwin=true
+            ;;
+        Darwin*)
+            darwin=true
+            ;;
+        AIX*)
+            aix=true
+            ;;
+        OS400*)
+            os400=true
+            ;;
+    esac
+    # For AIX, set an environment variable
+    if $aix; then
+         export LDR_CNTRL=MAXDATA=0xB0000000@DSA
+         echo $LDR_CNTRL
+    fi
+}
+
+unlimitFD() {
+    # Use the maximum available, or set MAX_FD != -1 to use that
+    if [ "x$MAX_FD" = "x" ]; then
+        MAX_FD="maximum"
+    fi
+
+    # Increase the maximum file descriptors if we can
+    if [ "$os400" = "false" ] && [ "$cygwin" = "false" ]; then
+        MAX_FD_LIMIT=`ulimit -H -n`
+        if [ "$MAX_FD_LIMIT" != 'unlimited' ]; then 
+            if [ $? -eq 0 ]; then
+                if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then
+                    # use the system max
+                    MAX_FD="$MAX_FD_LIMIT"
+                fi
+
+                ulimit -n $MAX_FD > /dev/null
+                # echo "ulimit -n" `ulimit -n`
+                if [ $? -ne 0 ]; then
+                    warn "Could not set maximum file descriptor limit: $MAX_FD"
+                fi
+            else
+                warn "Could not query system maximum file descriptor limit: $MAX_FD_LIMIT"
+            fi
+        fi
+    fi
+}
+
+locateHome() {
+    if [ "x$KARAF_HOME" != "x" ]; then
+        warn "Ignoring predefined value for KARAF_HOME"
+    fi
+
+    # In POSIX shells, CDPATH may cause cd to write to stdout
+    (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+    KARAF_HOME=`cd "$DIRNAME/.."; pwd`
+    if [ ! -d "$KARAF_HOME" ]; then
+        die "KARAF_HOME is not valid: $KARAF_HOME"
+    fi
+}
+
+locateBase() {
+    if [ "x$KARAF_BASE" != "x" ]; then
+        if [ ! -d "$KARAF_BASE" ]; then
+            die "KARAF_BASE is not valid: $KARAF_BASE"
+        fi
+    else
+        KARAF_BASE=$KARAF_HOME
+    fi
+}
+
+locateData() {
+    if [ "x$KARAF_DATA" != "x" ]; then
+        if [ ! -d "$KARAF_DATA" ]; then
+            die "KARAF_DATA is not valid: $KARAF_DATA"
+        fi
+    else
+        KARAF_DATA=$KARAF_BASE/data
+    fi
+}
+
+locateEtc() {
+    if [ "x$KARAF_ETC" != "x" ]; then
+        if [ ! -d "$KARAF_ETC" ]; then
+            die "KARAF_ETC is not valid: $KARAF_ETC"
+        fi
+    else
+        KARAF_ETC=$KARAF_BASE/etc
+    fi
+}
+
+setupNativePath() {
+    # Support for loading native libraries
+    LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:$KARAF_BASE/lib:$KARAF_HOME/lib"
+
+    # For Cygwin, set PATH from LD_LIBRARY_PATH
+    if $cygwin; then
+        LD_LIBRARY_PATH=`cygpath --path --windows "$LD_LIBRARY_PATH"`
+        PATH="$PATH;$LD_LIBRARY_PATH"
+        export PATH
+    fi
+    export LD_LIBRARY_PATH
+}
+
+pathCanonical() {
+    local dst="${1}"
+    while [ -h "${dst}" ] ; do
+        ls=`ls -ld "${dst}"`
+        link=`expr "$ls" : '.*-> \(.*\)$'`
+        if expr "$link" : '/.*' > /dev/null; then
+            dst="$link"
+        else
+            dst="`dirname "${dst}"`/$link"
+        fi
+    done
+    local bas=`basename "${dst}"`
+    local dir=`dirname "${dst}"`
+    if [ "$bas" != "$dir" ]; then
+      dst="`pathCanonical "$dir"`/$bas"
+    fi
+    echo "${dst}" | sed -e 's#//#/#g' -e 's#/./#/#g' -e 's#/[^/]*/../#/#g'
+}
+
+locateJava() {
+    # Setup the Java Virtual Machine
+    if $cygwin ; then
+        [ -n "$JAVA" ] && JAVA=`cygpath --unix "$JAVA"`
+        [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+    fi
+
+       if [ "x$JAVA_HOME" = "x" ] && [ "$darwin" = "true" ]; then
+               JAVA_HOME="$(/usr/libexec/java_home)"
+       fi
+    if [ "x$JAVA" = "x" ] && [ -r /etc/gentoo-release ] ; then
+        JAVA_HOME=`java-config --jre-home`
+    fi
+    if [ "x$JAVA" = "x" ]; then
+        if [ "x$JAVA_HOME" != "x" ]; then
+            if [ ! -d "$JAVA_HOME" ]; then
+                die "JAVA_HOME is not valid: $JAVA_HOME"
+            fi
+            JAVA="$JAVA_HOME/bin/java"
+        else
+            warn "JAVA_HOME not set; results may vary"
+            JAVA=`type java`
+            JAVA=`expr "$JAVA" : '.*is \(.*\)$'`
+            if [ "x$JAVA" = "x" ]; then
+                die "java command not found"
+            fi
+        fi
+    fi
+    if [ "x$JAVA_HOME" = "x" ]; then
+        JAVA_HOME="$(dirname $(dirname $(pathCanonical "$JAVA")))"
+    fi
+}
+
+detectJVM() {
+   #echo "`$JAVA -version`"
+   # This service should call `java -version`,
+   # read stdout, and look for hints
+   if $JAVA -version 2>&1 | grep "^IBM" ; then
+       JVM_VENDOR="IBM"
+   # on OS/400, java -version does not contain IBM explicitly
+   elif $os400; then
+       JVM_VENDOR="IBM"
+   else
+       JVM_VENDOR="SUN"
+   fi
+   # echo "JVM vendor is $JVM_VENDOR"
+}
+
+checkJvmVersion() {
+   # echo "`$JAVA -version`"
+   VERSION=`$JAVA -version 2>&1 | egrep '"([0-9].[0-9]\..*[0-9])"' | awk '{print substr($3,2,length($3)-2)}' | awk '{print substr($1, 3, 3)}' | sed -e 's;\.;;g'`
+   # echo $VERSION
+   if [ "$VERSION" -lt "60" ]; then
+       echo "JVM must be greater than 1.6"
+       exit 1;
+   fi
+}
+
+setupDebugOptions() {
+    if [ "x$JAVA_OPTS" = "x" ]; then
+        JAVA_OPTS="$DEFAULT_JAVA_OPTS"
+    fi
+    export JAVA_OPTS
+
+    # Set Debug options if enabled
+    if [ "x$KARAF_DEBUG" != "x" ]; then
+        # Ignore DEBUG in case of stop or client mode
+        if [ "x$MODE" = "xstop" ]; then
+            return
+        fi
+        if [ "x$MODE" = "xclient" ]; then
+            return
+        fi
+        # Use the defaults if JAVA_DEBUG_OPTS was not set
+        if [ "x$JAVA_DEBUG_OPTS" = "x" ]; then
+            JAVA_DEBUG_OPTS="$DEFAULT_JAVA_DEBUG_OPTS"
+        fi
+
+        JAVA_OPTS="$JAVA_DEBUG_OPTS $JAVA_OPTS"
+        warn "Enabling Java debug options: $JAVA_DEBUG_OPTS"
+    fi
+}
+
+setupDefaults() {
+    DEFAULT_JAVA_OPTS="-Xms$JAVA_MIN_MEM -Xmx$JAVA_MAX_MEM -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass "
+
+    #Set the JVM_VENDOR specific JVM flags
+    if [ "$JVM_VENDOR" = "SUN" ]; then
+        #
+        # Check some easily accessible MIN/MAX params for JVM mem usage
+        #
+        if [ "x$JAVA_PERM_MEM" != "x" ]; then
+            DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS -XX:PermSize=$JAVA_PERM_MEM"
+        fi
+        if [ "x$JAVA_MAX_PERM_MEM" != "x" ]; then
+            DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS -XX:MaxPermSize=$JAVA_MAX_PERM_MEM"
+        fi
+        DEFAULT_JAVA_OPTS="-server $DEFAULT_JAVA_OPTS -Dcom.sun.management.jmxremote"
+    elif [ "$JVM_VENDOR" = "IBM" ]; then
+        if $os400; then
+            DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS"
+        elif $aix; then
+            DEFAULT_JAVA_OPTS="-Xverify:none -Xdump:heap -Xlp $DEFAULT_JAVA_OPTS"
+        else
+            DEFAULT_JAVA_OPTS="-Xverify:none $DEFAULT_JAVA_OPTS"
+        fi
+    fi
+
+    # Add the jars in the lib dir
+    for file in "$KARAF_HOME"/lib/karaf*.jar
+    do
+        if [ -z "$CLASSPATH" ]; then
+            CLASSPATH="$file"
+        else
+            CLASSPATH="$CLASSPATH:$file"
+        fi
+    done
+    DEFAULT_JAVA_DEBUG_OPTS="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"
+
+    ##
+    ## TODO: Move to conf/profiler/yourkit.{sh|cmd}
+    ##
+    # Uncomment to enable YourKit profiling
+    #DEFAULT_JAVA_DEBUG_OPTS="-Xrunyjpagent"
+}
+
+init() {
+    # Determine if there is special OS handling we must perform
+    detectOS
+
+    # Unlimit the number of file descriptors if possible
+    unlimitFD
+
+    # Locate the Karaf home directory
+    locateHome
+
+    # Locate the Karaf base directory
+    locateBase
+
+    # Locate the Karaf data directory
+    locateData
+
+    # Locate the Karaf etc directory
+    locateEtc
+
+    # Setup the native library path
+    setupNativePath
+
+    # Locate the Java VM to execute
+    locateJava
+
+    # Determine the JVM vendor
+    detectJVM
+    
+    # Determine the JVM version >= 1.6
+    checkJvmVersion
+
+    # Setup default options
+    setupDefaults
+
+    # Install debug options
+    setupDebugOptions
+
+}
+
+run() {
+    OPTS="-Dkaraf.startLocalConsole=true -Dkaraf.startRemoteShell=true"
+    MAIN=org.apache.karaf.main.Main
+    while [ "$1" != "" ]; do
+        case $1 in
+            'clean')
+                rm -Rf "$KARAF_DATA"
+                shift
+                ;;
+            'debug')
+                if [ "x$JAVA_DEBUG_OPTS" = "x" ]; then
+                    JAVA_DEBUG_OPTS="$DEFAULT_JAVA_DEBUG_OPTS"
+                fi
+                JAVA_OPTS="$JAVA_DEBUG_OPTS $JAVA_OPTS"
+                shift
+                ;;
+            'status')
+                MAIN=org.apache.karaf.main.Status
+                shift
+                ;;
+            'stop')
+                MAIN=org.apache.karaf.main.Stop
+                shift
+                ;;
+            'console')
+                shift
+                ;;
+            'server')
+                OPTS="-Dkaraf.startLocalConsole=false -Dkaraf.startRemoteShell=true"
+                shift
+                ;;
+            'client')
+                OPTS="-Dkaraf.startLocalConsole=true -Dkaraf.startRemoteShell=false"
+                shift
+                ;;
+            *)
+                break
+                ;;
+        esac
+    done
+
+    JAVA_ENDORSED_DIRS="${JAVA_HOME}/jre/lib/endorsed:${JAVA_HOME}/lib/endorsed:${KARAF_HOME}/lib/endorsed"
+    JAVA_EXT_DIRS="${JAVA_HOME}/jre/lib/ext:${JAVA_HOME}/lib/ext:${KARAF_HOME}/lib/ext"
+    if $cygwin; then
+        KARAF_HOME=`cygpath --path --windows "$KARAF_HOME"`
+        KARAF_BASE=`cygpath --path --windows "$KARAF_BASE"`
+        KARAF_DATA=`cygpath --path --windows "$KARAF_DATA"`
+        KARAF_ETC=`cygpath --path --windows "$KARAF_ETC"`
+        CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+        JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+        JAVA_ENDORSED_DIRS=`cygpath --path --windows "$JAVA_ENDORSED_DIRS"`
+        JAVA_EXT_DIRS=`cygpath --path --windows "$JAVA_EXT_DIRS"`
+    fi
+    cd "$KARAF_BASE"
+
+    exec "$JAVA" $JAVA_OPTS -Djava.endorsed.dirs="${JAVA_ENDORSED_DIRS}" -Djava.ext.dirs="${JAVA_EXT_DIRS}" -Dkaraf.instances="${KARAF_HOME}/instances" -Dkaraf.home="$KARAF_HOME" -Dkaraf.base="$KARAF_BASE" -Dkaraf.data="$KARAF_DATA" -Dkaraf.etc="$KARAF_ETC" -Djava.io.tmpdir="$KARAF_DATA/tmp" -Djava.util.logging.config.file="$KARAF_BASE/etc/java.util.logging.properties" $KARAF_OPTS $OPTS -classpath "$CLASSPATH" $MAIN "$@"
+}
+
+main() {
+    init
+    run "$@"
+}
+
+main "$@"
diff --git a/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/karaf.bat b/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/karaf.bat
new file mode 100644 (file)
index 0000000..a450877
--- /dev/null
@@ -0,0 +1,336 @@
+@echo off\r
+rem\r
+rem\r
+rem    Licensed to the Apache Software Foundation (ASF) under one or more\r
+rem    contributor license agreements.  See the NOTICE file distributed with\r
+rem    this work for additional information regarding copyright ownership.\r
+rem    The ASF licenses this file to You under the Apache License, Version 2.0\r
+rem    (the "License"); you may not use this file except in compliance with\r
+rem    the License.  You may obtain a copy of the License at\r
+rem\r
+rem       http://www.apache.org/licenses/LICENSE-2.0\r
+rem\r
+rem    Unless required by applicable law or agreed to in writing, software\r
+rem    distributed under the License is distributed on an "AS IS" BASIS,\r
+rem    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+rem    See the License for the specific language governing permissions and\r
+rem    limitations under the License.\r
+rem\r
+\r
+if not "%ECHO%" == "" echo %ECHO%\r
+\r
+setlocal\r
+set DIRNAME=%~dp0%\r
+set PROGNAME=%~nx0%\r
+set ARGS=%*\r
+\r
+rem Sourcing environment settings for karaf similar to tomcats setenv\r
+SET KARAF_SCRIPT="karaf.bat"\r
+if exist "%DIRNAME%setenv.bat" (\r
+  call "%DIRNAME%setenv.bat"\r
+)\r
+\r
+rem Check console window title. Set to Karaf by default\r
+if not "%KARAF_TITLE%" == "" (\r
+    title %KARAF_TITLE%\r
+) else (\r
+    title Karaf\r
+)\r
+\r
+rem Check/Set up some easily accessible MIN/MAX params for JVM mem usage\r
+if "%JAVA_MIN_MEM%" == "" (\r
+    set JAVA_MIN_MEM=128M\r
+)\r
+if "%JAVA_MAX_MEM%" == "" (\r
+    set JAVA_MAX_MEM=512M\r
+)\r
+\r
+goto BEGIN\r
+\r
+:warn\r
+    echo %PROGNAME%: %*\r
+goto :EOF\r
+\r
+:BEGIN\r
+\r
+rem # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\r
+\r
+if not "%KARAF_HOME%" == "" (\r
+    call :warn Ignoring predefined value for KARAF_HOME\r
+)\r
+set KARAF_HOME=%DIRNAME%..\r
+if not exist "%KARAF_HOME%" (\r
+    call :warn KARAF_HOME is not valid: "%KARAF_HOME%"\r
+    goto END\r
+)\r
+\r
+if not "%KARAF_BASE%" == "" (\r
+    if not exist "%KARAF_BASE%" (\r
+       call :warn KARAF_BASE is not valid: "%KARAF_BASE%"\r
+       goto END\r
+    )\r
+)\r
+if "%KARAF_BASE%" == "" (\r
+  set "KARAF_BASE=%KARAF_HOME%"\r
+)\r
+\r
+if not "%KARAF_DATA%" == "" (\r
+    if not exist "%KARAF_DATA%" (\r
+        call :warn KARAF_DATA is not valid: "%KARAF_DATA%"\r
+        goto END\r
+    )\r
+)\r
+if "%KARAF_DATA%" == "" (\r
+    set "KARAF_DATA=%KARAF_BASE%\data"\r
+)\r
+\r
+if not "%KARAF_ETC%" == "" (\r
+    if not exist "%KARAF_ETC%" (\r
+        call :warn KARAF_ETC is not valid: "%KARAF_ETC%"\r
+        goto END\r
+    )\r
+)\r
+if "%KARAF_ETC%" == "" (\r
+    set "KARAF_ETC=%KARAF_BASE%\etc"\r
+)\r
+\r
+set LOCAL_CLASSPATH=%CLASSPATH%\r
+set JAVA_MODE=-server\r
+if not exist "%JAVA_HOME%\bin\server\jvm.dll" (\r
+    if not exist "%JAVA_HOME%\jre\bin\server\jvm.dll" (\r
+        echo WARNING: Running karaf on a Java HotSpot Client VM because server-mode is not available.\r
+        echo Install Java Developer Kit to fix this.\r
+        echo For more details see http://java.sun.com/products/hotspot/whitepaper.html#client\r
+        set JAVA_MODE=-client\r
+    )\r
+)\r
+set DEFAULT_JAVA_OPTS=%JAVA_MODE% -Xms%JAVA_MIN_MEM% -Xmx%JAVA_MAX_MEM% -Dderby.system.home="%KARAF_DATA%\derby" -Dderby.storage.fileSyncTransactionLog=true -Dcom.sun.management.jmxremote  -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass\r
+\r
+rem Check some easily accessible MIN/MAX params for JVM mem usage\r
+if not "%JAVA_PERM_MEM%" == "" (\r
+    set DEFAULT_JAVA_OPTS=%DEFAULT_JAVA_OPTS% -XX:PermSize=%JAVA_PERM_MEM%\r
+)\r
+if not "%JAVA_MAX_PERM_MEM%" == "" (\r
+    set DEFAULT_JAVA_OPTS=%DEFAULT_JAVA_OPTS% -XX:MaxPermSize=%JAVA_MAX_PERM_MEM%\r
+)\r
+\r
+set CLASSPATH=%LOCAL_CLASSPATH%;%KARAF_BASE%\conf\r
+set DEFAULT_JAVA_DEBUG_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005\r
+\r
+if "%LOCAL_CLASSPATH%" == "" goto :KARAF_CLASSPATH_EMPTY\r
+    set CLASSPATH=%LOCAL_CLASSPATH%;%KARAF_BASE%\conf\r
+    goto :KARAF_CLASSPATH_END\r
+:KARAF_CLASSPATH_EMPTY\r
+    set CLASSPATH=%KARAF_BASE%\conf\r
+:KARAF_CLASSPATH_END\r
+\r
+rem Setup Karaf Home\r
+if exist "%KARAF_HOME%\conf\karaf-rc.cmd" call %KARAF_HOME%\conf\karaf-rc.cmd\r
+if exist "%HOME%\karaf-rc.cmd" call %HOME%\karaf-rc.cmd\r
+\r
+rem Support for loading native libraries\r
+set PATH=%PATH%;%KARAF_BASE%\lib;%KARAF_HOME%\lib\r
+\r
+rem Setup the Java Virtual Machine\r
+if not "%JAVA%" == "" goto :Check_JAVA_END\r
+    if not "%JAVA_HOME%" == "" goto :TryJDKEnd\r
+        call :warn JAVA_HOME not set; results may vary\r
+:TryJRE\r
+    start /w regedit /e __reg1.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment"\r
+    if not exist __reg1.txt goto :TryJDK\r
+    type __reg1.txt | find "CurrentVersion" > __reg2.txt\r
+    if errorlevel 1 goto :TryJDK\r
+    for /f "tokens=2 delims==" %%x in (__reg2.txt) do set JavaTemp=%%~x\r
+    if errorlevel 1 goto :TryJDK\r
+    set JavaTemp=%JavaTemp%##\r
+    set JavaTemp=%JavaTemp:                ##=##%\r
+    set JavaTemp=%JavaTemp:        ##=##%\r
+    set JavaTemp=%JavaTemp:    ##=##%\r
+    set JavaTemp=%JavaTemp:  ##=##%\r
+    set JavaTemp=%JavaTemp: ##=##%\r
+    set JavaTemp=%JavaTemp:##=%\r
+    del __reg1.txt\r
+    del __reg2.txt\r
+    start /w regedit /e __reg1.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\%JavaTemp%"\r
+    if not exist __reg1.txt goto :TryJDK\r
+    type __reg1.txt | find "JavaHome" > __reg2.txt\r
+    if errorlevel 1 goto :TryJDK\r
+    for /f "tokens=2 delims==" %%x in (__reg2.txt) do set JAVA_HOME=%%~x\r
+    if errorlevel 1 goto :TryJDK\r
+    del __reg1.txt\r
+    del __reg2.txt\r
+    goto TryJDKEnd\r
+:TryJDK\r
+    start /w regedit /e __reg1.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit"\r
+    if not exist __reg1.txt (\r
+        goto TryRegJRE\r
+    )\r
+    type __reg1.txt | find "CurrentVersion" > __reg2.txt\r
+    if errorlevel 1 (\r
+        goto TryRegJRE\r
+    )\r
+    for /f "tokens=2 delims==" %%x in (__reg2.txt) do set JavaTemp=%%~x\r
+    if errorlevel 1 (\r
+        goto TryRegJRE\r
+    )\r
+    set JavaTemp=%JavaTemp%##\r
+    set JavaTemp=%JavaTemp:                ##=##%\r
+    set JavaTemp=%JavaTemp:        ##=##%\r
+    set JavaTemp=%JavaTemp:    ##=##%\r
+    set JavaTemp=%JavaTemp:  ##=##%\r
+    set JavaTemp=%JavaTemp: ##=##%\r
+    set JavaTemp=%JavaTemp:##=%\r
+    del __reg1.txt\r
+    del __reg2.txt\r
+    start /w regedit /e __reg1.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit\%JavaTemp%"\r
+    if not exist __reg1.txt (\r
+        goto TryRegJRE\r
+    )\r
+    type __reg1.txt | find "JavaHome" > __reg2.txt\r
+    if errorlevel 1 (\r
+        goto TryRegJRE\r
+    )\r
+    for /f "tokens=2 delims==" %%x in (__reg2.txt) do set JAVA_HOME=%%~x\r
+    if errorlevel 1 (\r
+        goto TryRegJRE\r
+    )\r
+    del __reg1.txt\r
+    del __reg2.txt\r
+:TryRegJRE\r
+    rem try getting the JAVA_HOME from registry\r
+    FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKLM\Software\JavaSoft\Java Runtime Environment" /v CurrentVersion`) DO (\r
+       set JAVA_VERSION=%%A\r
+    )\r
+    FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKLM\Software\JavaSoft\Java Runtime Environment\%JAVA_VERSION%" /v JavaHome`) DO (\r
+       set JAVA_HOME=%%A %%B\r
+    )\r
+    if not exist "%JAVA_HOME%" (\r
+       goto TryRegJDK\r
+    )\r
+       goto TryJDKEnd\r
+:TryRegJDK\r
+    rem try getting the JAVA_HOME from registry\r
+    FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKLM\Software\JavaSoft\Java Development Kit" /v CurrentVersion`) DO (\r
+       set JAVA_VERSION=%%A\r
+    )\r
+    FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKLM\Software\JavaSoft\Java Development Kit\%JAVA_VERSION%" /v JavaHome`) DO (\r
+       set JAVA_HOME=%%A %%B\r
+    )\r
+    if not exist "%JAVA_HOME%" (\r
+       call :warn Unable to retrieve JAVA_HOME from Registry\r
+    )\r
+        goto TryJDKEnd\r
+:TryJDKEnd\r
+    if not exist "%JAVA_HOME%" (\r
+        call :warn JAVA_HOME is not valid: "%JAVA_HOME%"\r
+        goto END\r
+    )\r
+    set JAVA=%JAVA_HOME%\bin\java\r
+:Check_JAVA_END\r
+\r
+if "%JAVA_OPTS%" == "" set JAVA_OPTS=%DEFAULT_JAVA_OPTS%\r
+\r
+if "%KARAF_DEBUG%" == "" goto :KARAF_DEBUG_END\r
+    if "%1" == "stop" goto :KARAF_DEBUG_END\r
+    if "%1" == "client" goto :KARAF_DEBUG_END\r
+    rem Use the defaults if JAVA_DEBUG_OPTS was not set\r
+    if "%JAVA_DEBUG_OPTS%" == "" set JAVA_DEBUG_OPTS=%DEFAULT_JAVA_DEBUG_OPTS%\r
+\r
+    set "JAVA_OPTS=%JAVA_DEBUG_OPTS% %JAVA_OPTS%"\r
+    call :warn Enabling Java debug options: %JAVA_DEBUG_OPTS%\r
+:KARAF_DEBUG_END\r
+\r
+if "%KARAF_PROFILER%" == "" goto :KARAF_PROFILER_END\r
+    set KARAF_PROFILER_SCRIPT=%KARAF_HOME%\conf\profiler\%KARAF_PROFILER%.cmd\r
+\r
+    if exist "%KARAF_PROFILER_SCRIPT%" goto :KARAF_PROFILER_END\r
+    call :warn Missing configuration for profiler '%KARAF_PROFILER%': %KARAF_PROFILER_SCRIPT%\r
+    goto END\r
+:KARAF_PROFILER_END\r
+\r
+rem Setup the classpath\r
+pushd "%KARAF_HOME%\lib"\r
+for %%G in (karaf*.jar) do call:APPEND_TO_CLASSPATH %%G\r
+popd\r
+goto CLASSPATH_END\r
+\r
+: APPEND_TO_CLASSPATH\r
+set filename=%~1\r
+set suffix=%filename:~-4%\r
+if %suffix% equ .jar set CLASSPATH=%CLASSPATH%;%KARAF_HOME%\lib\%filename%\r
+goto :EOF\r
+\r
+:CLASSPATH_END\r
+\r
+rem Execute the JVM or the load the profiler\r
+if "%KARAF_PROFILER%" == "" goto :RUN\r
+    rem Execute the profiler if it has been configured\r
+    call :warn Loading profiler script: %KARAF_PROFILER_SCRIPT%\r
+    call %KARAF_PROFILER_SCRIPT%\r
+\r
+:RUN\r
+    SET OPTS=-Dkaraf.startLocalConsole=true -Dkaraf.startRemoteShell=true\r
+    SET MAIN=org.apache.karaf.main.Main\r
+    SET SHIFT=false\r
+\r
+:RUN_LOOP\r
+    if "%1" == "stop" goto :EXECUTE_STOP\r
+    if "%1" == "status" goto :EXECUTE_STATUS\r
+    if "%1" == "console" goto :EXECUTE_CONSOLE\r
+    if "%1" == "server" goto :EXECUTE_SERVER\r
+    if "%1" == "client" goto :EXECUTE_CLIENT\r
+    if "%1" == "clean" goto :EXECUTE_CLEAN\r
+    if "%1" == "debug" goto :EXECUTE_DEBUG\r
+    goto :EXECUTE\r
+\r
+:EXECUTE_STOP\r
+    SET MAIN=org.apache.karaf.main.Stop\r
+    shift\r
+    goto :RUN_LOOP\r
+\r
+:EXECUTE_STATUS\r
+    SET MAIN=org.apache.karaf.main.Status\r
+    shift\r
+    goto :RUN_LOOP\r
+\r
+:EXECUTE_CONSOLE\r
+    shift\r
+    goto :RUN_LOOP\r
+\r
+:EXECUTE_SERVER\r
+    SET OPTS=-Dkaraf.startLocalConsole=false -Dkaraf.startRemoteShell=true\r
+    shift\r
+    goto :RUN_LOOP\r
+\r
+:EXECUTE_CLIENT\r
+    SET OPTS=-Dkaraf.startLocalConsole=true -Dkaraf.startRemoteShell=false\r
+    shift\r
+    goto :RUN_LOOP\r
+\r
+:EXECUTE_CLEAN\r
+    rmdir /S /Q "%KARAF_DATA%"\r
+    shift\r
+    goto :RUN_LOOP\r
+\r
+:EXECUTE_DEBUG\r
+    if "%JAVA_DEBUG_OPTS%" == "" set JAVA_DEBUG_OPTS=%DEFAULT_JAVA_DEBUG_OPTS%\r
+    set "JAVA_OPTS=%JAVA_DEBUG_OPTS% %JAVA_OPTS%"\r
+    shift\r
+    goto :RUN_LOOP\r
+\r
+:EXECUTE\r
+    SET ARGS=%1 %2 %3 %4 %5 %6 %7 %8\r
+    rem Execute the Java Virtual Machine\r
+    cd "%KARAF_BASE%"\r
+    "%JAVA%" %JAVA_OPTS% %OPTS% -classpath "%CLASSPATH%" -Djava.endorsed.dirs="%JAVA_HOME%\jre\lib\endorsed;%JAVA_HOME%\lib\endorsed;%KARAF_HOME%\lib\endorsed" -Djava.ext.dirs="%JAVA_HOME%\jre\lib\ext;%JAVA_HOME%\lib\ext;%KARAF_HOME%\lib\ext" -Dkaraf.instances="%KARAF_HOME%\instances" -Dkaraf.home="%KARAF_HOME%" -Dkaraf.base="%KARAF_BASE%" -Dkaraf.etc="%KARAF_ETC%" -Djava.io.tmpdir="%KARAF_DATA%\tmp" -Dkaraf.data="%KARAF_DATA%" -Djava.util.logging.config.file="%KARAF_BASE%\etc\java.util.logging.properties" %KARAF_OPTS% %MAIN% %ARGS%\r
+\r
+rem # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\r
+\r
+:END\r
+\r
+endlocal\r
+\r
+if not "%PAUSE%" == "" pause\r
+\r
+:END_NO_PAUSE\r
+\r
index ef3b5f4fd99e79a3449fcb5846cac80f6271b332..541c1300f35da009dc0ca2aa4434fe3e51b3dee9 100644 (file)
 
   <build>
     <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.8</version>
+        <executions>
+          <execution>
+            <id>unpack-provided-configs</id>
+            <goals>
+              <goal>unpack-dependencies</goal>
+            </goals>
+            <phase>generate-resources</phase>
+            <configuration>
+               <outputDirectory>${project.build.directory}/configuration</outputDirectory>
+               <includeArtifactIds>sal-rest-connector-config</includeArtifactIds>
+               <includes>**\/*.xml</includes>
+               <excludeTransitive>true</excludeTransitive>
+               <ignorePermissions>false</ignorePermissions>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
       <plugin>
         <artifactId>maven-assembly-plugin</artifactId>
         <version>2.3</version>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>config-manager</artifactId>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>config-util</artifactId>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>config-netconf-connector</artifactId>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-rest-connector</artifactId>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>sal-rest-connector-config</artifactId>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-rest-docgen</artifactId>
           <groupId>org.opendaylight.controller.model</groupId>
           <artifactId>model-flow-base</artifactId>
         </dependency>
-        <dependency>
-          <groupId>org.opendaylight.controller.model</groupId>
-          <artifactId>model-flow-management</artifactId>
-        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller.model</groupId>
           <artifactId>model-flow-service</artifactId>
                 </goals>
                 <phase>package</phase>
               </execution>
+              <execution>
+                <id>unpack-provided-configs</id>
+                <goals>
+                  <goal>unpack-dependencies</goal>
+                </goals>
+                <phase>generate-resources</phase>
+                <configuration>
+                   <outputDirectory>${project.build.directory}/configuration</outputDirectory>
+                   <includeArtifactIds>sal-rest-connector-config</includeArtifactIds>
+                   <includes>**\/*.xml</includes>
+                   <excludeTransitive>true</excludeTransitive>
+                   <ignorePermissions>false</ignorePermissions>
+                </configuration>
+              </execution>
             </executions>
           </plugin>
           <plugin>
index 0ff4c9a83c37a4182c9d26061b80d3d8b0e9a636..e5fc98a8639b88ceacb0c134631c32010c904ded 100644 (file)
         opendaylight/
       </outputDirectory>
     </fileSet>
+    <fileSet>
+      <directory>${project.build.directory}/configuration/initial</directory>
+      <outputDirectory>/opendaylight/configuration/initial</outputDirectory>
+      <excludes>
+        <exclude>**/META-INF/**</exclude>
+      </excludes>
+    </fileSet>
   </fileSets>
   <files>
     <file>
index f05afbb346f7f157162b313981874c4d3d6bdd40..b2fc3cb386ffa4525fb42dd3fae685c7b6a39e97 100644 (file)
@@ -113,8 +113,8 @@ org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
 ovsdb.listenPort=6640
 
 # ovsdb creates Openflow nodes/bridges. This configuration configures the bridge's Openflow version.
-# default Openflow version = 1.0, we also support 1.3.
-ovsdb.of.version=1.3
+# default Openflow version = 1.3, we also support 1.0.
+ovsdb.of.version=1.3
 
 # TLS configuration
 # To enable TLS, set secureChannelEnabled=true and specify the location of controller Java KeyStore and TrustStore files.
@@ -149,3 +149,6 @@ hosttracker.keyscheme=IP
 lisp.mappingOverwrite = true
 # Enable the Solicit-Map-Request (SMR) mechanism
 lisp.smr = false
+
+#RESTConf websocket listen port (default is 8181)
+restconf.websocket.port=8181
index 00abf6cf339a036de0fe3285fdfb73a817232808..c148b83a7a136d47905bcbb0019169e3f2c097f3 100644 (file)
@@ -7,48 +7,61 @@
   -->
 
 <Host>
-    <!-- Filters are allowed here, only serving as a template -->
-    <filter-template>
-        <filter-name>CorsFilter</filter-name>
-        <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
-        <init-param>
-            <param-name>cors.allowed.origins</param-name>
-            <param-value>*</param-value>
-        </init-param>
-        <init-param>
-            <param-name>cors.allowed.methods</param-name>
-            <param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>
-        </init-param>
-        <init-param>
-            <param-name>cors.allowed.headers</param-name>
-            <param-value>Content-Type,X-Requested-With,accept,authorization,
-                origin,Origin,Access-Control-Request-Method,Access-Control-Request-Headers
-            </param-value>
-        </init-param>
-        <init-param>
-            <param-name>cors.exposed.headers</param-name>
-            <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
-        </init-param>
-        <init-param>
-            <param-name>cors.support.credentials</param-name>
-            <param-value>true</param-value>
-        </init-param>
-        <init-param>
-            <param-name>cors.preflight.maxage</param-name>
-            <param-value>10</param-value>
-        </init-param>
-    </filter-template>
+  <!-- Filters are allowed here, only serving as a template -->
+  <filter-template>
+    <filter-name>CorsFilter</filter-name>
+    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
+    <init-param>
+      <param-name>cors.allowed.origins</param-name>
+      <param-value>*</param-value>
+    </init-param>
+    <init-param>
+      <param-name>cors.allowed.methods</param-name>
+      <param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>
+    </init-param>
+    <init-param>
+      <param-name>cors.allowed.headers</param-name>
+      <param-value>Content-Type,X-Requested-With,accept,authorization,
+        origin,Origin,Access-Control-Request-Method,Access-Control-Request-Headers
+      </param-value>
+    </init-param>
+    <init-param>
+      <param-name>cors.exposed.headers</param-name>
+      <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
+    </init-param>
+    <init-param>
+      <param-name>cors.support.credentials</param-name>
+      <param-value>true</param-value>
+    </init-param>
+    <init-param>
+      <param-name>cors.preflight.maxage</param-name>
+      <param-value>10</param-value>
+    </init-param>
+  </filter-template>
+
+  <Context path="/restconf">
+    <filter>
+      <filter-name>CorsFilter</filter-name>
+      <!-- init params can be added/overriden if template is used -->
+    </filter>
+    <!-- references to templates without <filter> declaration are not allowed -->
+    <filter-mapping>
+      <filter-name>CorsFilter</filter-name>
+      <url-pattern>/*</url-pattern>
+    </filter-mapping>
+  </Context>
+
+  <Context path="/apidoc">
+    <filter>
+      <filter-name>CorsFilter</filter-name>
+      <!-- init params can be added/overriden if template is used -->
+    </filter>
+    <!-- references to templates without <filter> declaration are not allowed -->
+    <filter-mapping>
+      <filter-name>CorsFilter</filter-name>
+      <url-pattern>/*</url-pattern>
+    </filter-mapping>
+  </Context>
 
-    <Context path="/restconf">
-        <filter>
-            <filter-name>CorsFilter</filter-name>
-            <!-- init params can be added/overriden if template is used -->
-        </filter>
-        <!-- references to templates without <filter> declaration are not allowed -->
-        <filter-mapping>
-            <filter-name>CorsFilter</filter-name>
-            <url-pattern>/*</url-pattern>
-        </filter-mapping>
-    </Context>
 
 </Host>
index 7b1df982471006c073b6b1b4b654149cc665bedc..f25b7d91bdb38b2f357ec5faa91283d2929e3128 100644 (file)
                         <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>
+                    <root-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-async-data-broker</type>
+                        <name>binding-data-broker</name>
+                    </root-data-broker>
                 </module>
 
 
                     </schema-service>
                 </module>
 
+                <!-- DISTRIBUTED_DATA_STORE -->
+                <!-- Enable the following modules if you want to use the Distributed Data Store instead of the InMemoryDataStore -->
+                <!--
                 <module>
-                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider">prefix:inmemory-operational-datastore-provider</type>
-                    <name>operational-store-service</name>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:distributed-datastore-provider">prefix:distributed-operational-datastore-provider</type>
+                    <name>distributed-operational-store-module</name>
+                    <schema-service>
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+                        <name>yang-schema-service</name>
+                    </schema-service>
+                </module>
+
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:distributed-datastore-provider">prefix:distributed-config-datastore-provider</type>
+                    <name>distributed-config-store-module</name>
                     <schema-service>
                         <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
                         <name>yang-schema-service</name>
                     </schema-service>
                 </module>
+                -->
 
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider">prefix:inmemory-operational-datastore-provider</type>
+                    <name>operational-store-service</name>
+                    <operational-schema-service>
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+                        <name>yang-schema-service</name>
+                    </operational-schema-service>
+                </module>
                 <!--
                      Tree-based in-memory data store. This is the data store which is currently
                      recommended for single-node deployments.
                    <config-data-store>
                         <type xmlns:config-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store">config-dom-store-spi:config-dom-datastore</type>
                         <name>config-store-service</name>
+                        <!-- DISTRIBUTED_DATA_STORE -->
+                        <!--
+                        <name>distributed-config-store-service</name>
+                        -->
                     </config-data-store>
 
                     <operational-data-store>
                         <type xmlns:operational-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store">operational-dom-store-spi:operational-dom-datastore</type>
                         <name>operational-store-service</name>
+                        <!-- DISTRIBUTED_DATA_STORE -->
+                        <!--
+                        <name>distributed-operational-store-service</name>
+                        -->
+
                     </operational-data-store>
                 </module>
                 <module>
                         </binding-mapping-service>
                     </binding-forwarded-data-broker>
                 </module>
+                <!-- Cluster RPC -->
+                <!-- Enable the following module if you want to use remote rpc connector
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:remote-rpc-connector">prefix:remote-rpc-connector</type>
+                    <name>remote-rpc-connector</name>
+                    <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:remote-rpc-connector">
+                        <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>
+                </module>
+                -->
             </modules>
             <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
                     <service>
                             <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
                         </instance>
                     </service>
+
+                <!-- DISTRIBUTED_DATA_STORE -->
+                <!-- Enable the following if you want to use the Distributed Data Store instead of the InMemory Data Store -->
+                <!-- Note that you MUST delete the InMemoryDataStore related services which provide config-dom-datastore and operational-dom-datastore -->
+                <!--
+                <service>
+                    <type xmlns:config-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store">config-dom-store-spi:config-dom-datastore</type>
+                    <instance>
+                        <name>distributed-config-store-service</name>
+                        <provider>/modules/module[type='distributed-config-datastore-provider'][name='distributed-config-store-module']</provider>
+                    </instance>
+                </service>
+                <service>
+                    <type xmlns:operational-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store">operational-dom-store-spi:operational-dom-datastore</type>
+                    <instance>
+                        <name>distributed-operational-store-service</name>
+                        <provider>/modules/module[type='distributed-operational-datastore-provider'][name='distributed-operational-store-module']</provider>
+                    </instance>
+                </service>
+                -->
+
+                <!-- DISTRIBUTED_DATA_STORE -->
+                <!-- Delete the following two services (config-store-service and operational-store-service) if you want to use the distributed data store instead -->
                 <service>
                     <type xmlns:config-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store">config-dom-store-spi:config-dom-datastore</type>
                     <instance>
index 8fedbe4d4c1c1b35d7404fa9f5c3daf4ce3997f0..f81a332ab6e8a2832b62e0e9a7ff164b1488ab46 100644 (file)
@@ -12,7 +12,7 @@
     <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
 
-        <!-- Netconf dispatcher to be used by all netconf-connectors --> 
+        <!-- Netconf dispatcher to be used by all netconf-connectors -->
         <module>
           <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">prefix:netconf-client-dispatcher</type>
           <name>global-netconf-dispatcher</name>
           </timer>
         </module>
 
-        <!-- Thread factory to be used by all threadpools in netconf-connectors --> 
+        <!-- Thread factory to be used by all threadpools in netconf-connectors -->
         <module>
           <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">prefix:threadfactory-naming</type>
           <name>global-netconf-processing-executor-threadfactory</name>
           <name-prefix xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">remote-connector-processing-executor</name-prefix>
-        </module> 
-        <!-- Flexible threadpool for all netconf connectors, Max thread count is set to 4 --> 
+        </module>
+        <!-- flexible threadpool for all netconf connectors, Max thread count is set to 4.  -->
         <module>
           <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">prefix:threadpool-flexible</type>
           <name>global-netconf-processing-executor</name>
           <minThreadCount xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">1</minThreadCount>
           <max-thread-count xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">4</max-thread-count>
           <keepAliveMillis xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">600000</keepAliveMillis>
+
           <threadFactory xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">
             <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
             <name>global-netconf-processing-executor-threadfactory</name>
           </threadFactory>
-        </module>  
+        </module>
       </modules>
 
       <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
index d1a5dcc416cc190dd3dabd80fdc5e8963a6af9a3..94a3702fdbc56d70073d593f6ed7b50a4a35d46a 100644 (file)
     <appender-ref ref="opendaylight.log"/>
   </logger>
 
+  <!-- BGPCEP plugin -->
+  <logger name="org.opendaylight.protocol" level="INFO"/>
+  <logger name="org.opendaylight.bgpcep" level="INFO"/>
+
   <!-- To debug MD-SAL schema loading issues, uncomment this -->
   <!--logger name="org.opendaylight.yangtools.yang.parser.impl.util.URLSchemaContextResolver" level="DEBUG"/>
   <logger name="org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl" level="TRACE"/-->
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/functions.sh b/opendaylight/distribution/opendaylight/src/main/resources/functions.sh
new file mode 100644 (file)
index 0000000..21dd4c1
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# Function harvestHelp searches in run.sh part for line starting with "##<name command>".
+# Next lines starting with "#<text>" will be printed without first char # (=help content).
+# Help content has to end with "##" on new line.
+# Example:
+##foo
+#   Foo is world wide used synnonym for bar.
+##
+function harvestHelp() {
+    key="$1"
+    if [ -z "${key}" ]; then
+         key='HELP'
+    fi
+    echo
+    sed -rn "/^##${key}$/,/^##/ p" $0 | sed -r '1 d; $ d; s/^#/  /'
+    grep "##${key}" $0 > /dev/null
+}
index 72ccd02707ba7f5c76f064e5a16767a42f5fd37f..ce13e3396862a042a37aeb89dad5b3ca66d59094 100644 (file)
@@ -14,6 +14,7 @@ SET jvmMaxMemory=
 SET extraJVMOpts=
 SET consoleOpts=-console -consoleLog
 SET PID=
+SET JAVA_H=%JAVA_HOME%\bin\jps.exe
 
 :LOOP
 IF "%~1" NEQ "" (
@@ -61,7 +62,7 @@ IF "%~1" NEQ "" (
        GOTO :LOOP
     )
     IF "!CARG!"=="-status" (
-       for /F "TOKENS=1" %%G in ('%JAVA_HOME%\bin\jps.exe -lvV ^| find /I "opendaylight"') do (
+       for /F "TOKENS=1" %%G in ('""!JAVA_H!" -lvV ^| find /I "opendaylight""') do (
            set PID=%%G
        )
        if "!PID!" NEQ "" (
@@ -72,7 +73,7 @@ IF "%~1" NEQ "" (
        GOTO :EOF
     )
     IF "!CARG!"=="-stop" (
-       for /F "TOKENS=1" %%G in ('%JAVA_HOME%\bin\jps.exe -lvV ^| find /I "opendaylight"') do (
+       for /F "TOKENS=1" %%G in ('""!JAVA_H!" -lvV ^| find /I "opendaylight""') do (
            set PID=%%G
        )
        if "!PID!" NEQ "" (
@@ -89,18 +90,23 @@ IF "%~1" NEQ "" (
        GOTO :LOOP
     )
     IF "!CARG:~0,2!"=="-D" (
-       SET extraJVMOpts=%extraJVMOpts% !CARG!
+       SET extraJVMOpts=!extraJVMOpts! !CARG!
        SHIFT
        GOTO :LOOP
     )
     IF "!CARG:~0,2!"=="-X" (
-       SET extraJVMOpts=%extraJVMOpts% !CARG!
+       SET extraJVMOpts=!extraJVMOpts! !CARG!
        SHIFT
        GOTO :LOOP
     )
     IF "!CARG!"=="-help" (
-        ECHO "Usage: %0 [-jmx] [-jmxport <num>] [-debug] [-debugsuspend] [-debugport <num>] [-start] [-consoleport <num>]] [-stop] [-status] [-console] [-help] [<other args will automatically be used for the JVM>]"
-        ECHO Note: Enclose any JVM or System properties within double quotes.
+        SHIFT
+        SET CARG=%2
+        IF "!CARG!" NEQ "" (
+             CALL:!CARG!
+        ) ELSE (
+              CALL:helper
+         )
         GOTO :EOF
     )
 
@@ -110,28 +116,24 @@ IF "%~1" NEQ "" (
 
 IF "%debugEnabled%" NEQ "" (
     REM ECHO "DEBUG enabled"
-    SET extraJVMOpts=%extraJVMOpts% -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=%debugport%
+    SET extraJVMOpts=!extraJVMOpts! -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=%debugport%
 )
+
 IF "%debugSuspended%" NEQ "" (
     REM ECHO "DEBUG enabled suspended"
-    SET extraJVMOpts=%extraJVMOpts% -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=%debugport%
+    SET extraJVMOpts=!extraJVMOpts! -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=%debugport%
 )
 
 IF "%jvmMaxMemory%"=="" (
     SET jvmMaxMemory=-Xmx1G
-    ECHO *****************************************************************
-    ECHO JVM maximum memory was not defined. Setting maximum memory to 1G.
-    ECHO To define the maximum memory, specify the -Xmx setting on the
-    ECHO command line.
-    ECHO                    e.g. run.bat -Xmx1G
-    ECHO *****************************************************************"
+    ECHO Setting maximum memory to 1G.
 )
 
-SET extraJVMOpts=%extraJVMOpts%  %jvmMaxMemory%
+SET extraJVMOpts=!extraJVMOpts!  %jvmMaxMemory%
 
 IF "%jmxEnabled%" NEQ "" (
     REM ECHO "JMX enabled "
-    SET extraJVMOpts=%extraJVMOpts% -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=%jmxport% -Dcom.sun.management.jmxremote
+    SET extraJVMOpts=!extraJVMOpts! -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=%jmxport% -Dcom.sun.management.jmxremote
 )
 IF "%startEnabled%" NEQ "" (
     REM ECHO "START enabled "
@@ -139,7 +141,7 @@ IF "%startEnabled%" NEQ "" (
 )
 
 REM       Check if controller is already running
-for /F "TOKENS=1" %%G in ('%JAVA_HOME%\bin\jps.exe -lvV ^| find /I "opendaylight"') do (
+for /F "TOKENS=1" %%G in ('""!JAVA_H!" -lvV ^| find /I "opendaylight""') do (
     SET PID=%%G
 )
 if "!PID!" NEQ "" (
@@ -154,16 +156,125 @@ SET cp="%basedir%lib\org.eclipse.osgi-3.8.1.v20120830-144521.jar;%basedir%lib\or
 REM       Now set framework classpath
 SET fwcp="file:\%basedir%lib\org.eclipse.osgi-3.8.1.v20120830-144521.jar,file:\%basedir%lib\org.eclipse.virgo.kernel.equinox.extensions-3.6.0.RELEASE.jar,file:\%basedir%lib\org.eclipse.equinox.launcher-1.3.0.v20120522-1813.jar"
 
-SET RUN_CMD="%JAVA_HOME%\bin\java.exe" -Dopendaylight.controller %extraJVMOpts% -Djava.io.tmpdir="%basedir%work\tmp" -Djava.awt.headless=true -Dosgi.install.area=%basedir% -Dosgi.configuration.area="%basedir%configuration" -Dosgi.frameworkClassPath=%fwcp% -Dosgi.framework="file:\%basedir%lib\org.eclipse.osgi-3.8.1.v20120830-144521.jar" -classpath %cp% org.eclipse.equinox.launcher.Main %consoleOpts%
+SET RUN_CMD="%JAVA_HOME%\bin\java.exe" -Dopendaylight.controller !extraJVMOpts! -Djava.io.tmpdir="%basedir%work\tmp" -Djava.awt.headless=true -Dosgi.install.area=%basedir% -Dosgi.configuration.area="%basedir%configuration" -Dosgi.frameworkClassPath=%fwcp% -Dosgi.framework="file:\%basedir%lib\org.eclipse.osgi-3.8.1.v20120830-144521.jar" -classpath %cp% org.eclipse.equinox.launcher.Main %consoleOpts%
 
-ECHO %RUN_CMD%
+ECHO !RUN_CMD!
 
 if "%startEnabled%" NEQ "" (
-    START /B cmd /C CALL %RUN_CMD% > %basedir%\logs\controller.out 2>&1
+    START /B cmd /C CALL !RUN_CMD! > %basedir%\logs\controller.out 2>&1
     ECHO Running controller in the background.
+    EXIT /B 1
 ) else (
-    %RUN_CMD%
+    !RUN_CMD!
     EXIT /B %ERRORLEVEL%
 )
 
+:helper
+echo. For more information on a specific command, type -help command-name.
+echo.
+echo   jmx              ^[-jmx^]
+echo   jmxport          ^[-jmxport ^<num^>^] - DEFAULT is 1088
+echo   debug            ^[-debug^]
+echo   debugsuspend     ^[-debugsuspend^]
+echo   debugport        ^[-debugport ^<num^>^] - DEFAULT is 8000
+echo   start            ^[-start ^[^<console port^>^]^] - DEFAULT port is 2400
+echo   stop             ^[-stop^]
+echo   status           ^[-status^]
+echo   console          ^[-console^]
+echo   agentpath        ^[-agentpath:^<path to lib^>^]
+exit/B 1
+
+:debugsuspend
+ECHO.
+ECHO. debugsuspend     ^[-debugsuspend^]
+ECHO.
+ECHO. This command sets suspend on true in runjdwp in extra JVM options. If its true, VMStartEvent has a suspendPolicy of SUSPEND_ALL. If its false, VMStartEvent has a suspendPolicy of SUSPEND_NONE.
+ECHO.
+EXIT /B 1
+
+:debugport
+ECHO.
+ECHO. debugport        ^[-debugport ^<num^>^] - DEFAULT is 8000
+ECHO.
+ECHO. Set address for settings in runjdwp in extra JVM options.
+ECHO. The address is transport address for the connection.
+ECHO. The address has to be in the range ^[1024,65535^]. If the option was not call, port will be set to default value.
+ECHO.
+EXIT /B 1
+
+:jmxport
+ECHO.
+ECHO. jmxport          ^[-jmxport ^<num^>^] - DEFAULT is 1088
+ECHO.
+ECHO.    Set jmx port for com.sun.management.jmxremote.port in JMX support. Port has to be in the range ^[1024,65535^]. If this option was not call, port will be set to default value.
+ECHO.
+EXIT /B 1
+
+:debug
+ECHO.
+ECHO. debug            [-debug]
+ECHO.
+ECHO. Run ODL controller with -Xdebug and -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=^$^{debugport^}
+ECHO.
+ECHO.    -Xdebug enables debugging capabilities in the JVM which are used by the Java Virtual Machine Tools Interface (JVMTI). JVMTI is a low-level debugging interface used by debuggers and profiling tools.
+ECHO.
+ECHO.    -Xrunjdwp option loads the JPDA reference implementation of JDWP. This library resides in the target VM and uses JVMDI and JNI to interact with it. It uses a transport and the JDWP protocol to communicate with a separate debugger application.
+ECHO.
+ECHO. settings for -Xrunjdwp:
+ECHO.            transport -  name of the transport to use in connecting to debugger application
+ECHO.            server    -  if 'y', listen for a debugger application to attach; otherwise, attach to the debugger application at the specified address
+ECHO.                      -  if 'y' and no address is specified, choose a transport address at which to listen for a debugger application, and print the address to the standard output stream
+ECHO.            suspend   -  if 'y', VMStartEvent has a suspend Policy of SUSPEND_ALL
+ECHO.                      -  if 'n', VMStartEvent has a suspend policy of SUSPEND_NONE
+ECHO.            address   -  transport address for the connection
+ECHO.                      -  if server=n, attempt to attach to debugger application at this address
+ECHO.          -  if server=y, listen for a connection at this address
+ECHO.
+EXIT /B 1
+
+:jmx
+ECHO.
+ECHO. jmx              [-jmx]
+ECHO.
+ECHO. Add JMX support. With settings for extra JVM options: -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=^$^{jmxport^} -Dcom.sun.management.jmxremote
+ECHO. jmxport can by set with option -jmxport ^<num^>. Default num for the option is 1088.
+ECHO.
+EXIT /B 1
+
+:stop
+ECHO.
+ECHO. stop             ^[-stop^]
+ECHO.
+ECHO. If a controller is running, the command stop controller. Pid will be clean.
+ECHO.
+EXIT /B 1
+
+:status
+ECHO.
+ECHO. status           ^[-status^]
+ECHO.
+ECHO. Find out whether a controller is running and print it.
+ECHO.
+EXIT /B 1
+
+:start
+ECHO.
+ECHO. start            ^[-start ^[^<console port^>^]^]
+ECHO.
+ECHO.    If controller is not running, the command with argument^(for set port, where controller has start^) will start new controller on a port. The port has to be in the range ^[1024,65535^]. If this option was not call, port will be set to default value. Pid will be create.
+EXIT /B 1
+
+:console
+ECHO.
+ECHO. console          [-console]
+ECHO.     Default option.
+EXIT /B 1
+
+:agentpath
+ECHO.
+ECHO. agentpath        ^[-agentpath:^<path to lib^>^]
+ECHO.
+ECHO.    Agentpath option passes path to agent to jvm in order to load native agent library, e.g. yourkit profiler agent.
+EXIT /B 1
+
 
index 1e903d06503c286d7a0e8b41556c826eb5d6d105..13be2336b6db94304d944b78ba912530bee25c5f 100755 (executable)
@@ -1,5 +1,20 @@
 #!/bin/bash
 
+##HELP
+# For more information on a specific command, type -help command-name.
+#
+#   jmx              [-jmx]
+#   jmxport          [-jmxport <num>] - DEFAULT is 1088
+#   debug            [-debug]
+#   debugsuspend     [-debugsuspend]
+#   debugport        [-debugport <num>] - DEFAULT is 8000
+#   start            [-start [<console port>]] - DEFAULT port is 2400
+#   stop             [-stop]
+#   status           [-status]
+#   console          [-console]
+#   agentpath        [-agentpath:<path to lib>]
+##
+
 platform='unknown'
 unamestr=`uname`
 if [[ "$unamestr" == 'Linux' ]]; then
@@ -58,11 +73,6 @@ else
     datadir=${ODL_DATADIR}
 fi
 
-function usage {
-    echo "Usage: $0 [-jmx] [-jmxport <num>] [-debug] [-debugsuspend] [-debugport <num>] [-start [<console port>]] [-stop] [-status] [-console] [-help] [-agentpath:<path to lib>] [<other args will automatically be used for the JVM>]"
-    exit 1
-}
-
 if [ -z ${TMP} ]; then
     pidfile="/tmp/opendaylight.PID"
 else
@@ -82,13 +92,15 @@ stopdaemon=0
 statusdaemon=0
 consolestart=1
 dohelp=0
-jvmMaxMemory=""
+jvmMaxMemory="-Xmx1G"
 extraJVMOpts=""
 agentPath=""
 unknown_option=0
+helper=""
 while true ; do
     case "$1" in
         -debug) debug=1; shift ;;
+        -help) dohelp=1; shift;  helper=$1; break ;;
         -jmx) startjmx=1; shift ;;
         -debugsuspend) debugsuspend=1; shift ;;
         -debugport) shift; debugportread="$1"; if [[ "${debugportread}" =~ ^[0-9]+$ ]] ; then debugport=${debugportread}; shift; else echo "-debugport expects a number but was not found"; exit -1; fi;;
@@ -97,37 +109,39 @@ while true ; do
         -stop) stopdaemon=1; shift ;;
         -status) statusdaemon=1; shift ;;
         -console) shift ;;
-        -help) dohelp=1; shift;;
         -Xmx*) jvmMaxMemory="$1"; shift;;
         -D*) extraJVMOpts="${extraJVMOpts} $1"; shift;;
         -X*) extraJVMOpts="${extraJVMOpts} $1"; shift;;
         -agentpath:*) agentPath="$1"; shift;;
         "") break ;;
-        *) echo "Unknown option $1"; unknown_option=1; shift ;;
+        *) echo "Unknown option $1"; unknown_option=1; break ;;
     esac
 done
 
-# Unknown Options and help
+
+
 if [ "${unknown_option}" -eq 1 ]; then
-    usage
+    echo "Use -help for more information."
+    exit 1
 fi
 
-if [ "${dohelp}" -eq 1 ]; then
-    usage
-fi
 
-if [ "${jvmMaxMemory}" == "" ]; then
-    jvmMaxMemory="-Xmx1G"
-    echo "*****************************************************************"
-    echo "JVM maximum memory was not defined. Setting maximum memory to 1G."
-    echo "To define the maximum memory, specify the -Xmx setting on the"
-    echo "command line. "
-    echo "        e.g. ./run.sh -Xmx1G"
-    echo "*****************************************************************"
+if [ "${dohelp}" -eq 1 ]; then
+    . ${basedir}/functions.sh
+    harvestHelp ${helper}
+    echo -e '\nFor other information type -help.\n'
+    exit 1
 fi
 
 extraJVMOpts="${extraJVMOpts} ${jvmMaxMemory}"
 
+##debugport
+#debugport        [-debugport <num>] - DEFAULT is 8000
+#
+#    Set address for settings in runjdwp in extra JVM options.
+#    The address is transport address for the connection.
+#    The address has to be in the range [1024,65535]. If this option was not call, port will be set to default value.
+##
 # Validate debug port
 if [[ "${debugport}" -lt 1024 ]] || [[ "${debugport}" -gt 65535 ]]; then
     echo "Debug Port not in the range [1024,65535] ${debugport}"
@@ -140,19 +154,51 @@ if [[ "${daemonport}" -lt 1024 ]] || [[ "${daemonport}" -gt 65535 ]]; then
     exit -1
 fi
 
+##jmxport
+#jmxport          [-jmxport <num>] - DEFAULT is 1088
+#
+#    Set jmx port for com.sun.management.jmxremote.port in JMX support. Port has to be in the range [1024,65535]. If this option was not call, port will be set to default value.
+##
 # Validate jmx port
 if [[ "${jmxport}" -lt 1024 ]] || [[ "${jmxport}" -gt 65535 ]]; then
     echo "JMX Port not in the range [1024,65535] value is ${jmxport}"
     exit -1
 fi
+##debug
+#debug            [-debug]
+#
+#Run ODL controller with -Xdebug and -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=\${debugport}
+#-Xdebug enables debugging capabilities in the JVM which are used by the Java Virtual Machine Tools Interface (JVMTI). JVMTI is a low-level debugging interface used by debuggers and profiling tools.
+#-Xrunjdwp option loads the JPDA reference implementation of JDWP. This library resides in the target VM and uses JVMDI and JNI to interact with it. It uses a transport and the JDWP protocol to
+#communicate with a separate debugger application.
+#settings for -Xrunjdwp:
+#            transport -  name of the transport to use in connecting to debugger application
+#            server    -  if “y”, listen for a debugger application to attach; otherwise, attach to the debugger application at the specified address
+#                      -  if “y” and no address is specified, choose a transport address at which to listen for a debugger application, and print the address to the standard output stream
+#            suspend   -  if “y”, VMStartEvent has a suspend Policy of SUSPEND_ALL
+#                      -  if “n”, VMStartEvent has a suspend policy of SUSPEND_NONE
+#            address   -  transport address for the connection
+#                      -  if server=n, attempt to attach to debugger application at this address
+#          -  if server=y, listen for a connection at this address
+##
 
+##debugsuspend
+#debugsuspend     [-debugsuspend]
+#
+#This command sets suspend on true in runjdwp in extra JVM options. If its true, VMStartEvent has a suspendPolicy of SUSPEND_ALL. If its false, VMStartEvent has a suspendPolicy of SUSPEND_NONE.
+##
 # Debug options
 if [ "${debugsuspend}" -eq 1 ]; then
     extraJVMOpts="${extraJVMOpts} -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=${debugport}"
 elif [ "${debug}" -eq 1 ]; then
     extraJVMOpts="${extraJVMOpts} -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=${debugport}"
 fi
-
+##jmx
+#jmx              [-jmx]
+#
+#Add JMX support. With settings for extra JVM options: -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=\${jmxport} -Dcom.sun.management.jmxremote
+#jmxport can by set with command -jmxport <num>. Default num for the option is 1088.
+##
 # Add JMX support
 if [ "${startjmx}" -eq 1 ]; then
     extraJVMOpts="${extraJVMOpts} -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=${jmxport} -Dcom.sun.management.jmxremote"
@@ -182,6 +228,11 @@ FWCLASSPATH=${FWCLASSPATH},file:${basedir}/lib/org.eclipse.equinox.launcher-1.3.
 
 cd $basedir
 
+##stop
+#stop             [-stop]
+#
+#If a controller is running, the command stop controller. Pid will be clean.
+##
 if [ "${stopdaemon}" -eq 1 ]; then
     if [ -e "${pidfile}" ]; then
         daemonpid=`cat "${pidfile}"`
@@ -195,6 +246,11 @@ if [ "${stopdaemon}" -eq 1 ]; then
     fi
 fi
 
+##status
+#status           [-status]
+#
+#Find out whether a controller is running and print it.
+##
 if [ "${statusdaemon}" -eq 1 ]; then
     if [ -e "${pidfile}" ]; then
         daemonpid=`cat "${pidfile}"`
@@ -219,6 +275,22 @@ bdir=`echo "${basedir}" | sed 's/ /\\ /g'`
 confarea=`echo "${datadir}" | sed 's/ /\\ /g'`
 fwclasspath=`echo "${FWCLASSPATH}" | sed 's/ /\\ /g'`
 
+##start
+#start            [-start [<console port>]]
+#
+#    If controller is not running, the command with argument(for set port, where controller has start) will start new controller on a port. The port has to be in the range [1024,65535]. If this option was not call, port will be set to default value. Pid will be create.
+##
+##console
+#console          [-console]
+#
+#    Default option.
+##
+##agentpath
+#agentpath        [-agentpath:<path to lib>]
+#
+#   Agentpath option passes path to agent to jvm in order to load native agent library, e.g. yourkit profiler agent.
+##
+echo "JVM maximum memory was set to ${jvmMaxMemory}."
 if [ "${startdaemon}" -eq 1 ]; then
     if [ -e "${pidfile}" ]; then
         echo "Another instance of controller running, check with $0 -status"
index c89cfc1b9e8914148bc58fc6f3a375baca026e53..e2b6642501edf8acefb9f47743c5166455c8e8db 100644 (file)
@@ -867,6 +867,7 @@ public class FlowConfig extends ConfigurationObject implements Serializable {
                     }
                     continue;
                 }
+
                 sstr = Pattern.compile(ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(actiongrp);
                 if (sstr.matches()) {
                     if (!NetUtils.isIPAddressValid(sstr.group(1))) {
@@ -875,7 +876,57 @@ public class FlowConfig extends ConfigurationObject implements Serializable {
                     }
                     continue;
                 }
-            }
+
+                sstr = Pattern.compile(ActionType.OUTPUT + "=(.*)").matcher(actiongrp);
+                if (sstr.matches()) {
+                    continue;
+                }
+
+                sstr = Pattern.compile(ActionType.DROP.toString()).matcher(actiongrp);
+                if (sstr.matches()) {
+                    continue;
+                }
+
+                sstr = Pattern.compile(ActionType.LOOPBACK.toString()).matcher(actiongrp);
+                if (sstr.matches()) {
+                    continue;
+                }
+
+                sstr = Pattern.compile(ActionType.FLOOD.toString()).matcher(actiongrp);
+                if (sstr.matches()) {
+                    continue;
+                }
+
+                sstr = Pattern.compile(ActionType.FLOOD_ALL.toString()).matcher(actiongrp);
+                if (sstr.matches()) {
+                    continue;
+                }
+
+                sstr = Pattern.compile(ActionType.SW_PATH.toString()).matcher(actiongrp);
+                if (sstr.matches()) {
+                    continue;
+                }
+
+                sstr = Pattern.compile(ActionType.HW_PATH.toString()).matcher(actiongrp);
+                if (sstr.matches()) {
+                    continue;
+                }
+
+                sstr = Pattern.compile(ActionType.CONTROLLER.toString()).matcher(actiongrp);
+                if (sstr.matches()) {
+                    continue;
+                }
+
+                sstr = Pattern.compile(ActionType.POP_VLAN.toString()).matcher(actiongrp);
+                if (sstr.matches()) {
+                    continue;
+                }
+
+                // If execution reached here, it means there is an Action
+                // which is not recognized by the controller. Return error
+
+                return new Status(StatusCode.BADREQUEST, String.format("%s is an UnSupported Action", actiongrp));
+           }
         } catch (NumberFormatException e) {
             return new Status(StatusCode.BADREQUEST, String.format("Invalid number format %s", e.getMessage()));
         }
index 685ccdb7c44ea78931de795bb21547c1bd116b36..3c367b9af45d267816bca893c257b35d8c42c8f8 100644 (file)
@@ -760,9 +760,9 @@ public class frmTest {
         actions.add(ActionType.SET_NW_SRC.toString() + "=1.1.1.1");
         actions.add(ActionType.SET_NW_DST.toString() + "=2.2.2.2");
         actions.add(ActionType.CONTROLLER.toString());
-        actions.add(ActionType.SET_NW_TOS.toString() + "1");
-        actions.add(ActionType.SET_TP_SRC.toString() + "60");
-        actions.add(ActionType.SET_TP_DST.toString() + "8080");
+        actions.add(ActionType.SET_NW_TOS.toString() + "=1");
+        actions.add(ActionType.SET_TP_SRC.toString() + "=60");
+        actions.add(ActionType.SET_TP_DST.toString() + "=8080");
         actions.add(ActionType.SET_NEXT_HOP.toString() + "=1.1.1.1");
 
         return actions;
index be3add104289951ef29a9564d03f7a197fcf73c7..0653eeb2a63810d5b89e291facbb4c4f7e822e2f 100644 (file)
@@ -7,8 +7,6 @@
  */
 package org.opendaylight.controller.md.frm.compatibility;
 
-import java.util.Collections;
-
 import org.opendaylight.controller.forwardingrulesmanager.FlowConfig;
 import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager;
 import org.opendaylight.controller.md.sal.common.api.data.DataChangeListener;
@@ -17,7 +15,6 @@ import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
 import org.opendaylight.controller.sal.common.util.Arguments;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey;
 import org.opendaylight.yangtools.concepts.Registration;
@@ -26,8 +23,8 @@ import org.opendaylight.yangtools.yang.binding.Identifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 
 import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
@@ -41,7 +38,7 @@ public class FRMRuntimeDataProvider implements RuntimeDataProvider, DataCommitHa
     private DataProviderService dataService;
     private IForwardingRulesManager manager;
 
-    public Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> init() {
+    public Registration init() {
         return this.dataService.registerCommitHandler(FRMRuntimeDataProvider.FLOWS_PATH, this);
     }
 
@@ -89,7 +86,7 @@ public class FRMRuntimeDataProvider implements RuntimeDataProvider, DataCommitHa
             this.manager.removeStaticFlow(flow.getName(), flow.getNode());
             this.manager.addStaticFlow(flow);
         }
-        return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+        return RpcResultBuilder.<Void> success().build();
     }
 
     public RpcResult<Void> rollback(final FlowCommitTransaction transaction) {
index 36045cabf4bfefc672d3edde8001a75deba46385..1b648dc98c36c0c6e05bfce6740b294dd730e8b8 100644 (file)
@@ -103,7 +103,8 @@ 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());
+            NodeConnector port = (NodeConnector)inPort.getValue();
+            return (NodeConnectorId)MDFlowMapping.toUri(port);
         }
         return null;
     }
@@ -203,9 +204,11 @@ public class FromSalConversionsUtils {
         MatchField vlan = sourceMatch.getField(MatchType.DL_VLAN);
         if (vlan != null && vlan.getValue() != null) {
             VlanIdBuilder vlanIDBuilder = new VlanIdBuilder();
+            short vid = (short)vlan.getValue();
+            boolean present = (vid != MatchType.DL_VLAN_NONE);
             vlanIDBuilder.setVlanId(new VlanId((NetUtils
-                    .getUnsignedShort((short) vlan.getValue()))));
-            vlanIDBuilder.setVlanIdPresent(true);
+                    .getUnsignedShort(vid))));
+            vlanIDBuilder.setVlanIdPresent(present);
             vlanMatchBuild.setVlanId(vlanIDBuilder.build());
         }
 
index 5959d233669264d98d904a1eca891aa2024854b5..e2c13867754d187f26f9f9a1dc4414a2b4114572 100644 (file)
@@ -7,9 +7,12 @@
  */
 package org.opendaylight.controller.sal.compatibility;
 
+import com.google.common.collect.Iterables;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -733,26 +736,45 @@ public class InventoryAndReadAdapter implements IPluginInReadService, IPluginInI
     }
 
     private boolean isKnownNodeConnector(final InstanceIdentifier<? extends Object> nodeConnectorIdentifier) {
-        final List<PathArgument> path = nodeConnectorIdentifier.getPath();
-        if (path.size() >= 3) {
-            final PathArgument nodePath = path.get(1);
-            final PathArgument nodeConnectorPath = path.get(2);
-            final List<PathArgument> nodeConnectors = nodeToNodeConnectorsMap.get(nodePath);
-            if (nodeConnectors != null) {
-                return nodeConnectors.contains(nodeConnectorPath);
-            }
+        final Iterator<PathArgument> it = nodeConnectorIdentifier.getPathArguments().iterator();
+
+        if (!it.hasNext()) {
+            return false;
         }
-        return false;
+        it.next();
+
+        if (!it.hasNext()) {
+            return false;
+        }
+        final PathArgument nodePath = it.next();
+
+        if (!it.hasNext()) {
+            return false;
+        }
+        final PathArgument nodeConnectorPath = it.next();
+
+        final List<PathArgument> nodeConnectors = nodeToNodeConnectorsMap.get(nodePath);
+        return nodeConnectors == null ? false :
+            nodeConnectors.contains(nodeConnectorPath);
     }
 
     private boolean recordNodeConnector(final InstanceIdentifier<? extends Object> nodeConnectorIdentifier) {
-        final List<PathArgument> path = nodeConnectorIdentifier.getPath();
-        if (path.size() < 3) {
+        final Iterator<PathArgument> it = nodeConnectorIdentifier.getPathArguments().iterator();
+
+        if (!it.hasNext()) {
             return false;
         }
+        it.next();
 
-        final PathArgument nodePath = path.get(1);
-        final PathArgument nodeConnectorPath = path.get(2);
+        if (!it.hasNext()) {
+            return false;
+        }
+        final PathArgument nodePath = it.next();
+
+        if (!it.hasNext()) {
+            return false;
+        }
+        final PathArgument nodeConnectorPath = it.next();
 
         synchronized (this) {
             List<PathArgument> nodeConnectors = this.nodeToNodeConnectorsMap.get(nodePath);
@@ -766,6 +788,6 @@ public class InventoryAndReadAdapter implements IPluginInReadService, IPluginInI
     }
 
     private List<PathArgument> removeNodeConnectors(final InstanceIdentifier<? extends Object> nodeIdentifier) {
-        return this.nodeToNodeConnectorsMap.remove(nodeIdentifier.getPath().get(1));
+        return this.nodeToNodeConnectorsMap.remove(Iterables.get(nodeIdentifier.getPathArguments(), 1));
     }
 }
index a700c86b9c5c00f41a3ade60a650298adfc5883d..02964c6d5531553d23abaa0cce39dfae1db30881 100644 (file)
@@ -11,6 +11,7 @@ import java.math.BigInteger;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
+
 import org.opendaylight.controller.sal.common.util.Arguments;
 import org.opendaylight.controller.sal.core.AdvertisedBandwidth;
 import org.opendaylight.controller.sal.core.Bandwidth;
@@ -61,6 +62,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
 
@@ -94,13 +96,14 @@ public final class NodeMapping {
 
     /**
      * @param adNodeId
-     * @return
+     * @return nodeId as long
      */
-    private static Long openflowFullNodeIdToLong(String adNodeId) {
+    @VisibleForTesting
+    public static Long openflowFullNodeIdToLong(String adNodeId) {
         if (adNodeId == null) {
             return null;
         }
-        return Long.valueOf(adNodeId.replaceFirst("^.*:", ""));
+        return new BigInteger(adNodeId.replaceFirst("^.*:", "")).longValue();
     }
 
     public static NodeId toNodeId(final InstanceIdentifier<?> id) {
index 7bbf7f10e0c2be3c8246849d468fdbc0a8be5996..58cfb20650930f82f5768fa9f96bbcd1e287ad14 100644 (file)
@@ -430,13 +430,17 @@ public class ToSalConversionsUtils {
         if (vlanMatch != null) {
             VlanId vlanId = vlanMatch.getVlanId();
             if (vlanId != null) {
-                org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId vlanIdInner = vlanId
-                        .getVlanId();
-                if (vlanIdInner != null) {
-                    Integer vlanValue = vlanIdInner.getValue();
-                    if (vlanValue != null) {
-                        target.setField(DL_VLAN, vlanValue.shortValue());
+                if (Boolean.TRUE.equals(vlanId.isVlanIdPresent())) {
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId vlanIdInner = vlanId
+                            .getVlanId();
+                    if (vlanIdInner != null) {
+                        Integer vlanValue = vlanIdInner.getValue();
+                        if (vlanValue != null) {
+                            target.setField(DL_VLAN, vlanValue.shortValue());
+                        }
                     }
+                } else {
+                    target.setField(DL_VLAN, MatchType.DL_VLAN_NONE);
                 }
             }
             VlanPcp vlanPcp = vlanMatch.getVlanPcp();
index 01d75acfe6332b3e6574683ad49736efdf58655f..56c7afb253a5224547f848b40b1b125bd376b553 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.controller.sal.compatibility.adsal;
 import java.math.BigInteger;
 
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.compatibility.InventoryMapping;
 import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils;
 import org.opendaylight.controller.sal.flowprogrammer.Flow;
@@ -32,6 +31,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -70,7 +70,8 @@ public class FlowServiceAdapter implements SalFlowService, IFlowProgrammerListen
         AddFlowOutputBuilder builder = new AddFlowOutputBuilder();
         builder.setTransactionId(new TransactionId(BigInteger.valueOf(status.getRequestId())));
         AddFlowOutput rpcResultType = builder.build();
-        return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
+        return Futures.immediateFuture(RpcResultBuilder.<AddFlowOutput>status(status.isSuccess())
+                .withResult(rpcResultType).build());
     }
 
     @Override
@@ -84,7 +85,8 @@ public class FlowServiceAdapter implements SalFlowService, IFlowProgrammerListen
         RemoveFlowOutputBuilder builder = new RemoveFlowOutputBuilder();
         builder.setTransactionId(new TransactionId(BigInteger.valueOf(status.getRequestId())));
         RemoveFlowOutput rpcResultType = builder.build();
-        return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
+        return Futures.immediateFuture(RpcResultBuilder.<RemoveFlowOutput>status(status.isSuccess())
+                                                         .withResult(rpcResultType).build());
 
     }
 
index c5cbecabedae35c96eb1fd0cad2ae5059253d074..e63cb54b8685174fafc7367bbe76bc130104a107 100644 (file)
@@ -13,7 +13,6 @@ import java.util.List;
 import java.util.concurrent.Future;
 
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.compatibility.FromSalConversionsUtils;
 import org.opendaylight.controller.sal.compatibility.InventoryMapping;
 import org.opendaylight.controller.sal.compatibility.NodeMapping;
@@ -60,6 +59,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.n
 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.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -107,7 +107,8 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
             LOG.error(e.getMessage());
         }
 
-        return Futures.immediateFuture(Rpcs.getRpcResult(rpcResultBool, rpcResultType, null));
+        return Futures.immediateFuture(RpcResultBuilder.<GetAllFlowStatisticsFromFlowTableOutput>
+                                                status(rpcResultBool).withResult(rpcResultType).build());
     }
 
     /**
@@ -133,7 +134,8 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
             LOG.error(e.getMessage());
         }
 
-        return Futures.immediateFuture(Rpcs.getRpcResult(rpcResultBool, rpcResultType, null));
+        return Futures.immediateFuture(RpcResultBuilder.<GetAllFlowsStatisticsFromAllFlowTablesOutput>
+                                               status(rpcResultBool).withResult(rpcResultType).build());
     }
 
     @Override
@@ -154,7 +156,8 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
             LOG.error(e.getMessage());
         }
 
-        return Futures.immediateFuture(Rpcs.getRpcResult(rpcResultBool, rpcResultType, null));
+        return Futures.immediateFuture(RpcResultBuilder.<GetFlowStatisticsFromFlowTableOutput>
+                                              status(rpcResultBool).withResult(rpcResultType).build());
     }
 
     @Override
index 8a23ebc933b54359ed7f4dc0d5b4786c05a17d21..cef7ae7a427672b8276411b2e1ace77f66dc04fd 100644 (file)
@@ -174,6 +174,18 @@ public class NodeMappingTest {
         Assert.assertEquals("openflow:1", observedNodeConnectorId);
     }
 
+    /**
+     * Test method for
+     * {@link org.opendaylight.controller.sal.compatibility.NodeMapping#openflowFullNodeIdToLong(String)}
+     * .
+     * @throws ConstructionException
+     */
+    @Test
+    public void testOpenflowFullNodeIdToLong() throws ConstructionException {
+        Assert.assertEquals(42L, NodeMapping.openflowFullNodeIdToLong("42").longValue());
+        Assert.assertEquals(0xCC4E241C4A000000L, NodeMapping.openflowFullNodeIdToLong("14721743935839928320").longValue());
+    }
+
     /**
      * @param nodeId
      * @param portId
index 5d5a409445a4708bf3b04472ded1e3bac89be496..e9f56f6a0301798b963fe9fb567c34076a640a44 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2013-2014 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -41,6 +41,11 @@ import org.opendaylight.controller.sal.action.SetVlanPcp;
 import org.opendaylight.controller.sal.action.SwPath;
 import org.opendaylight.controller.sal.compatibility.MDFlowMapping;
 import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.Node.NodeIDType;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
 import org.opendaylight.controller.sal.flowprogrammer.Flow;
 import org.opendaylight.controller.sal.match.Match;
 import org.opendaylight.controller.sal.match.MatchType;
@@ -79,11 +84,11 @@ import com.google.common.net.InetAddresses;
 
 public class TestFromSalConversionsUtils {
     private enum MtchType {
-        other, ipv4, ipv6, arp, sctp, tcp, udp
+        other, untagged, ipv4, ipv6, arp, sctp, tcp, udp
     }
 
     @Test
-    public void testFromSalConversion() {
+    public void testFromSalConversion() throws ConstructionException {
 
         Flow salFlow = prepareSalFlowCommon();
         NodeFlow odNodeFlow = MDFlowMapping.flowAdded(salFlow);
@@ -93,6 +98,9 @@ public class TestFromSalConversionsUtils {
         odNodeFlow = MDFlowMapping.flowAdded(prepareSalMatch(salFlow, MtchType.other));
         checkOdMatch(odNodeFlow.getMatch(), MtchType.other);
 
+        odNodeFlow = MDFlowMapping.flowAdded(prepareSalMatch(salFlow, MtchType.untagged));
+        checkOdMatch(odNodeFlow.getMatch(), MtchType.untagged);
+
         odNodeFlow = MDFlowMapping.flowAdded(prepareSalMatch(salFlow, MtchType.arp));
         checkOdMatch(odNodeFlow.getMatch(), MtchType.arp);
 
@@ -160,15 +168,26 @@ public class TestFromSalConversionsUtils {
             assertNotNull("Ipv6 wasn't found", ipv6Found);
             break;
         case other:
+            assertEquals("Incoming port is wrong.", "openflow:12345:10", match.getInPort().getValue());
             assertEquals("Source MAC address is wrong.", "ff:ee:dd:cc:bb:aa", match.getEthernetMatch()
                     .getEthernetSource().getAddress().getValue());
             assertEquals("Destinatio MAC address is wrong.", "ff:ee:dd:cc:bb:aa", match.getEthernetMatch()
                     .getEthernetDestination().getAddress().getValue());
+            assertEquals("Vlan ID is not present.", Boolean.TRUE, match.getVlanMatch().getVlanId().isVlanIdPresent());
             assertEquals("Vlan ID is wrong.", (Integer) 0xfff, match.getVlanMatch().getVlanId().getVlanId().getValue());
             assertEquals("Vlan ID priority is wrong.", (short) 0x7, (short) match.getVlanMatch().getVlanPcp()
                     .getValue());
             assertEquals("DCSP is wrong.", (short) 0x3f, (short) match.getIpMatch().getIpDscp().getValue());
             break;
+        case untagged:
+            assertEquals("Source MAC address is wrong.", "ff:ee:dd:cc:bb:aa", match.getEthernetMatch()
+                    .getEthernetSource().getAddress().getValue());
+            assertEquals("Destinatio MAC address is wrong.", "ff:ee:dd:cc:bb:aa", match.getEthernetMatch()
+                    .getEthernetDestination().getAddress().getValue());
+            assertEquals("Vlan ID is present.", Boolean.FALSE, match.getVlanMatch().getVlanId().isVlanIdPresent());
+            assertEquals("Vlan ID is wrong.", Integer.valueOf(0), match.getVlanMatch().getVlanId().getVlanId().getValue());
+            assertEquals("DCSP is wrong.", (short) 0x3f, (short) match.getIpMatch().getIpDscp().getValue());
+            break;
         case sctp:
             boolean sctpFound = false;
             assertEquals("Wrong protocol", CRUDP, match.getIpMatch().getIpProtocol().byteValue());
@@ -223,30 +242,29 @@ public class TestFromSalConversionsUtils {
 
     private void checkOdActions(
             List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions) {
-        checkOdAction(actions, FloodActionCase.class, false);
-        checkOdAction(actions, FloodAllActionCase.class, false);
-        checkOdAction(actions, HwPathActionCase.class, false);
-        checkOdAction(actions, LoopbackActionCase.class, false);
-        checkOdAction(actions, PopVlanActionCase.class, false);
-        checkOdAction(actions, PushVlanActionCase.class, true);
-        checkOdAction(actions, SetDlDstActionCase.class, true);
-        checkOdAction(actions, SetDlSrcActionCase.class, true);
-        checkOdAction(actions, SetDlTypeActionCase.class, true);
-        checkOdAction(actions, SetNwTosActionCase.class, true);
-        checkOdAction(actions, SetNwDstActionCase.class, true);
-        checkOdAction(actions, SetNwSrcActionCase.class, true);
-        checkOdAction(actions, SetNextHopActionCase.class, true);
-        checkOdAction(actions, SetTpDstActionCase.class, true);
-        checkOdAction(actions, SetTpSrcActionCase.class, true);
-        checkOdAction(actions, SetVlanCfiActionCase.class, true);
-        checkOdAction(actions, SetVlanIdActionCase.class, true);
-        checkOdAction(actions, SetVlanPcpActionCase.class, true);
-        checkOdAction(actions, SwPathActionCase.class, false);
+        checkOdAction(actions, FloodActionCase.class);
+        checkOdAction(actions, FloodAllActionCase.class);
+        checkOdAction(actions, HwPathActionCase.class);
+        checkOdAction(actions, LoopbackActionCase.class);
+        checkOdAction(actions, PopVlanActionCase.class);
+        checkOdAction(actions, PushVlanActionCase.class);
+        checkOdAction(actions, SetDlDstActionCase.class);
+        checkOdAction(actions, SetDlSrcActionCase.class);
+        checkOdAction(actions, SetDlTypeActionCase.class);
+        checkOdAction(actions, SetNwTosActionCase.class);
+        checkOdAction(actions, SetNwDstActionCase.class);
+        checkOdAction(actions, SetNwSrcActionCase.class);
+        checkOdAction(actions, SetNextHopActionCase.class);
+        checkOdAction(actions, SetTpDstActionCase.class);
+        checkOdAction(actions, SetTpSrcActionCase.class);
+        checkOdAction(actions, SetVlanCfiActionCase.class);
+        checkOdAction(actions, SetVlanIdActionCase.class);
+        checkOdAction(actions, SetVlanPcpActionCase.class);
+        checkOdAction(actions, SwPathActionCase.class);
     }
 
     private void checkOdAction(
-            List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions, Class<?> cl,
-            boolean b) {
+            List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions, Class<?> cl) {
         int numOfFoundActions = 0;
         for (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action action : actions) {
             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action innerAction = action
@@ -334,7 +352,7 @@ public class TestFromSalConversionsUtils {
         return salFlow;
     }
 
-    private Flow prepareSalMatch(Flow salFlow, MtchType mt) {
+    private Flow prepareSalMatch(Flow salFlow, MtchType mt) throws ConstructionException {
         Match salMatch = new Match();
         switch (mt) {
         case arp:
@@ -355,12 +373,21 @@ public class TestFromSalConversionsUtils {
             salMatch.setField(MatchType.NW_DST, InetAddresses.forString("2001:0db8:85a3:0000:0000:8a2e:0370:7336"));
             break;
         case other:
+            Node node = new Node(NodeIDType.OPENFLOW, 12345L);
+            NodeConnector port = new NodeConnector(NodeConnectorIDType.OPENFLOW, Short.valueOf((short)10), node);
+            salMatch.setField(MatchType.IN_PORT, port);
             salMatch.setField(MatchType.DL_SRC, new byte[]{(byte )0xff,(byte )0xee,(byte )0xdd,(byte )0xcc,(byte )0xbb,(byte )0xaa});
             salMatch.setField(MatchType.DL_DST, new byte[]{(byte )0xff,(byte )0xee,(byte )0xdd,(byte )0xcc,(byte )0xbb,(byte )0xaa});
             salMatch.setField(MatchType.DL_VLAN, (short) 0xfff);
             salMatch.setField(MatchType.DL_VLAN_PR, (byte) 0x7);
             salMatch.setField(MatchType.NW_TOS, (byte) 0x3f);
             break;
+        case untagged:
+            salMatch.setField(MatchType.DL_SRC, new byte[]{(byte )0xff,(byte )0xee,(byte )0xdd,(byte )0xcc,(byte )0xbb,(byte )0xaa});
+            salMatch.setField(MatchType.DL_DST, new byte[]{(byte )0xff,(byte )0xee,(byte )0xdd,(byte )0xcc,(byte )0xbb,(byte )0xaa});
+            salMatch.setField(MatchType.DL_VLAN, MatchType.DL_VLAN_NONE);
+            salMatch.setField(MatchType.NW_TOS, (byte) 0x3f);
+            break;
         case sctp:
             salMatch.setField(MatchType.NW_PROTO, CRUDP);
             salMatch.setField(MatchType.TP_SRC, (short) 0xffff);
index 0157bc0c6415835b8ed52a7add015d707d57a6d8..7601a7d9cf67ba543d50d8e49b3fb0d6bbe1ae82 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2013-2014 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -50,6 +50,7 @@ import org.opendaylight.controller.sal.core.ConstructionException;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.Node.NodeIDType;
 import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
 import org.opendaylight.controller.sal.flowprogrammer.Flow;
 import org.opendaylight.controller.sal.match.MatchType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;
@@ -118,6 +119,7 @@ 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.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;
@@ -151,7 +153,7 @@ public class TestToSalConversionsUtils {
     // prefix:
     // od|Od = Open Daylight
     private enum MtchType {
-        other, ipv4, ipv6, arp, sctp, tcp, udp
+        other, untagged, ipv4, ipv6, arp, sctp, tcp, udp
     }
 
     @Test
@@ -164,6 +166,9 @@ public class TestToSalConversionsUtils {
         Flow salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.other), node);
         checkSalMatch(salFlow.getMatch(), MtchType.other);
 
+        salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.untagged), node);
+        checkSalMatch(salFlow.getMatch(), MtchType.untagged);
+
         salFlow = ToSalConversionsUtils.toFlow(prepareOdFlow(odNodeFlowBuilder, MtchType.ipv4), node);
         checkSalMatch(salFlow.getMatch(), MtchType.ipv4);
 
@@ -196,7 +201,7 @@ public class TestToSalConversionsUtils {
         Assert.assertEquals("OF|1@OF|00:00:00:00:00:00:00:2a", nodeConnector.toString());
     }
 
-    private void checkSalMatch(org.opendaylight.controller.sal.match.Match match, MtchType mt) {
+    private void checkSalMatch(org.opendaylight.controller.sal.match.Match match, MtchType mt) throws ConstructionException {
         switch (mt) {
         case other:
             /*assertNotNull("DL_DST isn't equal.", "3C:A9:F4:00:E0:C8",
@@ -204,12 +209,21 @@ public class TestToSalConversionsUtils {
             assertEquals("DL_SRC isn't equal.", "24:77:03:7C:C5:F1",
                     new String((byte[]) match.getField(MatchType.DL_SRC).getValue()));
             */
+            Node node = new Node(NodeIDType.OPENFLOW, 12L);
+            NodeConnector port = new NodeConnector(NodeConnectorIDType.OPENFLOW, Short.valueOf((short)345), node);
+            assertEquals("IN_PORT isn't equal.", port, match.getField(MatchType.IN_PORT).getValue());
             assertEquals("DL_TYPE isn't equal.", (short) 0xffff, (short) match.getField(MatchType.DL_TYPE).getValue());
             assertEquals("NW_TOS isn't equal.", (byte) 0x33, (byte) match.getField(MatchType.NW_TOS).getValue());
             assertEquals("NW_PROTO isn't equal.", (byte) 0x3f, (byte) match.getField(MatchType.NW_PROTO).getValue());
             assertEquals("DL_VLAN isn't equal.", (short) 0xfff, (short) match.getField(MatchType.DL_VLAN).getValue());
             assertEquals("DL_VLAN_PR isn't equal.", (byte) 0x7, (byte) match.getField(MatchType.DL_VLAN_PR).getValue());
             break;
+        case untagged:
+            assertEquals("DL_TYPE isn't equal.", (short) 0xffff, (short) match.getField(MatchType.DL_TYPE).getValue());
+            assertEquals("NW_TOS isn't equal.", (byte) 0x33, (byte) match.getField(MatchType.NW_TOS).getValue());
+            assertEquals("NW_PROTO isn't equal.", (byte) 0x3f, (byte) match.getField(MatchType.NW_PROTO).getValue());
+            assertEquals("DL_VLAN isn't equal.", MatchType.DL_VLAN_NONE, (short) match.getField(MatchType.DL_VLAN).getValue());
+            break;
         case arp:
             /*
             assertEquals("DL_SRC isn't equal.", "22:44:66:88:AA:CC",
@@ -578,10 +592,16 @@ public class TestToSalConversionsUtils {
         MatchBuilder odMatchBuilder = new MatchBuilder();
         switch (mt) {
         case other:
+            odMatchBuilder.setInPort(new NodeConnectorId("openflow:12:345"));
             odMatchBuilder.setEthernetMatch(prepEthernetMatch());
             odMatchBuilder.setIpMatch(prepIpMatch());
             odMatchBuilder.setVlanMatch(prepVlanMatch());
             break;
+        case untagged:
+            odMatchBuilder.setEthernetMatch(prepEthernetMatch());
+            odMatchBuilder.setIpMatch(prepIpMatch());
+            odMatchBuilder.setVlanMatch(prepVlanNoneMatch());
+            break;
         case ipv4:
             odMatchBuilder.setLayer3Match(prepLayer3MatchIpv4());
             break;
@@ -664,11 +684,20 @@ public class TestToSalConversionsUtils {
         VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
 
         VlanIdBuilder vlanIdBuilder = new VlanIdBuilder().setVlanId(new VlanId(0xfff));
-        vlanMatchBuilder.setVlanId(vlanIdBuilder.build());
+        vlanMatchBuilder.setVlanId(vlanIdBuilder.setVlanIdPresent(true).build());
         vlanMatchBuilder.setVlanPcp(new VlanPcp((short) 0x7));
 
         return vlanMatchBuilder.build();
+    }
+
+    private VlanMatch prepVlanNoneMatch() {
+        VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
 
+        VlanIdBuilder vlanIdBuilder = new VlanIdBuilder().
+            setVlanIdPresent(false);
+        vlanMatchBuilder.setVlanId(vlanIdBuilder.build());
+
+        return vlanMatchBuilder.build();
     }
 
     private IpMatch prepIpMatch() {
index b3096e6478857aa1ca0286efda6c7a78912b4813..ed5e19219353e3265a5b7f55ef58dccd5f6b7ad7 100644 (file)
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>flow-management-compatibility</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-binding-api</artifactId>
index 6ed61e3024b9522dbc89d99a979f93fbcb147c7f..9724d31f9ae6cd3ab8eaef0c23212bf626cfca84 100644 (file)
@@ -15,7 +15,7 @@ import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,7 +30,7 @@ class FlowCapableInventoryProvider implements AutoCloseable, Runnable {
     private final BlockingQueue<InventoryOperation> queue = new LinkedBlockingDeque<>(QUEUE_DEPTH);
     private final NotificationProviderService notificationService;
     private final DataProviderService dataService;
-    private Registration<?> listenerRegistration;
+    private ListenerRegistration<?> listenerRegistration;
     private Thread thread;
 
     FlowCapableInventoryProvider(final DataProviderService dataService, final NotificationProviderService notificationService) {
diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/flow/types/port/rev130925/PortNumberBuilder.java b/opendaylight/md-sal/model/model-flow-base/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/flow/types/port/rev130925/PortNumberBuilder.java
new file mode 100644 (file)
index 0000000..ff78a74
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.CommonPort.PortNumber;
+
+
+public class PortNumberBuilder {
+
+    public static PortNumber getDefaultInstance(java.lang.String defaultValue) {
+        try {
+            long uint32 = Long.parseLong(defaultValue);
+            return new PortNumber(uint32);
+        } catch(NumberFormatException e){
+            return new PortNumber(defaultValue);
+        }
+    }
+
+}
diff --git a/opendaylight/md-sal/model/model-flow-management/pom.xml b/opendaylight/md-sal/model/model-flow-management/pom.xml
deleted file mode 100644 (file)
index 64f1158..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.opendaylight.controller.model</groupId>
-    <artifactId>model-parent</artifactId>
-    <version>1.1-SNAPSHOT</version>
-  </parent>
-  <artifactId>model-flow-management</artifactId>
-  <packaging>bundle</packaging>
-
-  <dependencies>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>model-flow-base</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>model-inventory</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.yangtools.model</groupId>
-      <artifactId>opendaylight-l2-types</artifactId>
-    </dependency>
-  </dependencies>
-  <scm>
-    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
-    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
-    <tag>HEAD</tag>
-    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
-  </scm>
-</project>
diff --git a/opendaylight/md-sal/model/model-flow-management/src/main/yang/flow-management.yang b/opendaylight/md-sal/model/model-flow-management/src/main/yang/flow-management.yang
deleted file mode 100644 (file)
index b8579bc..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-module flow-management {
-    namespace "urn:opendaylight:flow:config";
-    prefix flow-cfg;
-
-    import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
-    import opendaylight-flow-types {prefix flow;}
-
-    revision "2013-08-19" {
-        description "Initial revision of flow service";
-    }
-
-
-    grouping flow-entry {
-        leaf node {
-            type inv:node-ref;
-        }
-        uses flow:flow;
-    }
-
-    container flows {
-        list flow {
-            key "node id"; 
-
-            leaf id {
-                type uint32;
-            }
-            uses flow-entry;
-        }
-    }
-}
diff --git a/opendaylight/md-sal/model/model-flow-management/src/main/yang/group-management.yang b/opendaylight/md-sal/model/model-flow-management/src/main/yang/group-management.yang
deleted file mode 100644 (file)
index 814c7e4..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-module group-management {
-    namespace "urn:opendaylight:group:config";
-    prefix group-cfg;
-
-    import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}  
-    import opendaylight-group-types {prefix group;}
-
-    revision "2013-10-24" {
-        description "Initial revision of group service";
-    }
-
-    grouping group-entry {
-        leaf node {
-            type inv:node-ref;
-        }
-        uses group:group;
-    }   
-     
-    container groups {
-        list group {
-            key "id node"; 
-                        
-            leaf id {
-                type uint32;
-            }                       
-            
-            uses group-entry;
-        }
-    }    
-}
diff --git a/opendaylight/md-sal/model/model-flow-management/src/main/yang/meter-management.yang b/opendaylight/md-sal/model/model-flow-management/src/main/yang/meter-management.yang
deleted file mode 100644 (file)
index 6d86c50..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-module meter-management {
-    namespace "urn:opendaylight:meter:config";
-    prefix meter-cfg;
-
-    import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}  
-    import opendaylight-meter-types {prefix meter;}
-
-    revision "2013-10-24" {
-        description "Initial revision of meter service";
-    }
-
-    grouping meter-entry {
-        leaf node {
-            type inv:node-ref;
-        }
-        uses meter:meter;
-    }   
-     
-    container meters {
-        list meter {
-            key "id node"; 
-                        
-            leaf id {
-                type uint32;
-            }                    
-            
-            uses meter-entry;
-        }
-    }    
-}
diff --git a/opendaylight/md-sal/model/model-flow-management/src/main/yang/port-management.yang b/opendaylight/md-sal/model/model-flow-management/src/main/yang/port-management.yang
deleted file mode 100644 (file)
index 77483de..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-module port-management {
-    namespace "urn:opendaylight:port:config";
-    prefix port-cfg;
-
-    import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}    
-    import opendaylight-port-types {prefix port;}
-
-    revision "2013-10-24" {
-        description "Initial revision of port service";
-    }
-
-    grouping port-entry {
-        leaf node {
-            type inv:node-ref;
-        }
-        uses port:port-mod;
-    }   
-     
-    container ports {
-        list port {
-            key "id node"; 
-                        
-            leaf id {
-                type uint32;
-            }                       
-            
-            uses port-entry;
-        }
-    }    
-}
diff --git a/opendaylight/md-sal/model/model-flow-management/src/main/yang/queue-management.yang b/opendaylight/md-sal/model/model-flow-management/src/main/yang/queue-management.yang
deleted file mode 100644 (file)
index c8a7fbb..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-module queue-management {
-    namespace "urn:opendaylight:queue:config";
-    prefix queue-cfg;
-
-    import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}      
-     
-    import opendaylight-queue-types {prefix queue; revision-date "2013-09-25";}
-
-   
-    revision "2013-10-24" {
-        description "Initial revision of queue service";
-    }
-
-    grouping queue-entry {
-        leaf node {
-            type inv:node-connector-ref;
-           
-        }
-        uses queue:queue-config-request;
-    }   
-     
-    container queues {
-        list queue {
-            key "id node"; 
-                        
-            leaf id {
-                type uint32;
-            }                       
-            
-            uses queue-entry;
-        }
-    }    
-}
diff --git a/opendaylight/md-sal/model/model-flow-management/src/main/yang/table-management.yang b/opendaylight/md-sal/model/model-flow-management/src/main/yang/table-management.yang
deleted file mode 100644 (file)
index 06edb04..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-module table-management {
-    namespace "urn:opendaylight:table:config";
-    prefix table-cfg;
-    
-    import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
-    import opendaylight-table-types {prefix table;}
-
-    revision "2013-10-24" {
-        description "Initial revision of table service";
-    }
-
-    grouping table-entry {
-    
-        leaf node {
-            type inv:node-ref;
-        }
-        
-        uses table:table-features;
-    }   
-     
-    container tables {
-        list table {
-            key "id node"; 
-                        
-            leaf id {
-                type uint32;
-            }                    
-            
-            uses table-entry;
-        }
-    }    
-}
index a8eec2693615a55ab49ffd6d566ef8e503bffd72..69db856b73b172fa7f2bd966b5ba6f29984a54ca 100644 (file)
@@ -73,7 +73,6 @@ module node-error {
             uses tr:transaction-metadata;
             uses flow:base-node-error-notification;
             uses flow:node-error-reference;
-            uses flow:node-error-reference;
         }
 
     notification group-mod-error-notification {
index e0df924a0ea5434f81a804efec6447169c22448b..f7a0652e45f042bf891c58a1a7fcdb017e811a2c 100644 (file)
@@ -25,7 +25,6 @@ module opendaylight-flow-statistics {
     grouping flow-statistics {
         container flow-statistics {
             //config "false";
-            uses flow-types:flow;
             uses stat-types:generic-statistics;
         }
     }
index 396206e28ed30f1a03c8b28f72fec645911fa86f..64d212e9bc57e514f4616d4fb5078d636315003a 100644 (file)
@@ -9,8 +9,8 @@ module opendaylight-inventory {
     revision "2013-08-19" {
         description "Initial revision of Inventory model";
     }
-    
-    
+
+
     typedef support-type {
         type enumeration {
             enum native;
@@ -21,43 +21,79 @@ module opendaylight-inventory {
 
     typedef node-id {
         type inet:uri;
+        description "Identifier for a particular node. For example:
+
+                        myprotocol:<unique_node_id>
+
+                        myprotocol:12
+
+                    It is a good practice to always lead with a scoping identifier.
+                    In the example above the scoping was 'myprotocol'. In your app you
+                    could use 'myapp' etc.";
     }
 
     typedef node-connector-id {
         type inet:uri;
+        description "Identifier for a particular node-connector. For example:
+
+                        myprotocol:<unique_node_connector_id>
+                        myprotocol:3
+
+                    It is a good practice to always lead with a scoping identifier.
+                    In the example above the scoping was 'myprotocol'. In your app you
+                    could use 'myapp' etc.";
+
     }
 
+    //YANG does not have a statement which limits the scope of an instance-identifier to a particular subtree,
+    //which is why we are using a type capture and not an instance-identifier to define a node-ref and a node-connector-ref.
     typedef node-ref {
         type instance-identifier;
+        description "A reference that points to an opendaylight-light:nodes/node in the data tree.";
     }
 
     typedef node-connector-ref {
         type instance-identifier;
+        description "A reference that points to an opendaylight-list:nodes/node/{node-id}/node-connector in the data tree.";
     }
 
     identity node-context {
-        description "Identity used to mark node context";
+        description "A node-context is a classifier for node elements which allows an RPC to provide a service on behalf of a particular element in the data tree.";
     }
 
     identity node-connector-context {
-        description "Identity used to mark node connector context";
+        description "A node-connector-context is a classifier for node-connector elements which allows an RPC to provide a service on behalf of a particular element in the data tree.";
     }
 
+    //We are defining a base identity here because there are limitations with yang enums. Yang doesn't allow you to extend enumeratations.
+    //Therefore by defining a base identity we allow other yang files to extend this identity to define additional "enumerations". By
+    //using node-type as their base they are able to pass their object to fields that accept "node-types" while uniquely describing their
+    //type of node, such as "router-node" or "switch-node" etc.
+    //See https://wiki.opendaylight.org/view/YANG_Tools:YANG_to_Java_Mapping#Identity for more information.
     identity node-type {
-        description "Base identity for node types";
+        description "A base identity definition which represents a generic node type and can be extended in other yang files.";
     }
 
     identity node-connector-type {
-        description "Base identity for node connectors type";
+        description "A base identity definition which represents a generic node connector type and can be extended in other yang files.";
     }
 
     grouping node {
+
+        description "Describes the contents of a generic node -
+                     essentially an ID and a list of node-connectors.
+                     Acts as an augmentation point where other yang files
+                      can add additional information.";
+
         leaf id {
             type node-id;
+            description "The unique identifier for the node.";
         }
 
         list "node-connector" {
             key "id";
+
+            description "A list of node connectors that belong this node.";
             ext:context-instance "node-connector-context";
 
             uses node-connector;
@@ -65,55 +101,117 @@ module opendaylight-inventory {
     }
 
     grouping node-connector {
+
+        description "Describes a generic node connector which consists of an ID.
+                     Acts as an augmentation point where other yang files can
+                      add additional information.";
+
         leaf id {
             type node-connector-id;
+            description "The unique identifier for the node-connector.";
         }
     }
 
     grouping node-context-ref {
-        description 
-        "Helper grouping which contains a reference to node context.";
+        description
+        "A helper grouping which contains a reference to a node classified with a node-context. This allows RPCs in other yang files to refine their input to a particular node instance.";
+
         leaf node {
             ext:context-reference "node-context";
             type node-ref;
+            description "A reference to a particular node.";
         }
     }
 
     /** Base structure **/
     container nodes {
+
+        description "The root container of all nodes.";
+
         list node {
             key "id";
             ext:context-instance "node-context";
-
-            uses node;
+            description "A list of nodes (as defined by the 'grouping node').";
+            uses node; //this refers to the 'grouping node' defined above.
         }
     }
 
+    //The following notifications should really be replaced by direct writes to the data tree with data change listeners listening to those changes.
+    //Notifications should be reserved for one time events which do not require persistence to the data tree.
     notification node-updated {
+
+        status deprecated;
+
+        description "A notification sent by someone who realized there was a modification to a node, but did not modify the data tree.
+                    Describes that something on the node has been updated (including addition of a new node), but is for
+                    whatever reason is not modifying the data tree.
+
+                    Deprecated: If a process determines that a node was updated, then that
+                    logic should update the node using the DataBroker directly. Listeners interested
+                    update changes should register a data change listener for notifications on removals.";
+
         leaf node-ref {
             ext:context-reference "node-context";
+            description "A reference to the node which changed.";
+
             type node-ref;
         }
         uses node;
     }
 
     notification node-connector-updated {
+
+        status deprecated;
+
+        description "A notification sent by someone who realized there was a modification to a node-connector, but did not modify the data tree.
+                    Describes that something on the node-connector has been updated (including addition of a new node-connector), but is for
+                    whatever reason is not modifying the data tree.
+
+                    Deprecated: If a process determines that a node-connector was updated, then that
+                    logic should update the node-connector using the DataBroker directly. Listeners interested
+                    update changes should register a data change listener for notifications on removals.";
+
         leaf node-connector-ref {
             ext:context-reference "node-connector-context";
             type node-connector-ref;
+            description "A reference to the node-connector which changed.";
         }
         uses node-connector;
     }
 
     notification node-removed {
+
+        status deprecated;
+
+        description "A notification sent by someone who realized there was a node was removed, but did not modify the data tree.
+                    Describes that a node has been removed but is for
+                    whatever reason is not modifying the data tree.
+
+                    Deprecated: If a process determines that a node was removed, then that
+                    logic should remove the node from the DataBroker directly. Listeners interested
+                    in changes should register a data change listener for notifications on removals.";
+
         leaf node-ref {
+            description "A reference to the node that was removed.";
             ext:context-reference "node-context";
             type node-ref;
         }
     }
 
     notification node-connector-removed {
+
+        status deprecated;
+
+        description "A notification sent by someone who realized there was a node-connector was removed, but did not modify the data tree.
+                    Describes that a node-connector has been removed but is for
+                    whatever reason is not modifying the data tree.
+
+                    Deprecated: If a process determines that a node-connector was removed, then that
+                    logic should remove the node-connector from the DataBroker directly. Listeners interested
+                    in changes should register a data change listener for notifications on removals.";
+
         leaf node-connector-ref {
+            description "A reference to the node-connector that was removed.";
             ext:context-reference "node-connector-context";
             type node-connector-ref;
         }
index 12b5f766254c933221217d0962f399139a436781..5e6a86745c0ae09b9bd200a5d49f495aafeba276 100644 (file)
@@ -17,7 +17,6 @@
     <module>model-flow-base</module>
     <module>model-flow-service</module>
     <module>model-flow-statistics</module>
-    <module>model-flow-management</module>
     <module>model-topology</module>
   </modules>
 
index 24dcfad02bf46b4e610aa1ad0bac0f76d9070671..3f02765affd8a062420f327fb489ed3adf5d3966 100644 (file)
@@ -43,6 +43,7 @@
     <!-- Connectors -->
     <module>sal-connector-api</module>
     <module>sal-rest-connector</module>
+    <module>sal-rest-connector-config</module>
     <module>sal-netconf-connector</module>
 
     <module>inventory-manager</module>
     <!-- Documentation -->
     <module>sal-rest-docgen</module>
 
+    <module>sal-akka-raft</module>
+
     <!--InMemory DOM DataStore-->
     <module>sal-inmemory-datastore</module>
 
     <!--sal-protocolbuffer-encoding-->
     <module>sal-protocolbuffer-encoding</module>
 
-      <!--  Karaf feature -->
-      <module>feature</module>
+    <!-- sal-distributed-datastore -->
+    <module>sal-distributed-datastore</module>
+
+    <!-- Yang Test Models for MD-SAL -->
+    <module>sal-test-model</module>
 
+    <!-- Clustering -->
+    <module>sal-remoterpc-connector</module>
   </modules>
 
   <build>
diff --git a/opendaylight/md-sal/sal-akka-raft/README-FIRST b/opendaylight/md-sal/sal-akka-raft/README-FIRST
new file mode 100644 (file)
index 0000000..d0be2cb
--- /dev/null
@@ -0,0 +1,28 @@
+Instructions on generating the protocol buffer Java source files
+
+These instructions are developers who are planning to generate the protocolbuffer java source files.
+
+1. We are using protocol buffer version 2.5.0 - you need to install the exact same version on your box.
+The download link is https://code.google.com/p/protobuf/downloads/list. Download .tar/zip based on
+your OS.
+
+2. Once downloaded the tar/zip and extracted follow the README instructions to compile protoc on your
+machine
+
+3. Create your .proto (IDL) file in resources folder. Give appropriate package name so that the source
+   get generation in proper packages. For more information  check
+   https://developers.google.com/protocol-buffers/docs/javatutorial
+
+   For detailed information https://developers.google.com/protocol-buffers/docs/reference/java-generated
+
+4. To generate the java source files execute in sal-protocolbuffer-encoding directory
+   just run.sh in sal-protocolbuffer-encoding or execute the following command
+
+ protoc --proto_path=src/main/resources --java_out=src/main/java src/main/resources/*.proto
+
+5. Run mvn clean install  & build the .jar
+
+6. !!!WARNING!!! - never edit the generated sources files of protocol buffer
+
+7. !!!NOTE!!! if you are planning to add new .proto file  option java_package should begin with
+   org.opendaylight.controller.protobuff.messages to properly exclude from sonar.
diff --git a/opendaylight/md-sal/sal-akka-raft/pom.xml b/opendaylight/md-sal/sal-akka-raft/pom.xml
new file mode 100644 (file)
index 0000000..3dcc546
--- /dev/null
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>sal-parent</artifactId>
+    <version>1.1-SNAPSHOT</version>
+  </parent>
+  <artifactId>sal-akka-raft</artifactId>
+  <packaging>bundle</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.protobuf</groupId>
+      <artifactId>protobuf-java</artifactId>
+      <version>2.5.0</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.typesafe.akka</groupId>
+      <artifactId>akka-actor_${scala.version}</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.typesafe.akka</groupId>
+      <artifactId>akka-cluster_${scala.version}</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.typesafe.akka</groupId>
+      <artifactId>akka-persistence-experimental_${scala.version}</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.typesafe.akka</groupId>
+      <artifactId>akka-remote_${scala.version}</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.typesafe.akka</groupId>
+      <artifactId>akka-testkit_${scala.version}</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.scala-lang</groupId>
+      <artifactId>scala-library</artifactId>
+    </dependency>
+
+    <!-- Test Dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <version>${slf4j.version}</version>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+    <plugins>
+
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+            <Export-package></Export-package>
+            <Private-Package></Private-Package>
+            <Import-Package></Import-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <groupId>org.jacoco</groupId>
+        <artifactId>jacoco-maven-plugin</artifactId>
+        <configuration>
+          <includes>
+            <include>org.opendaylight.controller.*</include>
+          </includes>
+          <check>false</check>
+        </configuration>
+        <executions>
+          <execution>
+            <id>pre-test</id>
+            <goals>
+              <goal>prepare-agent</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>post-test</id>
+            <goals>
+              <goal>report</goal>
+            </goals>
+            <phase>test</phase>
+          </execution>
+        </executions>
+      </plugin>
+
+     <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <configuration>
+            <excludes>**/protobuff/**/*</excludes>
+        </configuration>
+      </plugin>
+
+    </plugins>
+  </build>
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+    <tag>HEAD</tag>
+    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Architecture:Clustering</url>
+  </scm>
+</project>
diff --git a/opendaylight/md-sal/sal-akka-raft/run.sh b/opendaylight/md-sal/sal-akka-raft/run.sh
new file mode 100755 (executable)
index 0000000..7c588f0
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+#####################################################################################################
+#Instructions on generating the protocol buffer Java source files
+#
+#These instructions are developers who are planning to generate the protocolbuffer java source files.
+#
+#1. We are using protocol buffer version 2.5.0 - you need to install the exact same version on your box.
+#The download link is https://code.google.com/p/protobuf/downloads/list. Download .tar/zip based on
+#your OS.
+#
+#2. Once downloaded the tar/zip and extracted follow the README instructions to compile protoc on your
+#machine
+#
+#3. Create your .proto (IDL) file in resources folder. Give appropriate package name so that the source
+#   get generation in proper packages. For more information  check
+#   https://developers.google.com/protocol-buffers/docs/javatutorial
+#
+#   For detailed information https://developers.google.com/protocol-buffers/docs/reference/java-generated
+#
+#4. To generate the java source files execute in sal-protocolbuffer-encoding execute ./run.sh i.e. this script
+# or run command
+#       protoc --proto_path=src/main/resources --java_out=src/main/java src/main/resources/*.proto
+#
+#5. Run mvn clean install & build the .jar
+#
+#6  !!!WARNING!!!! never edit the source files generated
+#
+#7. !!!NOTE!!! if you are planning to add new .proto file  option java_package should begin with
+#   org.opendaylight.controller.protobuff.messages to properly exclude from sonar.
+########################################################################################################
+
+protoc --proto_path=src/main/resources --java_out=src/main/java src/main/resources/*.proto
+
+protoc --proto_path=src/main/resources --proto_path=src/test/resources --java_out=src/test/java src/test/resources/*.proto
+
+echo "Done generating Java source files."
+
+#to remove trailing spaces in the code files
+find src/main/java -type f -name '*.java' -exec sed --in-place 's/[[:space:]]\+$//' {} \+
+
+find src/test/java -type f -name '*.java' -exec sed --in-place 's/[[:space:]]\+$//' {} \+
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/ClientActor.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/ClientActor.java
new file mode 100644 (file)
index 0000000..2560f16
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.example;
+
+import akka.actor.ActorRef;
+import akka.actor.Props;
+import akka.actor.UntypedActor;
+import akka.event.Logging;
+import akka.event.LoggingAdapter;
+import akka.japi.Creator;
+import org.opendaylight.controller.cluster.example.messages.KeyValue;
+import org.opendaylight.controller.cluster.example.messages.KeyValueSaved;
+
+public class ClientActor extends UntypedActor {
+    protected final LoggingAdapter LOG =
+        Logging.getLogger(getContext().system(), this);
+
+    private final ActorRef target;
+
+    public ClientActor(ActorRef target){
+        this.target = target;
+    }
+
+    public static Props props(final ActorRef target){
+        return Props.create(new Creator<ClientActor>(){
+
+            @Override public ClientActor create() throws Exception {
+                return new ClientActor(target);
+            }
+        });
+    }
+
+    @Override public void onReceive(Object message) throws Exception {
+        if(message instanceof KeyValue) {
+            target.tell(message, getSelf());
+        } else if(message instanceof KeyValueSaved){
+            LOG.info("KeyValue saved");
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/ExampleActor.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/ExampleActor.java
new file mode 100644 (file)
index 0000000..641ec05
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.example;
+
+import akka.actor.ActorRef;
+import akka.actor.Props;
+import akka.japi.Creator;
+import org.opendaylight.controller.cluster.example.messages.KeyValue;
+import org.opendaylight.controller.cluster.example.messages.KeyValueSaved;
+import org.opendaylight.controller.cluster.example.messages.PrintRole;
+import org.opendaylight.controller.cluster.example.messages.PrintState;
+import org.opendaylight.controller.cluster.raft.RaftActor;
+import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A sample actor showing how the RaftActor is to be extended
+ */
+public class ExampleActor extends RaftActor {
+
+    private final Map<String, String> state = new HashMap();
+
+    private long persistIdentifier = 1;
+
+
+    public ExampleActor(String id, Map<String, String> peerAddresses) {
+        super(id, peerAddresses);
+    }
+
+    public static Props props(final String id, final Map<String, String> peerAddresses){
+        return Props.create(new Creator<ExampleActor>(){
+
+            @Override public ExampleActor create() throws Exception {
+                return new ExampleActor(id, peerAddresses);
+            }
+        });
+    }
+
+    @Override public void onReceiveCommand(Object message){
+        if(message instanceof KeyValue){
+            if(isLeader()) {
+                String persistId = Long.toString(persistIdentifier++);
+                persistData(getSender(), persistId, (Payload) message);
+            } else {
+                if(getLeader() != null) {
+                    getLeader().forward(message, getContext());
+                }
+            }
+
+        } else if (message instanceof PrintState) {
+            LOG.debug("State of the node:"+getId() + " has = "+state.size() + " entries");
+
+        } else if (message instanceof PrintRole) {
+            LOG.debug(getId() + " = " + getRaftState());
+        } else {
+            super.onReceiveCommand(message);
+        }
+    }
+
+    @Override protected void applyState(ActorRef clientActor, String identifier,
+        Object data) {
+        if(data instanceof KeyValue){
+            KeyValue kv = (KeyValue) data;
+            state.put(kv.getKey(), kv.getValue());
+            if(clientActor != null) {
+                clientActor.tell(new KeyValueSaved(), getSelf());
+            }
+        }
+    }
+
+    @Override protected Object createSnapshot() {
+        return state;
+    }
+
+    @Override protected void applySnapshot(Object snapshot) {
+        state.clear();
+        state.putAll((HashMap) snapshot);
+    }
+
+    @Override public void onReceiveRecover(Object message) {
+        super.onReceiveRecover(message);
+    }
+
+    @Override public String persistenceId() {
+        return getId();
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/LogGenerator.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/LogGenerator.java
new file mode 100644 (file)
index 0000000..fbe1447
--- /dev/null
@@ -0,0 +1,67 @@
+package org.opendaylight.controller.cluster.example;
+
+import akka.actor.ActorRef;
+import org.opendaylight.controller.cluster.example.messages.KeyValue;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * Created by kramesha on 7/16/14.
+ */
+public class LogGenerator {
+    private Map<ActorRef, LoggingThread> clientToLoggingThread = new HashMap<ActorRef, LoggingThread>();
+
+    public void startLoggingForClient(ActorRef client) {
+        LoggingThread lt = new LoggingThread(client);
+        clientToLoggingThread.put(client, lt);
+        Thread t = new Thread(lt);
+        t.start();
+    }
+
+    public void stopLoggingForClient(ActorRef client) {
+        clientToLoggingThread.get(client).stopLogging();
+        clientToLoggingThread.remove(client);
+    }
+
+    public class LoggingThread implements Runnable {
+
+        private ActorRef clientActor;
+        private volatile boolean stopLogging = false;
+
+        public LoggingThread(ActorRef clientActor) {
+            this.clientActor = clientActor;
+        }
+
+        public void run() {
+            Random r = new Random();
+            while (true) {
+                if (stopLogging) {
+                    System.out.println("Logging stopped for client:" + clientActor.path());
+                    break;
+                }
+                String key = clientActor.path().name();
+                int random = r.nextInt(100);
+                clientActor.tell(new KeyValue(key+"-key-" + random, "value-" + random), null);
+                try {
+                    Thread.sleep((random%10) * 1000);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        public void stopLogging() {
+            stopLogging = true;
+        }
+
+        public void startLogging() {
+            stopLogging = false;
+        }
+
+
+    }
+
+
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/Main.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/Main.java
new file mode 100644 (file)
index 0000000..a148ed4
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.example;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.actor.PoisonPill;
+import org.opendaylight.controller.cluster.example.messages.KeyValue;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Main {
+    private static final ActorSystem actorSystem = ActorSystem.create();
+    // Create three example actors
+    private static Map<String, String> allPeers = new HashMap<>();
+
+    static {
+        allPeers.put("example-1", "akka://default/user/example-1");
+        allPeers.put("example-2", "akka://default/user/example-2");
+        allPeers.put("example-3", "akka://default/user/example-3");
+    }
+
+    public static void main(String[] args) throws Exception{
+        ActorRef example1Actor =
+            actorSystem.actorOf(ExampleActor.props("example-1",
+                withoutPeer("example-1")), "example-1");
+
+        ActorRef example2Actor =
+            actorSystem.actorOf(ExampleActor.props("example-2",
+                withoutPeer("example-2")), "example-2");
+
+        ActorRef example3Actor =
+            actorSystem.actorOf(ExampleActor.props("example-3",
+                withoutPeer("example-3")), "example-3");
+
+
+        List<ActorRef> examples = Arrays.asList(example1Actor, example2Actor, example3Actor);
+
+        ActorRef clientActor = actorSystem.actorOf(ClientActor.props(example1Actor));
+        BufferedReader br =
+            new BufferedReader(new InputStreamReader(System.in));
+
+        System.out.println("Usage :");
+        System.out.println("s <1-3> to start a peer");
+        System.out.println("k <1-3> to kill a peer");
+
+        while(true) {
+            System.out.print("Enter command (0 to exit):");
+            try {
+                String s = br.readLine();
+                String[] split = s.split(" ");
+                if(split.length > 1) {
+                    String command = split[0];
+                    String actor = split[1];
+
+                    if ("k".equals(command)) {
+                        int i = Integer.parseInt(actor);
+                        examples.get(i - 1)
+                            .tell(PoisonPill.getInstance(), null);
+                        continue;
+                    } else if ("s".equals(command)) {
+                        int i = Integer.parseInt(actor);
+                        String actorName = "example-" + i;
+                        examples.add(i - 1,
+                            actorSystem.actorOf(ExampleActor.props(actorName,
+                                withoutPeer(actorName)), actorName));
+                        System.out.println("Created actor : " + actorName);
+                        continue;
+                    }
+                }
+
+                int i = Integer.parseInt(s);
+                if(i == 0){
+                    System.exit(0);
+                }
+                clientActor.tell(new KeyValue("key " + i, "value " + i), null);
+            } catch (NumberFormatException nfe) {
+                System.err.println("Invalid Format!");
+            }
+        }
+    }
+
+    private static Map<String, String> withoutPeer(String peerId) {
+        Map<String, String> without = new HashMap<>(allPeers);
+        without.remove(peerId);
+        return without;
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/TestDriver.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/TestDriver.java
new file mode 100644 (file)
index 0000000..c2d0b3a
--- /dev/null
@@ -0,0 +1,251 @@
+package org.opendaylight.controller.cluster.example;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import org.opendaylight.controller.cluster.example.messages.PrintRole;
+import org.opendaylight.controller.cluster.example.messages.PrintState;
+import org.opendaylight.controller.cluster.raft.client.messages.AddRaftPeer;
+import org.opendaylight.controller.cluster.raft.client.messages.RemoveRaftPeer;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * This is a test driver for testing akka-raft implementation
+ * Its uses ExampleActors and threads to push content(key-vals) to these actors
+ * Each ExampleActor can have one or more ClientActors. Each ClientActor spawns
+ * a thread and starts push logs to the actor its assignged to.
+ */
+public class TestDriver {
+
+    private static final ActorSystem actorSystem = ActorSystem.create();
+    private static Map<String, String> allPeers = new HashMap<>();
+    private static Map<String, ActorRef> clientActorRefs  = new HashMap<String, ActorRef>();
+    private static Map<String, ActorRef> actorRefs = new HashMap<String, ActorRef>();
+    private static LogGenerator logGenerator = new LogGenerator();;
+
+    /**
+     * Create nodes, add clients and start logging.
+     * Commands
+     *  bye
+     *  createNodes:{num}
+     *  addNodes:{num}
+     *  stopNode:{nodeName}
+     *  addClients:{num}
+     *  addClientsToNode:{nodeName, num}
+     *  startLogging
+     *  stopLogging
+     *  startLoggingForClient:{nodeName}
+     *  stopLoggingForClient:{nodeName}
+     *  printNodes
+     *  printState
+     * @param args
+     * @throws Exception
+     */
+    public static void main(String[] args) throws Exception {
+        TestDriver td = new TestDriver();
+
+        System.out.println("Enter command (type bye to exit):");
+
+
+        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+        while(true) {
+            String command = br.readLine();
+            if (command.startsWith("bye")) {
+                System.exit(0);
+
+            } else if (command.startsWith("createNodes")) {
+                String[] arr = command.split(":");
+                int n = Integer.parseInt(arr[1]);
+                td.createNodes(n);
+
+            } else if (command.startsWith("addNodes")) {
+                String[] arr = command.split(":");
+                int n = Integer.parseInt(arr[1]);
+                td.addNodes(n);
+
+            } else if (command.startsWith("addClients")) {
+                String[] arr = command.split(":");
+                int n = Integer.parseInt(arr[1]);
+                td.addClients(n);
+
+            } else if (command.startsWith("addClientsToNode")) {
+                String[] arr = command.split(":");
+                String nodeName = arr[1];
+                int n = Integer.parseInt(arr[1]);
+                td.addClientsToNode(nodeName, n);
+
+            } else if (command.startsWith("stopNode")) {
+                String[] arr = command.split(":");
+                td.stopNode(arr[1]);
+
+            } else if (command.startsWith("startLogging")) {
+                td.startAllLogging();
+
+            } else if (command.startsWith("startLoggingForClient")) {
+                String[] arr = command.split(":");
+                td.startLoggingForClient(clientActorRefs.get(arr[1]));
+
+            } else if (command.startsWith("stopLogging")) {
+                td.stopAllLogging();
+
+            } else if (command.startsWith("stopLoggingForClient")) {
+                String[] arr = command.split(":");
+                td.stopLoggingForClient(clientActorRefs.get(arr[1]));
+
+            } else if (command.startsWith("printState")) {
+                td.printState();
+            } else if (command.startsWith("printNodes")) {
+                td.printNodes();
+            }
+
+        }
+    }
+
+    public void createNodes(int num) {
+        for (int i=0; i < num; i++)  {
+            int rand = getUnusedRandom(num);
+            allPeers.put("example-"+rand, "akka://default/user/example-"+rand);
+        }
+
+        for (String s : allPeers.keySet())  {
+            ActorRef exampleActor = actorSystem.actorOf(
+                ExampleActor.props(s, withoutPeer(s)), s);
+            actorRefs.put(s, exampleActor);
+            System.out.println("Created node:"+s);
+
+        }
+    }
+
+    // add new nodes , pass in the count
+    public void addNodes(int num) {
+        Map<String, String> newPeers = new HashMap<>();
+        for (int i=0; i < num; i++)  {
+            int rand = getUnusedRandom(num);
+            newPeers.put("example-"+rand, "akka://default/user/example-"+rand);
+            allPeers.put("example-"+rand, "akka://default/user/example-"+rand);
+
+        }
+        Map<String, ActorRef> newActorRefs = new HashMap<String, ActorRef>(num);
+        for (Map.Entry<String, String> entry : newPeers.entrySet())  {
+            ActorRef exampleActor = actorSystem.actorOf(
+                ExampleActor.props(entry.getKey(), withoutPeer(entry.getKey())), entry.getKey());
+            newActorRefs.put(entry.getKey(), exampleActor);
+
+            //now also add these new nodes as peers from the previous nodes
+            for (ActorRef actor : actorRefs.values()) {
+                actor.tell(new AddRaftPeer(entry.getKey(), entry.getValue()), null);
+            }
+
+            System.out.println("Added node:" + entry);
+        }
+
+        actorRefs.putAll(newActorRefs);
+    }
+
+
+    // add num clients to all nodes in the system
+    public void addClients(int num) {
+        for(Map.Entry<String,ActorRef> actorRefEntry : actorRefs.entrySet()) {
+            for (int i=0; i < num; i++) {
+                String clientName = "client-" + i + "-" + actorRefEntry.getKey();
+                ActorRef clientActor = actorSystem.actorOf(
+                    ClientActor.props(actorRefEntry.getValue()), clientName);
+                clientActorRefs.put(clientName, clientActor);
+                System.out.println("Created client-node:" + clientName);
+            }
+        }
+    }
+
+    // add num clients to a node
+    public void addClientsToNode(String actorName, int num) {
+        ActorRef actorRef = actorRefs.get(actorName);
+        for (int i=0; i < num; i++) {
+            String clientName = "client-" + i + "-" + actorRef;
+            clientActorRefs.put(clientName,
+                actorSystem.actorOf(ClientActor.props(actorRef), clientName));
+            System.out.println("Added client-node:" + clientName);
+        }
+    }
+
+    public void stopNode(String actorName) {
+        ActorRef actorRef = actorRefs.get(actorName);
+        String clientName = "client-"+actorName;
+        if(clientActorRefs.containsKey(clientName)) {
+            actorSystem.stop(clientActorRefs.get(clientName));
+            clientActorRefs.remove(clientName);
+        }
+        actorSystem.stop(actorRef);
+        actorRefs.remove(actorName);
+
+        for (ActorRef actor : actorRefs.values()) {
+            actor.tell(new RemoveRaftPeer(actorName), null);
+        }
+
+        allPeers.remove(actorName);
+
+    }
+
+    public void startAllLogging() {
+        if(!clientActorRefs.isEmpty()) {
+            for(Map.Entry<String,ActorRef> client : clientActorRefs.entrySet()) {
+                logGenerator.startLoggingForClient(client.getValue());
+                System.out.println("Started logging for client:"+client.getKey());
+            }
+        } else {
+            System.out.println("There are no clients for any nodes. First create clients using commands- addClients:<num> or addClientsToNode:<nodename>:<num>");
+        }
+
+    }
+
+    public void startLoggingForClient(ActorRef client) {
+        logGenerator.startLoggingForClient(client);
+    }
+
+    public void stopAllLogging() {
+        for(Map.Entry<String,ActorRef> client : clientActorRefs.entrySet()) {
+            logGenerator.stopLoggingForClient(client.getValue());
+        }
+    }
+
+    public void stopLoggingForClient(ActorRef client) {
+        logGenerator.stopLoggingForClient(client);
+    }
+
+    public void printState() {
+        for (ActorRef ref : actorRefs.values()) {
+            ref.tell(new PrintState(), null);
+        }
+    }
+
+    public void printNodes() {
+        for (ActorRef ref : actorRefs.values()) {
+            ref.tell(new PrintRole(), null);
+        }
+    }
+
+    public ActorRef getLeader() {
+        return null;
+    }
+
+    private int getUnusedRandom(int num) {
+        int rand = -1;
+        do {
+            rand = (new Random()).nextInt(num * num);
+        } while (allPeers.keySet().contains("example-"+rand));
+
+        return rand;
+    }
+
+    private static Map<String, String> withoutPeer(String peerId) {
+        Map<String, String> without = new ConcurrentHashMap<>(allPeers);
+        without.remove(peerId);
+
+        return without;
+    }
+}
+
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/messages/KeyValue.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/messages/KeyValue.java
new file mode 100644 (file)
index 0000000..560d5fc
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.example.messages;
+
+import com.google.protobuf.GeneratedMessage;
+import org.opendaylight.controller.cluster.example.protobuff.messages.KeyValueMessages;
+import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
+import org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+public class KeyValue extends Payload implements Serializable {
+    private String key;
+    private String value;
+
+    public KeyValue() {
+    }
+
+    public KeyValue(String key, String value){
+        this.key = key;
+        this.value = value;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    @Override public String toString() {
+        return "KeyValue{" +
+            "key='" + key + '\'' +
+            ", value='" + value + '\'' +
+            '}';
+    }
+
+    // override this method to return  the protobuff related extension fields and their values
+    @Override public Map<GeneratedMessage.GeneratedExtension, String> encode() {
+        Map<GeneratedMessage.GeneratedExtension, String> map = new HashMap<>();
+        map.put(KeyValueMessages.key, getKey());
+        map.put(KeyValueMessages.value, getValue());
+        return map;
+    }
+
+    // override this method to assign the values from protobuff
+    @Override public Payload decode(
+        AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload payloadProtoBuff) {
+        String key = payloadProtoBuff.getExtension(KeyValueMessages.key);
+        String value = payloadProtoBuff.getExtension(KeyValueMessages.value);
+        this.setKey(key);
+        this.setValue(value);
+        return this;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/messages/KeyValueSaved.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/messages/KeyValueSaved.java
new file mode 100644 (file)
index 0000000..9b2a2e9
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.example.messages;
+
+import java.io.Serializable;
+
+public class KeyValueSaved implements Serializable {
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/messages/PrintRole.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/messages/PrintRole.java
new file mode 100644 (file)
index 0000000..a5105f0
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.example.messages;
+
+import java.io.Serializable;
+
+public class PrintRole implements Serializable {
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/messages/PrintState.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/messages/PrintState.java
new file mode 100644 (file)
index 0000000..20ed142
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.example.messages;
+
+import java.io.Serializable;
+
+public class PrintState implements Serializable {
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/protobuff/messages/KeyValueMessages.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/protobuff/messages/KeyValueMessages.java
new file mode 100644 (file)
index 0000000..c3d4bbf
--- /dev/null
@@ -0,0 +1,73 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: KeyValueMessages.proto
+
+package org.opendaylight.controller.cluster.example.protobuff.messages;
+
+public final class KeyValueMessages {
+  private KeyValueMessages() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registry.add(org.opendaylight.controller.cluster.example.protobuff.messages.KeyValueMessages.key);
+    registry.add(org.opendaylight.controller.cluster.example.protobuff.messages.KeyValueMessages.value);
+  }
+  public static final int KEY_FIELD_NUMBER = 2;
+  /**
+   * <code>extend .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload { ... }</code>
+   */
+  public static final
+    com.google.protobuf.GeneratedMessage.GeneratedExtension<
+      org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload,
+      java.lang.String> key = com.google.protobuf.GeneratedMessage
+          .newFileScopedGeneratedExtension(
+        java.lang.String.class,
+        null);
+  public static final int VALUE_FIELD_NUMBER = 3;
+  /**
+   * <code>extend .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload { ... }</code>
+   */
+  public static final
+    com.google.protobuf.GeneratedMessage.GeneratedExtension<
+      org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload,
+      java.lang.String> value = com.google.protobuf.GeneratedMessage
+          .newFileScopedGeneratedExtension(
+        java.lang.String.class,
+        null);
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\026KeyValueMessages.proto\022(org.opendaylig" +
+      "ht.controller.cluster.raft\032\033AppendEntrie" +
+      "sMessages.proto:_\n\003key\022R.org.opendayligh" +
+      "t.controller.cluster.raft.AppendEntries." +
+      "ReplicatedLogEntry.Payload\030\002 \001(\t:a\n\005valu" +
+      "e\022R.org.opendaylight.controller.cluster." +
+      "raft.AppendEntries.ReplicatedLogEntry.Pa" +
+      "yload\030\003 \001(\tBT\n>org.opendaylight.controll" +
+      "er.cluster.example.protobuff.messagesB\020K" +
+      "eyValueMessagesH\001"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          key.internalInit(descriptor.getExtensions().get(0));
+          value.internalInit(descriptor.getExtensions().get(1));
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.getDescriptor(),
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ClientRequestTracker.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ClientRequestTracker.java
new file mode 100644 (file)
index 0000000..4972b34
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+import akka.actor.ActorRef;
+
+public interface ClientRequestTracker {
+    /**
+     * The client actor who is waiting for a response
+     *
+     * @return
+     */
+    ActorRef getClientActor();
+
+    /**
+     *
+     * @return
+     */
+    String getIdentifier();
+
+    /**
+     * The index of the log entry which needs to be replicated
+     *
+     * @return
+     */
+    long getIndex();
+
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ClientRequestTrackerImpl.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ClientRequestTrackerImpl.java
new file mode 100644 (file)
index 0000000..15de6d0
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+import akka.actor.ActorRef;
+
+public class ClientRequestTrackerImpl implements ClientRequestTracker {
+
+    private final ActorRef clientActor;
+    private final String identifier;
+    private final long logIndex;
+
+    public ClientRequestTrackerImpl(ActorRef clientActor, String identifier,
+        long logIndex) {
+
+        this.clientActor = clientActor;
+
+        this.identifier = identifier;
+
+        this.logIndex = logIndex;
+    }
+
+    @Override public ActorRef getClientActor() {
+        return clientActor;
+    }
+
+    @Override public long getIndex() {
+        return logIndex;
+    }
+
+    public String getIdentifier() {
+        return identifier;
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ElectionTerm.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ElectionTerm.java
new file mode 100644 (file)
index 0000000..9f0d02e
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+/**
+ * ElectionTerm contains information about a RaftActors election term.
+ * <p>
+ * This information includes the last known current term of the RaftActor
+ * and which peer was voted for by the RaftActor in that term
+ * <p>
+ * This class ensures that election term information is persisted
+ */
+public interface ElectionTerm {
+    /**
+     * latest term server has seen (initialized to 0
+     * on first boot, increases monotonically)
+     */
+    long getCurrentTerm();
+
+    /**
+     * candidateId that received vote in current
+     * term (or null if none)
+     */
+    String getVotedFor();
+
+    /**
+     * To be called mainly when we are recovering in-memory election state from
+     * persistent storage
+     *
+     * @param currentTerm
+     * @param votedFor
+     */
+    void update(long currentTerm, String votedFor);
+
+    /**
+     * To be called when we need to update the current term either because we
+     * received a message from someone with a more up-to-date term or because we
+     * just voted for someone
+     * <p>
+     * This information needs to be persisted so that on recovery the replica
+     * can start itself in the right term and know if it has already voted in
+     * that term or not
+     *
+     * @param currentTerm
+     * @param votedFor
+     */
+    void updateAndPersist(long currentTerm, String votedFor);
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/FollowerLogInformation.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/FollowerLogInformation.java
new file mode 100644 (file)
index 0000000..f3de983
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * The state of the followers log as known by the Leader
+ */
+public interface FollowerLogInformation {
+
+    /**
+     * Increment the value of the nextIndex
+     * @return
+     */
+    public long incrNextIndex();
+
+    /**
+     * Decrement the value of the nextIndex
+     * @return
+     */
+    public long decrNextIndex();
+
+    /**
+     *
+     * @param nextIndex
+     */
+    void setNextIndex(long nextIndex);
+
+    /**
+     * Increment the value of the matchIndex
+     * @return
+     */
+    public long incrMatchIndex();
+
+    public void setMatchIndex(long matchIndex);
+
+    /**
+     * The identifier of the follower
+     * This could simply be the url of the remote actor
+     */
+    public String getId();
+
+    /**
+     * for each server, index of the next log entry
+     * to send to that server (initialized to leader
+     *    last log index + 1)
+     */
+    public AtomicLong getNextIndex();
+
+    /**
+     * for each server, index of highest log entry
+     * known to be replicated on server
+     *    (initialized to 0, increases monotonically)
+     */
+    public AtomicLong getMatchIndex();
+
+
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/FollowerLogInformationImpl.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/FollowerLogInformationImpl.java
new file mode 100644 (file)
index 0000000..94f9a53
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+public class FollowerLogInformationImpl implements FollowerLogInformation{
+
+    private final String id;
+
+    private final AtomicLong nextIndex;
+
+    private final AtomicLong matchIndex;
+
+    public FollowerLogInformationImpl(String id, AtomicLong nextIndex,
+        AtomicLong matchIndex) {
+        this.id = id;
+        this.nextIndex = nextIndex;
+        this.matchIndex = matchIndex;
+    }
+
+    public long incrNextIndex(){
+        return nextIndex.incrementAndGet();
+    }
+
+    @Override public long decrNextIndex() {
+        return nextIndex.decrementAndGet();
+    }
+
+    @Override public void setNextIndex(long nextIndex) {
+        this.nextIndex.set(nextIndex);
+    }
+
+    public long incrMatchIndex(){
+        return matchIndex.incrementAndGet();
+    }
+
+    @Override public void setMatchIndex(long matchIndex) {
+        this.matchIndex.set(matchIndex);
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public AtomicLong getNextIndex() {
+        return nextIndex;
+    }
+
+    public AtomicLong getMatchIndex() {
+        return matchIndex;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java
new file mode 100644 (file)
index 0000000..b8e9653
--- /dev/null
@@ -0,0 +1,668 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSelection;
+import akka.event.Logging;
+import akka.event.LoggingAdapter;
+import akka.japi.Procedure;
+import akka.persistence.RecoveryCompleted;
+import akka.persistence.SaveSnapshotFailure;
+import akka.persistence.SaveSnapshotSuccess;
+import akka.persistence.SnapshotOffer;
+import akka.persistence.SnapshotSelectionCriteria;
+import akka.persistence.UntypedPersistentActor;
+import org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot;
+import org.opendaylight.controller.cluster.raft.base.messages.ApplyState;
+import org.opendaylight.controller.cluster.raft.base.messages.Replicate;
+import org.opendaylight.controller.cluster.raft.behaviors.Candidate;
+import org.opendaylight.controller.cluster.raft.behaviors.Follower;
+import org.opendaylight.controller.cluster.raft.behaviors.Leader;
+import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior;
+import org.opendaylight.controller.cluster.raft.client.messages.AddRaftPeer;
+import org.opendaylight.controller.cluster.raft.client.messages.FindLeader;
+import org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply;
+import org.opendaylight.controller.cluster.raft.client.messages.RemoveRaftPeer;
+import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * RaftActor encapsulates a state machine that needs to be kept synchronized
+ * in a cluster. It implements the RAFT algorithm as described in the paper
+ * <a href='https://ramcloud.stanford.edu/wiki/download/attachments/11370504/raft.pdf'>
+ * In Search of an Understandable Consensus Algorithm</a>
+ * <p/>
+ * RaftActor has 3 states and each state has a certain behavior associated
+ * with it. A Raft actor can behave as,
+ * <ul>
+ * <li> A Leader </li>
+ * <li> A Follower (or) </li>
+ * <li> A Candidate </li>
+ * </ul>
+ * <p/>
+ * <p/>
+ * A RaftActor MUST be a Leader in order to accept requests from clients to
+ * change the state of it's encapsulated state machine. Once a RaftActor becomes
+ * a Leader it is also responsible for ensuring that all followers ultimately
+ * have the same log and therefore the same state machine as itself.
+ * <p/>
+ * <p/>
+ * The current behavior of a RaftActor determines how election for leadership
+ * is initiated and how peer RaftActors react to request for votes.
+ * <p/>
+ * <p/>
+ * Each RaftActor also needs to know the current election term. It uses this
+ * information for a couple of things. One is to simply figure out who it
+ * voted for in the last election. Another is to figure out if the message
+ * it received to update it's state is stale.
+ * <p/>
+ * <p/>
+ * The RaftActor uses akka-persistence to store it's replicated log.
+ * Furthermore through it's behaviors a Raft Actor determines
+ * <p/>
+ * <ul>
+ * <li> when a log entry should be persisted </li>
+ * <li> when a log entry should be applied to the state machine (and) </li>
+ * <li> when a snapshot should be saved </li>
+ * </ul>
+ */
+public abstract class RaftActor extends UntypedPersistentActor {
+    protected final LoggingAdapter LOG =
+        Logging.getLogger(getContext().system(), this);
+
+    /**
+     * The current state determines the current behavior of a RaftActor
+     * A Raft Actor always starts off in the Follower State
+     */
+    private RaftActorBehavior currentBehavior;
+
+    /**
+     * This context should NOT be passed directly to any other actor it is
+     * only to be consumed by the RaftActorBehaviors
+     */
+    private RaftActorContext context;
+
+    /**
+     * The in-memory journal
+     */
+    private ReplicatedLogImpl replicatedLog = new ReplicatedLogImpl();
+
+
+    public RaftActor(String id, Map<String, String> peerAddresses) {
+        context = new RaftActorContextImpl(this.getSelf(),
+            this.getContext(),
+            id, new ElectionTermImpl(),
+            -1, -1, replicatedLog, peerAddresses, LOG);
+    }
+
+    @Override public void onReceiveRecover(Object message) {
+        if (message instanceof SnapshotOffer) {
+            SnapshotOffer offer = (SnapshotOffer) message;
+            Snapshot snapshot = (Snapshot) offer.snapshot();
+
+            // Create a replicated log with the snapshot information
+            // The replicated log can be used later on to retrieve this snapshot
+            // when we need to install it on a peer
+            replicatedLog = new ReplicatedLogImpl(snapshot);
+
+            // Apply the snapshot to the actors state
+            applySnapshot(snapshot.getState());
+
+        } else if (message instanceof ReplicatedLogEntry) {
+            replicatedLog.append((ReplicatedLogEntry) message);
+        } else if (message instanceof DeleteEntries) {
+            replicatedLog.removeFrom(((DeleteEntries) message).getFromIndex());
+        } else if (message instanceof UpdateElectionTerm) {
+            context.getTermInformation().update(((UpdateElectionTerm) message).getCurrentTerm(), ((UpdateElectionTerm) message).getVotedFor());
+        } else if (message instanceof RecoveryCompleted) {
+            LOG.debug(
+                "Last index in log : " + replicatedLog.lastIndex());
+            currentBehavior = switchBehavior(RaftState.Follower);
+        }
+    }
+
+    @Override public void onReceiveCommand(Object message) {
+        if (message instanceof ApplyState){
+            ApplyState applyState = (ApplyState) message;
+
+            LOG.debug("Applying state for log index {} data {}",
+                applyState.getReplicatedLogEntry().getIndex(),
+                applyState.getReplicatedLogEntry().getData());
+
+            applyState(applyState.getClientActor(), applyState.getIdentifier(),
+                applyState.getReplicatedLogEntry().getData());
+
+        } else if(message instanceof ApplySnapshot ) {
+            applySnapshot(((ApplySnapshot) message).getSnapshot());
+
+        } else if (message instanceof FindLeader) {
+            getSender().tell(
+                new FindLeaderReply(
+                    context.getPeerAddress(currentBehavior.getLeaderId())),
+                getSelf()
+            );
+
+        } else if (message instanceof SaveSnapshotSuccess) {
+            SaveSnapshotSuccess success = (SaveSnapshotSuccess) message;
+
+            // TODO: Not sure if we want to be this aggressive with trimming stuff
+            trimPersistentData(success.metadata().sequenceNr());
+
+        } else if (message instanceof SaveSnapshotFailure) {
+
+            // TODO: Handle failure in saving the snapshot
+
+        } else if (message instanceof FindLeader){
+
+            getSender().tell(new FindLeaderReply(
+                context.getPeerAddress(currentBehavior.getLeaderId())),
+                getSelf());
+
+        } else if (message instanceof AddRaftPeer){
+
+            // FIXME : Do not add raft peers like this.
+            // When adding a new Peer we have to ensure that the a majority of
+            // the peers know about the new Peer. Doing it this way may cause
+            // a situation where multiple Leaders may emerge
+            AddRaftPeer arp = (AddRaftPeer)message;
+           context.addToPeers(arp.getName(), arp.getAddress());
+
+        } else if (message instanceof RemoveRaftPeer){
+
+            RemoveRaftPeer rrp = (RemoveRaftPeer)message;
+            context.removePeer(rrp.getName());
+
+        } else {
+
+            RaftState state =
+                currentBehavior.handleMessage(getSender(), message);
+            currentBehavior = switchBehavior(state);
+        }
+    }
+
+
+
+    /**
+     * When a derived RaftActor needs to persist something it must call
+     * persistData.
+     *
+     * @param clientActor
+     * @param identifier
+     * @param data
+     */
+    protected void persistData(ActorRef clientActor, String identifier,
+        Payload data) {
+
+        ReplicatedLogEntry replicatedLogEntry = new ReplicatedLogImplEntry(
+            context.getReplicatedLog().lastIndex() + 1,
+            context.getTermInformation().getCurrentTerm(), data);
+
+        LOG.debug("Persist data {}", replicatedLogEntry);
+
+        replicatedLog
+            .appendAndPersist(clientActor, identifier, replicatedLogEntry);
+    }
+
+    protected String getId() {
+        return context.getId();
+    }
+
+    /**
+     * Derived actors can call the isLeader method to check if the current
+     * RaftActor is the Leader or not
+     *
+     * @return true it this RaftActor is a Leader false otherwise
+     */
+    protected boolean isLeader() {
+        return context.getId().equals(currentBehavior.getLeaderId());
+    }
+
+    /**
+     * Derived actor can call getLeader if they need a reference to the Leader.
+     * This would be useful for example in forwarding a request to an actor
+     * which is the leader
+     *
+     * @return A reference to the leader if known, null otherwise
+     */
+    protected ActorSelection getLeader(){
+        String leaderId = currentBehavior.getLeaderId();
+        if (leaderId == null) {
+            return null;
+        }
+        String peerAddress = context.getPeerAddress(leaderId);
+        LOG.debug("getLeader leaderId = " + leaderId + " peerAddress = "
+            + peerAddress);
+        return context.actorSelection(peerAddress);
+    }
+
+    protected RaftState getRaftState() {
+        return currentBehavior.state();
+    }
+
+    /**
+     * setPeerAddress sets the address of a known peer at a later time.
+     * <p>
+     * This is to account for situations where a we know that a peer
+     * exists but we do not know an address up-front. This may also be used in
+     * situations where a known peer starts off in a different location and we
+     * need to change it's address
+     * <p>
+     * Note that if the peerId does not match the list of peers passed to
+     * this actor during construction an IllegalStateException will be thrown.
+     *
+     * @param peerId
+     * @param peerAddress
+     */
+    protected void setPeerAddress(String peerId, String peerAddress){
+        context.setPeerAddress(peerId, peerAddress);
+    }
+
+
+
+    /**
+     * The applyState method will be called by the RaftActor when some data
+     * needs to be applied to the actor's state
+     *
+     * @param clientActor A reference to the client who sent this message. This
+     *                    is the same reference that was passed to persistData
+     *                    by the derived actor. clientActor may be null when
+     *                    the RaftActor is behaving as a follower or during
+     *                    recovery.
+     * @param identifier  The identifier of the persisted data. This is also
+     *                    the same identifier that was passed to persistData by
+     *                    the derived actor. identifier may be null when
+     *                    the RaftActor is behaving as a follower or during
+     *                    recovery
+     * @param data        A piece of data that was persisted by the persistData call.
+     *                    This should NEVER be null.
+     */
+    protected abstract void applyState(ActorRef clientActor, String identifier,
+        Object data);
+
+    /**
+     * This method will be called by the RaftActor when a snapshot needs to be
+     * created. The derived actor should respond with its current state.
+     * <p/>
+     * During recovery the state that is returned by the derived actor will
+     * be passed back to it by calling the applySnapshot  method
+     *
+     * @return The current state of the actor
+     */
+    protected abstract Object createSnapshot();
+
+    /**
+     * This method will be called by the RaftActor during recovery to
+     * reconstruct the state of the actor.
+     * <p/>
+     * This method may also be called at any other point during normal
+     * operations when the derived actor is out of sync with it's peers
+     * and the only way to bring it in sync is by applying a snapshot
+     *
+     * @param snapshot A snapshot of the state of the actor
+     */
+    protected abstract void applySnapshot(Object snapshot);
+
+    private RaftActorBehavior switchBehavior(RaftState state) {
+        if (currentBehavior != null) {
+            if (currentBehavior.state() == state) {
+                return currentBehavior;
+            }
+            LOG.info("Switching from state " + currentBehavior.state() + " to "
+                + state);
+
+            try {
+                currentBehavior.close();
+            } catch (Exception e) {
+                LOG.error(e,
+                    "Failed to close behavior : " + currentBehavior.state());
+            }
+
+        } else {
+            LOG.info("Switching behavior to " + state);
+        }
+        RaftActorBehavior behavior = null;
+        if (state == RaftState.Candidate) {
+            behavior = new Candidate(context);
+        } else if (state == RaftState.Follower) {
+            behavior = new Follower(context);
+        } else {
+            behavior = new Leader(context);
+        }
+        return behavior;
+    }
+
+    private void trimPersistentData(long sequenceNumber) {
+        // Trim snapshots
+        // FIXME : Not sure how exactly the SnapshotSelectionCriteria is applied
+        // For now guessing that it is ANDed.
+        deleteSnapshots(new SnapshotSelectionCriteria(
+            sequenceNumber - 100000, 43200000));
+
+        // Trim journal
+        deleteMessages(sequenceNumber);
+    }
+
+
+    private class ReplicatedLogImpl implements ReplicatedLog {
+        private final List<ReplicatedLogEntry> journal;
+        private final Object snapshot;
+        private long snapshotIndex = -1;
+        private long snapshotTerm = -1;
+
+        public ReplicatedLogImpl(Snapshot snapshot) {
+            this.snapshot = snapshot.getState();
+            this.snapshotIndex = snapshot.getLastAppliedIndex();
+            this.snapshotTerm = snapshot.getLastAppliedTerm();
+
+            this.journal = new ArrayList<>(snapshot.getUnAppliedEntries());
+        }
+
+        public ReplicatedLogImpl() {
+            this.snapshot = null;
+            this.journal = new ArrayList<>();
+        }
+
+        @Override public ReplicatedLogEntry get(long index) {
+            int adjustedIndex = adjustedIndex(index);
+
+            if (adjustedIndex < 0 || adjustedIndex >= journal.size()) {
+                return null;
+            }
+
+            return journal.get(adjustedIndex);
+        }
+
+        @Override public ReplicatedLogEntry last() {
+            if (journal.size() == 0) {
+                return null;
+            }
+            return get(journal.size() - 1);
+        }
+
+        @Override public long lastIndex() {
+            if (journal.size() == 0) {
+                return -1;
+            }
+
+            return last().getIndex();
+        }
+
+        @Override public long lastTerm() {
+            if (journal.size() == 0) {
+                return -1;
+            }
+
+            return last().getTerm();
+        }
+
+
+        @Override public void removeFrom(long index) {
+            int adjustedIndex = adjustedIndex(index);
+
+            if (adjustedIndex < 0 || adjustedIndex >= journal.size()) {
+                return;
+            }
+
+            journal.subList(adjustedIndex , journal.size()).clear();
+        }
+
+
+        @Override public void removeFromAndPersist(long index) {
+            int adjustedIndex = adjustedIndex(index);
+
+            if (adjustedIndex < 0 || adjustedIndex >= journal.size()) {
+                return;
+            }
+
+            // FIXME: Maybe this should be done after the command is saved
+            journal.subList(adjustedIndex , journal.size()).clear();
+
+            persist(new DeleteEntries(adjustedIndex), new Procedure<DeleteEntries>(){
+
+                @Override public void apply(DeleteEntries param)
+                    throws Exception {
+                    //FIXME : Doing nothing for now
+                }
+            });
+
+
+        }
+
+        @Override public void append(
+            final ReplicatedLogEntry replicatedLogEntry) {
+            journal.add(replicatedLogEntry);
+        }
+
+        @Override public List<ReplicatedLogEntry> getFrom(long index) {
+            int adjustedIndex = adjustedIndex(index);
+
+            List<ReplicatedLogEntry> entries = new ArrayList<>(100);
+            if (adjustedIndex < 0 || adjustedIndex >= journal.size()) {
+                return entries;
+            }
+
+
+            for (int i = adjustedIndex;
+                 i < journal.size(); i++) {
+                entries.add(journal.get(i));
+            }
+            return entries;
+        }
+
+        @Override public void appendAndPersist(
+            final ReplicatedLogEntry replicatedLogEntry) {
+            appendAndPersist(null, null, replicatedLogEntry);
+        }
+
+        public void appendAndPersist(final ActorRef clientActor,
+            final String identifier,
+            final ReplicatedLogEntry replicatedLogEntry) {
+            context.getLogger().debug(
+                "Append log entry and persist {} ", replicatedLogEntry);
+            // FIXME : By adding the replicated log entry to the in-memory journal we are not truly ensuring durability of the logs
+            journal.add(replicatedLogEntry);
+
+            // When persisting events with persist it is guaranteed that the
+            // persistent actor will not receive further commands between the
+            // persist call and the execution(s) of the associated event
+            // handler. This also holds for multiple persist calls in context
+            // of a single command.
+            persist(replicatedLogEntry,
+                new Procedure<ReplicatedLogEntry>() {
+                    public void apply(ReplicatedLogEntry evt) throws Exception {
+                        // FIXME : Tentatively create a snapshot every hundred thousand entries. To be tuned.
+                        if (size() > 100000) {
+                            ReplicatedLogEntry lastAppliedEntry =
+                                get(context.getLastApplied());
+                            long lastAppliedIndex = -1;
+                            long lastAppliedTerm = -1;
+                            if (lastAppliedEntry != null) {
+                                lastAppliedIndex = lastAppliedEntry.getIndex();
+                                lastAppliedTerm = lastAppliedEntry.getTerm();
+                            }
+
+                            saveSnapshot(Snapshot.create(createSnapshot(),
+                                getFrom(context.getLastApplied() + 1),
+                                lastIndex(), lastTerm(), lastAppliedIndex,
+                                lastAppliedTerm));
+                        }
+                        // Send message for replication
+                        if (clientActor != null) {
+                            currentBehavior.handleMessage(getSelf(),
+                                new Replicate(clientActor, identifier,
+                                    replicatedLogEntry)
+                            );
+                        }
+                    }
+                }
+            );
+        }
+
+        @Override public long size() {
+            return journal.size() + snapshotIndex + 1;
+        }
+
+        @Override public boolean isPresent(long index) {
+            int adjustedIndex = adjustedIndex(index);
+
+            if (adjustedIndex < 0 || adjustedIndex >= journal.size()) {
+                return false;
+            }
+            return true;
+        }
+
+        @Override public boolean isInSnapshot(long index) {
+            return index <= snapshotIndex;
+        }
+
+        @Override public Object getSnapshot() {
+            return snapshot;
+        }
+
+        @Override public long getSnapshotIndex() {
+            return snapshotIndex;
+        }
+
+        @Override public long getSnapshotTerm() {
+            return snapshotTerm;
+        }
+
+        private int adjustedIndex(long index) {
+            if(snapshotIndex < 0){
+                return (int) index;
+            }
+            return (int) (index - snapshotIndex);
+        }
+    }
+
+
+
+
+    private static class DeleteEntries implements Serializable {
+        private final int fromIndex;
+
+
+        public DeleteEntries(int fromIndex) {
+            this.fromIndex = fromIndex;
+        }
+
+        public int getFromIndex() {
+            return fromIndex;
+        }
+    }
+
+
+    private static class Snapshot implements Serializable {
+        private final Object state;
+        private final List<ReplicatedLogEntry> unAppliedEntries;
+        private final long lastIndex;
+        private final long lastTerm;
+        private final long lastAppliedIndex;
+        private final long lastAppliedTerm;
+
+        private Snapshot(Object state,
+            List<ReplicatedLogEntry> unAppliedEntries, long lastIndex,
+            long lastTerm, long lastAppliedIndex, long lastAppliedTerm) {
+            this.state = state;
+            this.unAppliedEntries = unAppliedEntries;
+            this.lastIndex = lastIndex;
+            this.lastTerm = lastTerm;
+            this.lastAppliedIndex = lastAppliedIndex;
+            this.lastAppliedTerm = lastAppliedTerm;
+        }
+
+
+        public static Snapshot create(Object state,
+            List<ReplicatedLogEntry> entries, long lastIndex, long lastTerm,
+            long lastAppliedIndex, long lastAppliedTerm) {
+            return new Snapshot(state, entries, lastIndex, lastTerm,
+                lastAppliedIndex, lastAppliedTerm);
+        }
+
+        public Object getState() {
+            return state;
+        }
+
+        public List<ReplicatedLogEntry> getUnAppliedEntries() {
+            return unAppliedEntries;
+        }
+
+        public long getLastTerm() {
+            return lastTerm;
+        }
+
+        public long getLastAppliedIndex() {
+            return lastAppliedIndex;
+        }
+
+        public long getLastAppliedTerm() {
+            return lastAppliedTerm;
+        }
+    }
+
+    private class ElectionTermImpl implements ElectionTerm {
+        /**
+         * Identifier of the actor whose election term information this is
+         */
+        private long currentTerm = 0;
+        private String votedFor = null;
+
+        public long getCurrentTerm() {
+            return currentTerm;
+        }
+
+        public String getVotedFor() {
+            return votedFor;
+        }
+
+        @Override public void update(long currentTerm, String votedFor) {
+            LOG.info("Set currentTerm={}, votedFor={}", currentTerm, votedFor);
+
+            this.currentTerm = currentTerm;
+            this.votedFor = votedFor;
+        }
+
+        @Override
+        public void updateAndPersist(long currentTerm, String votedFor){
+            update(currentTerm, votedFor);
+            // FIXME : Maybe first persist then update the state
+            persist(new UpdateElectionTerm(this.currentTerm, this.votedFor), new Procedure<UpdateElectionTerm>(){
+
+                @Override public void apply(UpdateElectionTerm param)
+                    throws Exception {
+
+                }
+            });
+        }
+    }
+
+    private static class UpdateElectionTerm implements Serializable {
+        private final long currentTerm;
+        private final String votedFor;
+
+        public UpdateElectionTerm(long currentTerm, String votedFor) {
+            this.currentTerm = currentTerm;
+            this.votedFor = votedFor;
+        }
+
+        public long getCurrentTerm() {
+            return currentTerm;
+        }
+
+        public String getVotedFor() {
+            return votedFor;
+        }
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorContext.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorContext.java
new file mode 100644 (file)
index 0000000..ae9431a
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSelection;
+import akka.actor.ActorSystem;
+import akka.actor.Props;
+import akka.event.LoggingAdapter;
+
+import java.util.Map;
+
+/**
+ * The RaftActorContext contains that portion of the RaftActors state that
+ * needs to be shared with it's behaviors. A RaftActorContext should NEVER be
+ * used in any actor context outside the RaftActor that constructed it.
+ */
+public interface RaftActorContext {
+    /**
+     * Create a new local actor
+      * @param props
+     * @return
+     */
+    ActorRef actorOf(Props props);
+
+    /**
+     * Create a actor selection
+     * @param path
+     * @return
+     */
+    ActorSelection actorSelection(String path);
+
+    /**
+     * Get the identifier for the RaftActor. This identifier represents the
+     * name of the actor whose common state is being shared. For example the
+     * id could be 'inventory'
+     * @return the identifier
+     */
+    String getId();
+
+    /**
+     * A reference to the RaftActor itself. This could be used to send messages
+     * to the RaftActor
+     * @return
+     */
+    ActorRef getActor();
+
+    /**
+     * Get the ElectionTerm information
+     * @return
+     */
+    ElectionTerm getTermInformation();
+
+    /**
+     * index of highest log entry known to be
+     * committed (initialized to 0, increases
+     *    monotonically)
+     * @return
+     */
+    long getCommitIndex();
+
+
+    /**
+     *
+     */
+    void setCommitIndex(long commitIndex);
+
+    /**
+     * index of highest log entry applied to state
+     * machine (initialized to 0, increases
+     *    monotonically)
+     * @return
+     */
+    long getLastApplied();
+
+
+    /**
+     *
+     */
+    void setLastApplied(long lastApplied);
+
+    /**
+     * @return A representation of the log
+     */
+    ReplicatedLog getReplicatedLog();
+
+    /**
+     * @return The ActorSystem associated with this context
+     */
+    ActorSystem getActorSystem();
+
+    /**
+     * Get the logger to be used for logging messages
+     *
+     * @return
+     */
+    LoggingAdapter getLogger();
+
+    /**
+     * Get a mapping of peerId's to their addresses
+     *
+     * @return
+     *
+     */
+    Map<String, String> getPeerAddresses();
+
+    /**
+     * Get the address of the peer as a String. This is the same format in
+     * which a consumer would provide the address
+     *
+     * @param peerId
+     * @return The address of the peer or null if the address has not yet been
+     *         resolved
+     */
+    String getPeerAddress(String peerId);
+
+    /**
+     * Add to actor peers
+     * @param name
+     * @param address
+     */
+    void addToPeers(String name, String address);
+
+    /**
+     *
+     * @param name
+     */
+    public void removePeer(String name);
+
+    /**
+     * Given a peerId return the corresponding actor
+     * <p>
+     *
+     *
+     * @param peerId
+     * @return The actorSelection corresponding to the peer or null if the
+     *         address has not yet been resolved
+     */
+    ActorSelection getPeerActorSelection(String peerId);
+
+    /**
+     * Set Peer Address can be called at a later time to change the address of
+     * a known peer.
+     *
+     * <p>
+     * Throws an IllegalStateException if the peer is unknown
+     *
+     * @param peerId
+     * @param peerAddress
+     */
+    void setPeerAddress(String peerId, String peerAddress);
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorContextImpl.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorContextImpl.java
new file mode 100644 (file)
index 0000000..833c8a9
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSelection;
+import akka.actor.ActorSystem;
+import akka.actor.Props;
+import akka.actor.UntypedActorContext;
+import akka.event.LoggingAdapter;
+
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkState;
+
+public class RaftActorContextImpl implements RaftActorContext{
+
+    private final ActorRef actor;
+
+    private final UntypedActorContext context;
+
+    private final String id;
+
+    private final ElectionTerm termInformation;
+
+    private long commitIndex;
+
+    private long lastApplied;
+
+    private final ReplicatedLog replicatedLog;
+
+    private final Map<String, String> peerAddresses;
+
+    private final LoggingAdapter LOG;
+
+    public RaftActorContextImpl(ActorRef actor, UntypedActorContext context,
+        String id,
+        ElectionTerm termInformation, long commitIndex,
+        long lastApplied, ReplicatedLog replicatedLog, Map<String, String> peerAddresses, LoggingAdapter logger) {
+        this.actor = actor;
+        this.context = context;
+        this.id = id;
+        this.termInformation = termInformation;
+        this.commitIndex = commitIndex;
+        this.lastApplied = lastApplied;
+        this.replicatedLog = replicatedLog;
+        this.peerAddresses = peerAddresses;
+        this.LOG = logger;
+    }
+
+    public ActorRef actorOf(Props props){
+        return context.actorOf(props);
+    }
+
+    public ActorSelection actorSelection(String path){
+        return context.actorSelection(path);
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public ActorRef getActor() {
+        return actor;
+    }
+
+    public ElectionTerm getTermInformation() {
+        return termInformation;
+    }
+
+    public long getCommitIndex() {
+        return commitIndex;
+    }
+
+    @Override public void setCommitIndex(long commitIndex) {
+        this.commitIndex = commitIndex;
+    }
+
+    public long getLastApplied() {
+        return lastApplied;
+    }
+
+    @Override public void setLastApplied(long lastApplied) {
+        this.lastApplied = lastApplied;
+    }
+
+    @Override public ReplicatedLog getReplicatedLog() {
+        return replicatedLog;
+    }
+
+    @Override public ActorSystem getActorSystem() {
+        return context.system();
+    }
+
+    @Override public LoggingAdapter getLogger() {
+        return this.LOG;
+    }
+
+    @Override public Map<String, String> getPeerAddresses() {
+        return peerAddresses;
+    }
+
+    @Override public String getPeerAddress(String peerId) {
+        return peerAddresses.get(peerId);
+    }
+
+    @Override public void addToPeers(String name, String address) {
+        peerAddresses.put(name, address);
+    }
+
+    @Override public void removePeer(String name) {
+        peerAddresses.remove(name);
+    }
+
+    @Override public ActorSelection getPeerActorSelection(String peerId) {
+        String peerAddress = getPeerAddress(peerId);
+        if(peerAddress != null){
+            return actorSelection(peerAddress);
+        }
+        return null;
+    }
+
+    @Override public void setPeerAddress(String peerId, String peerAddress) {
+        LOG.info("Peer address for peer {} set to {}", peerId, peerAddress);
+        checkState(peerAddresses.containsKey(peerId), peerId + " is unknown");
+
+        peerAddresses.put(peerId, peerAddress);
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftState.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftState.java
new file mode 100644 (file)
index 0000000..65114eb
--- /dev/null
@@ -0,0 +1,7 @@
+package org.opendaylight.controller.cluster.raft;
+
+public enum RaftState {
+    Candidate,
+    Follower,
+    Leader
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLog.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLog.java
new file mode 100644 (file)
index 0000000..b7c8955
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+import java.util.List;
+
+/**
+ * Represents the ReplicatedLog that needs to be kept in sync by the RaftActor
+ */
+public interface ReplicatedLog {
+    /**
+     * Get a replicated log entry at the specified index
+     *
+     * @param index the index of the log entry
+     * @return the ReplicatedLogEntry at index. null if index less than 0 or
+     * greater than the size of the in-memory journal.
+     */
+    ReplicatedLogEntry get(long index);
+
+
+    /**
+     * Get the last replicated log entry
+     *
+     * @return
+     */
+    ReplicatedLogEntry last();
+
+    /**
+     *
+     * @return
+     */
+    long lastIndex();
+
+    /**
+     *
+     * @return
+     */
+    long lastTerm();
+
+    /**
+     * To be called when we need to remove entries from the in-memory log.
+     * This method will remove all entries >= index. This method should be used
+     * during recovery to appropriately trim the log based on persisted
+     * information
+     *
+     * @param index the index of the log entry
+     */
+    void removeFrom(long index);
+
+
+    /**
+     * To be called when we need to remove entries from the in-memory log and we
+     * need that information persisted to disk. This method will remove all
+     * entries >= index.
+     * <p>
+     * The persisted information would then be used during recovery to properly
+     * reconstruct the state of the in-memory replicated log
+     *
+     * @param index the index of the log entry
+     */
+    void removeFromAndPersist(long index);
+
+    /**
+     * Append an entry to the log
+     * @param replicatedLogEntry
+     */
+    void append(ReplicatedLogEntry replicatedLogEntry);
+
+    /**
+     *
+     * @param replicatedLogEntry
+     */
+    void appendAndPersist(final ReplicatedLogEntry replicatedLogEntry);
+
+    /**
+     *
+     * @param index the index of the log entry
+     */
+    List<ReplicatedLogEntry> getFrom(long index);
+
+
+    /**
+     *
+     * @return
+     */
+    long size();
+
+    /**
+     * Checks if the entry at the specified index is present or not
+     *
+     * @param index the index of the log entry
+     * @return true if the entry is present in the in-memory journal
+     */
+    boolean isPresent(long index);
+
+    /**
+     * Checks if the entry is present in a snapshot
+     *
+     * @param index the index of the log entry
+     * @return true if the entry is in the snapshot. false if the entry is not
+     * in the snapshot even if the entry may be present in the replicated log
+     */
+    boolean isInSnapshot(long index);
+
+    /**
+     * Get the snapshot
+     *
+     * @return an object representing the snapshot if it exists. null otherwise
+     */
+    Object getSnapshot();
+
+    /**
+     * Get the index of the snapshot
+     *
+     * @return the index from which the snapshot was created. -1 otherwise.
+     */
+    long getSnapshotIndex();
+
+    /**
+     * Get the term of the snapshot
+     *
+     * @return the term of the index from which the snapshot was created. -1
+     * otherwise
+     */
+    long getSnapshotTerm();
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLogEntry.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLogEntry.java
new file mode 100644 (file)
index 0000000..f501c4d
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
+
+/**
+ * Represents one entry in the replicated log
+ */
+public interface ReplicatedLogEntry {
+    /**
+     * The data stored in that entry
+     *
+     * @return
+     */
+    Payload getData();
+
+    /**
+     * The term stored in that entry
+     *
+     * @return
+     */
+    long getTerm();
+
+    /**
+     * The index of the entry
+     *
+     * @return
+     */
+    long getIndex();
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLogImplEntry.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLogImplEntry.java
new file mode 100644 (file)
index 0000000..fc2ec5c
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
+
+import java.io.Serializable;
+
+public class ReplicatedLogImplEntry implements ReplicatedLogEntry,
+    Serializable {
+
+    private final long index;
+    private final long term;
+    private final Payload payload;
+
+    public ReplicatedLogImplEntry(long index, long term, Payload payload) {
+
+        this.index = index;
+        this.term = term;
+        this.payload = payload;
+    }
+
+    @Override public Payload getData() {
+        return payload;
+    }
+
+    @Override public long getTerm() {
+        return term;
+    }
+
+    @Override public long getIndex() {
+        return index;
+    }
+
+    @Override public String toString() {
+        return "Entry{" +
+            "index=" + index +
+            ", term=" + term +
+            '}';
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/SerializationUtils.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/SerializationUtils.java
new file mode 100644 (file)
index 0000000..374e0fa
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
+
+public class SerializationUtils {
+
+    public static Object fromSerializable(Object serializable){
+        if(serializable.getClass().equals(AppendEntries.SERIALIZABLE_CLASS)){
+            return AppendEntries.fromSerializable(serializable);
+        }
+        return serializable;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/ApplySnapshot.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/ApplySnapshot.java
new file mode 100644 (file)
index 0000000..9739fb2
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.base.messages;
+
+import java.io.Serializable;
+
+public class ApplySnapshot implements Serializable {
+    private final Object snapshot;
+
+    public ApplySnapshot(Object snapshot) {
+        this.snapshot = snapshot;
+    }
+
+    public Object getSnapshot() {
+        return snapshot;
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/ApplyState.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/ApplyState.java
new file mode 100644 (file)
index 0000000..b904335
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.base.messages;
+
+import akka.actor.ActorRef;
+import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
+
+import java.io.Serializable;
+
+public class ApplyState implements Serializable {
+    private final ActorRef clientActor;
+    private final String identifier;
+    private final ReplicatedLogEntry replicatedLogEntry;
+
+    public ApplyState(ActorRef clientActor, String identifier,
+        ReplicatedLogEntry replicatedLogEntry) {
+        this.clientActor = clientActor;
+        this.identifier = identifier;
+        this.replicatedLogEntry = replicatedLogEntry;
+    }
+
+    public ActorRef getClientActor() {
+        return clientActor;
+    }
+
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    public ReplicatedLogEntry getReplicatedLogEntry() {
+        return replicatedLogEntry;
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/CommitEntry.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/CommitEntry.java
new file mode 100644 (file)
index 0000000..07e376f
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.base.messages;
+
+import java.io.Serializable;
+
+/**
+ * Message sent to commit an entry to the log
+ */
+public class CommitEntry implements Serializable {
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/ElectionTimeout.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/ElectionTimeout.java
new file mode 100644 (file)
index 0000000..a844849
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.base.messages;
+
+import java.io.Serializable;
+
+public class ElectionTimeout implements Serializable {
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/PersistEntry.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/PersistEntry.java
new file mode 100644 (file)
index 0000000..6a62817
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.base.messages;
+
+import java.io.Serializable;
+
+/**
+ * Message sent to Persist an entry into the transaction journal
+ */
+public class PersistEntry implements Serializable {
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/Replicate.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/Replicate.java
new file mode 100644 (file)
index 0000000..9bc737a
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.base.messages;
+
+import akka.actor.ActorRef;
+import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
+
+import java.io.Serializable;
+
+public class Replicate implements Serializable {
+    private final ActorRef clientActor;
+    private final String identifier;
+    private final ReplicatedLogEntry replicatedLogEntry;
+
+    public Replicate(ActorRef clientActor, String identifier,
+        ReplicatedLogEntry replicatedLogEntry) {
+
+        this.clientActor = clientActor;
+        this.identifier = identifier;
+        this.replicatedLogEntry = replicatedLogEntry;
+    }
+
+    public ActorRef getClientActor() {
+        return clientActor;
+    }
+
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    public ReplicatedLogEntry getReplicatedLogEntry() {
+        return replicatedLogEntry;
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/SaveSnapshot.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/SaveSnapshot.java
new file mode 100644 (file)
index 0000000..861f5ee
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.base.messages;
+
+import java.io.Serializable;
+
+/**
+ * This message is sent by a RaftActor to itself so that a subclass can process
+ * it and use it to save it's state
+ */
+public class SaveSnapshot implements Serializable {
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/SendHeartBeat.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/SendHeartBeat.java
new file mode 100644 (file)
index 0000000..3c8c845
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.base.messages;
+
+import java.io.Serializable;
+
+/**
+ * This messages is sent to the Leader to prompt it to send a heartbeat
+ * to it's followers.
+ *
+ * Typically the Leader to itself on a schedule
+ */
+public class SendHeartBeat implements Serializable {
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/SendInstallSnapshot.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/SendInstallSnapshot.java
new file mode 100644 (file)
index 0000000..6c3313f
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.base.messages;
+
+import java.io.Serializable;
+
+public class SendInstallSnapshot implements Serializable {
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/AbstractRaftActorBehavior.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/AbstractRaftActorBehavior.java
new file mode 100644 (file)
index 0000000..f7281bb
--- /dev/null
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.behaviors;
+
+import akka.actor.ActorRef;
+import akka.actor.Cancellable;
+import org.opendaylight.controller.cluster.raft.ClientRequestTracker;
+import org.opendaylight.controller.cluster.raft.RaftActorContext;
+import org.opendaylight.controller.cluster.raft.RaftState;
+import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
+import org.opendaylight.controller.cluster.raft.SerializationUtils;
+import org.opendaylight.controller.cluster.raft.base.messages.ApplyState;
+import org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply;
+import org.opendaylight.controller.cluster.raft.messages.RequestVote;
+import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
+import scala.concurrent.duration.FiniteDuration;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Abstract class that represents the behavior of a RaftActor
+ * <p/>
+ * All Servers:
+ * <ul>
+ * <li> If commitIndex > lastApplied: increment lastApplied, apply
+ * log[lastApplied] to state machine (§5.3)
+ * <li> If RPC request or response contains term T > currentTerm:
+ * set currentTerm = T, convert to follower (§5.1)
+ */
+public abstract class AbstractRaftActorBehavior implements RaftActorBehavior {
+
+    /**
+     * Information about the RaftActor whose behavior this class represents
+     */
+    protected final RaftActorContext context;
+
+    /**
+     * The maximum election time variance
+     */
+    private static final int ELECTION_TIME_MAX_VARIANCE = 100;
+
+    /**
+     * The interval at which a heart beat message will be sent to the remote
+     * RaftActor
+     * <p/>
+     * Since this is set to 100 milliseconds the Election timeout should be
+     * at least 200 milliseconds
+     */
+    protected static final FiniteDuration HEART_BEAT_INTERVAL =
+        new FiniteDuration(100, TimeUnit.MILLISECONDS);
+
+    /**
+     * The interval in which a new election would get triggered if no leader is found
+     */
+    private static final long ELECTION_TIME_INTERVAL =
+        HEART_BEAT_INTERVAL.toMillis() * 2;
+
+    /**
+     *
+     */
+    private Cancellable electionCancel = null;
+
+    /**
+     *
+     */
+    protected String leaderId = null;
+
+
+    protected AbstractRaftActorBehavior(RaftActorContext context) {
+        this.context = context;
+    }
+
+    /**
+     * Derived classes should not directly handle AppendEntries messages it
+     * should let the base class handle it first. Once the base class handles
+     * the AppendEntries message and does the common actions that are applicable
+     * in all RaftState's it will delegate the handling of the AppendEntries
+     * message to the derived class to do more state specific handling by calling
+     * this method
+     *
+     * @param sender         The actor that sent this message
+     * @param appendEntries  The AppendEntries message
+     * @return
+     */
+    protected abstract RaftState handleAppendEntries(ActorRef sender,
+        AppendEntries appendEntries);
+
+
+    /**
+     * appendEntries first processes the AppendEntries message and then
+     * delegates handling to a specific behavior
+     *
+     * @param sender
+     * @param appendEntries
+     * @return
+     */
+    protected RaftState appendEntries(ActorRef sender,
+        AppendEntries appendEntries) {
+
+        // 1. Reply false if term < currentTerm (§5.1)
+        if (appendEntries.getTerm() < currentTerm()) {
+            context.getLogger().debug(
+                "Cannot append entries because sender term " + appendEntries
+                    .getTerm() + " is less than " + currentTerm());
+            sender.tell(
+                new AppendEntriesReply(context.getId(), currentTerm(), false,
+                    lastIndex(), lastTerm()), actor()
+            );
+            return state();
+        }
+
+
+        return handleAppendEntries(sender, appendEntries);
+    }
+
+    /**
+     * Derived classes should not directly handle AppendEntriesReply messages it
+     * should let the base class handle it first. Once the base class handles
+     * the AppendEntriesReply message and does the common actions that are
+     * applicable in all RaftState's it will delegate the handling of the
+     * AppendEntriesReply message to the derived class to do more state specific
+     * handling by calling this method
+     *
+     * @param sender             The actor that sent this message
+     * @param appendEntriesReply The AppendEntriesReply message
+     * @return
+     */
+    protected abstract RaftState handleAppendEntriesReply(ActorRef sender,
+        AppendEntriesReply appendEntriesReply);
+
+    /**
+     * requestVote handles the RequestVote message. This logic is common
+     * for all behaviors
+     *
+     * @param sender
+     * @param requestVote
+     * @return
+     */
+    protected RaftState requestVote(ActorRef sender,
+        RequestVote requestVote) {
+
+        boolean grantVote = false;
+
+        //  Reply false if term < currentTerm (§5.1)
+        if (requestVote.getTerm() < currentTerm()) {
+            grantVote = false;
+
+            // If votedFor is null or candidateId, and candidate’s log is at
+            // least as up-to-date as receiver’s log, grant vote (§5.2, §5.4)
+        } else if (votedFor() == null || votedFor()
+            .equals(requestVote.getCandidateId())) {
+
+            boolean candidateLatest = false;
+
+            // From §5.4.1
+            // Raft determines which of two logs is more up-to-date
+            // by comparing the index and term of the last entries in the
+            // logs. If the logs have last entries with different terms, then
+            // the log with the later term is more up-to-date. If the logs
+            // end with the same term, then whichever log is longer is
+            // more up-to-date.
+            if (requestVote.getLastLogTerm() > lastTerm()) {
+                candidateLatest = true;
+            } else if ((requestVote.getLastLogTerm() == lastTerm())
+                && requestVote.getLastLogIndex() >= lastIndex()) {
+                candidateLatest = true;
+            }
+
+            if (candidateLatest) {
+                grantVote = true;
+                context.getTermInformation().updateAndPersist(requestVote.getTerm(),
+                    requestVote.getCandidateId());
+            }
+        }
+
+        sender.tell(new RequestVoteReply(currentTerm(), grantVote), actor());
+
+        return state();
+    }
+
+    /**
+     * Derived classes should not directly handle RequestVoteReply messages it
+     * should let the base class handle it first. Once the base class handles
+     * the RequestVoteReply message and does the common actions that are
+     * applicable in all RaftState's it will delegate the handling of the
+     * RequestVoteReply message to the derived class to do more state specific
+     * handling by calling this method
+     *
+     * @param sender           The actor that sent this message
+     * @param requestVoteReply The RequestVoteReply message
+     * @return
+     */
+    protected abstract RaftState handleRequestVoteReply(ActorRef sender,
+        RequestVoteReply requestVoteReply);
+
+    /**
+     * Creates a random election duration
+     *
+     * @return
+     */
+    protected FiniteDuration electionDuration() {
+        long variance = new Random().nextInt(ELECTION_TIME_MAX_VARIANCE);
+        return new FiniteDuration(ELECTION_TIME_INTERVAL + variance,
+            TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * stop the scheduled election
+     */
+    protected void stopElection() {
+        if (electionCancel != null && !electionCancel.isCancelled()) {
+            electionCancel.cancel();
+        }
+    }
+
+    /**
+     * schedule a new election
+     *
+     * @param interval
+     */
+    protected void scheduleElection(FiniteDuration interval) {
+        stopElection();
+
+        // Schedule an election. When the scheduler triggers an ElectionTimeout
+        // message is sent to itself
+        electionCancel =
+            context.getActorSystem().scheduler().scheduleOnce(interval,
+                context.getActor(), new ElectionTimeout(),
+                context.getActorSystem().dispatcher(), context.getActor());
+    }
+
+    /**
+     * Get the current term
+     * @return
+     */
+    protected long currentTerm() {
+        return context.getTermInformation().getCurrentTerm();
+    }
+
+    /**
+     * Get the candidate for whom we voted in the current term
+     * @return
+     */
+    protected String votedFor() {
+        return context.getTermInformation().getVotedFor();
+    }
+
+    /**
+     * Get the actor associated with this behavior
+     * @return
+     */
+    protected ActorRef actor() {
+        return context.getActor();
+    }
+
+    /**
+     * Get the term from the last entry in the log
+     *
+     * @return
+     */
+    protected long lastTerm() {
+        return context.getReplicatedLog().lastTerm();
+    }
+
+    /**
+     * Get the index from the last entry in the log
+     *
+     * @return
+     */
+    protected long lastIndex() {
+        return context.getReplicatedLog().lastIndex();
+    }
+
+    /**
+     * Find the client request tracker for a specific logIndex
+     *
+     * @param logIndex
+     * @return
+     */
+    protected ClientRequestTracker findClientRequestTracker(long logIndex) {
+        return null;
+    }
+
+    /**
+     * Find the log index from the previous to last entry in the log
+     *
+     * @return
+     */
+    protected long prevLogIndex(long index){
+        ReplicatedLogEntry prevEntry =
+            context.getReplicatedLog().get(index - 1);
+        if (prevEntry != null) {
+            return prevEntry.getIndex();
+        }
+        return -1;
+    }
+
+    /**
+     * Find the log term from the previous to last entry in the log
+     * @return
+     */
+    protected long prevLogTerm(long index){
+        ReplicatedLogEntry prevEntry =
+            context.getReplicatedLog().get(index - 1);
+        if (prevEntry != null) {
+            return prevEntry.getTerm();
+        }
+        return -1;
+    }
+
+    /**
+     * Apply the provided index to the state machine
+     *
+     * @param index a log index that is known to be committed
+     */
+    protected void applyLogToStateMachine(long index) {
+        // Now maybe we apply to the state machine
+        for (long i = context.getLastApplied() + 1;
+             i < index + 1; i++) {
+            ActorRef clientActor = null;
+            String identifier = null;
+            ClientRequestTracker tracker = findClientRequestTracker(i);
+
+            if (tracker != null) {
+                clientActor = tracker.getClientActor();
+                identifier = tracker.getIdentifier();
+            }
+            ReplicatedLogEntry replicatedLogEntry =
+                context.getReplicatedLog().get(i);
+
+            if (replicatedLogEntry != null) {
+                actor().tell(new ApplyState(clientActor, identifier,
+                    replicatedLogEntry), actor());
+            } else {
+                context.getLogger().error(
+                    "Missing index " + i + " from log. Cannot apply state.");
+            }
+        }
+        // Send a local message to the local RaftActor (it's derived class to be
+        // specific to apply the log to it's index)
+        context.setLastApplied(index);
+    }
+
+    protected Object fromSerializableMessage(Object serializable){
+        return SerializationUtils.fromSerializable(serializable);
+    }
+
+    @Override
+    public RaftState handleMessage(ActorRef sender, Object message) {
+        if (message instanceof AppendEntries) {
+            return appendEntries(sender, (AppendEntries) message);
+        } else if (message instanceof AppendEntriesReply) {
+            return handleAppendEntriesReply(sender, (AppendEntriesReply) message);
+        } else if (message instanceof RequestVote) {
+            return requestVote(sender, (RequestVote) message);
+        } else if (message instanceof RequestVoteReply) {
+            return handleRequestVoteReply(sender, (RequestVoteReply) message);
+        }
+        return state();
+    }
+
+    @Override public String getLeaderId() {
+        return leaderId;
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Candidate.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Candidate.java
new file mode 100644 (file)
index 0000000..c125bd3
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.behaviors;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSelection;
+import org.opendaylight.controller.cluster.raft.RaftActorContext;
+import org.opendaylight.controller.cluster.raft.RaftState;
+import org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply;
+import org.opendaylight.controller.cluster.raft.messages.RaftRPC;
+import org.opendaylight.controller.cluster.raft.messages.RequestVote;
+import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
+
+import java.util.Set;
+
+/**
+ * The behavior of a RaftActor when it is in the CandidateState
+ * <p/>
+ * Candidates (§5.2):
+ * <ul>
+ * <li> On conversion to candidate, start election:
+ * <ul>
+ * <li> Increment currentTerm
+ * <li> Vote for self
+ * <li> Reset election timer
+ * <li> Send RequestVote RPCs to all other servers
+ * </ul>
+ * <li> If votes received from majority of servers: become leader
+ * <li> If AppendEntries RPC received from new leader: convert to
+ * follower
+ * <li> If election timeout elapses: start new election
+ * </ul>
+ */
+public class Candidate extends AbstractRaftActorBehavior {
+
+    private int voteCount;
+
+    private final int votesRequired;
+
+    private final Set<String> peers;
+
+    public Candidate(RaftActorContext context) {
+        super(context);
+
+        peers = context.getPeerAddresses().keySet();
+
+        context.getLogger().debug("Election:Candidate has following peers:"+ peers);
+
+        if(peers.size() > 0) {
+            // Votes are required from a majority of the peers including self.
+            // The votesRequired field therefore stores a calculated value
+            // of the number of votes required for this candidate to win an
+            // election based on it's known peers.
+            // If a peer was added during normal operation and raft replicas
+            // came to know about them then the new peer would also need to be
+            // taken into consideration when calculating this value.
+            // Here are some examples for what the votesRequired would be for n
+            // peers
+            // 0 peers = 1 votesRequired (0 + 1) / 2 + 1 = 1
+            // 2 peers = 2 votesRequired (2 + 1) / 2 + 1 = 2
+            // 4 peers = 3 votesRequired (4 + 1) / 2 + 1 = 3
+            int noOfPeers = peers.size();
+            int self = 1;
+            votesRequired = (noOfPeers + self) / 2 + 1;
+        } else {
+            votesRequired = 0;
+        }
+
+        startNewTerm();
+        scheduleElection(electionDuration());
+    }
+
+    @Override protected RaftState handleAppendEntries(ActorRef sender,
+        AppendEntries appendEntries) {
+
+        context.getLogger().info("Candidate: Received {}", appendEntries.toString());
+
+        return state();
+    }
+
+    @Override protected RaftState handleAppendEntriesReply(ActorRef sender,
+        AppendEntriesReply appendEntriesReply) {
+
+        return state();
+    }
+
+    @Override protected RaftState handleRequestVoteReply(ActorRef sender,
+        RequestVoteReply requestVoteReply) {
+
+        if (requestVoteReply.isVoteGranted()) {
+            voteCount++;
+        }
+
+        if (voteCount >= votesRequired) {
+            return RaftState.Leader;
+        }
+
+        return state();
+    }
+
+    @Override public RaftState state() {
+        return RaftState.Candidate;
+    }
+
+    @Override
+    public RaftState handleMessage(ActorRef sender, Object originalMessage) {
+
+        Object message = fromSerializableMessage(originalMessage);
+
+        if (message instanceof RaftRPC) {
+
+            RaftRPC rpc = (RaftRPC) message;
+
+            context.getLogger().debug("RaftRPC message received {} my term is {}", rpc.toString(), context.getTermInformation().getCurrentTerm());
+
+            // If RPC request or response contains term T > currentTerm:
+            // set currentTerm = T, convert to follower (§5.1)
+            // This applies to all RPC messages and responses
+            if (rpc.getTerm() > context.getTermInformation().getCurrentTerm()) {
+                context.getTermInformation().updateAndPersist(rpc.getTerm(), null);
+                return RaftState.Follower;
+            }
+        }
+
+        if (message instanceof ElectionTimeout) {
+            if (votesRequired == 0) {
+                // If there are no peers then we should be a Leader
+                // We wait for the election timeout to occur before declare
+                // ourselves the leader. This gives enough time for a leader
+                // who we do not know about (as a peer)
+                // to send a message to the candidate
+                return RaftState.Leader;
+            }
+            startNewTerm();
+            scheduleElection(electionDuration());
+            return state();
+        }
+
+        return super.handleMessage(sender, message);
+    }
+
+
+    private void startNewTerm() {
+
+
+        // set voteCount back to 1 (that is voting for self)
+        voteCount = 1;
+
+        // Increment the election term and vote for self
+        long currentTerm = context.getTermInformation().getCurrentTerm();
+        context.getTermInformation().updateAndPersist(currentTerm + 1,
+            context.getId());
+
+        context.getLogger().debug("Starting new term " + (currentTerm + 1));
+
+        // Request for a vote
+        // TODO: Retry request for vote if replies do not arrive in a reasonable
+        // amount of time TBD
+        for (String peerId : peers) {
+            ActorSelection peerActor = context.getPeerActorSelection(peerId);
+            if(peerActor != null) {
+                peerActor.tell(new RequestVote(
+                        context.getTermInformation().getCurrentTerm(),
+                        context.getId(),
+                        context.getReplicatedLog().lastIndex(),
+                        context.getReplicatedLog().lastTerm()),
+                    context.getActor()
+                );
+            }
+        }
+
+
+    }
+
+    @Override public void close() throws Exception {
+        stopElection();
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Follower.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Follower.java
new file mode 100644 (file)
index 0000000..db62dfc
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.behaviors;
+
+import akka.actor.ActorRef;
+import org.opendaylight.controller.cluster.raft.RaftActorContext;
+import org.opendaylight.controller.cluster.raft.RaftState;
+import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
+import org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot;
+import org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply;
+import org.opendaylight.controller.cluster.raft.messages.InstallSnapshot;
+import org.opendaylight.controller.cluster.raft.messages.RaftRPC;
+import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
+
+/**
+ * The behavior of a RaftActor in the Follower state
+ * <p/>
+ * <ul>
+ * <li> Respond to RPCs from candidates and leaders
+ * <li> If election timeout elapses without receiving AppendEntries
+ * RPC from current leader or granting vote to candidate:
+ * convert to candidate
+ * </ul>
+ */
+public class Follower extends AbstractRaftActorBehavior {
+    public Follower(RaftActorContext context) {
+        super(context);
+
+        scheduleElection(electionDuration());
+    }
+
+    @Override protected RaftState handleAppendEntries(ActorRef sender,
+        AppendEntries appendEntries) {
+
+        if(appendEntries.getEntries() != null && appendEntries.getEntries().size() > 0) {
+            context.getLogger()
+                .info("Follower: Received {}", appendEntries.toString());
+        }
+
+        // TODO : Refactor this method into a bunch of smaller methods
+        // to make it easier to read. Before refactoring ensure tests
+        // cover the code properly
+
+        // 1. Reply false if term < currentTerm (§5.1)
+        // This is handled in the appendEntries method of the base class
+
+        // If we got here then we do appear to be talking to the leader
+        leaderId = appendEntries.getLeaderId();
+
+        // 2. Reply false if log doesn’t contain an entry at prevLogIndex
+        // whose term matches prevLogTerm (§5.3)
+
+        ReplicatedLogEntry previousEntry = context.getReplicatedLog()
+            .get(appendEntries.getPrevLogIndex());
+
+
+        boolean outOfSync = true;
+
+        // First check if the logs are in sync or not
+        if (lastIndex() == -1
+            && appendEntries.getPrevLogIndex() != -1) {
+
+            // The follower's log is out of sync because the leader does have
+            // an entry at prevLogIndex and this follower has no entries in
+            // it's log.
+
+            context.getLogger().debug(
+                "The followers log is empty and the senders prevLogIndex is {}",
+                appendEntries.getPrevLogIndex());
+
+        } else if (lastIndex() > -1
+            && appendEntries.getPrevLogIndex() != -1
+            && previousEntry == null) {
+
+            // The follower's log is out of sync because the Leader's
+            // prevLogIndex entry was not found in it's log
+
+            context.getLogger().debug(
+                "The log is not empty but the prevLogIndex {} was not found in it",
+                appendEntries.getPrevLogIndex());
+
+        } else if (lastIndex() > -1
+            && previousEntry != null
+            && previousEntry.getTerm()!= appendEntries.getPrevLogTerm()) {
+
+            // The follower's log is out of sync because the Leader's
+            // prevLogIndex entry does exist in the follower's log but it has
+            // a different term in it
+
+            context.getLogger().debug(
+                "Cannot append entries because previous entry term {}  is not equal to append entries prevLogTerm {}"
+                , previousEntry.getTerm()
+                , appendEntries.getPrevLogTerm());
+        } else {
+            outOfSync = false;
+        }
+
+        if (outOfSync) {
+            // We found that the log was out of sync so just send a negative
+            // reply and return
+            sender.tell(
+                new AppendEntriesReply(context.getId(), currentTerm(), false,
+                    lastIndex(), lastTerm()), actor()
+            );
+            return state();
+        }
+
+        if (appendEntries.getEntries() != null
+            && appendEntries.getEntries().size() > 0) {
+            context.getLogger().debug(
+                "Number of entries to be appended = " + appendEntries
+                    .getEntries().size()
+            );
+
+            // 3. If an existing entry conflicts with a new one (same index
+            // but different terms), delete the existing entry and all that
+            // follow it (§5.3)
+            int addEntriesFrom = 0;
+            if (context.getReplicatedLog().size() > 0) {
+
+                // Find the entry up until which the one that is not in the
+                // follower's log
+                for (int i = 0;
+                     i < appendEntries.getEntries()
+                         .size(); i++, addEntriesFrom++) {
+                    ReplicatedLogEntry matchEntry =
+                        appendEntries.getEntries().get(i);
+                    ReplicatedLogEntry newEntry = context.getReplicatedLog()
+                        .get(matchEntry.getIndex());
+
+                    if (newEntry == null) {
+                        //newEntry not found in the log
+                        break;
+                    }
+
+                    if (newEntry.getTerm() == matchEntry
+                        .getTerm()) {
+                        continue;
+                    }
+
+                    context.getLogger().debug(
+                        "Removing entries from log starting at "
+                            + matchEntry.getIndex()
+                    );
+
+                    // Entries do not match so remove all subsequent entries
+                    context.getReplicatedLog()
+                        .removeFromAndPersist(matchEntry.getIndex());
+                    break;
+                }
+            }
+
+            context.getLogger().debug(
+                "After cleanup entries to be added from = " + (addEntriesFrom
+                    + lastIndex())
+            );
+
+            // 4. Append any new entries not already in the log
+            for (int i = addEntriesFrom;
+                 i < appendEntries.getEntries().size(); i++) {
+
+                context.getLogger().info(
+                    "Append entry to log " + appendEntries.getEntries().get(
+                        i).getData()
+                        .toString()
+                );
+                context.getReplicatedLog()
+                    .appendAndPersist(appendEntries.getEntries().get(i));
+            }
+
+            context.getLogger().debug(
+                "Log size is now " + context.getReplicatedLog().size());
+        }
+
+
+        // 5. If leaderCommit > commitIndex, set commitIndex =
+        // min(leaderCommit, index of last new entry)
+
+        long prevCommitIndex = context.getCommitIndex();
+
+        context.setCommitIndex(Math.min(appendEntries.getLeaderCommit(),
+            context.getReplicatedLog().lastIndex()));
+
+        if (prevCommitIndex != context.getCommitIndex()) {
+            context.getLogger()
+                .debug("Commit index set to " + context.getCommitIndex());
+        }
+
+        // If commitIndex > lastApplied: increment lastApplied, apply
+        // log[lastApplied] to state machine (§5.3)
+        if (appendEntries.getLeaderCommit() > context.getLastApplied()) {
+            applyLogToStateMachine(appendEntries.getLeaderCommit());
+        }
+
+        sender.tell(new AppendEntriesReply(context.getId(), currentTerm(), true,
+            lastIndex(), lastTerm()), actor());
+
+        return state();
+    }
+
+    @Override protected RaftState handleAppendEntriesReply(ActorRef sender,
+        AppendEntriesReply appendEntriesReply) {
+        return state();
+    }
+
+    @Override protected RaftState handleRequestVoteReply(ActorRef sender,
+        RequestVoteReply requestVoteReply) {
+        return state();
+    }
+
+    @Override public RaftState state() {
+        return RaftState.Follower;
+    }
+
+    @Override public RaftState handleMessage(ActorRef sender, Object originalMessage) {
+
+        Object message = fromSerializableMessage(originalMessage);
+
+        if (message instanceof RaftRPC) {
+            RaftRPC rpc = (RaftRPC) message;
+            // If RPC request or response contains term T > currentTerm:
+            // set currentTerm = T, convert to follower (§5.1)
+            // This applies to all RPC messages and responses
+            if (rpc.getTerm() > context.getTermInformation().getCurrentTerm()) {
+                context.getTermInformation().updateAndPersist(rpc.getTerm(), null);
+            }
+        }
+
+        if (message instanceof ElectionTimeout) {
+            return RaftState.Candidate;
+
+        } else if (message instanceof InstallSnapshot) {
+            InstallSnapshot installSnapshot = (InstallSnapshot) message;
+            actor().tell(new ApplySnapshot(installSnapshot.getData()), actor());
+        }
+
+        scheduleElection(electionDuration());
+
+        return super.handleMessage(sender, message);
+    }
+
+    @Override public void close() throws Exception {
+        stopElection();
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Leader.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Leader.java
new file mode 100644 (file)
index 0000000..53e47c2
--- /dev/null
@@ -0,0 +1,427 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.behaviors;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSelection;
+import akka.actor.Cancellable;
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.cluster.raft.ClientRequestTracker;
+import org.opendaylight.controller.cluster.raft.ClientRequestTrackerImpl;
+import org.opendaylight.controller.cluster.raft.FollowerLogInformation;
+import org.opendaylight.controller.cluster.raft.FollowerLogInformationImpl;
+import org.opendaylight.controller.cluster.raft.RaftActorContext;
+import org.opendaylight.controller.cluster.raft.RaftState;
+import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
+import org.opendaylight.controller.cluster.raft.base.messages.ApplyState;
+import org.opendaylight.controller.cluster.raft.base.messages.Replicate;
+import org.opendaylight.controller.cluster.raft.base.messages.SendHeartBeat;
+import org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply;
+import org.opendaylight.controller.cluster.raft.messages.InstallSnapshot;
+import org.opendaylight.controller.cluster.raft.messages.InstallSnapshotReply;
+import org.opendaylight.controller.cluster.raft.messages.RaftRPC;
+import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
+import scala.concurrent.duration.FiniteDuration;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * The behavior of a RaftActor when it is in the Leader state
+ * <p/>
+ * Leaders:
+ * <ul>
+ * <li> Upon election: send initial empty AppendEntries RPCs
+ * (heartbeat) to each server; repeat during idle periods to
+ * prevent election timeouts (§5.2)
+ * <li> If command received from client: append entry to local log,
+ * respond after entry applied to state machine (§5.3)
+ * <li> If last log index ≥ nextIndex for a follower: send
+ * AppendEntries RPC with log entries starting at nextIndex
+ * <ul>
+ * <li> If successful: update nextIndex and matchIndex for
+ * follower (§5.3)
+ * <li> If AppendEntries fails because of log inconsistency:
+ * decrement nextIndex and retry (§5.3)
+ * </ul>
+ * <li> If there exists an N such that N > commitIndex, a majority
+ * of matchIndex[i] ≥ N, and log[N].term == currentTerm:
+ * set commitIndex = N (§5.3, §5.4).
+ */
+public class Leader extends AbstractRaftActorBehavior {
+
+
+    private final Map<String, FollowerLogInformation> followerToLog =
+        new HashMap();
+
+    private final Set<String> followers;
+
+    private Cancellable heartbeatSchedule = null;
+    private Cancellable appendEntriesSchedule = null;
+    private Cancellable installSnapshotSchedule = null;
+
+    private List<ClientRequestTracker> trackerList = new ArrayList<>();
+
+    private final int minReplicationCount;
+
+    public Leader(RaftActorContext context) {
+        super(context);
+
+        if (lastIndex() >= 0) {
+            context.setCommitIndex(lastIndex());
+        }
+
+        followers = context.getPeerAddresses().keySet();
+
+        for (String followerId : followers) {
+            FollowerLogInformation followerLogInformation =
+                new FollowerLogInformationImpl(followerId,
+                    new AtomicLong(lastIndex()),
+                    new AtomicLong(-1));
+
+            followerToLog.put(followerId, followerLogInformation);
+        }
+
+        context.getLogger().debug("Election:Leader has following peers:"+ followers);
+
+        if (followers.size() > 0) {
+            minReplicationCount = (followers.size() + 1) / 2 + 1;
+        } else {
+            minReplicationCount = 0;
+        }
+
+
+        // Immediately schedule a heartbeat
+        // Upon election: send initial empty AppendEntries RPCs
+        // (heartbeat) to each server; repeat during idle periods to
+        // prevent election timeouts (§5.2)
+        scheduleHeartBeat(new FiniteDuration(0, TimeUnit.SECONDS));
+
+        scheduleInstallSnapshotCheck(
+            new FiniteDuration(HEART_BEAT_INTERVAL.length() * 1000,
+                HEART_BEAT_INTERVAL.unit())
+        );
+
+    }
+
+    @Override protected RaftState handleAppendEntries(ActorRef sender,
+        AppendEntries appendEntries) {
+
+        context.getLogger().info("Leader: Received {}", appendEntries.toString());
+
+        return state();
+    }
+
+    @Override protected RaftState handleAppendEntriesReply(ActorRef sender,
+        AppendEntriesReply appendEntriesReply) {
+
+        if(! appendEntriesReply.isSuccess()) {
+            context.getLogger()
+                .info("Leader: Received {}", appendEntriesReply.toString());
+        }
+
+        // Update the FollowerLogInformation
+        String followerId = appendEntriesReply.getFollowerId();
+        FollowerLogInformation followerLogInformation =
+            followerToLog.get(followerId);
+
+        if(followerLogInformation == null){
+            context.getLogger().error("Unknown follower {}", followerId);
+            return state();
+        }
+
+        if (appendEntriesReply.isSuccess()) {
+            followerLogInformation
+                .setMatchIndex(appendEntriesReply.getLogLastIndex());
+            followerLogInformation
+                .setNextIndex(appendEntriesReply.getLogLastIndex() + 1);
+        } else {
+
+            // TODO: When we find that the follower is out of sync with the
+            // Leader we simply decrement that followers next index by 1.
+            // Would it be possible to do better than this? The RAFT spec
+            // does not explicitly deal with it but may be something for us to
+            // think about
+
+            followerLogInformation.decrNextIndex();
+        }
+
+        // Now figure out if this reply warrants a change in the commitIndex
+        // If there exists an N such that N > commitIndex, a majority
+        // of matchIndex[i] ≥ N, and log[N].term == currentTerm:
+        // set commitIndex = N (§5.3, §5.4).
+        for (long N = context.getCommitIndex() + 1; ; N++) {
+            int replicatedCount = 1;
+
+            for (FollowerLogInformation info : followerToLog.values()) {
+                if (info.getMatchIndex().get() >= N) {
+                    replicatedCount++;
+                }
+            }
+
+            if (replicatedCount >= minReplicationCount) {
+                ReplicatedLogEntry replicatedLogEntry =
+                    context.getReplicatedLog().get(N);
+                if (replicatedLogEntry != null
+                    && replicatedLogEntry.getTerm()
+                    == currentTerm()) {
+                    context.setCommitIndex(N);
+                }
+            } else {
+                break;
+            }
+        }
+
+        // Apply the change to the state machine
+        if (context.getCommitIndex() > context.getLastApplied()) {
+            applyLogToStateMachine(context.getCommitIndex());
+        }
+
+        return state();
+    }
+
+    protected ClientRequestTracker findClientRequestTracker(long logIndex) {
+        for (ClientRequestTracker tracker : trackerList) {
+            if (tracker.getIndex() == logIndex) {
+                return tracker;
+            }
+        }
+
+        return null;
+    }
+
+    @Override protected RaftState handleRequestVoteReply(ActorRef sender,
+        RequestVoteReply requestVoteReply) {
+        return state();
+    }
+
+    @Override public RaftState state() {
+        return RaftState.Leader;
+    }
+
+    @Override public RaftState handleMessage(ActorRef sender, Object originalMessage) {
+        Preconditions.checkNotNull(sender, "sender should not be null");
+
+        Object message = fromSerializableMessage(originalMessage);
+
+        if (message instanceof RaftRPC) {
+            RaftRPC rpc = (RaftRPC) message;
+            // If RPC request or response contains term T > currentTerm:
+            // set currentTerm = T, convert to follower (§5.1)
+            // This applies to all RPC messages and responses
+            if (rpc.getTerm() > context.getTermInformation().getCurrentTerm()) {
+                context.getTermInformation().updateAndPersist(rpc.getTerm(), null);
+                return RaftState.Follower;
+            }
+        }
+
+        try {
+            if (message instanceof SendHeartBeat) {
+                return sendHeartBeat();
+            } else if(message instanceof SendInstallSnapshot) {
+                installSnapshotIfNeeded();
+            } else if (message instanceof Replicate) {
+                replicate((Replicate) message);
+            } else if (message instanceof InstallSnapshotReply){
+                handleInstallSnapshotReply(
+                    (InstallSnapshotReply) message);
+            }
+        } finally {
+            scheduleHeartBeat(HEART_BEAT_INTERVAL);
+        }
+
+        return super.handleMessage(sender, message);
+    }
+
+    private void handleInstallSnapshotReply(InstallSnapshotReply message) {
+        InstallSnapshotReply reply = message;
+        String followerId = reply.getFollowerId();
+        FollowerLogInformation followerLogInformation =
+            followerToLog.get(followerId);
+
+        followerLogInformation
+            .setMatchIndex(context.getReplicatedLog().getSnapshotIndex());
+        followerLogInformation
+            .setNextIndex(context.getReplicatedLog().getSnapshotIndex() + 1);
+    }
+
+    private void replicate(Replicate replicate) {
+        long logIndex = replicate.getReplicatedLogEntry().getIndex();
+
+        context.getLogger().debug("Replicate message " + logIndex);
+
+        if (followers.size() == 0) {
+            context.setCommitIndex(
+                replicate.getReplicatedLogEntry().getIndex());
+
+            context.getActor()
+                .tell(new ApplyState(replicate.getClientActor(),
+                        replicate.getIdentifier(),
+                        replicate.getReplicatedLogEntry()),
+                    context.getActor()
+                );
+        } else {
+
+            // Create a tracker entry we will use this later to notify the
+            // client actor
+            trackerList.add(
+                new ClientRequestTrackerImpl(replicate.getClientActor(),
+                    replicate.getIdentifier(),
+                    logIndex)
+            );
+
+            sendAppendEntries();
+        }
+    }
+
+    private void sendAppendEntries() {
+        // Send an AppendEntries to all followers
+        for (String followerId : followers) {
+            ActorSelection followerActor =
+                context.getPeerActorSelection(followerId);
+
+            if (followerActor != null) {
+                FollowerLogInformation followerLogInformation =
+                    followerToLog.get(followerId);
+
+                long nextIndex = followerLogInformation.getNextIndex().get();
+
+                List<ReplicatedLogEntry> entries = Collections.emptyList();
+
+                if (context.getReplicatedLog().isPresent(nextIndex)) {
+                    // TODO: Instead of sending all entries from nextIndex
+                    // only send a fixed number of entries to each follower
+                    // This is to avoid the situation where there are a lot of
+                    // entries to install for a fresh follower or to a follower
+                    // that has fallen too far behind with the log but yet is not
+                    // eligible to receive a snapshot
+                    entries =
+                        context.getReplicatedLog().getFrom(nextIndex);
+                }
+
+                followerActor.tell(
+                    new AppendEntries(currentTerm(), context.getId(),
+                        prevLogIndex(nextIndex),
+                        prevLogTerm(nextIndex), entries,
+                        context.getCommitIndex()).toSerializable(),
+                    actor()
+                );
+            }
+        }
+    }
+
+    /**
+     * An installSnapshot is scheduled at a interval that is a multiple of
+     * a HEARTBEAT_INTERVAL. This is to avoid the need to check for installing
+     * snapshots at every heartbeat.
+     */
+    private void installSnapshotIfNeeded(){
+        for (String followerId : followers) {
+            ActorSelection followerActor =
+                context.getPeerActorSelection(followerId);
+
+            if(followerActor != null) {
+                FollowerLogInformation followerLogInformation =
+                    followerToLog.get(followerId);
+
+                long nextIndex = followerLogInformation.getNextIndex().get();
+
+                if (!context.getReplicatedLog().isPresent(nextIndex) && context
+                    .getReplicatedLog().isInSnapshot(nextIndex)) {
+                    followerActor.tell(
+                        new InstallSnapshot(currentTerm(), context.getId(),
+                            context.getReplicatedLog().getSnapshotIndex(),
+                            context.getReplicatedLog().getSnapshotTerm(),
+                            context.getReplicatedLog().getSnapshot()
+                        ),
+                        actor()
+                    );
+                }
+            }
+        }
+    }
+
+    private RaftState sendHeartBeat() {
+        if (followers.size() > 0) {
+            sendAppendEntries();
+        }
+        return state();
+    }
+
+    private void stopHeartBeat() {
+        if (heartbeatSchedule != null && !heartbeatSchedule.isCancelled()) {
+            heartbeatSchedule.cancel();
+        }
+    }
+
+    private void stopInstallSnapshotSchedule() {
+        if (installSnapshotSchedule != null && !installSnapshotSchedule.isCancelled()) {
+            installSnapshotSchedule.cancel();
+        }
+    }
+
+    private void scheduleHeartBeat(FiniteDuration interval) {
+        if(followers.size() == 0){
+            // Optimization - do not bother scheduling a heartbeat as there are
+            // no followers
+            return;
+        }
+
+        stopHeartBeat();
+
+        // Schedule a heartbeat. When the scheduler triggers a SendHeartbeat
+        // message is sent to itself.
+        // Scheduling the heartbeat only once here because heartbeats do not
+        // need to be sent if there are other messages being sent to the remote
+        // actor.
+        heartbeatSchedule =
+            context.getActorSystem().scheduler().scheduleOnce(
+                interval,
+                context.getActor(), new SendHeartBeat(),
+                context.getActorSystem().dispatcher(), context.getActor());
+    }
+
+
+    private void scheduleInstallSnapshotCheck(FiniteDuration interval) {
+        if(followers.size() == 0){
+            // Optimization - do not bother scheduling a heartbeat as there are
+            // no followers
+            return;
+        }
+
+        stopInstallSnapshotSchedule();
+
+        // Schedule a message to send append entries to followers that can
+        // accept an append entries with some data in it
+        installSnapshotSchedule =
+            context.getActorSystem().scheduler().scheduleOnce(
+                interval,
+                context.getActor(), new SendInstallSnapshot(),
+                context.getActorSystem().dispatcher(), context.getActor());
+    }
+
+
+
+    @Override public void close() throws Exception {
+        stopHeartBeat();
+    }
+
+    @Override public String getLeaderId() {
+        return context.getId();
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/RaftActorBehavior.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/RaftActorBehavior.java
new file mode 100644 (file)
index 0000000..ca2d916
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.behaviors;
+
+import akka.actor.ActorRef;
+import org.opendaylight.controller.cluster.raft.RaftState;
+
+/**
+ * A RaftActorBehavior represents the specific behavior of a RaftActor
+ * <p>
+ * A RaftActor can behave as one of the following,
+ * <ul>
+ *     <li> Follower </li>
+ *     <li> Candidate </li>
+ *     <li> Leader </li>
+ * </ul>
+ * <p>
+ * In each of these behaviors the Raft Actor handles the same Raft messages
+ * differently.
+ */
+public interface RaftActorBehavior extends AutoCloseable{
+    /**
+     * Handle a message. If the processing of the message warrants a state
+     * change then a new state should be returned otherwise this method should
+     * return the state for the current behavior.
+     *
+     * @param sender The sender of the message
+     * @param message A message that needs to be processed
+     *
+     * @return The new state or self (this)
+     */
+    RaftState handleMessage(ActorRef sender, Object message);
+
+    /**
+     * The state associated with a given behavior
+     *
+     * @return
+     */
+    RaftState state();
+
+    /**
+     *
+     * @return
+     */
+    String getLeaderId();
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/AddRaftPeer.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/AddRaftPeer.java
new file mode 100644 (file)
index 0000000..d1f4c43
--- /dev/null
@@ -0,0 +1,23 @@
+package org.opendaylight.controller.cluster.raft.client.messages;
+
+/**
+ * Created by kramesha on 7/17/14.
+ */
+public class AddRaftPeer {
+
+    private String name;
+    private String address;
+
+    public AddRaftPeer(String name, String address) {
+        this.name = name;
+        this.address = address;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+}
@@ -5,8 +5,9 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.controller.sal.binding.impl.connect.dom;
 
-public class CompositeNodeUtils {
+package org.opendaylight.controller.cluster.raft.client.messages;
+
+public class FindLeader {
 
 }
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/FindLeaderReply.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/FindLeaderReply.java
new file mode 100644 (file)
index 0000000..b36ef11
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.client.messages;
+
+public class FindLeaderReply {
+    private final String leaderActor;
+
+    public FindLeaderReply(String leaderActor) {
+        this.leaderActor = leaderActor;
+    }
+
+    public String getLeaderActor() {
+        return leaderActor;
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/RemoveRaftPeer.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/RemoveRaftPeer.java
new file mode 100644 (file)
index 0000000..4b766e0
--- /dev/null
@@ -0,0 +1,16 @@
+package org.opendaylight.controller.cluster.raft.client.messages;
+
+/**
+ * Created by kramesha on 7/17/14.
+ */
+public class RemoveRaftPeer {
+    private String name;
+
+    public RemoveRaftPeer(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AbstractRaftRPC.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AbstractRaftRPC.java
new file mode 100644 (file)
index 0000000..33d8a68
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.messages;
+
+public class AbstractRaftRPC implements RaftRPC {
+    // term
+    protected long term;
+
+    protected AbstractRaftRPC(long term){
+        this.term = term;
+    }
+
+    // added for testing while serialize-messages=on
+    public AbstractRaftRPC() {
+    }
+
+    public long getTerm() {
+        return term;
+    }
+
+    public void setTerm(long term) {
+        this.term = term;
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AppendEntries.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AppendEntries.java
new file mode 100644 (file)
index 0000000..94366ef
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.messages;
+
+import com.google.protobuf.GeneratedMessage;
+import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
+import org.opendaylight.controller.cluster.raft.ReplicatedLogImplEntry;
+import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
+import org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Invoked by leader to replicate log entries (§5.3); also used as
+ * heartbeat (§5.2).
+ */
+public class AppendEntries extends AbstractRaftRPC {
+
+    public static final Class SERIALIZABLE_CLASS = AppendEntriesMessages.AppendEntries.class;
+
+    private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(AppendEntries.class);
+
+    // So that follower can redirect clients
+    private final String leaderId;
+
+    // Index of log entry immediately preceding new ones
+    private final long prevLogIndex;
+
+    // term of prevLogIndex entry
+    private final long prevLogTerm;
+
+    // log entries to store (empty for heartbeat;
+    // may send more than one for efficiency)
+    private final List<ReplicatedLogEntry> entries;
+
+    // leader's commitIndex
+    private final long leaderCommit;
+
+    public AppendEntries(long term, String leaderId, long prevLogIndex,
+        long prevLogTerm, List<ReplicatedLogEntry> entries, long leaderCommit) {
+        super(term);
+        this.leaderId = leaderId;
+        this.prevLogIndex = prevLogIndex;
+        this.prevLogTerm = prevLogTerm;
+        this.entries = entries;
+        this.leaderCommit = leaderCommit;
+    }
+
+    public String getLeaderId() {
+        return leaderId;
+    }
+
+    public long getPrevLogIndex() {
+        return prevLogIndex;
+    }
+
+    public long getPrevLogTerm() {
+        return prevLogTerm;
+    }
+
+    public List<ReplicatedLogEntry> getEntries() {
+        return entries;
+    }
+
+    public long getLeaderCommit() {
+        return leaderCommit;
+    }
+
+    @Override public String toString() {
+        final StringBuilder sb =
+            new StringBuilder("AppendEntries{");
+        sb.append("term=").append(getTerm());
+        sb.append("leaderId='").append(leaderId).append('\'');
+        sb.append(", prevLogIndex=").append(prevLogIndex);
+        sb.append(", prevLogTerm=").append(prevLogTerm);
+        sb.append(", entries=").append(entries);
+        sb.append(", leaderCommit=").append(leaderCommit);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    public <T extends Object> Object toSerializable(){
+        AppendEntriesMessages.AppendEntries.Builder to = AppendEntriesMessages.AppendEntries.newBuilder();
+        to.setTerm(this.getTerm())
+            .setLeaderId(this.getLeaderId())
+            .setPrevLogTerm(this.getPrevLogTerm())
+            .setPrevLogIndex(this.getPrevLogIndex())
+            .setLeaderCommit(this.getLeaderCommit());
+
+        for (ReplicatedLogEntry logEntry : this.getEntries()) {
+
+            AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder arBuilder =
+                AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.newBuilder();
+
+            AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder arpBuilder =
+                AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.newBuilder();
+
+            //get the client specific payload extensions and add them to the payload builder
+            Map<GeneratedMessage.GeneratedExtension, T> map = logEntry.getData().encode();
+            Iterator<Map.Entry<GeneratedMessage.GeneratedExtension, T>> iter = map.entrySet().iterator();
+
+            while (iter.hasNext()) {
+                Map.Entry<GeneratedMessage.GeneratedExtension, T> entry = iter.next();
+                arpBuilder.setExtension(entry.getKey(), entry.getValue());
+            }
+
+            arpBuilder.setClientPayloadClassName(logEntry.getData().getClientPayloadClassName());
+
+            arBuilder.setData(arpBuilder).setIndex(logEntry.getIndex()).setTerm(logEntry.getTerm());
+            to.addLogEntries(arBuilder);
+        }
+
+        return to.build();
+    }
+
+    public static AppendEntries fromSerializable(Object o){
+        AppendEntriesMessages.AppendEntries from = (AppendEntriesMessages.AppendEntries) o;
+
+        List<ReplicatedLogEntry> logEntryList = new ArrayList<>();
+        for (AppendEntriesMessages.AppendEntries.ReplicatedLogEntry leProtoBuff : from.getLogEntriesList()) {
+
+            Payload payload = null ;
+            try {
+                if(leProtoBuff.getData() != null && leProtoBuff.getData().getClientPayloadClassName() != null) {
+                    String clientPayloadClassName = leProtoBuff.getData().getClientPayloadClassName();
+                    payload = (Payload)Class.forName(clientPayloadClassName).newInstance();
+                    payload = payload.decode(leProtoBuff.getData());
+                    payload.setClientPayloadClassName(clientPayloadClassName);
+                } else {
+                    LOG.error("Payload is null or payload does not have client payload class name");
+                }
+
+            } catch (InstantiationException e) {
+                LOG.error("InstantiationException when instantiating "+leProtoBuff.getData().getClientPayloadClassName(), e);
+            } catch (IllegalAccessException e) {
+                LOG.error("IllegalAccessException when accessing "+leProtoBuff.getData().getClientPayloadClassName(), e);
+            } catch (ClassNotFoundException e) {
+                LOG.error("ClassNotFoundException when loading "+leProtoBuff.getData().getClientPayloadClassName(), e);
+            }
+            ReplicatedLogEntry logEntry = new ReplicatedLogImplEntry(
+                leProtoBuff.getIndex(), leProtoBuff.getTerm(), payload);
+            logEntryList.add(logEntry);
+        }
+
+        AppendEntries to = new AppendEntries(from.getTerm(),
+            from.getLeaderId(),
+            from.getPrevLogIndex(),
+            from.getPrevLogTerm(),
+            logEntryList,
+            from.getLeaderCommit());
+
+        return to;
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AppendEntriesReply.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AppendEntriesReply.java
new file mode 100644 (file)
index 0000000..b923baa
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.messages;
+
+/**
+ * Reply for the AppendEntriesRpc message
+ */
+public class AppendEntriesReply extends AbstractRaftRPC {
+
+    // true if follower contained entry matching
+    // prevLogIndex and prevLogTerm
+    private final boolean success;
+
+    // The index of the last entry in the followers log
+    // This will be used to set the matchIndex for the follower on the
+    // Leader
+    private final long logLastIndex;
+
+    private final long logLastTerm;
+
+    // The followerId - this will be used to figure out which follower is
+    // responding
+    private final String followerId;
+
+    public AppendEntriesReply(String followerId, long term, boolean success, long logLastIndex, long logLastTerm) {
+        super(term);
+
+        this.followerId = followerId;
+        this.success = success;
+        this.logLastIndex = logLastIndex;
+        this.logLastTerm = logLastTerm;
+    }
+
+    public long getTerm() {
+        return term;
+    }
+
+    public boolean isSuccess() {
+        return success;
+    }
+
+    public long getLogLastIndex() {
+        return logLastIndex;
+    }
+
+    public long getLogLastTerm() {
+        return logLastTerm;
+    }
+
+    public String getFollowerId() {
+        return followerId;
+    }
+
+    @Override public String toString() {
+        final StringBuilder sb =
+            new StringBuilder("AppendEntriesReply{");
+        sb.append("term=").append(term);
+        sb.append(", success=").append(success);
+        sb.append(", logLastIndex=").append(logLastIndex);
+        sb.append(", logLastTerm=").append(logLastTerm);
+        sb.append(", followerId='").append(followerId).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/InstallSnapshot.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/InstallSnapshot.java
new file mode 100644 (file)
index 0000000..888854f
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.messages;
+
+public class InstallSnapshot extends AbstractRaftRPC {
+
+    private final String leaderId;
+    private final long lastIncludedIndex;
+    private final long lastIncludedTerm;
+    private final Object data;
+
+    public InstallSnapshot(long term, String leaderId, long lastIncludedIndex, long lastIncludedTerm, Object data) {
+        super(term);
+        this.leaderId = leaderId;
+        this.lastIncludedIndex = lastIncludedIndex;
+        this.lastIncludedTerm = lastIncludedTerm;
+        this.data = data;
+    }
+
+    public String getLeaderId() {
+        return leaderId;
+    }
+
+    public long getLastIncludedIndex() {
+        return lastIncludedIndex;
+    }
+
+    public long getLastIncludedTerm() {
+        return lastIncludedTerm;
+    }
+
+    public Object getData() {
+        return data;
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/InstallSnapshotReply.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/InstallSnapshotReply.java
new file mode 100644 (file)
index 0000000..85b89b7
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.messages;
+
+public class InstallSnapshotReply extends AbstractRaftRPC {
+
+    // The followerId - this will be used to figure out which follower is
+    // responding
+    private final String followerId;
+
+    protected InstallSnapshotReply(long term, String followerId) {
+        super(term);
+        this.followerId = followerId;
+    }
+
+    public String getFollowerId() {
+        return followerId;
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/RaftRPC.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/RaftRPC.java
new file mode 100644 (file)
index 0000000..10d9998
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.messages;
+
+import java.io.Serializable;
+
+public interface RaftRPC extends Serializable {
+    public long getTerm();
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/RequestVote.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/RequestVote.java
new file mode 100644 (file)
index 0000000..6ef2a06
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.messages;
+
+/**
+ * Invoked by candidates to gather votes (§5.2).
+ */
+public class RequestVote extends AbstractRaftRPC {
+
+    // candidate requesting vote
+    private String candidateId;
+
+    // index of candidate’s last log entry (§5.4)
+    private long lastLogIndex;
+
+    // term of candidate’s last log entry (§5.4)
+    private long lastLogTerm;
+
+    public RequestVote(long term, String candidateId, long lastLogIndex,
+        long lastLogTerm) {
+        super(term);
+        this.candidateId = candidateId;
+        this.lastLogIndex = lastLogIndex;
+        this.lastLogTerm = lastLogTerm;
+    }
+
+    // added for testing while serialize-messages=on
+    public RequestVote() {
+    }
+
+    public long getTerm() {
+        return term;
+    }
+
+    public String getCandidateId() {
+        return candidateId;
+    }
+
+    public long getLastLogIndex() {
+        return lastLogIndex;
+    }
+
+    public long getLastLogTerm() {
+        return lastLogTerm;
+    }
+
+    public void setCandidateId(String candidateId) {
+        this.candidateId = candidateId;
+    }
+
+    public void setLastLogIndex(long lastLogIndex) {
+        this.lastLogIndex = lastLogIndex;
+    }
+
+    public void setLastLogTerm(long lastLogTerm) {
+        this.lastLogTerm = lastLogTerm;
+    }
+
+    @Override public String toString() {
+        final StringBuilder sb =
+            new StringBuilder("RequestVote{");
+        sb.append("term='").append(getTerm()).append('\'');
+        sb.append("candidateId='").append(candidateId).append('\'');
+        sb.append(", lastLogIndex=").append(lastLogIndex);
+        sb.append(", lastLogTerm=").append(lastLogTerm);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/RequestVoteReply.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/RequestVoteReply.java
new file mode 100644 (file)
index 0000000..df80b4e
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.messages;
+
+public class RequestVoteReply extends AbstractRaftRPC {
+
+    // true means candidate received vot
+    private final boolean voteGranted;
+
+    public RequestVoteReply(long term, boolean voteGranted) {
+        super(term);
+        this.voteGranted = voteGranted;
+    }
+
+    public long getTerm() {
+        return term;
+    }
+
+    public boolean isVoteGranted() {
+        return voteGranted;
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/protobuff/client/messages/Payload.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/protobuff/client/messages/Payload.java
new file mode 100644 (file)
index 0000000..9a251cd
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.protobuff.client.messages;
+
+
+import com.google.protobuf.GeneratedMessage;
+import org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages;
+
+import java.util.Map;
+
+/**
+ * An instance of a Payload class is meant to be used as the Payload for
+ * AppendEntries.
+ * <p>
+ *
+ * When an actor which is derived from RaftActor attempts to persistData it
+ * must pass an instance of the Payload class. Similarly when state needs to
+ * be applied to the derived RaftActor it will be passed an instance of the
+ * Payload class.
+ * <p>
+ *
+ * To define your own payload do the following,
+ * <ol>
+ *     <li>Create your own protocol buffer message which extends the AppendEntries Payload</li>
+ *     <li>Extend this Payload class</li>
+ *     <li>Implement encode</li>
+ *     <li>Implement decode</li>
+ * </ol>
+ *
+ * Your own protocol buffer message can be create like so, <br/>
+ * <pre>
+ * {@code
+ *
+ * import "AppendEntriesMessages.proto";
+ *
+ * package org.opendaylight.controller.cluster.raft;
+ *
+ * option java_package = "org.opendaylight.controller.cluster.raft.protobuff.messages";
+ * option java_outer_classname = "MockPayloadMessages";
+ *
+ * extend AppendEntries.ReplicatedLogEntry.Payload {
+ *      optional string value = 2;
+ * }
+ * }
+ * </pre>
+ *
+ */
+public abstract class Payload {
+    private String clientPayloadClassName;
+
+    public String getClientPayloadClassName() {
+        return this.getClass().getName();
+    }
+
+    public void setClientPayloadClassName(String clientPayloadClassName) {
+        this.clientPayloadClassName = clientPayloadClassName;
+    }
+
+    /**
+     * Encode the payload data as a protocol buffer extension.
+     * <p>
+     * TODO: Add more meat in here
+     * @param <T>
+     * @return Map of <GeneratedMessage.GeneratedExtension, T>
+     */
+    public abstract <T extends Object> Map<GeneratedMessage.GeneratedExtension, T> encode();
+
+    /**
+     * Decode the protocol buffer payload into a specific Payload as defined
+     * by the class extending RaftActor
+     *
+     * @param payload The payload in protocol buffer format
+     * @return
+     */
+    public abstract Payload decode(
+        AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload payload);
+
+
+
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/protobuff/messages/AppendEntriesMessages.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/protobuff/messages/AppendEntriesMessages.java
new file mode 100644 (file)
index 0000000..00aeaf2
--- /dev/null
@@ -0,0 +1,2420 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: AppendEntriesMessages.proto
+
+package org.opendaylight.controller.cluster.raft.protobuff.messages;
+
+public final class AppendEntriesMessages {
+  private AppendEntriesMessages() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface AppendEntriesOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // optional int64 term = 1;
+    /**
+     * <code>optional int64 term = 1;</code>
+     */
+    boolean hasTerm();
+    /**
+     * <code>optional int64 term = 1;</code>
+     */
+    long getTerm();
+
+    // optional string leaderId = 2;
+    /**
+     * <code>optional string leaderId = 2;</code>
+     */
+    boolean hasLeaderId();
+    /**
+     * <code>optional string leaderId = 2;</code>
+     */
+    java.lang.String getLeaderId();
+    /**
+     * <code>optional string leaderId = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getLeaderIdBytes();
+
+    // optional int64 prevLogIndex = 3;
+    /**
+     * <code>optional int64 prevLogIndex = 3;</code>
+     */
+    boolean hasPrevLogIndex();
+    /**
+     * <code>optional int64 prevLogIndex = 3;</code>
+     */
+    long getPrevLogIndex();
+
+    // optional int64 prevLogTerm = 4;
+    /**
+     * <code>optional int64 prevLogTerm = 4;</code>
+     */
+    boolean hasPrevLogTerm();
+    /**
+     * <code>optional int64 prevLogTerm = 4;</code>
+     */
+    long getPrevLogTerm();
+
+    // repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;
+    /**
+     * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+     */
+    java.util.List<org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry> 
+        getLogEntriesList();
+    /**
+     * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+     */
+    org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry getLogEntries(int index);
+    /**
+     * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+     */
+    int getLogEntriesCount();
+    /**
+     * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+     */
+    java.util.List<? extends org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder> 
+        getLogEntriesOrBuilderList();
+    /**
+     * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+     */
+    org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder getLogEntriesOrBuilder(
+        int index);
+
+    // optional int64 leaderCommit = 6;
+    /**
+     * <code>optional int64 leaderCommit = 6;</code>
+     */
+    boolean hasLeaderCommit();
+    /**
+     * <code>optional int64 leaderCommit = 6;</code>
+     */
+    long getLeaderCommit();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.cluster.raft.AppendEntries}
+   */
+  public static final class AppendEntries extends
+      com.google.protobuf.GeneratedMessage
+      implements AppendEntriesOrBuilder {
+    // Use AppendEntries.newBuilder() to construct.
+    private AppendEntries(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private AppendEntries(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final AppendEntries defaultInstance;
+    public static AppendEntries getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public AppendEntries getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private AppendEntries(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              bitField0_ |= 0x00000001;
+              term_ = input.readInt64();
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              leaderId_ = input.readBytes();
+              break;
+            }
+            case 24: {
+              bitField0_ |= 0x00000004;
+              prevLogIndex_ = input.readInt64();
+              break;
+            }
+            case 32: {
+              bitField0_ |= 0x00000008;
+              prevLogTerm_ = input.readInt64();
+              break;
+            }
+            case 42: {
+              if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
+                logEntries_ = new java.util.ArrayList<org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry>();
+                mutable_bitField0_ |= 0x00000010;
+              }
+              logEntries_.add(input.readMessage(org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PARSER, extensionRegistry));
+              break;
+            }
+            case 48: {
+              bitField0_ |= 0x00000010;
+              leaderCommit_ = input.readInt64();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
+          logEntries_ = java.util.Collections.unmodifiableList(logEntries_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.class, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<AppendEntries> PARSER =
+        new com.google.protobuf.AbstractParser<AppendEntries>() {
+      public AppendEntries parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new AppendEntries(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<AppendEntries> getParserForType() {
+      return PARSER;
+    }
+
+    public interface ReplicatedLogEntryOrBuilder
+        extends com.google.protobuf.MessageOrBuilder {
+
+      // optional int64 term = 1;
+      /**
+       * <code>optional int64 term = 1;</code>
+       */
+      boolean hasTerm();
+      /**
+       * <code>optional int64 term = 1;</code>
+       */
+      long getTerm();
+
+      // optional int64 index = 2;
+      /**
+       * <code>optional int64 index = 2;</code>
+       */
+      boolean hasIndex();
+      /**
+       * <code>optional int64 index = 2;</code>
+       */
+      long getIndex();
+
+      // optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;
+      /**
+       * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+       */
+      boolean hasData();
+      /**
+       * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+       */
+      org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload getData();
+      /**
+       * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+       */
+      org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PayloadOrBuilder getDataOrBuilder();
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry}
+     */
+    public static final class ReplicatedLogEntry extends
+        com.google.protobuf.GeneratedMessage
+        implements ReplicatedLogEntryOrBuilder {
+      // Use ReplicatedLogEntry.newBuilder() to construct.
+      private ReplicatedLogEntry(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+        super(builder);
+        this.unknownFields = builder.getUnknownFields();
+      }
+      private ReplicatedLogEntry(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+      private static final ReplicatedLogEntry defaultInstance;
+      public static ReplicatedLogEntry getDefaultInstance() {
+        return defaultInstance;
+      }
+
+      public ReplicatedLogEntry getDefaultInstanceForType() {
+        return defaultInstance;
+      }
+
+      private final com.google.protobuf.UnknownFieldSet unknownFields;
+      @java.lang.Override
+      public final com.google.protobuf.UnknownFieldSet
+          getUnknownFields() {
+        return this.unknownFields;
+      }
+      private ReplicatedLogEntry(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        initFields();
+        int mutable_bitField0_ = 0;
+        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+            com.google.protobuf.UnknownFieldSet.newBuilder();
+        try {
+          boolean done = false;
+          while (!done) {
+            int tag = input.readTag();
+            switch (tag) {
+              case 0:
+                done = true;
+                break;
+              default: {
+                if (!parseUnknownField(input, unknownFields,
+                                       extensionRegistry, tag)) {
+                  done = true;
+                }
+                break;
+              }
+              case 8: {
+                bitField0_ |= 0x00000001;
+                term_ = input.readInt64();
+                break;
+              }
+              case 16: {
+                bitField0_ |= 0x00000002;
+                index_ = input.readInt64();
+                break;
+              }
+              case 26: {
+                org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder subBuilder = null;
+                if (((bitField0_ & 0x00000004) == 0x00000004)) {
+                  subBuilder = data_.toBuilder();
+                }
+                data_ = input.readMessage(org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.PARSER, extensionRegistry);
+                if (subBuilder != null) {
+                  subBuilder.mergeFrom(data_);
+                  data_ = subBuilder.buildPartial();
+                }
+                bitField0_ |= 0x00000004;
+                break;
+              }
+            }
+          }
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          throw e.setUnfinishedMessage(this);
+        } catch (java.io.IOException e) {
+          throw new com.google.protobuf.InvalidProtocolBufferException(
+              e.getMessage()).setUnfinishedMessage(this);
+        } finally {
+          this.unknownFields = unknownFields.build();
+          makeExtensionsImmutable();
+        }
+      }
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.class, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder.class);
+      }
+
+      public static com.google.protobuf.Parser<ReplicatedLogEntry> PARSER =
+          new com.google.protobuf.AbstractParser<ReplicatedLogEntry>() {
+        public ReplicatedLogEntry parsePartialFrom(
+            com.google.protobuf.CodedInputStream input,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws com.google.protobuf.InvalidProtocolBufferException {
+          return new ReplicatedLogEntry(input, extensionRegistry);
+        }
+      };
+
+      @java.lang.Override
+      public com.google.protobuf.Parser<ReplicatedLogEntry> getParserForType() {
+        return PARSER;
+      }
+
+      public interface PayloadOrBuilder extends
+          com.google.protobuf.GeneratedMessage.
+              ExtendableMessageOrBuilder<Payload> {
+
+        // optional string clientPayloadClassName = 1;
+        /**
+         * <code>optional string clientPayloadClassName = 1;</code>
+         */
+        boolean hasClientPayloadClassName();
+        /**
+         * <code>optional string clientPayloadClassName = 1;</code>
+         */
+        java.lang.String getClientPayloadClassName();
+        /**
+         * <code>optional string clientPayloadClassName = 1;</code>
+         */
+        com.google.protobuf.ByteString
+            getClientPayloadClassNameBytes();
+      }
+      /**
+       * Protobuf type {@code org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload}
+       */
+      public static final class Payload extends
+          com.google.protobuf.GeneratedMessage.ExtendableMessage<
+            Payload> implements PayloadOrBuilder {
+        // Use Payload.newBuilder() to construct.
+        private Payload(com.google.protobuf.GeneratedMessage.ExtendableBuilder<org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload, ?> builder) {
+          super(builder);
+          this.unknownFields = builder.getUnknownFields();
+        }
+        private Payload(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+        private static final Payload defaultInstance;
+        public static Payload getDefaultInstance() {
+          return defaultInstance;
+        }
+
+        public Payload getDefaultInstanceForType() {
+          return defaultInstance;
+        }
+
+        private final com.google.protobuf.UnknownFieldSet unknownFields;
+        @java.lang.Override
+        public final com.google.protobuf.UnknownFieldSet
+            getUnknownFields() {
+          return this.unknownFields;
+        }
+        private Payload(
+            com.google.protobuf.CodedInputStream input,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws com.google.protobuf.InvalidProtocolBufferException {
+          initFields();
+          int mutable_bitField0_ = 0;
+          com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+              com.google.protobuf.UnknownFieldSet.newBuilder();
+          try {
+            boolean done = false;
+            while (!done) {
+              int tag = input.readTag();
+              switch (tag) {
+                case 0:
+                  done = true;
+                  break;
+                default: {
+                  if (!parseUnknownField(input, unknownFields,
+                                         extensionRegistry, tag)) {
+                    done = true;
+                  }
+                  break;
+                }
+                case 10: {
+                  bitField0_ |= 0x00000001;
+                  clientPayloadClassName_ = input.readBytes();
+                  break;
+                }
+              }
+            }
+          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+            throw e.setUnfinishedMessage(this);
+          } catch (java.io.IOException e) {
+            throw new com.google.protobuf.InvalidProtocolBufferException(
+                e.getMessage()).setUnfinishedMessage(this);
+          } finally {
+            this.unknownFields = unknownFields.build();
+            makeExtensionsImmutable();
+          }
+        }
+        public static final com.google.protobuf.Descriptors.Descriptor
+            getDescriptor() {
+          return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_Payload_descriptor;
+        }
+
+        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+            internalGetFieldAccessorTable() {
+          return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_Payload_fieldAccessorTable
+              .ensureFieldAccessorsInitialized(
+                  org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.class, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder.class);
+        }
+
+        public static com.google.protobuf.Parser<Payload> PARSER =
+            new com.google.protobuf.AbstractParser<Payload>() {
+          public Payload parsePartialFrom(
+              com.google.protobuf.CodedInputStream input,
+              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+              throws com.google.protobuf.InvalidProtocolBufferException {
+            return new Payload(input, extensionRegistry);
+          }
+        };
+
+        @java.lang.Override
+        public com.google.protobuf.Parser<Payload> getParserForType() {
+          return PARSER;
+        }
+
+        private int bitField0_;
+        // optional string clientPayloadClassName = 1;
+        public static final int CLIENTPAYLOADCLASSNAME_FIELD_NUMBER = 1;
+        private java.lang.Object clientPayloadClassName_;
+        /**
+         * <code>optional string clientPayloadClassName = 1;</code>
+         */
+        public boolean hasClientPayloadClassName() {
+          return ((bitField0_ & 0x00000001) == 0x00000001);
+        }
+        /**
+         * <code>optional string clientPayloadClassName = 1;</code>
+         */
+        public java.lang.String getClientPayloadClassName() {
+          java.lang.Object ref = clientPayloadClassName_;
+          if (ref instanceof java.lang.String) {
+            return (java.lang.String) ref;
+          } else {
+            com.google.protobuf.ByteString bs = 
+                (com.google.protobuf.ByteString) ref;
+            java.lang.String s = bs.toStringUtf8();
+            if (bs.isValidUtf8()) {
+              clientPayloadClassName_ = s;
+            }
+            return s;
+          }
+        }
+        /**
+         * <code>optional string clientPayloadClassName = 1;</code>
+         */
+        public com.google.protobuf.ByteString
+            getClientPayloadClassNameBytes() {
+          java.lang.Object ref = clientPayloadClassName_;
+          if (ref instanceof java.lang.String) {
+            com.google.protobuf.ByteString b = 
+                com.google.protobuf.ByteString.copyFromUtf8(
+                    (java.lang.String) ref);
+            clientPayloadClassName_ = b;
+            return b;
+          } else {
+            return (com.google.protobuf.ByteString) ref;
+          }
+        }
+
+        private void initFields() {
+          clientPayloadClassName_ = "";
+        }
+        private byte memoizedIsInitialized = -1;
+        public final boolean isInitialized() {
+          byte isInitialized = memoizedIsInitialized;
+          if (isInitialized != -1) return isInitialized == 1;
+
+          if (!extensionsAreInitialized()) {
+            memoizedIsInitialized = 0;
+            return false;
+          }
+          memoizedIsInitialized = 1;
+          return true;
+        }
+
+        public void writeTo(com.google.protobuf.CodedOutputStream output)
+                            throws java.io.IOException {
+          getSerializedSize();
+          com.google.protobuf.GeneratedMessage
+            .ExtendableMessage<org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload>.ExtensionWriter extensionWriter =
+              newExtensionWriter();
+          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+            output.writeBytes(1, getClientPayloadClassNameBytes());
+          }
+          extensionWriter.writeUntil(101, output);
+          getUnknownFields().writeTo(output);
+        }
+
+        private int memoizedSerializedSize = -1;
+        public int getSerializedSize() {
+          int size = memoizedSerializedSize;
+          if (size != -1) return size;
+
+          size = 0;
+          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+            size += com.google.protobuf.CodedOutputStream
+              .computeBytesSize(1, getClientPayloadClassNameBytes());
+          }
+          size += extensionsSerializedSize();
+          size += getUnknownFields().getSerializedSize();
+          memoizedSerializedSize = size;
+          return size;
+        }
+
+        private static final long serialVersionUID = 0L;
+        @java.lang.Override
+        protected java.lang.Object writeReplace()
+            throws java.io.ObjectStreamException {
+          return super.writeReplace();
+        }
+
+        public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload parseFrom(
+            com.google.protobuf.ByteString data)
+            throws com.google.protobuf.InvalidProtocolBufferException {
+          return PARSER.parseFrom(data);
+        }
+        public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload parseFrom(
+            com.google.protobuf.ByteString data,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws com.google.protobuf.InvalidProtocolBufferException {
+          return PARSER.parseFrom(data, extensionRegistry);
+        }
+        public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload parseFrom(byte[] data)
+            throws com.google.protobuf.InvalidProtocolBufferException {
+          return PARSER.parseFrom(data);
+        }
+        public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload parseFrom(
+            byte[] data,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws com.google.protobuf.InvalidProtocolBufferException {
+          return PARSER.parseFrom(data, extensionRegistry);
+        }
+        public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload parseFrom(java.io.InputStream input)
+            throws java.io.IOException {
+          return PARSER.parseFrom(input);
+        }
+        public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload parseFrom(
+            java.io.InputStream input,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws java.io.IOException {
+          return PARSER.parseFrom(input, extensionRegistry);
+        }
+        public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload parseDelimitedFrom(java.io.InputStream input)
+            throws java.io.IOException {
+          return PARSER.parseDelimitedFrom(input);
+        }
+        public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload parseDelimitedFrom(
+            java.io.InputStream input,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws java.io.IOException {
+          return PARSER.parseDelimitedFrom(input, extensionRegistry);
+        }
+        public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload parseFrom(
+            com.google.protobuf.CodedInputStream input)
+            throws java.io.IOException {
+          return PARSER.parseFrom(input);
+        }
+        public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload parseFrom(
+            com.google.protobuf.CodedInputStream input,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws java.io.IOException {
+          return PARSER.parseFrom(input, extensionRegistry);
+        }
+
+        public static Builder newBuilder() { return Builder.create(); }
+        public Builder newBuilderForType() { return newBuilder(); }
+        public static Builder newBuilder(org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload prototype) {
+          return newBuilder().mergeFrom(prototype);
+        }
+        public Builder toBuilder() { return newBuilder(this); }
+
+        @java.lang.Override
+        protected Builder newBuilderForType(
+            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          Builder builder = new Builder(parent);
+          return builder;
+        }
+        /**
+         * Protobuf type {@code org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload}
+         */
+        public static final class Builder extends
+            com.google.protobuf.GeneratedMessage.ExtendableBuilder<
+              org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload, Builder> implements org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PayloadOrBuilder {
+          public static final com.google.protobuf.Descriptors.Descriptor
+              getDescriptor() {
+            return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_Payload_descriptor;
+          }
+
+          protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+              internalGetFieldAccessorTable() {
+            return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_Payload_fieldAccessorTable
+                .ensureFieldAccessorsInitialized(
+                    org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.class, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder.class);
+          }
+
+          // Construct using org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.newBuilder()
+          private Builder() {
+            maybeForceBuilderInitialization();
+          }
+
+          private Builder(
+              com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+            super(parent);
+            maybeForceBuilderInitialization();
+          }
+          private void maybeForceBuilderInitialization() {
+            if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+            }
+          }
+          private static Builder create() {
+            return new Builder();
+          }
+
+          public Builder clear() {
+            super.clear();
+            clientPayloadClassName_ = "";
+            bitField0_ = (bitField0_ & ~0x00000001);
+            return this;
+          }
+
+          public Builder clone() {
+            return create().mergeFrom(buildPartial());
+          }
+
+          public com.google.protobuf.Descriptors.Descriptor
+              getDescriptorForType() {
+            return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_Payload_descriptor;
+          }
+
+          public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload getDefaultInstanceForType() {
+            return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.getDefaultInstance();
+          }
+
+          public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload build() {
+            org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload result = buildPartial();
+            if (!result.isInitialized()) {
+              throw newUninitializedMessageException(result);
+            }
+            return result;
+          }
+
+          public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload buildPartial() {
+            org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload result = new org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload(this);
+            int from_bitField0_ = bitField0_;
+            int to_bitField0_ = 0;
+            if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+              to_bitField0_ |= 0x00000001;
+            }
+            result.clientPayloadClassName_ = clientPayloadClassName_;
+            result.bitField0_ = to_bitField0_;
+            onBuilt();
+            return result;
+          }
+
+          public Builder mergeFrom(com.google.protobuf.Message other) {
+            if (other instanceof org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload) {
+              return mergeFrom((org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload)other);
+            } else {
+              super.mergeFrom(other);
+              return this;
+            }
+          }
+
+          public Builder mergeFrom(org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload other) {
+            if (other == org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.getDefaultInstance()) return this;
+            if (other.hasClientPayloadClassName()) {
+              bitField0_ |= 0x00000001;
+              clientPayloadClassName_ = other.clientPayloadClassName_;
+              onChanged();
+            }
+            this.mergeExtensionFields(other);
+            this.mergeUnknownFields(other.getUnknownFields());
+            return this;
+          }
+
+          public final boolean isInitialized() {
+            if (!extensionsAreInitialized()) {
+              
+              return false;
+            }
+            return true;
+          }
+
+          public Builder mergeFrom(
+              com.google.protobuf.CodedInputStream input,
+              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+              throws java.io.IOException {
+            org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload parsedMessage = null;
+            try {
+              parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+            } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+              parsedMessage = (org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload) e.getUnfinishedMessage();
+              throw e;
+            } finally {
+              if (parsedMessage != null) {
+                mergeFrom(parsedMessage);
+              }
+            }
+            return this;
+          }
+          private int bitField0_;
+
+          // optional string clientPayloadClassName = 1;
+          private java.lang.Object clientPayloadClassName_ = "";
+          /**
+           * <code>optional string clientPayloadClassName = 1;</code>
+           */
+          public boolean hasClientPayloadClassName() {
+            return ((bitField0_ & 0x00000001) == 0x00000001);
+          }
+          /**
+           * <code>optional string clientPayloadClassName = 1;</code>
+           */
+          public java.lang.String getClientPayloadClassName() {
+            java.lang.Object ref = clientPayloadClassName_;
+            if (!(ref instanceof java.lang.String)) {
+              java.lang.String s = ((com.google.protobuf.ByteString) ref)
+                  .toStringUtf8();
+              clientPayloadClassName_ = s;
+              return s;
+            } else {
+              return (java.lang.String) ref;
+            }
+          }
+          /**
+           * <code>optional string clientPayloadClassName = 1;</code>
+           */
+          public com.google.protobuf.ByteString
+              getClientPayloadClassNameBytes() {
+            java.lang.Object ref = clientPayloadClassName_;
+            if (ref instanceof String) {
+              com.google.protobuf.ByteString b = 
+                  com.google.protobuf.ByteString.copyFromUtf8(
+                      (java.lang.String) ref);
+              clientPayloadClassName_ = b;
+              return b;
+            } else {
+              return (com.google.protobuf.ByteString) ref;
+            }
+          }
+          /**
+           * <code>optional string clientPayloadClassName = 1;</code>
+           */
+          public Builder setClientPayloadClassName(
+              java.lang.String value) {
+            if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+            clientPayloadClassName_ = value;
+            onChanged();
+            return this;
+          }
+          /**
+           * <code>optional string clientPayloadClassName = 1;</code>
+           */
+          public Builder clearClientPayloadClassName() {
+            bitField0_ = (bitField0_ & ~0x00000001);
+            clientPayloadClassName_ = getDefaultInstance().getClientPayloadClassName();
+            onChanged();
+            return this;
+          }
+          /**
+           * <code>optional string clientPayloadClassName = 1;</code>
+           */
+          public Builder setClientPayloadClassNameBytes(
+              com.google.protobuf.ByteString value) {
+            if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+            clientPayloadClassName_ = value;
+            onChanged();
+            return this;
+          }
+
+          // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload)
+        }
+
+        static {
+          defaultInstance = new Payload(true);
+          defaultInstance.initFields();
+        }
+
+        // @@protoc_insertion_point(class_scope:org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload)
+      }
+
+      private int bitField0_;
+      // optional int64 term = 1;
+      public static final int TERM_FIELD_NUMBER = 1;
+      private long term_;
+      /**
+       * <code>optional int64 term = 1;</code>
+       */
+      public boolean hasTerm() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional int64 term = 1;</code>
+       */
+      public long getTerm() {
+        return term_;
+      }
+
+      // optional int64 index = 2;
+      public static final int INDEX_FIELD_NUMBER = 2;
+      private long index_;
+      /**
+       * <code>optional int64 index = 2;</code>
+       */
+      public boolean hasIndex() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional int64 index = 2;</code>
+       */
+      public long getIndex() {
+        return index_;
+      }
+
+      // optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;
+      public static final int DATA_FIELD_NUMBER = 3;
+      private org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload data_;
+      /**
+       * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+       */
+      public boolean hasData() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+       */
+      public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload getData() {
+        return data_;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+       */
+      public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PayloadOrBuilder getDataOrBuilder() {
+        return data_;
+      }
+
+      private void initFields() {
+        term_ = 0L;
+        index_ = 0L;
+        data_ = org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.getDefaultInstance();
+      }
+      private byte memoizedIsInitialized = -1;
+      public final boolean isInitialized() {
+        byte isInitialized = memoizedIsInitialized;
+        if (isInitialized != -1) return isInitialized == 1;
+
+        if (hasData()) {
+          if (!getData().isInitialized()) {
+            memoizedIsInitialized = 0;
+            return false;
+          }
+        }
+        memoizedIsInitialized = 1;
+        return true;
+      }
+
+      public void writeTo(com.google.protobuf.CodedOutputStream output)
+                          throws java.io.IOException {
+        getSerializedSize();
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          output.writeInt64(1, term_);
+        }
+        if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          output.writeInt64(2, index_);
+        }
+        if (((bitField0_ & 0x00000004) == 0x00000004)) {
+          output.writeMessage(3, data_);
+        }
+        getUnknownFields().writeTo(output);
+      }
+
+      private int memoizedSerializedSize = -1;
+      public int getSerializedSize() {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+
+        size = 0;
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          size += com.google.protobuf.CodedOutputStream
+            .computeInt64Size(1, term_);
+        }
+        if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          size += com.google.protobuf.CodedOutputStream
+            .computeInt64Size(2, index_);
+        }
+        if (((bitField0_ & 0x00000004) == 0x00000004)) {
+          size += com.google.protobuf.CodedOutputStream
+            .computeMessageSize(3, data_);
+        }
+        size += getUnknownFields().getSerializedSize();
+        memoizedSerializedSize = size;
+        return size;
+      }
+
+      private static final long serialVersionUID = 0L;
+      @java.lang.Override
+      protected java.lang.Object writeReplace()
+          throws java.io.ObjectStreamException {
+        return super.writeReplace();
+      }
+
+      public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry parseFrom(
+          com.google.protobuf.ByteString data)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data);
+      }
+      public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry parseFrom(
+          com.google.protobuf.ByteString data,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data, extensionRegistry);
+      }
+      public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry parseFrom(byte[] data)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data);
+      }
+      public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry parseFrom(
+          byte[] data,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data, extensionRegistry);
+      }
+      public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry parseFrom(java.io.InputStream input)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input);
+      }
+      public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry parseFrom(
+          java.io.InputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input, extensionRegistry);
+      }
+      public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry parseDelimitedFrom(java.io.InputStream input)
+          throws java.io.IOException {
+        return PARSER.parseDelimitedFrom(input);
+      }
+      public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry parseDelimitedFrom(
+          java.io.InputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      }
+      public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry parseFrom(
+          com.google.protobuf.CodedInputStream input)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input);
+      }
+      public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry parseFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input, extensionRegistry);
+      }
+
+      public static Builder newBuilder() { return Builder.create(); }
+      public Builder newBuilderForType() { return newBuilder(); }
+      public static Builder newBuilder(org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry prototype) {
+        return newBuilder().mergeFrom(prototype);
+      }
+      public Builder toBuilder() { return newBuilder(this); }
+
+      @java.lang.Override
+      protected Builder newBuilderForType(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        Builder builder = new Builder(parent);
+        return builder;
+      }
+      /**
+       * Protobuf type {@code org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry}
+       */
+      public static final class Builder extends
+          com.google.protobuf.GeneratedMessage.Builder<Builder>
+         implements org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder {
+        public static final com.google.protobuf.Descriptors.Descriptor
+            getDescriptor() {
+          return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_descriptor;
+        }
+
+        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+            internalGetFieldAccessorTable() {
+          return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_fieldAccessorTable
+              .ensureFieldAccessorsInitialized(
+                  org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.class, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder.class);
+        }
+
+        // Construct using org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.newBuilder()
+        private Builder() {
+          maybeForceBuilderInitialization();
+        }
+
+        private Builder(
+            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          super(parent);
+          maybeForceBuilderInitialization();
+        }
+        private void maybeForceBuilderInitialization() {
+          if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+            getDataFieldBuilder();
+          }
+        }
+        private static Builder create() {
+          return new Builder();
+        }
+
+        public Builder clear() {
+          super.clear();
+          term_ = 0L;
+          bitField0_ = (bitField0_ & ~0x00000001);
+          index_ = 0L;
+          bitField0_ = (bitField0_ & ~0x00000002);
+          if (dataBuilder_ == null) {
+            data_ = org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.getDefaultInstance();
+          } else {
+            dataBuilder_.clear();
+          }
+          bitField0_ = (bitField0_ & ~0x00000004);
+          return this;
+        }
+
+        public Builder clone() {
+          return create().mergeFrom(buildPartial());
+        }
+
+        public com.google.protobuf.Descriptors.Descriptor
+            getDescriptorForType() {
+          return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_descriptor;
+        }
+
+        public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry getDefaultInstanceForType() {
+          return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.getDefaultInstance();
+        }
+
+        public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry build() {
+          org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry result = buildPartial();
+          if (!result.isInitialized()) {
+            throw newUninitializedMessageException(result);
+          }
+          return result;
+        }
+
+        public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry buildPartial() {
+          org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry result = new org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry(this);
+          int from_bitField0_ = bitField0_;
+          int to_bitField0_ = 0;
+          if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+            to_bitField0_ |= 0x00000001;
+          }
+          result.term_ = term_;
+          if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+            to_bitField0_ |= 0x00000002;
+          }
+          result.index_ = index_;
+          if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+            to_bitField0_ |= 0x00000004;
+          }
+          if (dataBuilder_ == null) {
+            result.data_ = data_;
+          } else {
+            result.data_ = dataBuilder_.build();
+          }
+          result.bitField0_ = to_bitField0_;
+          onBuilt();
+          return result;
+        }
+
+        public Builder mergeFrom(com.google.protobuf.Message other) {
+          if (other instanceof org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry) {
+            return mergeFrom((org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry)other);
+          } else {
+            super.mergeFrom(other);
+            return this;
+          }
+        }
+
+        public Builder mergeFrom(org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry other) {
+          if (other == org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.getDefaultInstance()) return this;
+          if (other.hasTerm()) {
+            setTerm(other.getTerm());
+          }
+          if (other.hasIndex()) {
+            setIndex(other.getIndex());
+          }
+          if (other.hasData()) {
+            mergeData(other.getData());
+          }
+          this.mergeUnknownFields(other.getUnknownFields());
+          return this;
+        }
+
+        public final boolean isInitialized() {
+          if (hasData()) {
+            if (!getData().isInitialized()) {
+              
+              return false;
+            }
+          }
+          return true;
+        }
+
+        public Builder mergeFrom(
+            com.google.protobuf.CodedInputStream input,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws java.io.IOException {
+          org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry parsedMessage = null;
+          try {
+            parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+            parsedMessage = (org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry) e.getUnfinishedMessage();
+            throw e;
+          } finally {
+            if (parsedMessage != null) {
+              mergeFrom(parsedMessage);
+            }
+          }
+          return this;
+        }
+        private int bitField0_;
+
+        // optional int64 term = 1;
+        private long term_ ;
+        /**
+         * <code>optional int64 term = 1;</code>
+         */
+        public boolean hasTerm() {
+          return ((bitField0_ & 0x00000001) == 0x00000001);
+        }
+        /**
+         * <code>optional int64 term = 1;</code>
+         */
+        public long getTerm() {
+          return term_;
+        }
+        /**
+         * <code>optional int64 term = 1;</code>
+         */
+        public Builder setTerm(long value) {
+          bitField0_ |= 0x00000001;
+          term_ = value;
+          onChanged();
+          return this;
+        }
+        /**
+         * <code>optional int64 term = 1;</code>
+         */
+        public Builder clearTerm() {
+          bitField0_ = (bitField0_ & ~0x00000001);
+          term_ = 0L;
+          onChanged();
+          return this;
+        }
+
+        // optional int64 index = 2;
+        private long index_ ;
+        /**
+         * <code>optional int64 index = 2;</code>
+         */
+        public boolean hasIndex() {
+          return ((bitField0_ & 0x00000002) == 0x00000002);
+        }
+        /**
+         * <code>optional int64 index = 2;</code>
+         */
+        public long getIndex() {
+          return index_;
+        }
+        /**
+         * <code>optional int64 index = 2;</code>
+         */
+        public Builder setIndex(long value) {
+          bitField0_ |= 0x00000002;
+          index_ = value;
+          onChanged();
+          return this;
+        }
+        /**
+         * <code>optional int64 index = 2;</code>
+         */
+        public Builder clearIndex() {
+          bitField0_ = (bitField0_ & ~0x00000002);
+          index_ = 0L;
+          onChanged();
+          return this;
+        }
+
+        // optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;
+        private org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload data_ = org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.getDefaultInstance();
+        private com.google.protobuf.SingleFieldBuilder<
+            org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PayloadOrBuilder> dataBuilder_;
+        /**
+         * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+         */
+        public boolean hasData() {
+          return ((bitField0_ & 0x00000004) == 0x00000004);
+        }
+        /**
+         * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+         */
+        public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload getData() {
+          if (dataBuilder_ == null) {
+            return data_;
+          } else {
+            return dataBuilder_.getMessage();
+          }
+        }
+        /**
+         * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+         */
+        public Builder setData(org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload value) {
+          if (dataBuilder_ == null) {
+            if (value == null) {
+              throw new NullPointerException();
+            }
+            data_ = value;
+            onChanged();
+          } else {
+            dataBuilder_.setMessage(value);
+          }
+          bitField0_ |= 0x00000004;
+          return this;
+        }
+        /**
+         * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+         */
+        public Builder setData(
+            org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder builderForValue) {
+          if (dataBuilder_ == null) {
+            data_ = builderForValue.build();
+            onChanged();
+          } else {
+            dataBuilder_.setMessage(builderForValue.build());
+          }
+          bitField0_ |= 0x00000004;
+          return this;
+        }
+        /**
+         * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+         */
+        public Builder mergeData(org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload value) {
+          if (dataBuilder_ == null) {
+            if (((bitField0_ & 0x00000004) == 0x00000004) &&
+                data_ != org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.getDefaultInstance()) {
+              data_ =
+                org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.newBuilder(data_).mergeFrom(value).buildPartial();
+            } else {
+              data_ = value;
+            }
+            onChanged();
+          } else {
+            dataBuilder_.mergeFrom(value);
+          }
+          bitField0_ |= 0x00000004;
+          return this;
+        }
+        /**
+         * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+         */
+        public Builder clearData() {
+          if (dataBuilder_ == null) {
+            data_ = org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.getDefaultInstance();
+            onChanged();
+          } else {
+            dataBuilder_.clear();
+          }
+          bitField0_ = (bitField0_ & ~0x00000004);
+          return this;
+        }
+        /**
+         * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+         */
+        public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder getDataBuilder() {
+          bitField0_ |= 0x00000004;
+          onChanged();
+          return getDataFieldBuilder().getBuilder();
+        }
+        /**
+         * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+         */
+        public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PayloadOrBuilder getDataOrBuilder() {
+          if (dataBuilder_ != null) {
+            return dataBuilder_.getMessageOrBuilder();
+          } else {
+            return data_;
+          }
+        }
+        /**
+         * <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
+         */
+        private com.google.protobuf.SingleFieldBuilder<
+            org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PayloadOrBuilder> 
+            getDataFieldBuilder() {
+          if (dataBuilder_ == null) {
+            dataBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+                org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PayloadOrBuilder>(
+                    data_,
+                    getParentForChildren(),
+                    isClean());
+            data_ = null;
+          }
+          return dataBuilder_;
+        }
+
+        // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry)
+      }
+
+      static {
+        defaultInstance = new ReplicatedLogEntry(true);
+        defaultInstance.initFields();
+      }
+
+      // @@protoc_insertion_point(class_scope:org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry)
+    }
+
+    private int bitField0_;
+    // optional int64 term = 1;
+    public static final int TERM_FIELD_NUMBER = 1;
+    private long term_;
+    /**
+     * <code>optional int64 term = 1;</code>
+     */
+    public boolean hasTerm() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional int64 term = 1;</code>
+     */
+    public long getTerm() {
+      return term_;
+    }
+
+    // optional string leaderId = 2;
+    public static final int LEADERID_FIELD_NUMBER = 2;
+    private java.lang.Object leaderId_;
+    /**
+     * <code>optional string leaderId = 2;</code>
+     */
+    public boolean hasLeaderId() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional string leaderId = 2;</code>
+     */
+    public java.lang.String getLeaderId() {
+      java.lang.Object ref = leaderId_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          leaderId_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string leaderId = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getLeaderIdBytes() {
+      java.lang.Object ref = leaderId_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        leaderId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional int64 prevLogIndex = 3;
+    public static final int PREVLOGINDEX_FIELD_NUMBER = 3;
+    private long prevLogIndex_;
+    /**
+     * <code>optional int64 prevLogIndex = 3;</code>
+     */
+    public boolean hasPrevLogIndex() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>optional int64 prevLogIndex = 3;</code>
+     */
+    public long getPrevLogIndex() {
+      return prevLogIndex_;
+    }
+
+    // optional int64 prevLogTerm = 4;
+    public static final int PREVLOGTERM_FIELD_NUMBER = 4;
+    private long prevLogTerm_;
+    /**
+     * <code>optional int64 prevLogTerm = 4;</code>
+     */
+    public boolean hasPrevLogTerm() {
+      return ((bitField0_ & 0x00000008) == 0x00000008);
+    }
+    /**
+     * <code>optional int64 prevLogTerm = 4;</code>
+     */
+    public long getPrevLogTerm() {
+      return prevLogTerm_;
+    }
+
+    // repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;
+    public static final int LOGENTRIES_FIELD_NUMBER = 5;
+    private java.util.List<org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry> logEntries_;
+    /**
+     * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+     */
+    public java.util.List<org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry> getLogEntriesList() {
+      return logEntries_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+     */
+    public java.util.List<? extends org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder> 
+        getLogEntriesOrBuilderList() {
+      return logEntries_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+     */
+    public int getLogEntriesCount() {
+      return logEntries_.size();
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+     */
+    public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry getLogEntries(int index) {
+      return logEntries_.get(index);
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+     */
+    public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder getLogEntriesOrBuilder(
+        int index) {
+      return logEntries_.get(index);
+    }
+
+    // optional int64 leaderCommit = 6;
+    public static final int LEADERCOMMIT_FIELD_NUMBER = 6;
+    private long leaderCommit_;
+    /**
+     * <code>optional int64 leaderCommit = 6;</code>
+     */
+    public boolean hasLeaderCommit() {
+      return ((bitField0_ & 0x00000010) == 0x00000010);
+    }
+    /**
+     * <code>optional int64 leaderCommit = 6;</code>
+     */
+    public long getLeaderCommit() {
+      return leaderCommit_;
+    }
+
+    private void initFields() {
+      term_ = 0L;
+      leaderId_ = "";
+      prevLogIndex_ = 0L;
+      prevLogTerm_ = 0L;
+      logEntries_ = java.util.Collections.emptyList();
+      leaderCommit_ = 0L;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      for (int i = 0; i < getLogEntriesCount(); i++) {
+        if (!getLogEntries(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeInt64(1, term_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, getLeaderIdBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeInt64(3, prevLogIndex_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        output.writeInt64(4, prevLogTerm_);
+      }
+      for (int i = 0; i < logEntries_.size(); i++) {
+        output.writeMessage(5, logEntries_.get(i));
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        output.writeInt64(6, leaderCommit_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(1, term_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, getLeaderIdBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(3, prevLogIndex_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(4, prevLogTerm_);
+      }
+      for (int i = 0; i < logEntries_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(5, logEntries_.get(i));
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(6, leaderCommit_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.cluster.raft.AppendEntries}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntriesOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.class, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getLogEntriesFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        term_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        leaderId_ = "";
+        bitField0_ = (bitField0_ & ~0x00000002);
+        prevLogIndex_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        prevLogTerm_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000008);
+        if (logEntriesBuilder_ == null) {
+          logEntries_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000010);
+        } else {
+          logEntriesBuilder_.clear();
+        }
+        leaderCommit_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000020);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_descriptor;
+      }
+
+      public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries getDefaultInstanceForType() {
+        return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries build() {
+        org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries buildPartial() {
+        org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries result = new org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.term_ = term_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.leaderId_ = leaderId_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.prevLogIndex_ = prevLogIndex_;
+        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+          to_bitField0_ |= 0x00000008;
+        }
+        result.prevLogTerm_ = prevLogTerm_;
+        if (logEntriesBuilder_ == null) {
+          if (((bitField0_ & 0x00000010) == 0x00000010)) {
+            logEntries_ = java.util.Collections.unmodifiableList(logEntries_);
+            bitField0_ = (bitField0_ & ~0x00000010);
+          }
+          result.logEntries_ = logEntries_;
+        } else {
+          result.logEntries_ = logEntriesBuilder_.build();
+        }
+        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+          to_bitField0_ |= 0x00000010;
+        }
+        result.leaderCommit_ = leaderCommit_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries) {
+          return mergeFrom((org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries other) {
+        if (other == org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.getDefaultInstance()) return this;
+        if (other.hasTerm()) {
+          setTerm(other.getTerm());
+        }
+        if (other.hasLeaderId()) {
+          bitField0_ |= 0x00000002;
+          leaderId_ = other.leaderId_;
+          onChanged();
+        }
+        if (other.hasPrevLogIndex()) {
+          setPrevLogIndex(other.getPrevLogIndex());
+        }
+        if (other.hasPrevLogTerm()) {
+          setPrevLogTerm(other.getPrevLogTerm());
+        }
+        if (logEntriesBuilder_ == null) {
+          if (!other.logEntries_.isEmpty()) {
+            if (logEntries_.isEmpty()) {
+              logEntries_ = other.logEntries_;
+              bitField0_ = (bitField0_ & ~0x00000010);
+            } else {
+              ensureLogEntriesIsMutable();
+              logEntries_.addAll(other.logEntries_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.logEntries_.isEmpty()) {
+            if (logEntriesBuilder_.isEmpty()) {
+              logEntriesBuilder_.dispose();
+              logEntriesBuilder_ = null;
+              logEntries_ = other.logEntries_;
+              bitField0_ = (bitField0_ & ~0x00000010);
+              logEntriesBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getLogEntriesFieldBuilder() : null;
+            } else {
+              logEntriesBuilder_.addAllMessages(other.logEntries_);
+            }
+          }
+        }
+        if (other.hasLeaderCommit()) {
+          setLeaderCommit(other.getLeaderCommit());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        for (int i = 0; i < getLogEntriesCount(); i++) {
+          if (!getLogEntries(i).isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // optional int64 term = 1;
+      private long term_ ;
+      /**
+       * <code>optional int64 term = 1;</code>
+       */
+      public boolean hasTerm() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional int64 term = 1;</code>
+       */
+      public long getTerm() {
+        return term_;
+      }
+      /**
+       * <code>optional int64 term = 1;</code>
+       */
+      public Builder setTerm(long value) {
+        bitField0_ |= 0x00000001;
+        term_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 term = 1;</code>
+       */
+      public Builder clearTerm() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        term_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // optional string leaderId = 2;
+      private java.lang.Object leaderId_ = "";
+      /**
+       * <code>optional string leaderId = 2;</code>
+       */
+      public boolean hasLeaderId() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional string leaderId = 2;</code>
+       */
+      public java.lang.String getLeaderId() {
+        java.lang.Object ref = leaderId_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          leaderId_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string leaderId = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getLeaderIdBytes() {
+        java.lang.Object ref = leaderId_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          leaderId_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string leaderId = 2;</code>
+       */
+      public Builder setLeaderId(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        leaderId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string leaderId = 2;</code>
+       */
+      public Builder clearLeaderId() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        leaderId_ = getDefaultInstance().getLeaderId();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string leaderId = 2;</code>
+       */
+      public Builder setLeaderIdBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        leaderId_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional int64 prevLogIndex = 3;
+      private long prevLogIndex_ ;
+      /**
+       * <code>optional int64 prevLogIndex = 3;</code>
+       */
+      public boolean hasPrevLogIndex() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>optional int64 prevLogIndex = 3;</code>
+       */
+      public long getPrevLogIndex() {
+        return prevLogIndex_;
+      }
+      /**
+       * <code>optional int64 prevLogIndex = 3;</code>
+       */
+      public Builder setPrevLogIndex(long value) {
+        bitField0_ |= 0x00000004;
+        prevLogIndex_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 prevLogIndex = 3;</code>
+       */
+      public Builder clearPrevLogIndex() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        prevLogIndex_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // optional int64 prevLogTerm = 4;
+      private long prevLogTerm_ ;
+      /**
+       * <code>optional int64 prevLogTerm = 4;</code>
+       */
+      public boolean hasPrevLogTerm() {
+        return ((bitField0_ & 0x00000008) == 0x00000008);
+      }
+      /**
+       * <code>optional int64 prevLogTerm = 4;</code>
+       */
+      public long getPrevLogTerm() {
+        return prevLogTerm_;
+      }
+      /**
+       * <code>optional int64 prevLogTerm = 4;</code>
+       */
+      public Builder setPrevLogTerm(long value) {
+        bitField0_ |= 0x00000008;
+        prevLogTerm_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 prevLogTerm = 4;</code>
+       */
+      public Builder clearPrevLogTerm() {
+        bitField0_ = (bitField0_ & ~0x00000008);
+        prevLogTerm_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;
+      private java.util.List<org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry> logEntries_ =
+        java.util.Collections.emptyList();
+      private void ensureLogEntriesIsMutable() {
+        if (!((bitField0_ & 0x00000010) == 0x00000010)) {
+          logEntries_ = new java.util.ArrayList<org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry>(logEntries_);
+          bitField0_ |= 0x00000010;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder> logEntriesBuilder_;
+
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public java.util.List<org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry> getLogEntriesList() {
+        if (logEntriesBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(logEntries_);
+        } else {
+          return logEntriesBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public int getLogEntriesCount() {
+        if (logEntriesBuilder_ == null) {
+          return logEntries_.size();
+        } else {
+          return logEntriesBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry getLogEntries(int index) {
+        if (logEntriesBuilder_ == null) {
+          return logEntries_.get(index);
+        } else {
+          return logEntriesBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public Builder setLogEntries(
+          int index, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry value) {
+        if (logEntriesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureLogEntriesIsMutable();
+          logEntries_.set(index, value);
+          onChanged();
+        } else {
+          logEntriesBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public Builder setLogEntries(
+          int index, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder builderForValue) {
+        if (logEntriesBuilder_ == null) {
+          ensureLogEntriesIsMutable();
+          logEntries_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          logEntriesBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public Builder addLogEntries(org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry value) {
+        if (logEntriesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureLogEntriesIsMutable();
+          logEntries_.add(value);
+          onChanged();
+        } else {
+          logEntriesBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public Builder addLogEntries(
+          int index, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry value) {
+        if (logEntriesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureLogEntriesIsMutable();
+          logEntries_.add(index, value);
+          onChanged();
+        } else {
+          logEntriesBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public Builder addLogEntries(
+          org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder builderForValue) {
+        if (logEntriesBuilder_ == null) {
+          ensureLogEntriesIsMutable();
+          logEntries_.add(builderForValue.build());
+          onChanged();
+        } else {
+          logEntriesBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public Builder addLogEntries(
+          int index, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder builderForValue) {
+        if (logEntriesBuilder_ == null) {
+          ensureLogEntriesIsMutable();
+          logEntries_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          logEntriesBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public Builder addAllLogEntries(
+          java.lang.Iterable<? extends org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry> values) {
+        if (logEntriesBuilder_ == null) {
+          ensureLogEntriesIsMutable();
+          super.addAll(values, logEntries_);
+          onChanged();
+        } else {
+          logEntriesBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public Builder clearLogEntries() {
+        if (logEntriesBuilder_ == null) {
+          logEntries_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000010);
+          onChanged();
+        } else {
+          logEntriesBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public Builder removeLogEntries(int index) {
+        if (logEntriesBuilder_ == null) {
+          ensureLogEntriesIsMutable();
+          logEntries_.remove(index);
+          onChanged();
+        } else {
+          logEntriesBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder getLogEntriesBuilder(
+          int index) {
+        return getLogEntriesFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder getLogEntriesOrBuilder(
+          int index) {
+        if (logEntriesBuilder_ == null) {
+          return logEntries_.get(index);  } else {
+          return logEntriesBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public java.util.List<? extends org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder> 
+           getLogEntriesOrBuilderList() {
+        if (logEntriesBuilder_ != null) {
+          return logEntriesBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(logEntries_);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder addLogEntriesBuilder() {
+        return getLogEntriesFieldBuilder().addBuilder(
+            org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder addLogEntriesBuilder(
+          int index) {
+        return getLogEntriesFieldBuilder().addBuilder(
+            index, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
+       */
+      public java.util.List<org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder> 
+           getLogEntriesBuilderList() {
+        return getLogEntriesFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder> 
+          getLogEntriesFieldBuilder() {
+        if (logEntriesBuilder_ == null) {
+          logEntriesBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder>(
+                  logEntries_,
+                  ((bitField0_ & 0x00000010) == 0x00000010),
+                  getParentForChildren(),
+                  isClean());
+          logEntries_ = null;
+        }
+        return logEntriesBuilder_;
+      }
+
+      // optional int64 leaderCommit = 6;
+      private long leaderCommit_ ;
+      /**
+       * <code>optional int64 leaderCommit = 6;</code>
+       */
+      public boolean hasLeaderCommit() {
+        return ((bitField0_ & 0x00000020) == 0x00000020);
+      }
+      /**
+       * <code>optional int64 leaderCommit = 6;</code>
+       */
+      public long getLeaderCommit() {
+        return leaderCommit_;
+      }
+      /**
+       * <code>optional int64 leaderCommit = 6;</code>
+       */
+      public Builder setLeaderCommit(long value) {
+        bitField0_ |= 0x00000020;
+        leaderCommit_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 leaderCommit = 6;</code>
+       */
+      public Builder clearLeaderCommit() {
+        bitField0_ = (bitField0_ & ~0x00000020);
+        leaderCommit_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.cluster.raft.AppendEntries)
+    }
+
+    static {
+      defaultInstance = new AppendEntries(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.cluster.raft.AppendEntries)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_Payload_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_Payload_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\033AppendEntriesMessages.proto\022(org.opend" +
+      "aylight.controller.cluster.raft\"\227\003\n\rAppe" +
+      "ndEntries\022\014\n\004term\030\001 \001(\003\022\020\n\010leaderId\030\002 \001(" +
+      "\t\022\024\n\014prevLogIndex\030\003 \001(\003\022\023\n\013prevLogTerm\030\004" +
+      " \001(\003\022^\n\nlogEntries\030\005 \003(\0132J.org.opendayli" +
+      "ght.controller.cluster.raft.AppendEntrie" +
+      "s.ReplicatedLogEntry\022\024\n\014leaderCommit\030\006 \001" +
+      "(\003\032\304\001\n\022ReplicatedLogEntry\022\014\n\004term\030\001 \001(\003\022" +
+      "\r\n\005index\030\002 \001(\003\022`\n\004data\030\003 \001(\0132R.org.opend" +
+      "aylight.controller.cluster.raft.AppendEn",
+      "tries.ReplicatedLogEntry.Payload\032/\n\007Payl" +
+      "oad\022\036\n\026clientPayloadClassName\030\001 \001(\t*\004\010\002\020" +
+      "eBV\n;org.opendaylight.controller.cluster" +
+      ".raft.protobuff.messagesB\025AppendEntriesM" +
+      "essagesH\001"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_descriptor,
+              new java.lang.String[] { "Term", "LeaderId", "PrevLogIndex", "PrevLogTerm", "LogEntries", "LeaderCommit", });
+          internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_descriptor =
+            internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_descriptor.getNestedTypes().get(0);
+          internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_descriptor,
+              new java.lang.String[] { "Term", "Index", "Data", });
+          internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_Payload_descriptor =
+            internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_descriptor.getNestedTypes().get(0);
+          internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_Payload_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_Payload_descriptor,
+              new java.lang.String[] { "ClientPayloadClassName", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/protobuff/messages/VotingMessages.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/protobuff/messages/VotingMessages.java
new file mode 100644 (file)
index 0000000..5b3bd2b
--- /dev/null
@@ -0,0 +1,767 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: VotingMessages.proto
+
+package org.opendaylight.controller.cluster.raft.protobuff.messages;
+
+public final class VotingMessages {
+  private VotingMessages() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface RequestVoteOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // optional int64 term = 1;
+    /**
+     * <code>optional int64 term = 1;</code>
+     */
+    boolean hasTerm();
+    /**
+     * <code>optional int64 term = 1;</code>
+     */
+    long getTerm();
+
+    // optional string candidateId = 2;
+    /**
+     * <code>optional string candidateId = 2;</code>
+     */
+    boolean hasCandidateId();
+    /**
+     * <code>optional string candidateId = 2;</code>
+     */
+    java.lang.String getCandidateId();
+    /**
+     * <code>optional string candidateId = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getCandidateIdBytes();
+
+    // optional int64 lastLongIndex = 3;
+    /**
+     * <code>optional int64 lastLongIndex = 3;</code>
+     */
+    boolean hasLastLongIndex();
+    /**
+     * <code>optional int64 lastLongIndex = 3;</code>
+     */
+    long getLastLongIndex();
+
+    // optional int64 lastLongTerm = 4;
+    /**
+     * <code>optional int64 lastLongTerm = 4;</code>
+     */
+    boolean hasLastLongTerm();
+    /**
+     * <code>optional int64 lastLongTerm = 4;</code>
+     */
+    long getLastLongTerm();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.cluster.raft.RequestVote}
+   */
+  public static final class RequestVote extends
+      com.google.protobuf.GeneratedMessage
+      implements RequestVoteOrBuilder {
+    // Use RequestVote.newBuilder() to construct.
+    private RequestVote(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private RequestVote(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final RequestVote defaultInstance;
+    public static RequestVote getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public RequestVote getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private RequestVote(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              bitField0_ |= 0x00000001;
+              term_ = input.readInt64();
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              candidateId_ = input.readBytes();
+              break;
+            }
+            case 24: {
+              bitField0_ |= 0x00000004;
+              lastLongIndex_ = input.readInt64();
+              break;
+            }
+            case 32: {
+              bitField0_ |= 0x00000008;
+              lastLongTerm_ = input.readInt64();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.internal_static_org_opendaylight_controller_cluster_raft_RequestVote_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.internal_static_org_opendaylight_controller_cluster_raft_RequestVote_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote.class, org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<RequestVote> PARSER =
+        new com.google.protobuf.AbstractParser<RequestVote>() {
+      public RequestVote parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new RequestVote(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<RequestVote> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // optional int64 term = 1;
+    public static final int TERM_FIELD_NUMBER = 1;
+    private long term_;
+    /**
+     * <code>optional int64 term = 1;</code>
+     */
+    public boolean hasTerm() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional int64 term = 1;</code>
+     */
+    public long getTerm() {
+      return term_;
+    }
+
+    // optional string candidateId = 2;
+    public static final int CANDIDATEID_FIELD_NUMBER = 2;
+    private java.lang.Object candidateId_;
+    /**
+     * <code>optional string candidateId = 2;</code>
+     */
+    public boolean hasCandidateId() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional string candidateId = 2;</code>
+     */
+    public java.lang.String getCandidateId() {
+      java.lang.Object ref = candidateId_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          candidateId_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string candidateId = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getCandidateIdBytes() {
+      java.lang.Object ref = candidateId_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        candidateId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional int64 lastLongIndex = 3;
+    public static final int LASTLONGINDEX_FIELD_NUMBER = 3;
+    private long lastLongIndex_;
+    /**
+     * <code>optional int64 lastLongIndex = 3;</code>
+     */
+    public boolean hasLastLongIndex() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>optional int64 lastLongIndex = 3;</code>
+     */
+    public long getLastLongIndex() {
+      return lastLongIndex_;
+    }
+
+    // optional int64 lastLongTerm = 4;
+    public static final int LASTLONGTERM_FIELD_NUMBER = 4;
+    private long lastLongTerm_;
+    /**
+     * <code>optional int64 lastLongTerm = 4;</code>
+     */
+    public boolean hasLastLongTerm() {
+      return ((bitField0_ & 0x00000008) == 0x00000008);
+    }
+    /**
+     * <code>optional int64 lastLongTerm = 4;</code>
+     */
+    public long getLastLongTerm() {
+      return lastLongTerm_;
+    }
+
+    private void initFields() {
+      term_ = 0L;
+      candidateId_ = "";
+      lastLongIndex_ = 0L;
+      lastLongTerm_ = 0L;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeInt64(1, term_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, getCandidateIdBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeInt64(3, lastLongIndex_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        output.writeInt64(4, lastLongTerm_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(1, term_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, getCandidateIdBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(3, lastLongIndex_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(4, lastLongTerm_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.cluster.raft.RequestVote}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVoteOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.internal_static_org_opendaylight_controller_cluster_raft_RequestVote_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.internal_static_org_opendaylight_controller_cluster_raft_RequestVote_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote.class, org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        term_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        candidateId_ = "";
+        bitField0_ = (bitField0_ & ~0x00000002);
+        lastLongIndex_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        lastLongTerm_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000008);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.internal_static_org_opendaylight_controller_cluster_raft_RequestVote_descriptor;
+      }
+
+      public org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote getDefaultInstanceForType() {
+        return org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote build() {
+        org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote buildPartial() {
+        org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote result = new org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.term_ = term_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.candidateId_ = candidateId_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.lastLongIndex_ = lastLongIndex_;
+        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+          to_bitField0_ |= 0x00000008;
+        }
+        result.lastLongTerm_ = lastLongTerm_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote) {
+          return mergeFrom((org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote other) {
+        if (other == org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote.getDefaultInstance()) return this;
+        if (other.hasTerm()) {
+          setTerm(other.getTerm());
+        }
+        if (other.hasCandidateId()) {
+          bitField0_ |= 0x00000002;
+          candidateId_ = other.candidateId_;
+          onChanged();
+        }
+        if (other.hasLastLongIndex()) {
+          setLastLongIndex(other.getLastLongIndex());
+        }
+        if (other.hasLastLongTerm()) {
+          setLastLongTerm(other.getLastLongTerm());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // optional int64 term = 1;
+      private long term_ ;
+      /**
+       * <code>optional int64 term = 1;</code>
+       */
+      public boolean hasTerm() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional int64 term = 1;</code>
+       */
+      public long getTerm() {
+        return term_;
+      }
+      /**
+       * <code>optional int64 term = 1;</code>
+       */
+      public Builder setTerm(long value) {
+        bitField0_ |= 0x00000001;
+        term_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 term = 1;</code>
+       */
+      public Builder clearTerm() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        term_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // optional string candidateId = 2;
+      private java.lang.Object candidateId_ = "";
+      /**
+       * <code>optional string candidateId = 2;</code>
+       */
+      public boolean hasCandidateId() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional string candidateId = 2;</code>
+       */
+      public java.lang.String getCandidateId() {
+        java.lang.Object ref = candidateId_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          candidateId_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string candidateId = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getCandidateIdBytes() {
+        java.lang.Object ref = candidateId_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          candidateId_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string candidateId = 2;</code>
+       */
+      public Builder setCandidateId(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        candidateId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string candidateId = 2;</code>
+       */
+      public Builder clearCandidateId() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        candidateId_ = getDefaultInstance().getCandidateId();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string candidateId = 2;</code>
+       */
+      public Builder setCandidateIdBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        candidateId_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional int64 lastLongIndex = 3;
+      private long lastLongIndex_ ;
+      /**
+       * <code>optional int64 lastLongIndex = 3;</code>
+       */
+      public boolean hasLastLongIndex() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>optional int64 lastLongIndex = 3;</code>
+       */
+      public long getLastLongIndex() {
+        return lastLongIndex_;
+      }
+      /**
+       * <code>optional int64 lastLongIndex = 3;</code>
+       */
+      public Builder setLastLongIndex(long value) {
+        bitField0_ |= 0x00000004;
+        lastLongIndex_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 lastLongIndex = 3;</code>
+       */
+      public Builder clearLastLongIndex() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        lastLongIndex_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // optional int64 lastLongTerm = 4;
+      private long lastLongTerm_ ;
+      /**
+       * <code>optional int64 lastLongTerm = 4;</code>
+       */
+      public boolean hasLastLongTerm() {
+        return ((bitField0_ & 0x00000008) == 0x00000008);
+      }
+      /**
+       * <code>optional int64 lastLongTerm = 4;</code>
+       */
+      public long getLastLongTerm() {
+        return lastLongTerm_;
+      }
+      /**
+       * <code>optional int64 lastLongTerm = 4;</code>
+       */
+      public Builder setLastLongTerm(long value) {
+        bitField0_ |= 0x00000008;
+        lastLongTerm_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 lastLongTerm = 4;</code>
+       */
+      public Builder clearLastLongTerm() {
+        bitField0_ = (bitField0_ & ~0x00000008);
+        lastLongTerm_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.cluster.raft.RequestVote)
+    }
+
+    static {
+      defaultInstance = new RequestVote(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.cluster.raft.RequestVote)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_cluster_raft_RequestVote_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_cluster_raft_RequestVote_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\024VotingMessages.proto\022(org.opendaylight" +
+      ".controller.cluster.raft\"]\n\013RequestVote\022" +
+      "\014\n\004term\030\001 \001(\003\022\023\n\013candidateId\030\002 \001(\t\022\025\n\rla" +
+      "stLongIndex\030\003 \001(\003\022\024\n\014lastLongTerm\030\004 \001(\003B" +
+      "O\n;org.opendaylight.controller.cluster.r" +
+      "aft.protobuff.messagesB\016VotingMessagesH\001"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_org_opendaylight_controller_cluster_raft_RequestVote_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_org_opendaylight_controller_cluster_raft_RequestVote_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_cluster_raft_RequestVote_descriptor,
+              new java.lang.String[] { "Term", "CandidateId", "LastLongIndex", "LastLongTerm", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/resources/AppendEntriesMessages.proto b/opendaylight/md-sal/sal-akka-raft/src/main/resources/AppendEntriesMessages.proto
new file mode 100644 (file)
index 0000000..ab591ea
--- /dev/null
@@ -0,0 +1,30 @@
+package org.opendaylight.controller.cluster.raft;
+
+option java_package = "org.opendaylight.controller.cluster.raft.protobuff.messages";
+option java_outer_classname = "AppendEntriesMessages";
+option optimize_for = SPEED;
+
+message AppendEntries {
+    optional int64 term = 1;
+    optional string leaderId = 2;
+    optional int64 prevLogIndex = 3;
+    optional int64 prevLogTerm = 4;
+
+    message ReplicatedLogEntry {
+        optional int64 term = 1;
+        optional int64 index = 2;
+
+        message Payload {
+            optional string clientPayloadClassName = 1;
+            extensions 2 to 100;
+        }
+
+        optional Payload data = 3;
+    }
+
+    repeated ReplicatedLogEntry logEntries = 5;
+    optional int64 leaderCommit = 6;
+
+}
+
+
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/resources/KeyValueMessages.proto b/opendaylight/md-sal/sal-akka-raft/src/main/resources/KeyValueMessages.proto
new file mode 100644 (file)
index 0000000..7ee0b21
--- /dev/null
@@ -0,0 +1,13 @@
+package org.opendaylight.controller.cluster.raft;
+
+import "AppendEntriesMessages.proto";
+
+option java_package = "org.opendaylight.controller.cluster.example.protobuff.messages";
+option java_outer_classname = "KeyValueMessages";
+option optimize_for = SPEED;
+
+// proto file for the payload of Example, extending AppendEntries
+extend AppendEntries.ReplicatedLogEntry.Payload {
+    optional string key = 2;
+    optional string value = 3;
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/resources/VotingMessages.proto b/opendaylight/md-sal/sal-akka-raft/src/main/resources/VotingMessages.proto
new file mode 100644 (file)
index 0000000..6a45a2b
--- /dev/null
@@ -0,0 +1,13 @@
+package org.opendaylight.controller.cluster.raft;
+
+option java_package = "org.opendaylight.controller.cluster.raft.protobuff.messages";
+option java_outer_classname = "VotingMessages";
+option optimize_for = SPEED;
+
+message RequestVote {
+    optional int64 term = 1;
+    optional string candidateId = 2;
+    optional int64 lastLongIndex = 3;
+    optional int64 lastLongTerm = 4;
+
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/resources/application.conf b/opendaylight/md-sal/sal-akka-raft/src/main/resources/application.conf
new file mode 100644 (file)
index 0000000..9e42a13
--- /dev/null
@@ -0,0 +1,20 @@
+akka {
+
+    loglevel = "DEBUG"
+
+    actor {
+        # enable to test serialization only.
+        # serialize-messages = on
+
+        serializers {
+          java  = "akka.serialization.JavaSerializer"
+          proto = "akka.remote.serialization.ProtobufSerializer"
+        }
+
+        serialization-bindings {
+            "org.opendaylight.controller.cluster.raft.ReplicatedLogImplEntry" = java
+            "com.google.protobuf.Message" = proto
+            "com.google.protobuf.GeneratedMessage" = proto
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/AbstractActorTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/AbstractActorTest.java
new file mode 100644 (file)
index 0000000..1971432
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+import akka.actor.ActorSystem;
+import akka.testkit.JavaTestKit;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public abstract class AbstractActorTest {
+    private static ActorSystem system;
+
+    @BeforeClass
+    public static void setUpClass() {
+        System.setProperty("shard.persistent", "false");
+        system = ActorSystem.create("test");
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        JavaTestKit.shutdownActorSystem(system);
+        system = null;
+    }
+
+    protected ActorSystem getSystem() {
+        return system;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActorContext.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActorContext.java
new file mode 100644 (file)
index 0000000..2e200cb
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSelection;
+import akka.actor.ActorSystem;
+import akka.actor.Props;
+import akka.event.Logging;
+import akka.event.LoggingAdapter;
+import com.google.protobuf.GeneratedMessage;
+import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
+import org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages;
+import org.opendaylight.controller.cluster.raft.protobuff.messages.MockPayloadMessages;
+import com.google.common.base.Preconditions;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class MockRaftActorContext implements RaftActorContext {
+
+    private String id;
+    private ActorSystem system;
+    private ActorRef actor;
+    private long index = 0;
+    private long lastApplied = 0;
+    private final ElectionTerm electionTerm;
+    private ReplicatedLog replicatedLog;
+    private Map<String, String> peerAddresses = new HashMap();
+
+    public MockRaftActorContext(){
+        electionTerm = null;
+
+        initReplicatedLog();
+    }
+
+    public MockRaftActorContext(String id, ActorSystem system, ActorRef actor){
+        this.id = id;
+        this.system = system;
+        this.actor = actor;
+
+        final String id1 = id;
+        electionTerm = new ElectionTerm() {
+            /**
+             * Identifier of the actor whose election term information this is
+             */
+            private final String id = id1;
+            private long currentTerm = 0;
+            private String votedFor = "";
+
+            public long getCurrentTerm() {
+                return currentTerm;
+            }
+
+            public String getVotedFor() {
+                return votedFor;
+            }
+
+            public void update(long currentTerm, String votedFor){
+                this.currentTerm = currentTerm;
+                this.votedFor = votedFor;
+
+                // TODO : Write to some persistent state
+            }
+
+            @Override public void updateAndPersist(long currentTerm,
+                String votedFor) {
+                update(currentTerm, votedFor);
+            }
+        };
+
+        initReplicatedLog();
+    }
+
+
+    public void initReplicatedLog(){
+        this.replicatedLog = new SimpleReplicatedLog();
+        this.replicatedLog.append(new MockReplicatedLogEntry(1, 1, new MockPayload("")));
+    }
+
+    @Override public ActorRef actorOf(Props props) {
+        return system.actorOf(props);
+    }
+
+    @Override public ActorSelection actorSelection(String path) {
+        return system.actorSelection(path);
+    }
+
+    @Override public String getId() {
+        return id;
+    }
+
+    @Override public ActorRef getActor() {
+        return actor;
+    }
+
+    @Override public ElectionTerm getTermInformation() {
+        return electionTerm;
+    }
+
+    public void setIndex(long index){
+        this.index = index;
+    }
+
+    @Override public long getCommitIndex() {
+        return index;
+    }
+
+    @Override public void setCommitIndex(long commitIndex) {
+        this.index = commitIndex;
+    }
+
+    @Override public void setLastApplied(long lastApplied){
+        this.lastApplied = lastApplied;
+    }
+
+    @Override public long getLastApplied() {
+        return lastApplied;
+    }
+
+    public void setReplicatedLog(ReplicatedLog replicatedLog) {
+        this.replicatedLog = replicatedLog;
+    }
+
+    @Override public ReplicatedLog getReplicatedLog() {
+        return replicatedLog;
+    }
+
+    @Override public ActorSystem getActorSystem() {
+        return this.system;
+    }
+
+    @Override public LoggingAdapter getLogger() {
+        return Logging.getLogger(system, this);
+    }
+
+    @Override public Map<String, String> getPeerAddresses() {
+        return peerAddresses;
+    }
+
+    @Override public String getPeerAddress(String peerId) {
+        return peerAddresses.get(peerId);
+    }
+
+    @Override public void addToPeers(String name, String address) {
+        peerAddresses.put(name, address);
+    }
+
+    @Override public void removePeer(String name) {
+        peerAddresses.remove(name);
+    }
+
+    @Override public ActorSelection getPeerActorSelection(String peerId) {
+        String peerAddress = getPeerAddress(peerId);
+        if(peerAddress != null){
+            return actorSelection(peerAddress);
+        }
+        return null;
+    }
+
+    @Override public void setPeerAddress(String peerId, String peerAddress) {
+        Preconditions.checkState(peerAddresses.containsKey(peerId));
+        peerAddresses.put(peerId, peerAddress);
+    }
+
+    public void setPeerAddresses(Map<String, String> peerAddresses) {
+        this.peerAddresses = peerAddresses;
+    }
+
+
+
+    public static class SimpleReplicatedLog implements ReplicatedLog {
+        private final List<ReplicatedLogEntry> log = new ArrayList<>();
+
+        @Override public ReplicatedLogEntry get(long index) {
+            if(index >= log.size() || index < 0){
+                return null;
+            }
+            return log.get((int) index);
+        }
+
+        @Override public ReplicatedLogEntry last() {
+            if(log.size() == 0){
+                return null;
+            }
+            return log.get(log.size()-1);
+        }
+
+        @Override public long lastIndex() {
+            if(log.size() == 0){
+                return -1;
+            }
+
+            return last().getIndex();
+        }
+
+        @Override public long lastTerm() {
+            if(log.size() == 0){
+                return -1;
+            }
+
+            return last().getTerm();
+        }
+
+        @Override public void removeFrom(long index) {
+            if(index >= log.size() || index < 0){
+                return;
+            }
+
+            log.subList((int) index, log.size()).clear();
+            //log.remove((int) index);
+        }
+
+        @Override public void removeFromAndPersist(long index) {
+            removeFrom(index);
+        }
+
+        @Override public void append(ReplicatedLogEntry replicatedLogEntry) {
+            log.add(replicatedLogEntry);
+        }
+
+        @Override public void appendAndPersist(
+            ReplicatedLogEntry replicatedLogEntry) {
+            append(replicatedLogEntry);
+        }
+
+        @Override public List<ReplicatedLogEntry> getFrom(long index) {
+            if(index >= log.size() || index < 0){
+                return Collections.EMPTY_LIST;
+            }
+            List<ReplicatedLogEntry> entries = new ArrayList<>();
+            for(int i=(int) index ; i < log.size() ; i++) {
+                entries.add(get(i));
+            }
+            return entries;
+        }
+
+        @Override public long size() {
+            return log.size();
+        }
+
+        @Override public boolean isPresent(long index) {
+            if(index >= log.size() || index < 0){
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override public boolean isInSnapshot(long index) {
+            return false;
+        }
+
+        @Override public Object getSnapshot() {
+            return null;
+        }
+
+        @Override public long getSnapshotIndex() {
+            return -1;
+        }
+
+        @Override public long getSnapshotTerm() {
+            return -1;
+        }
+    }
+
+    public static class MockPayload extends Payload implements Serializable {
+        private String value = "";
+
+        public MockPayload(String s) {
+            this.value = s;
+        }
+
+        @Override public  Map<GeneratedMessage.GeneratedExtension, String> encode() {
+            Map<GeneratedMessage.GeneratedExtension, String> map = new HashMap<GeneratedMessage.GeneratedExtension, String>();
+            map.put(MockPayloadMessages.value, value);
+            return map;
+        }
+
+        @Override public Payload decode(
+            AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload payloadProtoBuff) {
+            String value = payloadProtoBuff.getExtension(MockPayloadMessages.value);
+            this.value = value;
+            return this;
+        }
+
+        @Override public String getClientPayloadClassName() {
+            return MockPayload.class.getName();
+        }
+
+        public String toString() {
+            return value;
+        }
+    }
+
+    public static class MockReplicatedLogEntry implements ReplicatedLogEntry, Serializable {
+
+        private final long term;
+        private final long index;
+        private final Payload data;
+
+        public MockReplicatedLogEntry(long term, long index, Payload data){
+
+            this.term = term;
+            this.index = index;
+            this.data = data;
+        }
+
+        @Override public Payload getData() {
+            return data;
+        }
+
+        @Override public long getTerm() {
+            return term;
+        }
+
+        @Override public long getIndex() {
+            return index;
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/AbstractRaftActorBehaviorTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/AbstractRaftActorBehaviorTest.java
new file mode 100644 (file)
index 0000000..8068dfb
--- /dev/null
@@ -0,0 +1,368 @@
+package org.opendaylight.controller.cluster.raft.behaviors;
+
+import akka.actor.ActorRef;
+import akka.actor.Props;
+import akka.testkit.JavaTestKit;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.raft.AbstractActorTest;
+import org.opendaylight.controller.cluster.raft.MockRaftActorContext;
+import org.opendaylight.controller.cluster.raft.RaftActorContext;
+import org.opendaylight.controller.cluster.raft.RaftState;
+import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
+import org.opendaylight.controller.cluster.raft.SerializationUtils;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply;
+import org.opendaylight.controller.cluster.raft.messages.RaftRPC;
+import org.opendaylight.controller.cluster.raft.messages.RequestVote;
+import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
+import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
+import org.opendaylight.controller.cluster.raft.utils.DoNothingActor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public abstract class AbstractRaftActorBehaviorTest extends AbstractActorTest {
+
+    private final ActorRef behaviorActor = getSystem().actorOf(Props.create(
+        DoNothingActor.class));
+
+    /**
+     * This test checks that when a new Raft RPC message is received with a newer
+     * term the RaftActor gets into the Follower state.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testHandleRaftRPCWithNewerTerm() throws Exception {
+        new JavaTestKit(getSystem()) {{
+
+            assertStateChangesToFollowerWhenRaftRPCHasNewerTerm(getTestActor(),
+                createAppendEntriesWithNewerTerm());
+
+            assertStateChangesToFollowerWhenRaftRPCHasNewerTerm(getTestActor(),
+                createAppendEntriesReplyWithNewerTerm());
+
+            assertStateChangesToFollowerWhenRaftRPCHasNewerTerm(getTestActor(),
+                createRequestVoteWithNewerTerm());
+
+            assertStateChangesToFollowerWhenRaftRPCHasNewerTerm(getTestActor(),
+                createRequestVoteReplyWithNewerTerm());
+
+
+        }};
+    }
+
+
+    /**
+     * This test verifies that when an AppendEntries is received with a term that
+     * is less that the currentTerm of the RaftActor then the RaftActor does not
+     * change it's state and it responds back with a failure
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testHandleAppendEntriesSenderTermLessThanReceiverTerm()
+        throws Exception {
+        new JavaTestKit(getSystem()) {{
+
+            MockRaftActorContext context = (MockRaftActorContext)
+                createActorContext();
+
+            // First set the receivers term to a high number (1000)
+            context.getTermInformation().update(1000, "test");
+
+            AppendEntries appendEntries =
+                new AppendEntries(100, "leader-1", 0, 0, null, 101);
+
+            RaftActorBehavior behavior = createBehavior(context);
+
+            // Send an unknown message so that the state of the RaftActor remains unchanged
+            RaftState expected = behavior.handleMessage(getRef(), "unknown");
+
+            RaftState raftState =
+                behavior.handleMessage(getRef(), appendEntries);
+
+            assertEquals(expected, raftState);
+
+            // Also expect an AppendEntriesReply to be sent where success is false
+            final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"),
+                "AppendEntriesReply") {
+                // do not put code outside this method, will run afterwards
+                protected Boolean match(Object in) {
+                    if (in instanceof AppendEntriesReply) {
+                        AppendEntriesReply reply = (AppendEntriesReply) in;
+                        return reply.isSuccess();
+                    } else {
+                        throw noMatch();
+                    }
+                }
+            }.get();
+
+            assertEquals(false, out);
+
+
+        }};
+    }
+
+
+    @Test
+    public void testHandleAppendEntriesAddSameEntryToLog(){
+        new JavaTestKit(getSystem()) {
+            {
+
+                MockRaftActorContext context = (MockRaftActorContext)
+                    createActorContext();
+
+                // First set the receivers term to lower number
+                context.getTermInformation().update(2, "test");
+
+                // Prepare the receivers log
+                MockRaftActorContext.SimpleReplicatedLog log =
+                    new MockRaftActorContext.SimpleReplicatedLog();
+                log.append(
+                    new MockRaftActorContext.MockReplicatedLogEntry(1, 0, new MockRaftActorContext.MockPayload("zero")));
+
+                context.setReplicatedLog(log);
+
+                List<ReplicatedLogEntry> entries = new ArrayList<>();
+                entries.add(
+                    new MockRaftActorContext.MockReplicatedLogEntry(1, 0, new MockRaftActorContext.MockPayload("zero")));
+
+                AppendEntries appendEntries =
+                    new AppendEntries(2, "leader-1", -1, 1, entries, 0);
+
+                RaftActorBehavior behavior = createBehavior(context);
+
+                if (AbstractRaftActorBehaviorTest.this instanceof CandidateTest) {
+                    // Resetting the Candidates term to make sure it will match
+                    // the term sent by AppendEntries. If this was not done then
+                    // the test will fail because the Candidate will assume that
+                    // the message was sent to it from a lower term peer and will
+                    // thus respond with a failure
+                    context.getTermInformation().update(2, "test");
+                }
+
+                // Send an unknown message so that the state of the RaftActor remains unchanged
+                RaftState expected = behavior.handleMessage(getRef(), "unknown");
+
+                RaftState raftState =
+                    behavior.handleMessage(getRef(), appendEntries);
+
+                assertEquals(expected, raftState);
+
+                assertEquals(1, log.size());
+
+
+            }};
+    }
+
+    /**
+     * This test verifies that when a RequestVote is received by the RaftActor
+     * with a term which is greater than the RaftActors' currentTerm and the
+     * senders' log is more upto date than the receiver that the receiver grants
+     * the vote to the sender
+     */
+    @Test
+    public void testHandleRequestVoteWhenSenderTermGreaterThanCurrentTermAndSenderLogMoreUpToDate() {
+        new JavaTestKit(getSystem()) {{
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    RaftActorBehavior behavior = createBehavior(
+                        createActorContext(behaviorActor));
+
+                    RaftState raftState = behavior.handleMessage(getTestActor(),
+                        new RequestVote(1000, "test", 10000, 999));
+
+                    if(behavior.state() != RaftState.Follower){
+                        assertEquals(RaftState.Follower, raftState);
+                    } else {
+
+                        final Boolean out =
+                            new ExpectMsg<Boolean>(duration("1 seconds"),
+                                "RequestVoteReply") {
+                                // do not put code outside this method, will run afterwards
+                                protected Boolean match(Object in) {
+                                    if (in instanceof RequestVoteReply) {
+                                        RequestVoteReply reply =
+                                            (RequestVoteReply) in;
+                                        return reply.isVoteGranted();
+                                    } else {
+                                        throw noMatch();
+                                    }
+                                }
+                            }.get();
+
+                        assertEquals(true, out);
+                    }
+                }
+            };
+        }};
+    }
+
+    /**
+     * This test verifies that when a RaftActor receives a RequestVote message
+     * with a term that is greater than it's currentTerm but a less up-to-date
+     * log then the receiving RaftActor will not grant the vote to the sender
+     */
+    @Test
+    public void testHandleRequestVoteWhenSenderTermGreaterThanCurrentTermButSenderLogLessUptoDate() {
+        new JavaTestKit(getSystem()) {{
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    RaftActorContext actorContext =
+                        createActorContext(behaviorActor);
+
+                    MockRaftActorContext.SimpleReplicatedLog
+                        log = new MockRaftActorContext.SimpleReplicatedLog();
+                    log.append(
+                        new MockRaftActorContext.MockReplicatedLogEntry(20000,
+                            1000000, new MockRaftActorContext.MockPayload("")));
+
+                    ((MockRaftActorContext) actorContext).setReplicatedLog(log);
+
+                    RaftActorBehavior behavior = createBehavior(actorContext);
+
+                    RaftState raftState = behavior.handleMessage(getTestActor(),
+                        new RequestVote(1000, "test", 10000, 999));
+
+                    if(behavior.state() != RaftState.Follower){
+                        assertEquals(RaftState.Follower, raftState);
+                    } else {
+                        final Boolean out =
+                            new ExpectMsg<Boolean>(duration("1 seconds"),
+                                "RequestVoteReply") {
+                                // do not put code outside this method, will run afterwards
+                                protected Boolean match(Object in) {
+                                    if (in instanceof RequestVoteReply) {
+                                        RequestVoteReply reply =
+                                            (RequestVoteReply) in;
+                                        return reply.isVoteGranted();
+                                    } else {
+                                        throw noMatch();
+                                    }
+                                }
+                            }.get();
+
+                        assertEquals(false, out);
+                    }
+                }
+            };
+        }};
+    }
+
+
+
+    /**
+     * This test verifies that the receiving RaftActor will not grant a vote
+     * to a sender if the sender's term is lesser than the currentTerm of the
+     * recipient RaftActor
+     */
+    @Test
+    public void testHandleRequestVoteWhenSenderTermLessThanCurrentTerm() {
+        new JavaTestKit(getSystem()) {{
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    RaftActorContext context =
+                        createActorContext(behaviorActor);
+
+                    context.getTermInformation().update(1000, null);
+
+                    RaftActorBehavior follower = createBehavior(context);
+
+                    follower.handleMessage(getTestActor(),
+                        new RequestVote(999, "test", 10000, 999));
+
+                    final Boolean out =
+                        new ExpectMsg<Boolean>(duration("1 seconds"),
+                            "RequestVoteReply") {
+                            // do not put code outside this method, will run afterwards
+                            protected Boolean match(Object in) {
+                                if (in instanceof RequestVoteReply) {
+                                    RequestVoteReply reply =
+                                        (RequestVoteReply) in;
+                                    return reply.isVoteGranted();
+                                } else {
+                                    throw noMatch();
+                                }
+                            }
+                        }.get();
+
+                    assertEquals(false, out);
+                }
+            };
+        }};
+    }
+
+    protected void assertStateChangesToFollowerWhenRaftRPCHasNewerTerm(
+        ActorRef actorRef, RaftRPC rpc) {
+
+        RaftActorContext actorContext = createActorContext();
+        Payload p = new MockRaftActorContext.MockPayload("");
+        setLastLogEntry(
+            (MockRaftActorContext) actorContext, 0, 0, p);
+
+        RaftState raftState = createBehavior(actorContext)
+            .handleMessage(actorRef, rpc);
+
+        assertEquals(RaftState.Follower, raftState);
+    }
+
+    protected MockRaftActorContext.SimpleReplicatedLog setLastLogEntry(
+        MockRaftActorContext actorContext, long term, long index, Payload data) {
+        return setLastLogEntry(actorContext,
+            new MockRaftActorContext.MockReplicatedLogEntry(term, index, data));
+    }
+
+    protected MockRaftActorContext.SimpleReplicatedLog setLastLogEntry(
+        MockRaftActorContext actorContext, ReplicatedLogEntry logEntry) {
+        MockRaftActorContext.SimpleReplicatedLog
+            log = new MockRaftActorContext.SimpleReplicatedLog();
+        log.append(logEntry);
+        actorContext.setReplicatedLog(log);
+
+        return log;
+    }
+
+    protected abstract RaftActorBehavior createBehavior(
+        RaftActorContext actorContext);
+
+    protected RaftActorBehavior createBehavior() {
+        return createBehavior(createActorContext());
+    }
+
+    protected RaftActorContext createActorContext() {
+        return new MockRaftActorContext();
+    }
+
+    protected RaftActorContext createActorContext(ActorRef actor) {
+        return new MockRaftActorContext("test", getSystem(), actor);
+    }
+
+    protected AppendEntries createAppendEntriesWithNewerTerm() {
+        return new AppendEntries(100, "leader-1", 0, 0, null, 1);
+    }
+
+    protected AppendEntriesReply createAppendEntriesReplyWithNewerTerm() {
+        return new AppendEntriesReply("follower-1", 100, false, 100, 100);
+    }
+
+    protected RequestVote createRequestVoteWithNewerTerm() {
+        return new RequestVote(100, "candidate-1", 10, 100);
+    }
+
+    protected RequestVoteReply createRequestVoteReplyWithNewerTerm() {
+        return new RequestVoteReply(100, false);
+    }
+
+    protected Object fromSerializableMessage(Object serializable){
+        return SerializationUtils.fromSerializable(serializable);
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java
new file mode 100644 (file)
index 0000000..c763683
--- /dev/null
@@ -0,0 +1,299 @@
+package org.opendaylight.controller.cluster.raft.behaviors;
+
+import akka.actor.ActorRef;
+import akka.actor.Props;
+import akka.testkit.JavaTestKit;
+import junit.framework.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.raft.MockRaftActorContext;
+import org.opendaylight.controller.cluster.raft.RaftActorContext;
+import org.opendaylight.controller.cluster.raft.RaftState;
+import org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply;
+import org.opendaylight.controller.cluster.raft.messages.RequestVote;
+import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
+import org.opendaylight.controller.cluster.raft.utils.DoNothingActor;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+public class CandidateTest extends AbstractRaftActorBehaviorTest {
+
+    private final ActorRef candidateActor = getSystem().actorOf(Props.create(
+        DoNothingActor.class));
+
+    private final ActorRef peerActor1 = getSystem().actorOf(Props.create(
+        DoNothingActor.class));
+
+    private final ActorRef peerActor2 = getSystem().actorOf(Props.create(
+        DoNothingActor.class));
+
+    private final ActorRef peerActor3 = getSystem().actorOf(Props.create(
+        DoNothingActor.class));
+
+    private final ActorRef peerActor4 = getSystem().actorOf(Props.create(
+        DoNothingActor.class));
+
+    private final Map<String, String> onePeer = new HashMap<>();
+    private final Map<String, String> twoPeers = new HashMap<>();
+    private final Map<String, String> fourPeers = new HashMap<>();
+
+    @Before
+    public void setUp(){
+        onePeer.put(peerActor1.path().toString(),
+            peerActor1.path().toString());
+
+        twoPeers.put(peerActor1.path().toString(),
+            peerActor1.path().toString());
+        twoPeers.put(peerActor2.path().toString(),
+            peerActor2.path().toString());
+
+        fourPeers.put(peerActor1.path().toString(),
+            peerActor1.path().toString());
+        fourPeers.put(peerActor2.path().toString(),
+            peerActor2.path().toString());
+        fourPeers.put(peerActor3.path().toString(),
+            peerActor3.path().toString());
+        fourPeers.put(peerActor4.path().toString(),
+            peerActor3.path().toString());
+
+
+    }
+
+    @Test
+    public void testWhenACandidateIsCreatedItIncrementsTheCurrentTermAndVotesForItself(){
+        RaftActorContext raftActorContext = createActorContext();
+        long expectedTerm = raftActorContext.getTermInformation().getCurrentTerm();
+
+        new Candidate(raftActorContext);
+
+        assertEquals(expectedTerm+1, raftActorContext.getTermInformation().getCurrentTerm());
+        assertEquals(raftActorContext.getId(), raftActorContext.getTermInformation().getVotedFor());
+    }
+
+    @Test
+    public void testThatAnElectionTimeoutIsTriggered(){
+        new JavaTestKit(getSystem()) {{
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    Candidate candidate = new Candidate(createActorContext(getTestActor()));
+
+                    final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"), "ElectionTimeout") {
+                        // do not put code outside this method, will run afterwards
+                        protected Boolean match(Object in) {
+                            if (in instanceof ElectionTimeout) {
+                                 return true;
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get();
+
+                    assertEquals(true, out);
+                }
+            };
+        }};
+    }
+
+    @Test
+    public void testHandleElectionTimeoutWhenThereAreZeroPeers(){
+        RaftActorContext raftActorContext = createActorContext();
+        Candidate candidate =
+            new Candidate(raftActorContext);
+
+        RaftState raftState =
+            candidate.handleMessage(candidateActor, new ElectionTimeout());
+
+        Assert.assertEquals(RaftState.Leader, raftState);
+    }
+
+    @Test
+    public void testHandleElectionTimeoutWhenThereAreTwoNodesInCluster(){
+        MockRaftActorContext raftActorContext =
+            (MockRaftActorContext) createActorContext();
+        raftActorContext.setPeerAddresses(onePeer);
+        Candidate candidate =
+            new Candidate(raftActorContext);
+
+        RaftState raftState =
+            candidate.handleMessage(candidateActor, new ElectionTimeout());
+
+        Assert.assertEquals(RaftState.Candidate, raftState);
+    }
+
+    @Test
+    public void testBecomeLeaderOnReceivingMajorityVotesInThreeNodesInCluster(){
+        MockRaftActorContext raftActorContext =
+            (MockRaftActorContext) createActorContext();
+        raftActorContext.setPeerAddresses(twoPeers);
+        Candidate candidate =
+            new Candidate(raftActorContext);
+
+        RaftState stateOnFirstVote = candidate.handleMessage(peerActor1, new RequestVoteReply(0, true));
+
+        Assert.assertEquals(RaftState.Leader, stateOnFirstVote);
+
+    }
+
+    @Test
+    public void testBecomeLeaderOnReceivingMajorityVotesInFiveNodesInCluster(){
+        MockRaftActorContext raftActorContext =
+            (MockRaftActorContext) createActorContext();
+        raftActorContext.setPeerAddresses(fourPeers);
+        Candidate candidate =
+            new Candidate(raftActorContext);
+
+        RaftState stateOnFirstVote = candidate.handleMessage(peerActor1, new RequestVoteReply(0, true));
+
+        RaftState stateOnSecondVote = candidate.handleMessage(peerActor2, new RequestVoteReply(0, true));
+
+        Assert.assertEquals(RaftState.Candidate, stateOnFirstVote);
+        Assert.assertEquals(RaftState.Leader, stateOnSecondVote);
+
+    }
+
+    @Test
+    public void testResponseToAppendEntriesWithLowerTerm(){
+        new JavaTestKit(getSystem()) {{
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    Candidate candidate = new Candidate(createActorContext(getTestActor()));
+
+                    candidate.handleMessage(getTestActor(), new AppendEntries(0, "test", 0,0,Collections.EMPTY_LIST, 0));
+
+                    final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"), "AppendEntriesResponse") {
+                        // do not put code outside this method, will run afterwards
+                        protected Boolean match(Object in) {
+                            if (in instanceof AppendEntriesReply) {
+                                AppendEntriesReply reply = (AppendEntriesReply) in;
+                                return reply.isSuccess();
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get();
+
+                    assertEquals(false, out);
+                }
+            };
+        }};
+    }
+
+    @Test
+    public void testResponseToRequestVoteWithLowerTerm(){
+        new JavaTestKit(getSystem()) {{
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    Candidate candidate = new Candidate(createActorContext(getTestActor()));
+
+                    candidate.handleMessage(getTestActor(), new RequestVote(0, "test", 0, 0));
+
+                    final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"), "AppendEntriesResponse") {
+                        // do not put code outside this method, will run afterwards
+                        protected Boolean match(Object in) {
+                            if (in instanceof RequestVoteReply) {
+                                RequestVoteReply reply = (RequestVoteReply) in;
+                                return reply.isVoteGranted();
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get();
+
+                    assertEquals(false, out);
+                }
+            };
+        }};
+    }
+
+    @Test
+    public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForIsNull(){
+        new JavaTestKit(getSystem()) {{
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    RaftActorContext context = createActorContext(getTestActor());
+
+                    context.getTermInformation().update(1000, null);
+
+                    // Once a candidate is created it will immediately increment the current term so after
+                    // construction the currentTerm should be 1001
+                    RaftActorBehavior follower = createBehavior(context);
+
+                    follower.handleMessage(getTestActor(), new RequestVote(1001, "test", 10000, 999));
+
+                    final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"), "RequestVoteReply") {
+                        // do not put code outside this method, will run afterwards
+                        protected Boolean match(Object in) {
+                            if (in instanceof RequestVoteReply) {
+                                RequestVoteReply reply = (RequestVoteReply) in;
+                                return reply.isVoteGranted();
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get();
+
+                    assertEquals(true, out);
+                }
+            };
+        }};
+    }
+
+    @Test
+    public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForIsNotTheSameAsCandidateId(){
+        new JavaTestKit(getSystem()) {{
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    RaftActorContext context = createActorContext(getTestActor());
+
+                    context.getTermInformation().update(1000, "test");
+
+                    RaftActorBehavior follower = createBehavior(context);
+
+                    follower.handleMessage(getTestActor(), new RequestVote(1001, "candidate", 10000, 999));
+
+                    final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"), "RequestVoteReply") {
+                        // do not put code outside this method, will run afterwards
+                        protected Boolean match(Object in) {
+                            if (in instanceof RequestVoteReply) {
+                                RequestVoteReply reply = (RequestVoteReply) in;
+                                return reply.isVoteGranted();
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get();
+
+                    assertEquals(false, out);
+                }
+            };
+        }};
+    }
+
+
+
+    @Override protected RaftActorBehavior createBehavior(RaftActorContext actorContext) {
+        return new Candidate(actorContext);
+    }
+
+    @Override protected RaftActorContext createActorContext() {
+        return new MockRaftActorContext("test", getSystem(), candidateActor);
+    }
+
+
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/FollowerTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/FollowerTest.java
new file mode 100644 (file)
index 0000000..c015d95
--- /dev/null
@@ -0,0 +1,410 @@
+package org.opendaylight.controller.cluster.raft.behaviors;
+
+import akka.actor.ActorRef;
+import akka.actor.Props;
+import akka.testkit.JavaTestKit;
+import junit.framework.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.raft.MockRaftActorContext;
+import org.opendaylight.controller.cluster.raft.RaftActorContext;
+import org.opendaylight.controller.cluster.raft.RaftState;
+import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
+import org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply;
+import org.opendaylight.controller.cluster.raft.messages.RequestVote;
+import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
+import org.opendaylight.controller.cluster.raft.utils.DoNothingActor;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class FollowerTest extends AbstractRaftActorBehaviorTest {
+
+    private final ActorRef followerActor = getSystem().actorOf(Props.create(
+        DoNothingActor.class));
+
+
+    @Override protected RaftActorBehavior createBehavior(RaftActorContext actorContext) {
+        return new Follower(actorContext);
+    }
+
+    @Override protected RaftActorContext createActorContext() {
+        return new MockRaftActorContext("test", getSystem(), followerActor);
+    }
+
+    @Test
+    public void testThatAnElectionTimeoutIsTriggered(){
+        new JavaTestKit(getSystem()) {{
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    Follower follower = new Follower(createActorContext(getTestActor()));
+
+                    final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"), "ElectionTimeout") {
+                        // do not put code outside this method, will run afterwards
+                        protected Boolean match(Object in) {
+                            if (in instanceof ElectionTimeout) {
+                                return true;
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get();
+
+                    assertEquals(true, out);
+                }
+            };
+        }};
+    }
+
+    @Test
+    public void testHandleElectionTimeout(){
+        RaftActorContext raftActorContext = createActorContext();
+        Follower follower =
+            new Follower(raftActorContext);
+
+        RaftState raftState =
+            follower.handleMessage(followerActor, new ElectionTimeout());
+
+        Assert.assertEquals(RaftState.Candidate, raftState);
+    }
+
+    @Test
+    public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForIsNull(){
+        new JavaTestKit(getSystem()) {{
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    RaftActorContext context = createActorContext(getTestActor());
+
+                    context.getTermInformation().update(1000, null);
+
+                    RaftActorBehavior follower = createBehavior(context);
+
+                    follower.handleMessage(getTestActor(), new RequestVote(1000, "test", 10000, 999));
+
+                    final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"), "RequestVoteReply") {
+                        // do not put code outside this method, will run afterwards
+                        protected Boolean match(Object in) {
+                            if (in instanceof RequestVoteReply) {
+                                RequestVoteReply reply = (RequestVoteReply) in;
+                                return reply.isVoteGranted();
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get();
+
+                    assertEquals(true, out);
+                }
+            };
+        }};
+    }
+
+    @Test
+    public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForIsNotTheSameAsCandidateId(){
+        new JavaTestKit(getSystem()) {{
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    RaftActorContext context = createActorContext(getTestActor());
+
+                    context.getTermInformation().update(1000, "test");
+
+                    RaftActorBehavior follower = createBehavior(context);
+
+                    follower.handleMessage(getTestActor(), new RequestVote(1000, "candidate", 10000, 999));
+
+                    final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"), "RequestVoteReply") {
+                        // do not put code outside this method, will run afterwards
+                        protected Boolean match(Object in) {
+                            if (in instanceof RequestVoteReply) {
+                                RequestVoteReply reply = (RequestVoteReply) in;
+                                return reply.isVoteGranted();
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get();
+
+                    assertEquals(false, out);
+                }
+            };
+        }};
+    }
+
+    /**
+     * This test verifies that when an AppendEntries RPC is received by a RaftActor
+     * with a commitIndex that is greater than what has been applied to the
+     * state machine of the RaftActor, the RaftActor applies the state and
+     * sets it current applied state to the commitIndex of the sender.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testHandleAppendEntriesWithNewerCommitIndex() throws Exception {
+        new JavaTestKit(getSystem()) {{
+
+            RaftActorContext context =
+                createActorContext();
+
+            context.setLastApplied(100);
+            setLastLogEntry((MockRaftActorContext) context, 0, 0, new MockRaftActorContext.MockPayload(""));
+
+            List<ReplicatedLogEntry> entries =
+                Arrays.asList(
+                    (ReplicatedLogEntry) new MockRaftActorContext.MockReplicatedLogEntry(100, 101,
+                        new MockRaftActorContext.MockPayload("foo"))
+                );
+
+            // The new commitIndex is 101
+            AppendEntries appendEntries =
+                new AppendEntries(100, "leader-1", 0, 0, entries, 101);
+
+            RaftState raftState =
+                createBehavior(context).handleMessage(getRef(), appendEntries);
+
+            assertEquals(101L, context.getLastApplied());
+
+        }};
+    }
+
+    /**
+     * This test verifies that when an AppendEntries is received a specific prevLogTerm
+     * which does not match the term that is in RaftActors log entry at prevLogIndex
+     * then the RaftActor does not change it's state and it returns a failure.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testHandleAppendEntriesSenderPrevLogTermNotSameAsReceiverPrevLogTerm()
+        throws Exception {
+        new JavaTestKit(getSystem()) {{
+
+            MockRaftActorContext context = (MockRaftActorContext)
+                createActorContext();
+
+            // First set the receivers term to lower number
+            context.getTermInformation().update(95, "test");
+
+            // Set the last log entry term for the receiver to be greater than
+            // what we will be sending as the prevLogTerm in AppendEntries
+            MockRaftActorContext.SimpleReplicatedLog mockReplicatedLog =
+                setLastLogEntry(context, 20, 0, new MockRaftActorContext.MockPayload(""));
+
+            // AppendEntries is now sent with a bigger term
+            // this will set the receivers term to be the same as the sender's term
+            AppendEntries appendEntries =
+                new AppendEntries(100, "leader-1", 0, 0, null, 101);
+
+            RaftActorBehavior behavior = createBehavior(context);
+
+            // Send an unknown message so that the state of the RaftActor remains unchanged
+            RaftState expected = behavior.handleMessage(getRef(), "unknown");
+
+            RaftState raftState =
+                behavior.handleMessage(getRef(), appendEntries);
+
+            assertEquals(expected, raftState);
+
+            // Also expect an AppendEntriesReply to be sent where success is false
+            final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"),
+                "AppendEntriesReply") {
+                // do not put code outside this method, will run afterwards
+                protected Boolean match(Object in) {
+                    if (in instanceof AppendEntriesReply) {
+                        AppendEntriesReply reply = (AppendEntriesReply) in;
+                        return reply.isSuccess();
+                    } else {
+                        throw noMatch();
+                    }
+                }
+            }.get();
+
+            assertEquals(false, out);
+
+
+        }};
+    }
+
+
+
+    /**
+     * This test verifies that when a new AppendEntries message is received with
+     * new entries and the logs of the sender and receiver match that the new
+     * entries get added to the log and the log is incremented by the number of
+     * entries received in appendEntries
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testHandleAppendEntriesAddNewEntries() throws Exception {
+        new JavaTestKit(getSystem()) {{
+
+            MockRaftActorContext context = (MockRaftActorContext)
+                createActorContext();
+
+            // First set the receivers term to lower number
+            context.getTermInformation().update(1, "test");
+
+            // Prepare the receivers log
+            MockRaftActorContext.SimpleReplicatedLog log =
+                new MockRaftActorContext.SimpleReplicatedLog();
+            log.append(
+                new MockRaftActorContext.MockReplicatedLogEntry(1, 0, new MockRaftActorContext.MockPayload("zero")));
+            log.append(
+                new MockRaftActorContext.MockReplicatedLogEntry(1, 1, new MockRaftActorContext.MockPayload("one")));
+            log.append(
+                new MockRaftActorContext.MockReplicatedLogEntry(1, 2, new MockRaftActorContext.MockPayload("two")));
+
+            context.setReplicatedLog(log);
+
+            // Prepare the entries to be sent with AppendEntries
+            List<ReplicatedLogEntry> entries = new ArrayList<>();
+            entries.add(
+                new MockRaftActorContext.MockReplicatedLogEntry(1, 3, new MockRaftActorContext.MockPayload("three")));
+            entries.add(
+                new MockRaftActorContext.MockReplicatedLogEntry(1, 4, new MockRaftActorContext.MockPayload("four")));
+
+            // Send appendEntries with the same term as was set on the receiver
+            // before the new behavior was created (1 in this case)
+            // This will not work for a Candidate because as soon as a Candidate
+            // is created it increments the term
+            AppendEntries appendEntries =
+                new AppendEntries(1, "leader-1", 2, 1, entries, 4);
+
+            RaftActorBehavior behavior = createBehavior(context);
+
+            // Send an unknown message so that the state of the RaftActor remains unchanged
+            RaftState expected = behavior.handleMessage(getRef(), "unknown");
+
+            RaftState raftState =
+                behavior.handleMessage(getRef(), appendEntries);
+
+            assertEquals(expected, raftState);
+            assertEquals(5, log.last().getIndex() + 1);
+            assertNotNull(log.get(3));
+            assertNotNull(log.get(4));
+
+            // Also expect an AppendEntriesReply to be sent where success is false
+            final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"),
+                "AppendEntriesReply") {
+                // do not put code outside this method, will run afterwards
+                protected Boolean match(Object in) {
+                    if (in instanceof AppendEntriesReply) {
+                        AppendEntriesReply reply = (AppendEntriesReply) in;
+                        return reply.isSuccess();
+                    } else {
+                        throw noMatch();
+                    }
+                }
+            }.get();
+
+            assertEquals(true, out);
+
+
+        }};
+    }
+
+
+
+    /**
+     * This test verifies that when a new AppendEntries message is received with
+     * new entries and the logs of the sender and receiver are out-of-sync that
+     * the log is first corrected by removing the out of sync entries from the
+     * log and then adding in the new entries sent with the AppendEntries message
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testHandleAppendEntriesCorrectReceiverLogEntries()
+        throws Exception {
+        new JavaTestKit(getSystem()) {{
+
+            MockRaftActorContext context = (MockRaftActorContext)
+                createActorContext();
+
+            // First set the receivers term to lower number
+            context.getTermInformation().update(2, "test");
+
+            // Prepare the receivers log
+            MockRaftActorContext.SimpleReplicatedLog log =
+                new MockRaftActorContext.SimpleReplicatedLog();
+            log.append(
+                new MockRaftActorContext.MockReplicatedLogEntry(1, 0, new MockRaftActorContext.MockPayload("zero")));
+            log.append(
+                new MockRaftActorContext.MockReplicatedLogEntry(1, 1, new MockRaftActorContext.MockPayload("one")));
+            log.append(
+                new MockRaftActorContext.MockReplicatedLogEntry(1, 2, new MockRaftActorContext.MockPayload("two")));
+
+            context.setReplicatedLog(log);
+
+            // Prepare the entries to be sent with AppendEntries
+            List<ReplicatedLogEntry> entries = new ArrayList<>();
+            entries.add(
+                new MockRaftActorContext.MockReplicatedLogEntry(2, 2, new MockRaftActorContext.MockPayload("two-1")));
+            entries.add(
+                new MockRaftActorContext.MockReplicatedLogEntry(2, 3, new MockRaftActorContext.MockPayload("three")));
+
+            // Send appendEntries with the same term as was set on the receiver
+            // before the new behavior was created (1 in this case)
+            // This will not work for a Candidate because as soon as a Candidate
+            // is created it increments the term
+            AppendEntries appendEntries =
+                new AppendEntries(2, "leader-1", 1, 1, entries, 3);
+
+            RaftActorBehavior behavior = createBehavior(context);
+
+            // Send an unknown message so that the state of the RaftActor remains unchanged
+            RaftState expected = behavior.handleMessage(getRef(), "unknown");
+
+            RaftState raftState =
+                behavior.handleMessage(getRef(), appendEntries);
+
+            assertEquals(expected, raftState);
+
+            // The entry at index 2 will be found out-of-sync with the leader
+            // and will be removed
+            // Then the two new entries will be added to the log
+            // Thus making the log to have 4 entries
+            assertEquals(4, log.last().getIndex() + 1);
+            assertNotNull(log.get(2));
+
+            assertEquals("one", log.get(1).getData().toString());
+
+            // Check that the entry at index 2 has the new data
+            assertEquals("two-1", log.get(2).getData().toString());
+
+            assertEquals("three", log.get(3).getData().toString());
+
+            assertNotNull(log.get(3));
+
+            // Also expect an AppendEntriesReply to be sent where success is false
+            final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"),
+                "AppendEntriesReply") {
+                // do not put code outside this method, will run afterwards
+                protected Boolean match(Object in) {
+                    if (in instanceof AppendEntriesReply) {
+                        AppendEntriesReply reply = (AppendEntriesReply) in;
+                        return reply.isSuccess();
+                    } else {
+                        throw noMatch();
+                    }
+                }
+            }.get();
+
+            assertEquals(true, out);
+
+
+        }};
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/LeaderTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/LeaderTest.java
new file mode 100644 (file)
index 0000000..d33b339
--- /dev/null
@@ -0,0 +1,203 @@
+package org.opendaylight.controller.cluster.raft.behaviors;
+
+import akka.actor.ActorRef;
+import akka.actor.Props;
+import akka.testkit.JavaTestKit;
+import junit.framework.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.raft.MockRaftActorContext;
+import org.opendaylight.controller.cluster.raft.RaftActorContext;
+import org.opendaylight.controller.cluster.raft.RaftState;
+import org.opendaylight.controller.cluster.raft.base.messages.ApplyState;
+import org.opendaylight.controller.cluster.raft.base.messages.Replicate;
+import org.opendaylight.controller.cluster.raft.base.messages.SendHeartBeat;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
+import org.opendaylight.controller.cluster.raft.utils.DoNothingActor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+public class LeaderTest extends AbstractRaftActorBehaviorTest {
+
+    private ActorRef leaderActor =
+        getSystem().actorOf(Props.create(DoNothingActor.class));
+    private ActorRef senderActor =
+        getSystem().actorOf(Props.create(DoNothingActor.class));
+
+    @Test
+    public void testHandleMessageForUnknownMessage() throws Exception {
+        new JavaTestKit(getSystem()) {{
+            Leader leader =
+                new Leader(createActorContext());
+
+            // handle message should return the Leader state when it receives an
+            // unknown message
+            RaftState state = leader.handleMessage(senderActor, "foo");
+            Assert.assertEquals(RaftState.Leader, state);
+        }};
+    }
+
+
+    @Test
+    public void testThatLeaderSendsAHeartbeatMessageToAllFollowers() {
+        new JavaTestKit(getSystem()) {{
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    ActorRef followerActor = getTestActor();
+
+                    MockRaftActorContext actorContext =
+                        (MockRaftActorContext) createActorContext();
+
+                    Map<String, String> peerAddresses = new HashMap();
+
+                    peerAddresses.put(followerActor.path().toString(),
+                        followerActor.path().toString());
+
+                    actorContext.setPeerAddresses(peerAddresses);
+
+                    Leader leader = new Leader(actorContext);
+                    leader.handleMessage(senderActor, new SendHeartBeat());
+
+                    final String out =
+                        new ExpectMsg<String>(duration("1 seconds"), "match hint") {
+                            // do not put code outside this method, will run afterwards
+                            protected String match(Object in) {
+                                Object msg = fromSerializableMessage(in);
+                                if (msg instanceof AppendEntries) {
+                                    if (((AppendEntries)msg).getTerm() == 0) {
+                                        return "match";
+                                    }
+                                    return null;
+                                } else {
+                                    throw noMatch();
+                                }
+                            }
+                        }.get(); // this extracts the received message
+
+                    assertEquals("match", out);
+
+                }
+
+
+            };
+        }};
+    }
+
+    @Test
+    public void testHandleReplicateMessageSendAppendEntriesToFollower() {
+        new JavaTestKit(getSystem()) {{
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    ActorRef followerActor = getTestActor();
+
+                    MockRaftActorContext actorContext =
+                        (MockRaftActorContext) createActorContext();
+
+                    Map<String, String> peerAddresses = new HashMap();
+
+                    peerAddresses.put(followerActor.path().toString(),
+                        followerActor.path().toString());
+
+                    actorContext.setPeerAddresses(peerAddresses);
+
+                    Leader leader = new Leader(actorContext);
+                    RaftState raftState = leader
+                        .handleMessage(senderActor, new Replicate(null, null,
+                            new MockRaftActorContext.MockReplicatedLogEntry(1,
+                                100,
+                                new MockRaftActorContext.MockPayload("foo"))
+                        ));
+
+                    // State should not change
+                    assertEquals(RaftState.Leader, raftState);
+
+                    final String out =
+                        new ExpectMsg<String>(duration("1 seconds"), "match hint") {
+                            // do not put code outside this method, will run afterwards
+                            protected String match(Object in) {
+                                Object msg = fromSerializableMessage(in);
+                                if (msg instanceof AppendEntries) {
+                                    if (((AppendEntries)msg).getTerm() == 0) {
+                                        return "match";
+                                    }
+                                    return null;
+                                } else {
+                                    throw noMatch();
+                                }
+                            }
+                        }.get(); // this extracts the received message
+
+                    assertEquals("match", out);
+
+                }
+
+
+            };
+        }};
+    }
+
+    @Test
+    public void testHandleReplicateMessageWhenThereAreNoFollowers() {
+        new JavaTestKit(getSystem()) {{
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    ActorRef raftActor = getTestActor();
+
+                    MockRaftActorContext actorContext =
+                        new MockRaftActorContext("test", getSystem(), raftActor);
+
+                    Leader leader = new Leader(actorContext);
+                    RaftState raftState = leader
+                        .handleMessage(senderActor, new Replicate(null, "state-id",
+                            new MockRaftActorContext.MockReplicatedLogEntry(1,
+                                100,
+                                new MockRaftActorContext.MockPayload("foo"))
+                        ));
+
+                    // State should not change
+                    assertEquals(RaftState.Leader, raftState);
+
+                    assertEquals(100, actorContext.getCommitIndex());
+
+                    final String out =
+                        new ExpectMsg<String>(duration("1 seconds"),
+                            "match hint") {
+                            // do not put code outside this method, will run afterwards
+                            protected String match(Object in) {
+                                if (in instanceof ApplyState) {
+                                    if (((ApplyState) in).getIdentifier().equals("state-id")) {
+                                        return "match";
+                                    }
+                                    return null;
+                                } else {
+                                    throw noMatch();
+                                }
+                            }
+                        }.get(); // this extracts the received message
+
+                    assertEquals("match", out);
+
+                }
+
+
+            };
+        }};
+    }
+
+    @Override protected RaftActorBehavior createBehavior(
+        RaftActorContext actorContext) {
+        return new Leader(actorContext);
+    }
+
+    @Override protected RaftActorContext createActorContext() {
+        return new MockRaftActorContext("test", getSystem(), leaderActor);
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/protobuff/messages/MockPayloadMessages.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/protobuff/messages/MockPayloadMessages.java
new file mode 100644 (file)
index 0000000..1f618a3
--- /dev/null
@@ -0,0 +1,57 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: MockPayload.proto
+
+package org.opendaylight.controller.cluster.raft.protobuff.messages;
+
+public final class MockPayloadMessages {
+  private MockPayloadMessages() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registry.add(org.opendaylight.controller.cluster.raft.protobuff.messages.MockPayloadMessages.value);
+  }
+  public static final int VALUE_FIELD_NUMBER = 2;
+  /**
+   * <code>extend .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload { ... }</code>
+   */
+  public static final
+    com.google.protobuf.GeneratedMessage.GeneratedExtension<
+      org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload,
+      java.lang.String> value = com.google.protobuf.GeneratedMessage
+          .newFileScopedGeneratedExtension(
+        java.lang.String.class,
+        null);
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\021MockPayload.proto\022(org.opendaylight.co" +
+      "ntroller.cluster.raft\032\033AppendEntriesMess" +
+      "ages.proto:a\n\005value\022R.org.opendaylight.c" +
+      "ontroller.cluster.raft.AppendEntries.Rep" +
+      "licatedLogEntry.Payload\030\002 \001(\tBR\n;org.ope" +
+      "ndaylight.controller.cluster.raft.protob" +
+      "uff.messagesB\023MockPayloadMessages"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          value.internalInit(descriptor.getExtensions().get(0));
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.getDescriptor(),
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/utils/DoNothingActor.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/utils/DoNothingActor.java
new file mode 100644 (file)
index 0000000..741c473
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.utils;
+
+import akka.actor.UntypedActor;
+
+public class DoNothingActor extends UntypedActor{
+    @Override public void onReceive(Object message) throws Exception {
+
+    }
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/resources/MockPayload.proto b/opendaylight/md-sal/sal-akka-raft/src/test/resources/MockPayload.proto
new file mode 100644 (file)
index 0000000..0e0c604
--- /dev/null
@@ -0,0 +1,10 @@
+import "AppendEntriesMessages.proto";
+
+package org.opendaylight.controller.cluster.raft;
+
+option java_package = "org.opendaylight.controller.cluster.raft.protobuff.messages";
+option java_outer_classname = "MockPayloadMessages";
+
+extend AppendEntries.ReplicatedLogEntry.Payload {
+    optional string value = 2;
+}
diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/resources/application.conf b/opendaylight/md-sal/sal-akka-raft/src/test/resources/application.conf
new file mode 100644 (file)
index 0000000..dbe7508
--- /dev/null
@@ -0,0 +1,20 @@
+akka {
+
+    loglevel = "DEBUG"
+
+    actor {
+        # enable to test serialization only.
+        serialize-messages = on
+
+        serializers {
+          java  = "akka.serialization.JavaSerializer"
+          proto = "akka.remote.serialization.ProtobufSerializer"
+        }
+
+        serialization-bindings {
+            "org.opendaylight.controller.cluster.raft.ReplicatedLogImplEntry" = java
+            "com.google.protobuf.Message" = proto
+            "com.google.protobuf.GeneratedMessage" = proto
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/BindingTransactionChain.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/BindingTransactionChain.java
new file mode 100644 (file)
index 0000000..24ec89e
--- /dev/null
@@ -0,0 +1,18 @@
+package org.opendaylight.controller.md.sal.binding.api;
+
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public interface BindingTransactionChain extends TransactionFactory, TransactionChain<InstanceIdentifier<?>, DataObject> {
+
+    @Override
+    ReadOnlyTransaction newReadOnlyTransaction();
+
+    @Override
+    ReadWriteTransaction newReadWriteTransaction();
+
+    @Override
+    WriteTransaction newWriteOnlyTransaction();
+
+}
index 0b3658a6a6b6e7b112fb89e0d9a0d1cc2ae5aa54..619a08eac5f30a6f3a7ff7f5f154b1be4c74bdbc 100644 (file)
@@ -9,6 +9,8 @@ package org.opendaylight.controller.md.sal.binding.api;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainFactory;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -19,7 +21,8 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
  * <p>
  * For more information on usage, please see the documentation in {@link AsyncDataBroker}.
  */
-public interface DataBroker extends AsyncDataBroker<InstanceIdentifier<?>, DataObject, DataChangeListener>, BindingService {
+public interface DataBroker extends TransactionFactory, AsyncDataBroker<InstanceIdentifier<?>, DataObject, DataChangeListener>, BindingService, TransactionChainFactory<InstanceIdentifier<?>, DataObject> {
+
     @Override
     ReadOnlyTransaction newReadOnlyTransaction();
 
@@ -32,4 +35,7 @@ public interface DataBroker extends AsyncDataBroker<InstanceIdentifier<?>, DataO
     @Override
     ListenerRegistration<DataChangeListener> registerDataChangeListener(LogicalDatastoreType store,
             InstanceIdentifier<?> path, DataChangeListener listener, DataChangeScope triggeringScope);
+
+    @Override
+    BindingTransactionChain createTransactionChain(TransactionChainListener listener);
 }
diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/MountPoint.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/MountPoint.java
new file mode 100644 (file)
index 0000000..ee0a113
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.api;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareService;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+
+public interface MountPoint extends Identifiable<InstanceIdentifier<?>>{
+
+    <T extends BindingAwareService> Optional<T> getService(Class<T> service);
+
+}
diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/MountPointService.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/MountPointService.java
new file mode 100644 (file)
index 0000000..dd3a37e
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.api;
+
+import java.util.EventListener;
+
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+
+public interface MountPointService {
+
+    Optional<MountPoint> getMountPoint(InstanceIdentifier<?> mountPoint);
+
+    <T extends MountPointListener> ListenerRegistration<T> registerListener(InstanceIdentifier<?> path, T listener);
+
+
+    public interface MountPointListener extends EventListener {
+
+        void onMountPointCreated(InstanceIdentifier<?> path);
+
+        void onMountPointRemoved(InstanceIdentifier<?> path);
+
+    }
+
+}
index a7b5f3295778c4f758e1c23785f3ef9fef9426bd..cc85d4337b93d5b1a2322af009052b7c26091bd8 100644 (file)
@@ -15,7 +15,32 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
 
+/**
+ * A transaction that provides read access to a logical data store.
+ * <p>
+ * For more information on usage and examples, please see the documentation in {@link AsyncReadTransaction}.
+ */
 public interface ReadTransaction extends AsyncReadTransaction<InstanceIdentifier<?>, DataObject> {
-    @Override
-    ListenableFuture<Optional<DataObject>> read(LogicalDatastoreType store, InstanceIdentifier<?> path);
+
+    /**
+     * Reads data from the provided logical data store located at the provided path.
+     *<p>
+     * If the target is a subtree, then the whole subtree is read (and will be
+     * accessible from the returned data object).
+     *
+     * @param store
+     *            Logical data store from which read should occur.
+     * @param path
+     *            Path which uniquely identifies subtree which client want to
+     *            read
+     * @return Listenable Future which contains read result
+     *         <ul>
+     *         <li>If data at supplied path exists the
+     *         {@link ListeblaFuture#get()} returns Optional object containing
+     *         data once read is done.
+     *         <li>If data at supplied path does not exists the
+     *         {@link ListenbleFuture#get()} returns {@link Optional#absent()}.
+     *         </ul>
+     */
+    <T extends DataObject> ListenableFuture<Optional<T>> read(LogicalDatastoreType store, InstanceIdentifier<T> path);
 }
diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/TransactionFactory.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/TransactionFactory.java
new file mode 100644 (file)
index 0000000..4483cf9
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.api;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataTransactionFactory;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public interface TransactionFactory extends AsyncDataTransactionFactory<InstanceIdentifier<?>, DataObject>{
+
+    @Override
+    ReadOnlyTransaction newReadOnlyTransaction();
+
+    @Override
+    ReadWriteTransaction newReadWriteTransaction();
+
+    @Override
+    WriteTransaction newWriteOnlyTransaction();
+
+}
index 0cef81d35922650357ee4bd7e502b5c79f11a3f8..a6ba2e2799b99f884c119dae6ef67e44bd85a562 100644 (file)
@@ -18,8 +18,110 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
  * For more information on usage and examples, please see the documentation in {@link AsyncWriteTransaction}.
  */
 public interface WriteTransaction extends AsyncWriteTransaction<InstanceIdentifier<?>, DataObject> {
-    @Override
-    void put(LogicalDatastoreType store, InstanceIdentifier<?> path, DataObject data);
+
+    /**
+     * Stores a piece of data at the specified path. This acts as an add / replace
+     * operation, which is to say that whole subtree will be replaced by the specified data.
+     * * <p>
+     * This method does not automatically create missing parent nodes. It is equivalent to invoking
+     * {@link #put(LogicalDatastoreType, InstanceIdentifier, DataObject, boolean)}
+     * with <code>createMissingParents</code> set to false.
+     * <p>
+     * For more information on usage and examples, please see the documentation in {@link AsyncWriteTransaction}.
+     * <p>
+     * If you need to make sure that a parent object exists but you do not want modify
+     * its pre-existing state by using put, consider using {@link #merge} instead.
+     *
+     * @param store
+     *            the logical data store which should be modified
+     * @param path
+     *            the data object path
+     * @param data
+     *            the data object to be written to the specified path
+     * @throws IllegalStateException
+     *             if the transaction has already been submitted
+     */
+    <T extends DataObject> void put(LogicalDatastoreType store, InstanceIdentifier<T> path, T data);
+
+
+    /**
+     * Stores a piece of data at the specified path. This acts as an add /
+     * replace operation, which is to say that whole subtree will be replaced by
+     * the specified data.
+     * <p>
+     * For more information on usage and examples, please see the documentation
+     * in {@link AsyncWriteTransaction}.
+     * <p>
+     * If you need to make sure that a parent object exists but you do not want
+     * modify its pre-existing state by using put, consider using {@link #merge}
+     * instead.
+     *
+     * Note: Using <code>createMissingParents</code> with value true, may
+     * introduce garbage in data store, or recreate nodes, which were deleted by
+     * previous transaction.
+     *
+     * @param store
+     *            the logical data store which should be modified
+     * @param path
+     *            the data object path
+     * @param data
+     *            the data object to be written to the specified path
+     * @param createMissingParents
+     *            if true, any missing parent nodes will be automatically
+     *            created using a merge operation.
+     * @throws IllegalStateException
+     *             if the transaction has already been submitted
+     */
+    <T extends DataObject> void put(LogicalDatastoreType store, InstanceIdentifier<T> path, T data,
+            boolean createMissingParents);
+
+    /**
+     * Merges a piece of data with the existing data at a specified path. Any pre-existing data
+     * which is not explicitly overwritten will be preserved. This means that if you store a container,
+     * its child lists will be merged.
+     * <p>
+     * This method does not automatically create missing parent nodes. It is equivalent to invoking
+     * {@link #merge(LogicalDatastoreType, InstanceIdentifier, DataObject, boolean)}
+     * with <code>createMissingParents</code> set to false.
+     * <p>
+     * For more information on usage and examples, please see the documentation in {@link AsyncWriteTransaction}.
+     *<p>
+     * If you require an explicit replace operation, use {@link #put} instead.
+     * @param store
+     *            the logical data store which should be modified
+     * @param path
+     *            the data object path
+     * @param data
+     *            the data object to be merged to the specified path
+     * @throws IllegalStateException
+     *             if the transaction has already been submitted
+     */
+    <T extends DataObject> void merge(LogicalDatastoreType store, InstanceIdentifier<T> path, T data);
+
+    /**
+     * Merges a piece of data with the existing data at a specified path. Any
+     * pre-existing data which is not explicitly overwritten will be preserved.
+     * This means that if you store a container, its child lists will be merged.
+     * <p>
+     * For more information on usage and examples, please see the documentation
+     * in {@link AsyncWriteTransaction}.
+     * <p>
+     * If you require an explicit replace operation, use {@link #put} instead.
+     *
+     * @param store
+     *            the logical data store which should be modified
+     * @param path
+     *            the data object path
+     * @param data
+     *            the data object to be merged to the specified path
+     * @param createMissingParents
+     *            if true, any missing parent nodes will be automatically created
+     *            using a merge operation.
+     * @throws IllegalStateException
+     *             if the transaction has already been submitted
+     */
+    <T extends DataObject> void merge(LogicalDatastoreType store, InstanceIdentifier<T> path, T data,
+            boolean createMissingParents);
 
     @Override
     void delete(LogicalDatastoreType store, InstanceIdentifier<?> path);
index 453ff449118ffab0898f429cb02c8ec0ca8ed5ff..5e24560853e733c42744512366721a4d8b12823c 100644 (file)
@@ -156,11 +156,29 @@ public interface BindingAwareBroker {
         void unregisterFunctionality(ProviderFunctionality functionality);
     }
 
+    /**
+     * Represents an RPC implementation registration. Users should call the
+     * {@link ObjectRegistration#close close} method when the registration is no longer needed.
+     *
+     * @param <T> the implemented RPC service interface
+     */
     public interface RpcRegistration<T extends RpcService> extends ObjectRegistration<T> {
 
+        /**
+         * Returns the implemented RPC service interface.
+         */
         Class<T> getServiceType();
+
+        @Override
+        void close();
     }
 
+    /**
+     * Represents a routed RPC implementation registration. Users should call the
+     * {@link RoutedRegistration#close close} method when the registration is no longer needed.
+     *
+     * @param <T> the implemented RPC service interface
+     */
     public interface RoutedRpcRegistration<T extends RpcService> extends RpcRegistration<T>,
             RoutedRegistration<Class<? extends BaseIdentity>, InstanceIdentifier<?>, T> {
 
index 4327451d2126fa51b6a3a7767e0c2fbd0781703c..bcbd6879d037d12a27c2781ab46f02887c571dff 100644 (file)
@@ -10,17 +10,64 @@ package org.opendaylight.controller.sal.binding.api;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
 
 /**
- *
- * Defines the component of controller and supplies additional metadata. A
- * component of the controller or application supplies a concrete implementation
- * of this interface.
- *
- * A user-implemented component (application) which facilitates the SAL and SAL
- * services to access infrastructure services or providers' functionality.
- *
- *
- *
- */
+*
+* A developer implemented component that gets registered with the Broker.
+*
+* Semantically, a consumer may:
+*
+* <ol>
+*   <li>Subscribe for Notifications </li>
+*   <li>Invoke RPCs</li>
+*   <li>Read from either the operational or config data tree</li>
+*   <li>Write to the config data tree</li>
+* </ol>
+* If you need to:
+* <ol>
+*   <li> Emit Notifications</li>
+*   <li> Provide the implementation of RPCs </li>
+*   <li> Write to the operational data tree </li>
+* </ol>
+*
+* Consider using a BindingAwareProvider
+*
+* Examples:
+*
+* To get a NotificationService:
+*
+* {code
+* public void onSessionInitiated(ProviderContext session) {
+*      NotificationProviderService notificationService = session.getSALService(NotificationProviderService.class);
+*      notificationService.publish(notification)
+* }
+* where notification is an instance of a modeled Notification.
+* For more information on sending notifications via the NotificationProviderService
+* @see org.opendaylight.controller.sal.binding.api.NotificationProviderService
+*
+*
+* A consumer can *invoke* and RPC ( ie, call foo(fooArgs)) but it cannot register an RPC
+* implementation with the MD-SAL that others can invoke(call).
+* To get an invokable RPC:
+*
+* {code
+* public void onSessionInitiated(ProviderContext session) {
+*    MyService rpcFlowSalService = session.getRpcService(MyService.class);
+* }
+*
+* Where MyService.class is a Service interface generated from a yang model with RPCs modeled in it.  The returned
+* rpcFlowSalService can be used like any other object by invoking its methods.  Note, nothing special needs to be done
+* for RoutedRPCs.  They just work.
+*
+* To get a DataBroker to allow access to the data tree:
+*
+* {code
+* public void onSessionInitiated(final ProviderContext session) {
+*      DataBroker databroker = session.getSALService(BindingDataBroker.class);
+* }
+* }
+* @see org.opendaylight.controller.md.sal.common.api.data.BindingDataBroker
+* for more info on using the DataBroker.
+*
+*/
 public interface BindingAwareConsumer {
 
     /**
index 0812e5f53c3d9193cbafaae8acabaaa06be3b880..cb26cad2f392cacc01757cd6c8bdff1b29920cad 100644 (file)
@@ -15,37 +15,131 @@ import org.opendaylight.yangtools.yang.binding.RpcService;
 
 /**
  *
- * Defines the component of controller and supplies additional metadata. A
- * component of the controller or application supplies a concrete implementation
- * of this interface.
+ * A developer implemented component that gets registered with the Broker.
  *
+ * Semantically, a provider may:
+ *
+ * <ol>
+ *   <li> Emit Notifications</li>
+ *   <li> Provide the implementation of RPCs </li>
+ *   <li> Write to the operational data tree </li>
+ * </ol>
+ *
+ * If a class is not doing at least one of those three, consider using
+ * a BindingAwareConsumer instead:
+ * @see org.opendaylight.controller.sal.binding.api.BindingAwareConsumer
+ *
+ * <p>
+ *
+ *In addition, a BindingAwareProvider can in pursuit of its goals:
+ *
+ * <ol>
+ *   <li>Subscribe for Notifications </li>
+ *   <li>Invoke RPCs</li>
+ *   <li>Read from either the operational or config data tree</li>
+ *   <li>Write to the config data tree</li>
+ * </ol>
+ * (All of the above are things a Consumer can also do).
+ *
+ *<p>
+ *
+ * Examples:
+ *
+ *<p>
+ *
+ * To get a NotificationService:
+ *
+ * {code
+ * public void onSessionInitiated(ProviderContext session) {
+ *      NotificationProviderService notificationService = session.getSALService(NotificationProviderService.class);
+ * }
+ * For more information on sending notifications via the NotificationProviderService
+ * @see org.opendaylight.controller.sal.binding.api.NotificationProviderService
+ *
+ * To register an RPC implementation:
+ *
+ * {code
+ * public void onSessionInitiated(ProviderContext session) {
+ *    RpcRegistration<MyService> registration = session.addRpcImplementation(MyService.class, myImplementationInstance);
+ * }
+ *
+ * <p>
+ *
+ * Where MyService.class is a Service interface generated from a yang model with RPCs modeled in it and myImplementationInstance
+ * is an instance of a class that implements MyService.
+ *
+ * To register a Routed RPC Implementation:
+ * {code
+ * public void onSessionInitiated(ProviderContext session) {
+ *   RoutedRpcRegistration<SalFlowService> flowRegistration = session.addRoutedRpcImplementation(SalFlowService.class, salFlowServiceImplementationInstance);
+     flowRegistration.registerPath(NodeContext.class, nodeInstanceId);
+ * }
+ * }
+ *
+ * Where SalFlowService.class is a Service interface generated from a yang model with RPCs modeled in it and salFlowServiceImplementationInstance is an instance
+ * of a class that implements SalFlowService.
  * <p>
- * A user-implemented component (application) which facilitates the SAL and SAL
- * services to access infrastructure services and to provide functionality to
- * {@link Consumer}s and other providers.
+ * The line:
+ * {code
+ * flowRegistration.registerPath(NodeContext.class, nodeInstanceId);
+ * }
+ * Is indicating that the RPC implementation is registered to handle RPC invocations that have their NodeContext pointing to the node with instance id nodeInstanceId.
+ * This bears a bit of further explanation.  RoutedRPCs can be 'routed' to an implementation based upon 'context'.  'context' is a pointer (instanceId) to some place
+ * in the data tree.  In this example, the 'context' is a pointer to a Node.  In this way, a provider can register its ability to provide a service for a particular
+ * Node, but not *all* Nodes.  The Broker routes the RPC by 'context' to the correct implementation, without the caller having to do extra work.  Because of this when
+ * a RoutedRPC is registered, it needs to also be able to indicate for which 'contexts' it is providing an implementation.
+ *
+ * An example of a Routed RPC would be an updateFlow(node, flow) that would be routed based on node to the provider which had registered to provide
+ * it *for that node*.
+ *
+ *<p>
  *
+ * To get a DataBroker to allow access to the data tree:
+ *
+ * {code
+ * public void onSessionInitiated(final ProviderContext session) {
+ *      DataBroker databroker = session.getSALService(BindingDataBroker.class);
+ * }
+ * }
+ * @see org.opendaylight.controller.md.sal.common.api.data.BindingDataBroker
+ * for more info on using the DataBroker.
  *
  */
 public interface BindingAwareProvider {
 
     /**
-     * Returns a set of provided implementations of YANG modules and their rpcs.
+     * @deprecated
      *
+     * This interface was originally intended to solve problems of how to get Implementations
+     * of functionality from a provider, but that is no longer necessary because the Provider
+     * Registers RPCs in onSessionInitiated.
      *
-     * @return Set of provided implementation of YANG modules and their Rpcs
+     * Recommend:
+     * {code
+     * public Collection<? extends RpcService> getImplementations() {
+     *   return Collections.emptySet();
+     * }
+     * }
      */
+    @Deprecated
     Collection<? extends RpcService> getImplementations();
 
     /**
-     * Gets a set of implementations of provider functionality to be registered
-     * into system during the provider registration to the SAL.
+     * @deprecated
      *
-     * <p>
-     * This method is invoked by {@link Broker#registerProvider(Provider)} to
-     * learn the initial provided functionality
+     * This interface was originally intended to solve problems of how to get Functionality
+     *  a provider could provide, but that is no longer necessary because the Provider
+     * Registers RPCs in onSessionInitiated.
+     *
+     * Recommend:
+     * {code
+     * public Collection<? extends ProviderFunctionality> getFunctionality() {
+     *   return Collections.emptySet();
+     * }
+     * }
      *
-     * @return Set of provider's functionality.
      */
+    @Deprecated
     Collection<? extends ProviderFunctionality> getFunctionality();
 
     /**
@@ -58,12 +152,38 @@ public interface BindingAwareProvider {
      *
      *
      */
+    @Deprecated
     public interface ProviderFunctionality {
 
     }
-
+    /**
+     * Callback signaling initialization of the consumer session to the SAL.
+     *
+     * The consumer MUST use the session for all communication with SAL or
+     * retrieving SAL infrastructure services.
+     *
+     * This method is invoked by
+     * {@link BindingAwareBroker#registerProvider(BindingAwareProvider)}
+     *
+     * @param session Unique session between consumer and SAL.
+     */
     void onSessionInitiated(ProviderContext session);
 
+    /*
+     * @deprecated
+     *
+     * A provider was at one point considered an extension of a consumer, thus this
+     * call.  It is deprecated and the @see org.opendaylight.controller.sal.binding.api.BindingAwareConsumer#onSessionInitiated
+     * used, or you should simply use {@link #onSessionInitiated(ProviderContext)}
+     *
+     * Recommend:
+     * {code
+     * public final void onSessionInitialized(ConsumerContext session) {
+     *   // NOOP - as method is deprecated
+     * }
+     * }
+     */
+    @Deprecated
     void onSessionInitialized(ConsumerContext session);
 
 }
index 9429d3f8fa33372dedbbc8b0a00201db695d99a9..be8e0cefc1a3115329ed3391d99bbc8a38810dcd 100644 (file)
@@ -12,20 +12,20 @@ import java.util.EventListener;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
 /**
- * Interface implemented by objects interested in some sort of Notification. This
- * class acts as a base interface for specific listeners which usually are a type
+ * Interface for a generic listener that is interested in receiving YANG modeled notifications.
+ * This interface acts as a base interface for specific listeners which usually are a type
  * capture of this interface.
  *
- * @param <T> Notification type
+ * @param <T> the interested notification type
  */
 public interface NotificationListener<T extends Notification> extends EventListener {
     /**
-     * Invoked to deliver the notification. Note that this method may be invoked
-     * from a shared thread pool, so implementations SHOULD NOT perform CPU-intensive
-     * operations and they definitely MUST NOT invoke any potentially blocking
-     * operations.
+     * Invoked to deliver a notification.
+     * <p>
+     * Note that this method may be invoked from a shared thread pool, so implementations SHOULD NOT
+     * perform CPU-intensive operations and MUST NOT invoke any potentially blocking operations.
      *
-     * @param notification Notification being delivered.
+     * @param notification the notification.
      */
     void onNotification(T notification);
 }
index b94695b83d437e31194e1e862da479b787ba8d80..00db80c19f7fd3fc9399dd303df74f7987eb2ce7 100644 (file)
@@ -14,29 +14,62 @@ import org.opendaylight.controller.md.sal.common.api.notify.NotificationPublishS
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
+/**
+ * Interface for a notification service that provides publish/subscribe capabilities for YANG
+ * modeled notifications. This interface is a combination of the {@link NotificationService} and
+ * {@link NotificationPublishService} interfaces.
+ */
 public interface NotificationProviderService extends NotificationService, NotificationPublishService<Notification> {
+
     /**
-     * Publishes a notification.
-     *
-     * @param Notification
-     *            notification to publish.
-     *
+     * {@inheritDoc}
      */
     @Override
-    void publish(Notification notification);
+    public void publish(Notification notification);
 
     /**
-     * Publishes a notification, listener calls are done in provided executor.
-     *
+     * {@inheritDoc}
      */
     @Override
-    void publish(Notification notification, ExecutorService service);
+    void publish(Notification notification, ExecutorService executor);
 
+    /**
+     * Registers a listener to be notified about notification subscriptions. This
+     * enables a component to know when there is a notification listener subscribed
+     * for a particular notification type.
+     * <p>
+     * On registration of this listener, the
+     * {@link NotificationInterestListener#onNotificationSubscribtion(Class)} method
+     * will be invoked for every notification type that currently has a notification listener
+     * subscribed.
+     *
+     * @param interestListener the listener that will be notified when subscriptions
+     *                         for new notification types occur.
+     * @return a {@link ListenerRegistration} instance that should be used to unregister the listener
+     *         by invoking the {@link ListenerRegistration#close()} method when no longer needed.
+     */
     ListenerRegistration<NotificationInterestListener> registerInterestListener(
             NotificationInterestListener interestListener);
 
+    /**
+     * Interface for a listener interested in being notified about notification subscriptions.
+     */
     public interface NotificationInterestListener extends EventListener {
 
+        /**
+         * Callback that is invoked when a notification listener subscribes for a
+         * particular notification type.
+         * <p>
+         * This method is only called for the first subscription that occurs for a
+         * particular notification type. Subsequent subscriptions for the same
+         * notification type do not trigger invocation of this method.
+         * <p>
+         * <b>Note:</b>This callback is delivered from thread not owned by this listener,
+         * all processing should be as fast as possible and implementations should
+         * not do any blocking calls or block this thread.
+         *
+         * @param notificationType the notification type for the subscription that occurred.
+         */
         void onNotificationSubscribtion(Class<? extends Notification> notificationType);
     }
 }
index 46e372aea652e29439408da9b6d1ccc963e86acc..335f55bcbbade9ce84898eafee05ff146ef2d382 100644 (file)
@@ -10,24 +10,108 @@ package org.opendaylight.controller.sal.binding.api;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
+/**
+ * Notification broker which allows clients to subscribe for and publish YANG-modeled notifications.
+ *
+ *<p>
+ * Two styles of listeners are supported:
+ * <ul>
+ * <li>Generic listener</li>
+ * <li>Dispatch listener - listener, which implements <code>{ModelName}Listener</code> interface,
+ * which has dispatch methods for each defined notification. Methods are invoked based on notification type (class).
+ * </li>
+ *
+ * <h3>Generic Listener</h3>
+ * <p>
+ * A generic listener implements the {@link NotificationListener} interface which has one callback method
+ * <code>onNotification</code> that is invoked for any notification type the listener is subscribed to.
+ * <p>
+ * A generic listener is subscribed using the {@link #registerNotificationListener(Class, NotificationListener)}
+ * method by which you specify the type of notification to receive. A generic listener may be registered for
+ * multiple notification types via multiple subscriptions.
+ * <p>
+ * Generic listeners allow for a more flexible approach, allowing you to subscribe for just
+ * one type of notification from a YANG model. You could also have a general subscription
+ * for all notification in the system via
+ * <pre>
+ *   service.registerNotificationListener(Notification.class, listener);
+ * </pre>
+ *
+ * <h3>Dispatch Listener</h3>
+ * <p>
+ * A dispatch listener implements a YANG-generated module interface <code>{ModuleName}Listener</code>
+ * which handles all the notifications defined in the YANG model. Each notification type translates to
+ * a specific method of the form <code>on{NotificationType}</code> on the generated interface.
+ * The generated interface also extends the
+ * {@link org.opendaylight.yangtools.yang.binding.NotificationListener} interface and implementations
+ * are registered using {@link #registerNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener)}
+ * method.
+ *
+ * <h5>Dispatch Listener Example</h5>
+ * <p>
+ * Lets assume we have following YANG model:
+ *
+ * <pre>
+ * module example {
+ *      ...
+ *
+ *      notification start {
+ *          ...
+ *      }
+ *
+ *      notification stop {
+ *           ...
+ *      }
+ * }
+ * </pre>
+ *
+ * The generated interface will be:
+ * <pre>
+ *  public interface ExampleListener extends NotificationListener {
+ *      void onStart(Start notification);
+ *      void onStop(Stop notification);
+ *  }
+ * </pre>
+ * The following defines an implementation of the generated interface:
+ * <pre>
+ *  public class MyExampleListener implements ExampleListener {
+ *      public void onStart(Start notification) {
+ *          // do something
+ *      }
+ *
+ *      public void onStop(Stop notification) {
+ *          // do something
+ *      }
+ *  }
+ * </pre>
+ * The implementation is registered as follows:
+ * <pre>
+ *  MyExampleListener listener = new MyExampleListener();
+ *  ListenerRegistration<NotificationListener> reg = service.registerNotificationListener( listener );
+ * </pre>
+ * The <code>onStart</code> method will be invoked when someone publishes a <code>Start</code> notification and
+ * the <code>onStop</code> method will be invoked when someone publishes a <code>Stop</code> notification.
+ */
 public interface NotificationService extends BindingAwareService {
     /**
-     * Register a generic listener for specified notification type only.
+     * Registers a generic listener implementation for a specified notification type.
      *
-     * @param notificationType
-     * @param listener
-     * @return Registration for listener. To unregister listener invoke {@link ListenerRegistration#close()} method.
+     * @param notificationType the YANG-generated interface of the notification type.
+     * @param listener the listener implementation that will receive notifications.
+     * @return a {@link ListenerRegistration} instance that should be used to unregister the listener
+     *         by invoking the {@link ListenerRegistration#close()} method when no longer needed.
      */
     <T extends Notification> ListenerRegistration<NotificationListener<T>> registerNotificationListener(
             Class<T> notificationType, NotificationListener<T> listener);
 
     /**
-     * Register a listener which implements generated notification interfaces derived from
+     * Registers a listener which implements a YANG-generated notification interface derived from
      * {@link org.opendaylight.yangtools.yang.binding.NotificationListener}.
-     * Listener is registered for all notifications present in implemented interfaces.
+     * The listener is registered for all notifications present in the implemented interface.
      *
-     * @param listener
-     * @return Registration for listener. To unregister listener invoke {@link ListenerRegistration#close()} method.
+     * @param listener the listener implementation that will receive notifications.
+     * @return a {@link ListenerRegistration} instance that should be used to unregister the listener
+     *         by invoking the {@link ListenerRegistration#close()} method when no longer needed.
      */
     ListenerRegistration<org.opendaylight.yangtools.yang.binding.NotificationListener> registerNotificationListener(
             org.opendaylight.yangtools.yang.binding.NotificationListener listener);
index 7da0a48517fddf715db5f55ced1d431680f0a755..615acd3195c8a99ed5b5f372f53dee46d5faac7b 100644 (file)
@@ -10,16 +10,60 @@ package org.opendaylight.controller.sal.binding.api;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 
 /**
- * Base interface defining contract for retrieving MD-SAL
- * version of RpcServices
+ * Provides access to registered Remote Procedure Call (RPC) service implementations. The RPCs are
+ * defined in YANG models.
+ * <p>
+ * RPC implementations are registered using the {@link RpcProviderRegistry}.
  *
  */
 public interface RpcConsumerRegistry extends BindingAwareService {
     /**
-     * Returns a session specific instance (implementation) of requested
-     * YANG module implementation / service provided by consumer.
+     * Returns an implementation of a requested RPC service.
      *
-     * @return Session specific implementation of service
+     * <p>
+     * The returned instance is not an actual implementation of the RPC service
+     * interface, but a proxy implementation of the interface that forwards to
+     * an actual implementation, if any.
+     * <p>
+     *
+     * The following describes the behavior of the proxy when invoking RPC methods:
+     * <ul>
+     * <li>If an actual implementation is registered with the MD-SAL, all invocations are
+     * forwarded to the registered implementation.</li>
+     * <li>If no actual implementation is registered, all invocations will fail by
+     * throwing {@link IllegalStateException}.</li>
+     * <li>Prior to invoking the actual implementation, the method arguments are are validated.
+     * If any are invalid, an {@link IllegalArgumentException} is thrown.
+     * </ul>
+     *
+     * The returned proxy is automatically updated with the most recent
+     * registered implementation.
+     * <p>
+     * The generated RPC method APIs require implementors to return a {@link java.util.concurrent.Future Future}
+     * instance that wraps the {@link org.opendaylight.yangtools.yang.common.RpcResult RpcResult}. Since
+     * RPC methods may be implemented asynchronously, callers should avoid blocking on the
+     * {@link java.util.concurrent.Future Future} result. Instead, it is recommended to use
+     * {@link com.google.common.util.concurrent.JdkFutureAdapters#listenInPoolThread(java.util.concurrent.Future)}
+     * or {@link com.google.common.util.concurrent.JdkFutureAdapters#listenInPoolThread(java.util.concurrent.Future, java.util.concurrent.Executor)}
+     * to listen for Rpc Result. This will asynchronously listen for future result in executor and
+     * will not block current thread.
+     *
+     * <pre>
+     *   final Future<RpcResult<SomeRpcOutput>> future = someRpcService.someRpc( ... );
+     *   Futures.addCallback(JdkFutureAdapters.listenInThreadPool(future), new FutureCallback<RpcResult<SomeRpcOutput>>() {
+     *
+     *       public void onSuccess(RpcResult<SomeRpcOutput> result) {
+     *          // process result ...
+     *       }
+     *
+     *       public void onFailure(Throwable t) {
+     *          // RPC failed
+     *       }
+     *   );
+     * </pre>
+     * @param serviceInterface the interface of the RPC Service. Typically this is an interface generated
+     *                         from a YANG model.
+     * @return the proxy for the requested RPC service. This method never returns null.
      */
-    <T extends RpcService> T getRpcService(Class<T> module);
+    <T extends RpcService> T getRpcService(Class<T> serviceInterface);
 }
index cdf55844b3d94d680a7a21ad052deb9a7aa73ac4..22db985ba96b82cc4245a42f28ccd3e1f9959774 100644 (file)
@@ -15,39 +15,256 @@ 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.
+ * Provides a registry for Remote Procedure Call (RPC) service implementations. The RPCs are
+ * defined in YANG models.
+ * <p>
+ * There are 2 types of RPCs:
+ * <ul>
+ * <li>Global</li>
+ * <li>Routed</li>
+ * </ul>
  *
- * @author ttkacik
+ * <h2>Global RPC</h2>
+ * <p>
+ * An RPC is global if there is intended to be only 1 registered implementation. A global RPC is not
+ * explicitly declared as such, essentially any RPC that is not defined to be routed is considered global.
+ * <p>
+ * Global RPCs are registered using the
+ * {@link #addRpcImplementation(Class, RpcService)} method.
  *
+ * <h2>Routed RPC</h2>
+ * <p>
+ * MD-SAL supports routing of RPC between multiple implementations where the appropriate
+ * implementation is selected at run time based on the content of the RPC message as described in
+ * YANG model.
+ * <p>
+ * RPC routing is based on:
+ * <ul>
+ * <li><b>Route identifier</b> -
+ * An {@link org.opendaylight.yangtools.yang.binding.InstanceIdentifier InstanceIdentifier} value
+ * which is part of the RPC input. This value is used to select the correct
+ * implementation at run time.</li>
+ * <li><b>Context Type</b> - A YANG-defined construct which constrains the subset of
+ * valid route identifiers for a particular RPC.</li>
+ * </ul>
+ *
+ * <h3>Context type</h3>
+ * <p>
+ * A context type is modeled in YANG using a combination of a YANG <code>identity</code>
+ * and Opendaylight specific extensions from <code>yang-ext</code> module. These extensions are:
+ * <ul>
+ * <li><b>context-instance</b> - This is used in the data tree part of a YANG model to
+ * define a context type that associates nodes with a specified context <code>identity</code>.
+ * Instance identifiers that reference these nodes are valid route identifiers for RPCs that
+ * reference this context type.</li>
+ * <li><b>context-reference</b> - This is used in RPC input to mark a leaf of type
+ * <code>instance-identifier</code> as a reference to the particular context type defined by the
+ * specified context <code>identity</code>. The value of this
+ * leaf is used by the RPC broker at run time to route the RPC request to the correct implementation.
+ * Note that <code>context-reference</code> may only be used on leaf elements of type
+ * <code>instance-identifier</code> or a type derived from <code>instance-identifier</code>.</li>
+ * </ul>
+ *
+ *
+ * <h3>Routed RPC example</h3>
+ * <p>
+ * <h5>1. Defining a Context Type</h5>
+ * <p>
+ * The following snippet declares a simple YANG <code>identity</code> named <code>example-context</code>:
+ *
+ * <pre>
+ * module example {
+ *     ...
+ *     identity example-context {
+ *          description "Identity used to define an example-context type";
+ *     }
+ *     ...
+ * }
+ * </pre>
+ * <p>
+ * We then use the declared identity to define a context type by using it in combination
+ * with the <code>context-instance</code> YANG extension. We'll associate the context type
+ * with a list element in the data tree. This defines the set of nodes whose instance
+ * identifiers are valid for the <code>example-context</code> context type.
+ * <p>
+ * The following YANG snippet imports the <code>yang-ext</code> module and defines the list
+ * element named <code>item</code> inside a container named <code>foo</code>:
+ *
+ * <pre>
+ * module foo {
+ *     ...
+ *     import yang-ext {prefix ext;}
+ *     ...
+ *     container foo {
+ *          list item {
+ *              key "id";
+ *              leaf id {type string;}
+ *              ext:context-instance "example-context";
+ *          }
+ *     }
+ *     ...
+ * }
+ * </pre>
+ * <p>
+ * The statement <code>ext:context-instance "example-context";</code> inside the list element
+ * declares that any instance identifier referencing <code>item</code> in the data
+ * tree is valid for <code>example-context</code>. For example, the following instance
+ * identifier:
+ * <pre>
+ *     InstanceIdentifier.create(Foo.class).child(Item.class,new ItemKey("Foo"))
+ * </pre>
+ * is valid for <code>example-context</code>. However the following:
+ * <pre>
+ *     InstanceIdentifier.create(Example.class)
+ * </pre>
+ * is not valid.
+ * <p>
+ * So using an <code>identity</code> in combination with <code>context-instance</code> we
+ * have effectively defined a context type that can be referenced in a YANG RPC input.
+ *
+ * <h5>2. Defining an RPC to use the Context Type</h5>
+ * <p>
+ * To define an RPC to be routed based on the context type we need to add an input leaf element
+ * that references the context type which will hold an instance identifier value to be
+ * used to route the RPC.
+ * <p>
+ * The following snippet defines an RPC named <code>show-item</code> with 2 leaf elements
+ * as input: <code>item</code> of type <code>instance-identifier</code> and <code>description</code>:
+ *
+ * <pre>
+ * module foo {
+ *      ...
+ *      import yang-ext {prefix ext;}
+ *      ...
+ *      rpc show-item {
+ *          input {
+ *              leaf item {
+ *                  type instance-identifier;
+ *                  ext:context-reference example-context;
+ *              }
+ *              leaf description {
+ *                  type "string";
+ *              }
+ *          }
+ *      }
+ * }
+ * </pre>
+ * <p>
+ * We mark the <code>item</code> leaf with a <code>context-reference</code> statement that
+ * references the <code>example-context</code> context type. RPC calls will then be routed
+ * based on the instance identifier value contained in <code>item</code>. Only instance
+ * identifiers that point to a <code>foo/item</code> node are valid as input.
+ * <p>
+ * The generated RPC Service interface for the module is:
+ *
+ * <pre>
+ * interface FooService implements RpcService {
+ *      Future&lt;RpcResult&lt;Void&gt;&gt; showItem(ShowItemInput input);
+ * }
+ * </pre>
+ * <p>
+ * For constructing the RPC input, there are generated classes ShowItemInput and ShowItemInputBuilder.
+ *
+ * <h5>3. Registering a routed RPC implementation</h5>
+ * <p>
+ * To register a routed implementation for the <code>show-item</code> RPC, we must use the
+ * {@link #addRoutedRpcImplementation(Class, RpcService)} method. This
+ * will return a {@link RoutedRpcRegistration} instance which can then be used to register /
+ * unregister routed paths associated with the registered implementation.
+ * <p>
+ * The following snippet registers <code>myImpl</code> as the RPC implementation for an
+ * <code>item</code> with key <code>"foo"</code>:
+ * <pre>
+ * // Create the instance identifier path for item "foo"
+ * InstanceIdentifier path = InstanceIdentifier.create(Foo.class).child(Item.class, new ItemKey(&quot;foo&quot;));
+ *
+ * // Register myImpl as the implementation for the FooService RPC interface
+ * RoutedRpcRegistration reg = rpcRegistry.addRoutedRpcImplementation(FooService.class, myImpl);
+ *
+ * // Now register for the context type and specific path ID. The context type is specified by the
+ * // YANG-generated class for the example-context identity.
+ * reg.registerPath(ExampleContext.class, path);
+ * </pre>
+ * <p>
+ * It is also possible to register the same implementation for multiple paths:
+ *
+ * <pre>
+ * InstanceIdentifier one = InstanceIdentifier.create(Foo.class).child(Item.class, new ItemKey(&quot;One&quot;));
+ * InstanceIdentifier two = InstanceIdentifier.create(Foo.class).child(Item.class, new ItemKey(&quot;Two&quot;));
+ *
+ * RoutedRpcRegistration reg = rpcRegistry.addRoutedRpcImplementation(FooService.class, myImpl);
+ * reg.registerPath(ExampleContext.class, one);
+ * reg.registerPath(ExampleContext.class, two);
+ * </pre>
+ *
+ * <p>
+ * When another client invokes the <code>showItem(ShowItemInput)</code> method on the proxy instance
+ * retrieved via {@link RpcConsumerRegistry#getRpcService(Class)}, the proxy will inspect the
+ * arguments in ShowItemInput, extract the InstanceIdentifier value of the <code>item</code> leaf and select
+ * the implementation whose registered path matches the InstanceIdentifier value of the <code>item</code> leaf.
+ *
+ * <h2>Notes for RPC Implementations</h2>
+ *
+ * <h3>RpcResult</h3>
+ * <p>
+ * The generated interfaces require implementors to return
+ *  {@link java.util.concurrent.Future Future}&lt;{@link org.opendaylight.yangtools.yang.common.RpcResult RpcResult}&lt;{RpcName}Output&gt;&gt; instances.
+ *
+ * Implementations should do processing of RPC calls asynchronously and update the
+ * returned {@link java.util.concurrent.Future Future} instance when processing is complete.
+ * However using {@link com.google.common.util.concurrent.Futures#immediateFuture(Object) Futures.immediateFuture}
+ * is valid only if the result is immediately available and asynchronous processing is unnecessary and
+ * would only introduce additional complexity.
+ *
+ * <p>
+ * The {@link org.opendaylight.yangtools.yang.common.RpcResult RpcResult} is a generic
+ * wrapper for the RPC output payload, if any, and also allows for attaching error or
+ * warning information (possibly along with the payload) should the RPC processing partially
+ * or completely fail. This is intended to provide additional human readable information
+ * for users of the API and to transfer warning / error information across the system
+ * so it may be visible via other external APIs such as Restconf.
+ * <p>
+ * It is recommended to use the {@link org.opendaylight.yangtools.yang.common.RpcResult RpcResult}
+ * for conveying appropriate error information
+ * on failure rather than purposely throwing unchecked exceptions if at all possible.
+ * While unchecked exceptions will fail the returned {@link java.util.concurrent.Future Future},
+ * using the intended RpcResult to convey the error information is more user-friendly.
  */
 public interface RpcProviderRegistry extends //
         RpcConsumerRegistry, //
         RouteChangePublisher<RpcContextIdentifier, InstanceIdentifier<?>> {
     /**
-     * Registers a global RpcService implementation.
+     * Registers a global implementation of the provided RPC service interface.
+     * All methods of the interface are required to be implemented.
+     *
+     * @param serviceInterface the YANG-generated interface of the RPC Service for which to register.
+     * @param implementation "the implementation of the RPC service interface.
+     * @return an RpcRegistration instance that should be used to unregister the RPC implementation
+     *         when no longer needed by calling {@link RpcRegistration#close()}.
      *
-     * @param type
-     * @param implementation
-     * @return
+     * @throws IllegalStateException
+     *             if the supplied RPC interface is a routed RPC type.
      */
-    <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
+    <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> serviceInterface, T implementation)
             throws IllegalStateException;
 
     /**
+     * Registers an implementation of the given routed RPC service interface.
+     * <p>
+     * See the {@link RpcProviderRegistry class} documentation for information and example on
+     * how to use routed RPCs.
      *
-     * Register a 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 class
-     * @param implementation
-     *            Implementation of RpcService
-     * @return Registration object for routed Rpc which could be used to unregister
+     * @param serviceInterface the YANG-generated interface of the RPC Service for which to register.
+     * @param implementation the implementation instance to register.
+     * @return a RoutedRpcRegistration instance which can be used to register paths for the RPC
+     *         implementation via invoking {@link RoutedRpcRegistration#registerPath(....).
+     *         {@link RoutedRpcRegistration#close()} should be called to unregister the implementation
+     *         and all previously registered paths when no longer needed.
      *
      * @throws IllegalStateException
+     *            if the supplied RPC interface is not a routed RPC type.
      */
-    <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type, T implementation)
+    <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> serviceInterface,
+                                                                               T implementation)
             throws IllegalStateException;
 }
index d0225768b4e2500acf0eccfb13e4999e0a8591e3..d30ca6beaf6fc209f600fbe09175895d4b9bdd62 100644 (file)
@@ -21,7 +21,9 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
  *
  *
  * @see DataProviderService
+ * @deprecated Replaced by newer better documented version {@link org.opendaylight.controller.md.sal.binding.api.DataBroker}
  */
+@Deprecated
 public interface DataBrokerService extends //
         BindingAwareService, //
         DataModificationTransactionFactory<InstanceIdentifier<? extends DataObject>, DataObject>, //
@@ -31,16 +33,26 @@ public interface DataBrokerService extends //
      * Creates a data modification transaction.
      *
      * @return new blank data modification transaction.
+     * @deprecated Replaced by more specific transaction types. Please use
+     *          {@link org.opendaylight.controller.md.sal.binding.api.DataBroker#newReadOnlyTransaction(),
+     *          {@link org.opendaylight.controller.md.sal.binding.api.DataBroker#newReadWriteTransaction()
+     *          or
+     *          {@link org.opendaylight.controller.md.sal.binding.api.DataBroker#newWriteOnlyTransaction().
      */
+    @Deprecated
     @Override
     DataModificationTransaction beginTransaction();
 
     /**
      * Reads data subtree from configurational store.
      * (Store which is populated by consumer, which is usually used to
-     * inject state into providers. E.g. Flow configuration)-
+     * inject state into providers. E.g. Flow configuration)
+     *
+     *
+     * @deprecated Please use {@link org.opendaylight.controller.md.sal.binding.api.DataBroker#newReadOnlyTransaction()}
      *
      */
+    @Deprecated
     @Override
     public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path);
 
@@ -49,7 +61,9 @@ public interface DataBrokerService extends //
      * (Store which is populated by providers, which is usually used to
      * capture state of providers. E.g. Topology)
      *
+     * @deprecated Please use {@link org.opendaylight.controller.md.sal.binding.api.DataBroker#newReadOnlyTransaction()}
      */
+    @Deprecated
     @Override
     public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path);
 
@@ -58,7 +72,10 @@ public interface DataBrokerService extends //
      *
      * Callback is invoked each time data in subtree changes.
      *
+     * @deprecated Please use {@link org.opendaylight.controller.md.sal.binding.api.DataBroker#registerDataChangeListener(org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType, InstanceIdentifier, org.opendaylight.controller.md.sal.binding.api.DataChangeListener, org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope)}
+     * which provides more fine-grained registration options.
      */
+    @Deprecated
     @Override
     public ListenerRegistration<DataChangeListener> registerDataChangeListener(
             InstanceIdentifier<? extends DataObject> path, DataChangeListener listener);
index 6373cfbf4a3ec6a67f8cdd2c3b423ea1eb5b4e28..e26cbcef29b7e40a3757425216f0253d706fcda1 100644 (file)
@@ -11,6 +11,12 @@ import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
+/**
+ *
+ * @deprecated Replaced by {@link org.opendaylight.controller.md.sal.binding.api.DataChangeListener}
+ *
+ */
+@Deprecated
 public interface DataChangeListener extends
         org.opendaylight.controller.md.sal.common.api.data.DataChangeListener<InstanceIdentifier<? extends DataObject>, DataObject> {
 
index 5fafabbd1b6e9104bd72c3946acce0aa2e580871..0c250fdbee4c2454d0d9c1afa981ef71b4c05acc 100644 (file)
@@ -17,6 +17,18 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
+/**
+ *
+ *
+ * @deprecated Replaced by more specific transaction types. Please use
+ *          {@link org.opendaylight.controller.md.sal.binding.api.DataBroker#newReadOnlyTransaction(),
+ *          {@link org.opendaylight.controller.md.sal.binding.api.DataBroker#newReadWriteTransaction()
+ *          or
+ *          {@link org.opendaylight.controller.md.sal.binding.api.DataBroker#newWriteOnlyTransaction().
+ *
+ *
+ */
+@Deprecated
 public interface DataModificationTransaction extends DataModification<InstanceIdentifier<? extends DataObject>, DataObject> {
     /**
      * Returns an unique identifier for transaction
index b496d1dfb4ba58636e2af34abcd1e7cd186f4f55..7fa40b8d070c8301ba892080d587b651318cf1d1 100644 (file)
@@ -16,7 +16,10 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 /**
  * DataProviderService is common access point for {@link org.opendaylight.controller.sal.binding.api.BindingAwareProvider} providers
  * to access data trees described by the YANG model.
+ *
+ * @deprecated Replaced by {@link org.opendaylight.controller.md.sal.common.api.data.AsyncConfigurationCommitCoordinator} service.
  */
+@Deprecated
 public interface DataProviderService extends DataBrokerService, DataProvisionService<InstanceIdentifier<? extends DataObject>, DataObject> {
     /**
      * Registers a data reader for particular subtree of overal YANG data tree.
@@ -27,6 +30,8 @@ public interface DataProviderService extends DataBrokerService, DataProvisionSer
      * @param path Subpath which is handled by registered data reader
      * @param reader Instance of reader which
      * @return Registration object for reader. Invoking {@link Registration#close()} will unregister reader.
+     * @deprecated Data Reader contract is removed from capabilities of MD-SAL and is replaced by  replaced by org.opendaylight.controller.sal.core.spi.data.DOMStore contract.
      */
-    Registration<DataReader<InstanceIdentifier<? extends DataObject>,DataObject>> registerDataReader(InstanceIdentifier<? extends DataObject> path,DataReader<InstanceIdentifier<? extends DataObject>,DataObject> reader);
+    @Deprecated
+    Registration registerDataReader(InstanceIdentifier<? extends DataObject> path,DataReader<InstanceIdentifier<? extends DataObject>,DataObject> reader);
 }
index 3334f2a037b119711916a52ad7c9d86b6424201d..c0c8f4f2112fd0ccb7dcde3427009595c880ccc2 100644 (file)
@@ -13,8 +13,9 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
  * Trigger for refreshing of the data exposed by the {@link Provider}
  *
  *
- *
+ * @deprecated Unused, not supported. Replaced by org.opendaylight.controller.sal.core.spi.data.DOMStore.
  */
+@Deprecated
 public interface DataRefresher extends BindingAwareProvider.ProviderFunctionality {
 
     /**
index 85a2b82ee0397174966e8e584a6607eb61de3433..273f20f01da8c27562017d7f4aede2a144c6bffe 100644 (file)
@@ -15,9 +15,11 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 /**
  * Utility interface which does type capture for BindingAware DataReader.
  *
- * @author
+ *
+ * @deprecated Removed, replaced by org.opendaylight.controller.sal.core.spi.data.DOMStore.
  *
  */
+@Deprecated
 public interface RuntimeDataProvider extends ProviderFunctionality,DataReader<InstanceIdentifier<? extends DataObject>, DataObject> {
 
 
index da6d46d499317d647673cfb2b7ef5d60e43b2eae..fc0d3964ea07ff7d107d99e0278a0df7263f9772 100644 (file)
@@ -25,12 +25,19 @@ import com.google.common.base.Preconditions;
  *
  * To get instance of synchronized wrapper use {@link #from(DataModificationTransaction)}
  *
+ * @deprecated Replaced by more specific transaction types. Please use
+ *          {@link org.opendaylight.controller.md.sal.binding.api.DataBroker#newReadOnlyTransaction(),
+ *          {@link org.opendaylight.controller.md.sal.binding.api.DataBroker#newReadWriteTransaction()
+ *          or
+ *          {@link org.opendaylight.controller.md.sal.binding.api.DataBroker#newWriteOnlyTransaction().
+ *
  */
+@Deprecated
 public final class SynchronizedTransaction implements DataModificationTransaction,Delegator<DataModificationTransaction> {
 
     private final DataModificationTransaction delegate;
 
-    private SynchronizedTransaction(DataModificationTransaction delegate) {
+    private SynchronizedTransaction(final DataModificationTransaction delegate) {
         this.delegate = delegate;
     }
 
@@ -40,7 +47,7 @@ public final class SynchronizedTransaction implements DataModificationTransactio
      * @param transaction Transaction for which synchronized wrapper should be created.
      * @return Synchronized wrapper over transaction.
      */
-    public static final SynchronizedTransaction from(DataModificationTransaction transaction) {
+    public static final SynchronizedTransaction from(final DataModificationTransaction transaction) {
         Preconditions.checkArgument(transaction != null, "Transaction must not be null.");
         if (transaction instanceof SynchronizedTransaction) {
             return (SynchronizedTransaction) transaction;
@@ -59,7 +66,7 @@ public final class SynchronizedTransaction implements DataModificationTransactio
     }
 
     @Override
-    public synchronized DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+    public synchronized DataObject readOperationalData(final InstanceIdentifier<? extends DataObject> path) {
         return delegate.readOperationalData(path);
     }
 
@@ -79,7 +86,7 @@ public final class SynchronizedTransaction implements DataModificationTransactio
     }
 
     @Override
-    public synchronized DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+    public synchronized DataObject readConfigurationData(final InstanceIdentifier<? extends DataObject> path) {
         return delegate.readConfigurationData(path);
     }
 
@@ -89,12 +96,12 @@ public final class SynchronizedTransaction implements DataModificationTransactio
     }
 
     @Override
-    public synchronized void putOperationalData(InstanceIdentifier<? extends DataObject> path, DataObject data) {
+    public synchronized void putOperationalData(final InstanceIdentifier<? extends DataObject> path, final DataObject data) {
         delegate.putOperationalData(path, data);
     }
 
     @Override
-    public synchronized void putConfigurationData(InstanceIdentifier<? extends DataObject> path, DataObject data) {
+    public synchronized void putConfigurationData(final InstanceIdentifier<? extends DataObject> path, final DataObject data) {
         delegate.putConfigurationData(path, data);
     }
 
@@ -104,12 +111,12 @@ public final class SynchronizedTransaction implements DataModificationTransactio
     }
 
     @Override
-    public synchronized void removeOperationalData(InstanceIdentifier<? extends DataObject> path) {
+    public synchronized void removeOperationalData(final InstanceIdentifier<? extends DataObject> path) {
         delegate.removeOperationalData(path);
     }
 
     @Override
-    public synchronized void removeConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+    public synchronized void removeConfigurationData(final InstanceIdentifier<? extends DataObject> path) {
         delegate.removeConfigurationData(path);
     }
 
@@ -129,7 +136,7 @@ public final class SynchronizedTransaction implements DataModificationTransactio
     }
 
     @Override
-    public synchronized ListenerRegistration<DataTransactionListener> registerListener(DataTransactionListener listener) {
+    public synchronized ListenerRegistration<DataTransactionListener> registerListener(final DataTransactionListener listener) {
         return delegate.registerListener(listener);
     }
 
@@ -152,7 +159,7 @@ public final class SynchronizedTransaction implements DataModificationTransactio
     }
 
     @Override
-    public boolean equals(Object obj) {
+    public boolean equals(final Object obj) {
         if (this == obj) {
             return true;
         }
index 35b186db6aeeaf5ed53ee8a7e43bf5d9e4fb1b82..74cceb1cbd55fc786b78e3f111b2a82a60bd8751 100644 (file)
       <groupId>org.opendaylight.yangtools.model</groupId>
       <artifactId>ietf-inet-types</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.reflections</groupId>
-      <artifactId>reflections</artifactId>
-      <scope>compile</scope>
-    </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
       <artifactId>ietf-topology-l3-unicast-igp</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-test-model</artifactId>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-simple</artifactId>
-      <version>${slf4j.version}</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
index 17cd67a8576018485d3f1162dab89d51be0fcf15..018e26878c9873490d6c3ed88822edb78efe0280 100644 (file)
@@ -10,12 +10,10 @@ import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
 import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
-import org.osgi.framework.BundleContext;
 
 public class BindingAsyncDataBrokerImplModule extends
         org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingAsyncDataBrokerImplModule implements
         Provider {
-    private BundleContext bundleContext;
 
     public BindingAsyncDataBrokerImplModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
             final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -42,25 +40,15 @@ public class BindingAsyncDataBrokerImplModule extends
 
         // FIXME: Switch this to DOM Broker registration which would not require
         // BundleContext when API are updated.
-        ProviderSession session = domBroker.registerProvider(this, getBundleContext());
+        ProviderSession session = domBroker.registerProvider(this, null);
         DOMDataBroker domDataBroker = session.getService(DOMDataBroker.class);
         SchemaService schemaService = session.getService(SchemaService.class);
         return new ForwardedBindingDataBroker(domDataBroker, mappingService, schemaService);
     }
 
-    // FIXME: Remove this when DOM Broker registration would not require
-    // BundleContext
-    @Deprecated
-    private BundleContext getBundleContext() {
-        return bundleContext;
-    }
 
-    // FIXME: Remove this when DOM Broker registration would not require
-    // BundleContext
-    @Deprecated
-    void setBundleContext(final BundleContext bundleContext) {
-        this.bundleContext = bundleContext;
-    }
+
+
 
     @Override
     public Collection<ProviderFunctionality> getProviderFunctionality() {
index 763e6ad3ca92e40e02a6e3c63a1ad2e96d46d747..a7c8843fcf3c48d1aa79fd85fbcc798a7b7c3efe 100644 (file)
@@ -9,29 +9,7 @@
 */
 package org.opendaylight.controller.config.yang.md.sal.binding.impl;
 
-import org.opendaylight.controller.config.api.DependencyResolver;
-import org.osgi.framework.BundleContext;
 
 public class BindingAsyncDataBrokerImplModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingAsyncDataBrokerImplModuleFactory {
 
-
-
-
-    @Override
-    public BindingAsyncDataBrokerImplModule instantiateModule(final String instanceName,
-            final DependencyResolver dependencyResolver, final BindingAsyncDataBrokerImplModule oldModule,
-            final AutoCloseable oldInstance, final BundleContext bundleContext) {
-        BindingAsyncDataBrokerImplModule module = super.instantiateModule(instanceName, dependencyResolver, oldModule, oldInstance, bundleContext);
-        module.setBundleContext(bundleContext);
-        return module;
-    }
-
-    @Override
-    public BindingAsyncDataBrokerImplModule instantiateModule(final String instanceName,
-            final DependencyResolver dependencyResolver, final BundleContext bundleContext) {
-        // TODO Auto-generated method stub
-        BindingAsyncDataBrokerImplModule module = super.instantiateModule(instanceName, dependencyResolver, bundleContext);
-        module.setBundleContext(bundleContext);
-        return module;
-    }
 }
index 188272fb60c186f07b472805776df83ee12899e0..61e7a2e6a240d9e7ab98574f7dd1bee2058ed987 100644 (file)
@@ -1,96 +1,85 @@
-/*\r
- * Copyright (c) 2014 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
-/**\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
-package org.opendaylight.controller.config.yang.md.sal.binding.impl;\r
-\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
-/**\r
-*\r
-*/\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(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,\r
-            final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {\r
-        super(identifier, dependencyResolver);\r
-    }\r
-\r
-    public BindingBrokerImplModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,\r
-            final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,\r
-            final BindingBrokerImplModule oldModule, final java.lang.AutoCloseable oldInstance) {\r
-        super(identifier, dependencyResolver, oldModule, oldInstance);\r
-    }\r
-\r
-    @Override\r
-    public void validate() {\r
-        super.validate();\r
-    }\r
-\r
-    @Override\r
-    public java.lang.AutoCloseable createInstance() {\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.setLegacyDataBroker(getDataBrokerDependency());\r
-        broker.setNotificationBroker(getNotificationServiceDependency());\r
-        broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier()));\r
-        // FIXME: Also set Async Data Broker\r
-        return broker;\r
-    }\r
-\r
-    private RootBindingAwareBroker createForwardedBroker() {\r
-        DomForwardedBindingBrokerImpl broker = new DomForwardedBindingBrokerImpl(getIdentifier().getInstanceName());\r
-\r
-        broker.setLegacyDataBroker(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
-        // FIXME: Also set Async Data Broker\r
-        DomForwardingUtils.reuseForwardingFrom(broker, broker.getDataBroker());\r
-        broker.startForwarding();\r
-        return broker;\r
-    }\r
-\r
-    public BundleContext getBundleContext() {\r
-        return bundleContext;\r
-    }\r
-\r
-    public void setBundleContext(final BundleContext bundleContext) {\r
-        this.bundleContext = bundleContext;\r
-    }\r
-}\r
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+/**
+ * Generated file
+
+ * Generated from: yang module name: opendaylight-sal-binding-broker-impl  yang module local name: binding-broker-impl
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 20 17:33:01 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
+import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardingUtils;
+
+/**
+*
+*/
+public final class BindingBrokerImplModule extends
+        org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule {
+
+    public BindingBrokerImplModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+            final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public BindingBrokerImplModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+            final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+            final BindingBrokerImplModule oldModule, final java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void validate() {
+        super.validate();
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+
+        RootBindingAwareBroker broker;
+        if (DomForwardingUtils.isDomForwardedBroker(getDataBrokerDependency())) {
+            broker = createForwardedBroker();
+        } else {
+            broker = createStandaloneBroker();
+        }
+        broker.start();
+        return broker;
+    }
+
+    private RootBindingAwareBroker createStandaloneBroker() {
+        RootBindingAwareBroker broker = new RootBindingAwareBroker(getIdentifier().getInstanceName());
+
+        broker.setLegacyDataBroker(getDataBrokerDependency());
+        broker.setNotificationBroker(getNotificationServiceDependency());
+        broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier()));
+        broker.setDataBroker(getRootDataBrokerDependency());
+        return broker;
+    }
+
+    private RootBindingAwareBroker createForwardedBroker() {
+        DomForwardedBindingBrokerImpl broker = new DomForwardedBindingBrokerImpl(getIdentifier().getInstanceName());
+
+        broker.setLegacyDataBroker(getDataBrokerDependency());
+        broker.setNotificationBroker(getNotificationServiceDependency());
+        broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier()));
+
+        broker.getMountManager().setDataCommitExecutor(SingletonHolder.getDefaultCommitExecutor());
+        broker.getMountManager().setNotificationExecutor(SingletonHolder.getDefaultNotificationExecutor());
+
+        broker.setDataBroker(getRootDataBrokerDependency());
+        DomForwardingUtils.reuseForwardingFrom(broker, broker.getDataBroker());
+        broker.startForwarding();
+        return broker;
+    }
+}
index a11a7d67f5d4077006676dc476cf154e1de8ade8..181b568cf51e898a807053dbe16ab353fdfab2de 100644 (file)
 */
 package org.opendaylight.controller.config.yang.md.sal.binding.impl;
 
-import org.opendaylight.controller.config.api.DependencyResolver;
-import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
-import org.opendaylight.controller.config.spi.Module;
-import org.osgi.framework.BundleContext;
 
 /**
 *
 */
 public class BindingBrokerImplModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModuleFactory {
 
-
-    @Override
-    public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
-        BindingBrokerImplModule module = (BindingBrokerImplModule) super.createModule(instanceName, dependencyResolver, bundleContext);
-        module.setBundleContext(bundleContext);
-        return module;
-    }
-
-    @Override
-    public Module createModule(String instanceName, DependencyResolver dependencyResolver,
-            DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
-        BindingBrokerImplModule module = (BindingBrokerImplModule) super.createModule(instanceName, dependencyResolver, old, bundleContext);
-        module.setBundleContext(bundleContext);
-        return module;
-    }
-
 }
index 7357926b9e6226a612bd0fc453dc28b737cff5b8..4a4e8000781381f906888369a8db0ac6b683e525 100644 (file)
@@ -5,8 +5,8 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.controller.config.yang.md.sal.binding.impl;\r
-\r
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
 import java.util.concurrent.ExecutorService;
 
 import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
@@ -16,85 +16,64 @@ import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndepende
 import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedDataBrokerImpl;
 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-\r
-/**\r
-*\r
-*/\r
-public final class DataBrokerImplModule extends\r
-        org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractDataBrokerImplModule {\r
-\r
-    private BundleContext bundleContext;\r
-\r
-    public DataBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,\r
-            org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {\r
-        super(identifier, dependencyResolver);\r
-    }\r
-\r
-    public DataBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,\r
-            org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,\r
-            DataBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {\r
-        super(identifier, dependencyResolver, oldModule, oldInstance);\r
-    }\r
-\r
-    @Override\r
-    public void validate() {\r
-        super.validate();\r
-    }\r
-\r
-    @Override\r
-    public java.lang.AutoCloseable createInstance() {\r
-        RootDataBrokerImpl dataBindingBroker;\r
-\r
-\r
-        ExecutorService listeningExecutor = SingletonHolder.getDefaultCommitExecutor();\r
-        BindingIndependentMappingService potentialMapping = resolveMappingServiceDependency();\r
-        if (getDomBrokerDependency() != null && potentialMapping != null) {\r
-\r
-            dataBindingBroker = createDomConnectedBroker(listeningExecutor,potentialMapping);\r
-        } else {\r
-            dataBindingBroker = createStandAloneBroker(listeningExecutor);\r
-        }\r
-        dataBindingBroker.registerRuntimeBean(getRootRuntimeBeanRegistratorWrapper());\r
-        dataBindingBroker.setNotificationExecutor(SingletonHolder.getDefaultChangeEventExecutor());\r
-        return dataBindingBroker;\r
-    }\r
-    private BindingIndependentMappingService resolveMappingServiceDependency() {\r
-        if(getMappingService() != null) {\r
-            return getMappingServiceDependency();\r
-        }\r
-\r
-        ServiceReference<BindingIndependentMappingService> potentialMappingService = bundleContext.getServiceReference(BindingIndependentMappingService.class);\r
-        if(potentialMappingService != null) {\r
-            return bundleContext.getService(potentialMappingService);\r
-        }\r
-        return null;\r
-    }\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, BindingIndependentMappingService mappingService) {\r
-        DomForwardedDataBrokerImpl forwardedBroker = new DomForwardedDataBrokerImpl();\r
-        forwardedBroker.setExecutor(listeningExecutor);\r
-        BindingIndependentConnector connector = BindingDomConnectorDeployer.createConnector(mappingService);\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
-    }\r
-\r
-    public void setBundleContext(BundleContext bundleContext2) {\r
-        this.bundleContext = bundleContext2;\r
-    }\r
-}\r
+
+/**
+*
+*/
+public final class DataBrokerImplModule extends
+        org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractDataBrokerImplModule {
+
+    public DataBrokerImplModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+            final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public DataBrokerImplModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+            final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+            final DataBrokerImplModule oldModule, final java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void validate() {
+        super.validate();
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        RootDataBrokerImpl dataBindingBroker;
+
+
+        ExecutorService listeningExecutor = SingletonHolder.getDefaultCommitExecutor();
+        BindingIndependentMappingService potentialMapping = getMappingServiceDependency();
+        if (getDomBrokerDependency() != null && potentialMapping != null) {
+
+            dataBindingBroker = createDomConnectedBroker(listeningExecutor,potentialMapping);
+        } else {
+            dataBindingBroker = createStandAloneBroker(listeningExecutor);
+        }
+        dataBindingBroker.registerRuntimeBean(getRootRuntimeBeanRegistratorWrapper());
+        dataBindingBroker.setNotificationExecutor(SingletonHolder.getDefaultChangeEventExecutor());
+        return dataBindingBroker;
+    }
+
+
+    private RootDataBrokerImpl createStandAloneBroker(final ExecutorService listeningExecutor) {
+        RootDataBrokerImpl broker = new RootDataBrokerImpl();
+        broker.setExecutor(listeningExecutor);
+        return broker;
+    }
+
+    private RootDataBrokerImpl createDomConnectedBroker(final ExecutorService listeningExecutor, final BindingIndependentMappingService mappingService) {
+        DomForwardedDataBrokerImpl forwardedBroker = new DomForwardedDataBrokerImpl();
+        forwardedBroker.setExecutor(listeningExecutor);
+        BindingIndependentConnector connector = BindingDomConnectorDeployer.createConnector(mappingService);
+        getDomBrokerDependency().registerProvider(forwardedBroker, null);
+        ProviderSession domContext = forwardedBroker.getDomProviderContext();
+        forwardedBroker.setConnector(connector);
+        forwardedBroker.setDomProviderContext(domContext);
+        forwardedBroker.startForwarding();
+        return forwardedBroker;
+    }
+
+}
index 9ce3ebf73f26793089c171126e33db8c6d3d956d..d3fc5ac215d7c201e66e9dfdf6022cc12d1fe3eb 100644 (file)
@@ -7,10 +7,6 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.binding.impl;
 
-import org.opendaylight.controller.config.api.DependencyResolver;
-import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
-import org.opendaylight.controller.config.spi.Module;
-import org.osgi.framework.BundleContext;
 
 /**
 *
@@ -18,21 +14,4 @@ import org.osgi.framework.BundleContext;
 public class DataBrokerImplModuleFactory extends
         org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractDataBrokerImplModuleFactory {
 
-    @Override
-    public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
-        DataBrokerImplModule module = (DataBrokerImplModule) super.createModule(instanceName, dependencyResolver,
-                bundleContext);
-        module.setBundleContext(bundleContext);
-        return module;
-    }
-
-    @Override
-    public Module createModule(String instanceName, DependencyResolver dependencyResolver,
-            DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
-        DataBrokerImplModule module = (DataBrokerImplModule) super.createModule(instanceName, dependencyResolver, old,
-                bundleContext);
-        module.setBundleContext(bundleContext);
-        return module;
-    }
-
 }
index 7467e544fdc8e2577447da8c62fca6319b7e3d0c..0ea30f7e66a817f63c63cc81e20f3890170ea7b5 100644 (file)
@@ -19,7 +19,6 @@ import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
 import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
-import org.osgi.framework.BundleContext;
 
 import com.google.common.util.concurrent.ListeningExecutorService;
 
@@ -30,8 +29,6 @@ public final class ForwardedCompatibleDataBrokerImplModule extends
         org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractForwardedCompatibleDataBrokerImplModule
         implements Provider {
 
-    private BundleContext bundleContext;
-
     public ForwardedCompatibleDataBrokerImplModule(
             final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
             final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -57,7 +54,7 @@ public final class ForwardedCompatibleDataBrokerImplModule extends
         BindingIndependentMappingService mappingService = getBindingMappingServiceDependency();
 
         Broker domBroker = getDomAsyncBrokerDependency();
-        ProviderSession session = domBroker.registerProvider(this, getBundleContext());
+        ProviderSession session = domBroker.registerProvider(this, null);
         DOMDataBroker domDataBroker = session.getService(DOMDataBroker.class);
         SchemaService schemaService = session.getService(SchemaService.class);
         ForwardedBackwardsCompatibleDataBroker dataBroker = new ForwardedBackwardsCompatibleDataBroker(domDataBroker,
@@ -68,14 +65,6 @@ public final class ForwardedCompatibleDataBrokerImplModule extends
         return dataBroker;
     }
 
-    public BundleContext getBundleContext() {
-        return bundleContext;
-    }
-
-    public void setBundleContext(final BundleContext bundleContext2) {
-        this.bundleContext = bundleContext2;
-    }
-
     @Override
     public void onSessionInitiated(final ProviderSession session) {
 
index f01977503e8239128ac5b3bb022d6c4278bc863b..5b5fb45fd9904eb80ece3e9de0faa56351f6f796 100644 (file)
@@ -7,10 +7,6 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.binding.impl;
 
-import org.opendaylight.controller.config.api.DependencyResolver;
-import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
-import org.opendaylight.controller.config.spi.Module;
-import org.osgi.framework.BundleContext;
 
 
 /**
@@ -19,20 +15,4 @@ import org.osgi.framework.BundleContext;
 public class ForwardedCompatibleDataBrokerImplModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractForwardedCompatibleDataBrokerImplModuleFactory
 {
 
-
-    @Override
-    public Module createModule(final String instanceName, final DependencyResolver dependencyResolver, final BundleContext bundleContext) {
-        ForwardedCompatibleDataBrokerImplModule module = (ForwardedCompatibleDataBrokerImplModule) super.createModule(instanceName, dependencyResolver, bundleContext);
-        module.setBundleContext(bundleContext);
-        return module;
-    }
-
-    @Override
-    public Module createModule(final String instanceName, final DependencyResolver dependencyResolver,
-            final DynamicMBeanWithInstance old, final BundleContext bundleContext) throws Exception {
-        ForwardedCompatibleDataBrokerImplModule module = (ForwardedCompatibleDataBrokerImplModule)  super.createModule(instanceName, dependencyResolver, old, bundleContext);
-        module.setBundleContext(bundleContext);
-        return module;
-    }
-
 }
index 0f0ce0dc9dd24fb41bc54bde70c196ba2d4d511e..823a4d9f322fe0b76726e7773bea0267132d45a5 100644 (file)
@@ -19,7 +19,7 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 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.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
 import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
@@ -127,13 +127,13 @@ public final class RuntimeMappingModule extends
         }
 
         @Override
-        public Entry<InstanceIdentifier, CompositeNode> toDataDom(
+        public Entry<YangInstanceIdentifier, CompositeNode> toDataDom(
                 Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> entry) {
             return delegate.toDataDom(entry);
         }
 
         @Override
-        public InstanceIdentifier toDataDom(
+        public YangInstanceIdentifier toDataDom(
                 org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path) {
             return delegate.toDataDom(path);
         }
@@ -146,7 +146,7 @@ public final class RuntimeMappingModule extends
         }
 
         @Override
-        public org.opendaylight.yangtools.yang.binding.InstanceIdentifier<?> fromDataDom(InstanceIdentifier entry)
+        public org.opendaylight.yangtools.yang.binding.InstanceIdentifier<?> fromDataDom(YangInstanceIdentifier entry)
                 throws DeserializationException {
             return delegate.fromDataDom(entry);
         }
index f24809de451dbb945f2eab0386bdedcb60f27f34..15e4a466cf688d67154d8a504cca0c5383d7feea 100644 (file)
@@ -7,9 +7,15 @@
  */
 package org.opendaylight.controller.md.sal.binding.impl;
 
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -29,6 +35,7 @@ import org.opendaylight.yangtools.concepts.Delegator;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
@@ -38,11 +45,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-
-public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBroker>, DomForwardedBroker,
-        SchemaContextListener, AutoCloseable {
+public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBroker>, DomForwardedBroker, SchemaContextListener, AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(AbstractForwardedDataBroker.class);
     // The Broker to whom we do all forwarding
@@ -88,17 +91,17 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
             final DataChangeScope triggeringScope) {
         DOMDataChangeListener domDataChangeListener = new TranslatingDataChangeInvoker(store, path, listener,
                 triggeringScope);
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = codec.toNormalized(path);
+        YangInstanceIdentifier domPath = codec.toNormalized(path);
         ListenerRegistration<DOMDataChangeListener> domRegistration = domDataBroker.registerDataChangeListener(store,
                 domPath, domDataChangeListener, triggeringScope);
         return new ListenerRegistrationImpl(listener, domRegistration);
     }
 
     protected Map<InstanceIdentifier<?>, DataObject> toBinding(
-            final Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, ? extends NormalizedNode<?, ?>> normalized) {
+            final Map<YangInstanceIdentifier, ? extends NormalizedNode<?, ?>> normalized) {
         Map<InstanceIdentifier<?>, DataObject> newMap = new HashMap<>();
-        for (Map.Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, ? extends NormalizedNode<?, ?>> entry : normalized
-                .entrySet()) {
+
+        for (Map.Entry<YangInstanceIdentifier, ? extends NormalizedNode<?, ?>> entry : sortedEntries(normalized)) {
             try {
                 Optional<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> potential = getCodec().toBinding(
                         entry);
@@ -113,10 +116,43 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
         return newMap;
     }
 
+    private static final Comparator<Entry<YangInstanceIdentifier, ?>> MAP_ENTRY_COMPARATOR = new Comparator<Entry<YangInstanceIdentifier, ?>>() {
+        @Override
+        public int compare(final Entry<YangInstanceIdentifier, ?> left,
+                final Entry<YangInstanceIdentifier, ?> right) {
+            final Iterator<?> li = left.getKey().getPathArguments().iterator();
+            final Iterator<?> ri = right.getKey().getPathArguments().iterator();
+
+            // Iterate until left is exhausted...
+            while (li.hasNext()) {
+                if (!ri.hasNext()) {
+                    // Left is deeper
+                    return 1;
+                }
+
+                li.next();
+                ri.next();
+            }
+
+            // Check if right is exhausted
+            return ri.hasNext() ? -1 : 0;
+        }
+    };
+
+    private static <T> Iterable<Entry<YangInstanceIdentifier,T>> sortedEntries(final Map<YangInstanceIdentifier, T> map) {
+        if (!map.isEmpty()) {
+            ArrayList<Entry<YangInstanceIdentifier, T>> entries = new ArrayList<>(map.entrySet());
+            Collections.sort(entries, MAP_ENTRY_COMPARATOR);
+            return entries;
+        } else {
+            return Collections.emptySet();
+        }
+    }
+
     protected Set<InstanceIdentifier<?>> toBinding(
-            final Set<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> normalized) {
+            final Set<YangInstanceIdentifier> normalized) {
         Set<InstanceIdentifier<?>> hashSet = new HashSet<>();
-        for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath : normalized) {
+        for (YangInstanceIdentifier normalizedPath : normalized) {
             try {
                 Optional<InstanceIdentifier<? extends DataObject>> potential = getCodec().toBinding(normalizedPath);
                 if (potential.isPresent()) {
@@ -158,24 +194,24 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
 
         @Override
         public void onDataChanged(
-                final AsyncDataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> change) {
+                final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
             bindingDataChangeListener.onDataChanged(new TranslatedDataChangeEvent(change, path));
         }
     }
 
     private class TranslatedDataChangeEvent implements AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> {
-        private final AsyncDataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> domEvent;
+        private final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> domEvent;
         private final InstanceIdentifier<?> path;
 
         private Map<InstanceIdentifier<?>, DataObject> createdCache;
         private Map<InstanceIdentifier<?>, DataObject> updatedCache;
-        private Map<InstanceIdentifier<?>, ? extends DataObject> originalCache;
+        private Map<InstanceIdentifier<?>, DataObject> originalCache;
         private Set<InstanceIdentifier<?>> removedCache;
         private Optional<DataObject> originalDataCache;
         private Optional<DataObject> updatedDataCache;
 
         public TranslatedDataChangeEvent(
-                final AsyncDataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> change,
+                final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change,
                 final InstanceIdentifier<?> path) {
             this.domEvent = change;
             this.path = path;
@@ -207,7 +243,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
         }
 
         @Override
-        public Map<InstanceIdentifier<?>, ? extends DataObject> getOriginalData() {
+        public Map<InstanceIdentifier<?>, DataObject> getOriginalData() {
             if (originalCache == null) {
                 originalCache = Collections.unmodifiableMap(toBinding(domEvent.getOriginalData()));
             }
index 3fac0dc93adf55b47002abedeff09ad0646d5726..e52fcdce23a075dfbc06a79401868d7d88ee3873 100644 (file)
  */
 package org.opendaylight.controller.md.sal.binding.impl;
 
-import java.util.ArrayList;
-import java.util.EnumMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.Nullable;
-
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
-import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.yangtools.concepts.Delegator;
+import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Function;
 import com.google.common.base.Optional;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
+import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 
-public class AbstractForwardedTransaction<T extends AsyncTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>>>
-        implements Delegator<T> {
 
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractForwardedTransaction.class);
+abstract class AbstractForwardedTransaction<T extends AsyncTransaction<YangInstanceIdentifier, NormalizedNode<?, ?>>>
+        implements Delegator<T>, Identifiable<Object> {
+
     private final T delegate;
-    private final static CacheBuilder<Object, Object> CACHE_BUILDER = CacheBuilder.newBuilder()
-            .expireAfterWrite(10, TimeUnit.MILLISECONDS).maximumSize(100);
     private final BindingToNormalizedNodeCodec codec;
-    private final EnumMap<LogicalDatastoreType, Cache<InstanceIdentifier<?>, DataObject>> cacheMap;
 
-    protected AbstractForwardedTransaction(final T delegate, final BindingToNormalizedNodeCodec codec) {
-        super();
-        this.delegate = delegate;
-        this.codec = codec;
+    public AbstractForwardedTransaction(final T delegateTx, final BindingToNormalizedNodeCodec codec) {
+        this.delegate = Preconditions.checkNotNull(delegateTx, "Delegate must not be null");
+        this.codec = Preconditions.checkNotNull(codec, "Codec must not be null");
+    }
 
-        this.cacheMap = new EnumMap<>(LogicalDatastoreType.class);
-        cacheMap.put(LogicalDatastoreType.OPERATIONAL, CACHE_BUILDER.<InstanceIdentifier<?>, DataObject> build());
-        cacheMap.put(LogicalDatastoreType.CONFIGURATION, CACHE_BUILDER.<InstanceIdentifier<?>, DataObject> build());
 
+    @Override
+    public final  Object getIdentifier() {
+        return delegate.getIdentifier();
     }
 
     @Override
-    public T getDelegate() {
+    public final  T getDelegate() {
         return delegate;
     }
 
-    protected final BindingToNormalizedNodeCodec getCodec() {
-        return codec;
-    }
-
-    protected ListenableFuture<Optional<DataObject>> transformFuture(final LogicalDatastoreType store,
-            final InstanceIdentifier<?> path, final ListenableFuture<Optional<NormalizedNode<?, ?>>> future) {
-        return Futures.transform(future, new Function<Optional<NormalizedNode<?, ?>>, Optional<DataObject>>() {
-            @Nullable
-            @Override
-            public Optional<DataObject> apply(@Nullable final Optional<NormalizedNode<?, ?>> normalizedNode) {
-                if (normalizedNode.isPresent()) {
-                    final DataObject dataObject;
-                    try {
-                        dataObject = codec.toBinding(path, normalizedNode.get());
-                    } catch (DeserializationException e) {
-                        LOG.warn("Failed to create dataobject from node {}", normalizedNode.get(), e);
-                        throw new IllegalStateException("Failed to create dataobject", e);
-                    }
-
-                    if (dataObject != null) {
-                        updateCache(store, path, dataObject);
-                        return Optional.of(dataObject);
-                    }
-                }
-                return Optional.absent();
-            }
-        });
-    }
-
-    protected void doPut(final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType store,
-            final InstanceIdentifier<?> path, final DataObject data) {
-        invalidateCache(store, path);
-        final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> normalized = codec
-                .toNormalizedNode(path, data);
-        writeTransaction.put(store, normalized.getKey(), normalized.getValue());
-    }
-
-    protected void doPutWithEnsureParents(final DOMDataReadWriteTransaction writeTransaction,
-            final LogicalDatastoreType store, final InstanceIdentifier<?> path, final DataObject data) {
-        invalidateCache(store, path);
-        final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> normalized = codec
-                .toNormalizedNode(path, data);
-
-        final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
-        ensureParentsByMerge(writeTransaction, store, normalizedPath, path);
-        LOG.debug("Tx: {} : Putting data {}", getDelegate().getIdentifier(), normalizedPath);
-        writeTransaction.put(store, normalizedPath, normalized.getValue());
-    }
-
-    protected void doMergeWithEnsureParents(final DOMDataReadWriteTransaction writeTransaction,
-            final LogicalDatastoreType store, final InstanceIdentifier<?> path, final DataObject data) {
-        invalidateCache(store, path);
-        final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> normalized = codec
-                .toNormalizedNode(path, data);
-
-        final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
-        ensureParentsByMerge(writeTransaction, store, normalizedPath, path);
-        LOG.debug("Tx: {} : Merge data {}",getDelegate().getIdentifier(),normalizedPath);
-        writeTransaction.merge(store, normalizedPath, normalized.getValue());
+    @SuppressWarnings("unchecked")
+    protected final <S extends AsyncTransaction<YangInstanceIdentifier, NormalizedNode<?, ?>>> S getDelegateChecked(final Class<S> txType) {
+        Preconditions.checkState(txType.isInstance(delegate));
+        return (S) delegate;
     }
 
-    private void ensureParentsByMerge(final DOMDataReadWriteTransaction writeTransaction,
-            final LogicalDatastoreType store,
-            final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath,
-            final InstanceIdentifier<?> path) {
-        List<PathArgument> currentArguments = new ArrayList<>();
-        DataNormalizationOperation<?> currentOp = codec.getDataNormalizer().getRootOperation();
-        Iterator<PathArgument> iterator = normalizedPath.getPath().iterator();
-        while (iterator.hasNext()) {
-            PathArgument currentArg = iterator.next();
-            try {
-                currentOp = currentOp.getChild(currentArg);
-            } catch (DataNormalizationException e) {
-                throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", path), e);
-            }
-            currentArguments.add(currentArg);
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier currentPath = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(
-                    currentArguments);
-
-            final Optional<NormalizedNode<?, ?>> d;
-            try {
-                d = writeTransaction.read(store, currentPath).get();
-            } catch (InterruptedException | ExecutionException e) {
-                LOG.error("Failed to read pre-existing data from store {} path {}", store, currentPath, e);
-                throw new IllegalStateException("Failed to read pre-existing data", e);
-            }
-
-            if (!d.isPresent() && iterator.hasNext()) {
-                writeTransaction.merge(store, currentPath, currentOp.createDefault(currentArg));
-            }
-        }
-    }
-
-    protected void doMerge(final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType store,
-            final InstanceIdentifier<?> path, final DataObject data) {
-        invalidateCache(store, path);
-        final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> normalized = codec
-                .toNormalizedNode(path, data);
-        writeTransaction.merge(store, normalized.getKey(), normalized.getValue());
-    }
-
-    protected void doDelete(final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType store,
-            final InstanceIdentifier<?> path) {
-        invalidateCache(store, path);
-        final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized = codec.toNormalized(path);
-        writeTransaction.delete(store, normalized);
-    }
-
-    protected ListenableFuture<RpcResult<TransactionStatus>> doCommit(final DOMDataWriteTransaction writeTransaction) {
-        return writeTransaction.commit();
-    }
-
-    protected boolean doCancel(final DOMDataWriteTransaction writeTransaction) {
-        return writeTransaction.cancel();
-    }
-
-    protected ListenableFuture<Optional<DataObject>> doRead(final DOMDataReadTransaction readTransaction,
-            final LogicalDatastoreType store, final InstanceIdentifier<?> path) {
-        final DataObject dataObject = getFromCache(store, path);
-        if (dataObject == null) {
-            final ListenableFuture<Optional<NormalizedNode<?, ?>>> future = readTransaction.read(store,
-                    codec.toNormalized(path));
-            return transformFuture(store, path, future);
-        } else {
-            return Futures.immediateFuture(Optional.of(dataObject));
-        }
-    }
-
-    private DataObject getFromCache(final LogicalDatastoreType store, final InstanceIdentifier<?> path) {
-        Cache<InstanceIdentifier<?>, DataObject> cache = cacheMap.get(store);
-        if (cache != null) {
-            return cache.getIfPresent(path);
-        }
-        return null;
-    }
-
-    private void updateCache(final LogicalDatastoreType store, final InstanceIdentifier<?> path,
-            final DataObject dataObject) {
-        // Check if cache exists. If not create one.
-        Cache<InstanceIdentifier<?>, DataObject> cache = cacheMap.get(store);
-        if (cache == null) {
-            cache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterWrite(1, TimeUnit.MINUTES).build();
-
-        }
-
-        cache.put(path, dataObject);
+    protected final BindingToNormalizedNodeCodec getCodec() {
+        return codec;
     }
 
-    private void invalidateCache(final LogicalDatastoreType store, final InstanceIdentifier<?> path) {
-        // FIXME: Optimization: invalidate only parents and children of path
-        Cache<InstanceIdentifier<?>, DataObject> cache = cacheMap.get(store);
-        cache.invalidateAll();
-        LOG.trace("Cache invalidated");
+    protected final <T extends DataObject> ListenableFuture<Optional<T>> doRead(final DOMDataReadTransaction readTx,
+            final LogicalDatastoreType store, final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<T> path) {
+        return Futures.transform(readTx.read(store, codec.toNormalized(path)), codec.deserializeFunction(path));
     }
-
 }
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractReadWriteTransaction.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractReadWriteTransaction.java
new file mode 100644 (file)
index 0000000..5ced7ba
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+public class AbstractReadWriteTransaction extends AbstractWriteTransaction<DOMDataReadWriteTransaction> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractReadWriteTransaction.class);
+
+    public AbstractReadWriteTransaction(final DOMDataReadWriteTransaction delegate, final BindingToNormalizedNodeCodec codec) {
+        super(delegate, codec);
+    }
+
+    @Override
+    protected final void ensureParentsByMerge(final LogicalDatastoreType store,
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalizedPath,
+            final InstanceIdentifier<?> path) {
+        List<PathArgument> currentArguments = new ArrayList<>();
+        DataNormalizationOperation<?> currentOp = getCodec().getDataNormalizer().getRootOperation();
+        Iterator<PathArgument> iterator = normalizedPath.getPathArguments().iterator();
+        while (iterator.hasNext()) {
+            PathArgument currentArg = iterator.next();
+            try {
+                currentOp = currentOp.getChild(currentArg);
+            } catch (DataNormalizationException e) {
+                throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", path), e);
+            }
+            currentArguments.add(currentArg);
+            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier currentPath = org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.create(
+                    currentArguments);
+
+            final Optional<NormalizedNode<?, ?>> d;
+            try {
+                d = getDelegate().read(store, currentPath).get();
+            } catch (InterruptedException | ExecutionException e) {
+                LOG.error("Failed to read pre-existing data from store {} path {}", store, currentPath, e);
+                throw new IllegalStateException("Failed to read pre-existing data", e);
+            }
+
+            if (!d.isPresent() && iterator.hasNext()) {
+                getDelegate().merge(store, currentPath, currentOp.createDefault(currentArg));
+            }
+        }
+    }
+
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractWriteTransaction.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractWriteTransaction.java
new file mode 100644 (file)
index 0000000..65a9c1a
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl;
+
+import java.util.Collections;
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+import com.google.common.util.concurrent.CheckedFuture;
+
+/**
+ *
+ * Abstract Base Transaction for transactions which are backed by
+ * {@link DOMDataWriteTransaction}
+ */
+public abstract class AbstractWriteTransaction<T extends DOMDataWriteTransaction> extends
+        AbstractForwardedTransaction<T> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractWriteTransaction.class);
+
+    protected AbstractWriteTransaction(final T delegate,
+            final BindingToNormalizedNodeCodec codec) {
+        super(delegate, codec);
+    }
+
+
+    public final <U extends DataObject> void put(final LogicalDatastoreType store,
+            final InstanceIdentifier<U> path, final U data, final boolean createParents) {
+       final Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>> normalized = getCodec()
+                .toNormalizedNode(path, data);
+        if(createParents) {
+            ensureParentsByMerge(store, normalized.getKey(), path);
+        } else {
+            ensureListParentIfNeeded(store,path,normalized);
+        }
+        getDelegate().put(store, normalized.getKey(), normalized.getValue());
+    }
+
+
+    public final <U extends DataObject> void merge(final LogicalDatastoreType store,
+            final InstanceIdentifier<U> path, final U data,final boolean createParents) {
+
+        final Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>> normalized = getCodec()
+                .toNormalizedNode(path, data);
+
+        if(createParents) {
+            ensureParentsByMerge(store, normalized.getKey(), path);
+        } else {
+            ensureListParentIfNeeded(store,path,normalized);
+        }
+
+        getDelegate().merge(store, normalized.getKey(), normalized.getValue());
+    }
+
+
+    /**
+     *
+     * Ensures list parent if item is list, otherwise noop.
+     *
+     * <p>
+     * One of properties of binding specification is that it is imposible
+     * to represent list as a whole and thus it is impossible to write
+     * empty variation of MapNode without creating parent node, with
+     * empty list.
+     *
+     * <p>
+     * This actually makes writes such as
+     * <pre>
+     * put("Nodes", new NodesBuilder().build());
+     * put("Nodes/Node[key]", new NodeBuilder().setKey("key").build());
+     * </pre>
+     * To result in three DOM operations:
+     * <pre>
+     * put("/nodes",domNodes);
+     * merge("/nodes/node",domNodeList);
+     * put("/nodes/node/node[key]",domNode);
+     * </pre>
+     *
+     *
+     * In order to allow that to be inserted if necessary, if we know
+     * item is list item, we will try to merge empty MapNode or OrderedNodeMap
+     * to ensure list exists.
+     *
+     * @param store Data Store type
+     * @param path Path to data (Binding Aware)
+     * @param normalized Normalized version of data to be written
+     */
+    private void ensureListParentIfNeeded(final LogicalDatastoreType store, final InstanceIdentifier<?> path,
+            final Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>> normalized) {
+        if(Identifiable.class.isAssignableFrom(path.getTargetType())) {
+            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier parentMapPath = getParent(normalized.getKey()).get();
+            NormalizedNode<?, ?> emptyParent = getCodec().getDefaultNodeFor(parentMapPath);
+            getDelegate().merge(store, parentMapPath, emptyParent);
+        }
+
+    }
+
+    // FIXME (should be probaly part of InstanceIdentifier)
+    protected static Optional<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier> getParent(
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier child) {
+
+        Iterable<PathArgument> mapEntryItemPath = child.getPathArguments();
+        int parentPathSize = Iterables.size(mapEntryItemPath) - 1;
+        if(parentPathSize > 1) {
+            return Optional.of(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.create(Iterables.limit(mapEntryItemPath,  parentPathSize)));
+        } else if(parentPathSize == 0) {
+            return Optional.of(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.create(Collections.<PathArgument>emptyList()));
+        } else {
+            return Optional.absent();
+        }
+    }
+
+    /**
+     * Subclasses of this class are required to implement creation of parent
+     * nodes based on behaviour of their underlying transaction.
+     *
+     * @param store
+     * @param key
+     * @param path
+     */
+    protected abstract void ensureParentsByMerge(LogicalDatastoreType store,
+            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier key, InstanceIdentifier<?> path);
+
+    protected final void doDelete(final LogicalDatastoreType store,
+            final InstanceIdentifier<?> path) {
+        final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized = getCodec().toNormalized(path);
+        getDelegate().delete(store, normalized);
+    }
+
+    protected final CheckedFuture<Void,TransactionCommitFailedException> doSubmit() {
+        return getDelegate().submit();
+    }
+
+    protected final boolean doCancel() {
+        return getDelegate().cancel();
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDataReadTransactionImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDataReadTransactionImpl.java
new file mode 100644 (file)
index 0000000..bb94204
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+
+class BindingDataReadTransactionImpl extends AbstractForwardedTransaction<DOMDataReadOnlyTransaction> implements
+        ReadOnlyTransaction {
+
+    protected BindingDataReadTransactionImpl(final DOMDataReadOnlyTransaction delegate,
+            final BindingToNormalizedNodeCodec codec) {
+        super(delegate, codec);
+    }
+
+    @Override
+    public <T extends DataObject> ListenableFuture<Optional<T>> read(final LogicalDatastoreType store,
+            final InstanceIdentifier<T> path) {
+        return doRead(getDelegate(),store, path);
+    }
+
+    @Override
+    public void close() {
+        getDelegate().close();
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDataReadWriteTransactionImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDataReadWriteTransactionImpl.java
new file mode 100644 (file)
index 0000000..c8b9d93
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+
+class BindingDataReadWriteTransactionImpl extends
+        BindingDataWriteTransactionImpl<DOMDataReadWriteTransaction> implements ReadWriteTransaction {
+
+    protected BindingDataReadWriteTransactionImpl(final DOMDataReadWriteTransaction delegate,
+            final BindingToNormalizedNodeCodec codec) {
+        super(delegate, codec);
+    }
+
+    @Override
+    public <T extends DataObject> ListenableFuture<Optional<T>> read(final LogicalDatastoreType store,
+            final InstanceIdentifier<T> path) {
+        return doRead(getDelegate(), store, path);
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDataWriteTransactionImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDataWriteTransactionImpl.java
new file mode 100644 (file)
index 0000000..f261deb
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.ListenableFuture;
+
+class BindingDataWriteTransactionImpl<T extends DOMDataWriteTransaction> extends
+        AbstractWriteTransaction<T> implements WriteTransaction {
+
+    protected BindingDataWriteTransactionImpl(final T delegateTx, final BindingToNormalizedNodeCodec codec) {
+        super(delegateTx, codec);
+    }
+
+    @Override
+    public <U extends DataObject> void put(final LogicalDatastoreType store, final InstanceIdentifier<U> path,
+                                           final U data) {
+        put(store, path, data,false);
+    }
+
+    @Override
+    public <T extends DataObject> void merge(final LogicalDatastoreType store, final InstanceIdentifier<T> path,
+                                             final T data) {
+        merge(store, path, data,false);
+    }
+
+
+    @Override
+    protected void ensureParentsByMerge(final LogicalDatastoreType store,
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalizedPath, final InstanceIdentifier<?> path) {
+        List<PathArgument> currentArguments = new ArrayList<>();
+        DataNormalizationOperation<?> currentOp = getCodec().getDataNormalizer().getRootOperation();
+        Iterator<PathArgument> iterator = normalizedPath.getPathArguments().iterator();
+        while (iterator.hasNext()) {
+            PathArgument currentArg = iterator.next();
+            try {
+                currentOp = currentOp.getChild(currentArg);
+            } catch (DataNormalizationException e) {
+                throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", path), e);
+            }
+            currentArguments.add(currentArg);
+            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier currentPath = org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.create(
+                    currentArguments);
+
+            getDelegate().merge(store, currentPath, currentOp.createDefault(currentArg));
+        }
+    }
+
+    @Override
+    public void delete(final LogicalDatastoreType store, final InstanceIdentifier<?> path) {
+        doDelete( store, path);
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<TransactionStatus>> commit() {
+        return AbstractDataTransaction.convertToLegacyCommitFuture(submit());
+    }
+
+    @Override
+    public CheckedFuture<Void,TransactionCommitFailedException> submit() {
+        return doSubmit();
+    }
+
+    @Override
+    public boolean cancel() {
+        return doCancel();
+    }
+}
\ No newline at end of file
index f1be5c6922ecda45cc75f343b3f6355e402e013d..66caaea7083af18f1ffaedc3113f4e35d167b4ff 100644 (file)
@@ -8,27 +8,30 @@
 package org.opendaylight.controller.md.sal.binding.impl;
 
 import java.lang.reflect.Method;
-import java.lang.reflect.Type;
 import java.util.AbstractMap.SimpleEntry;
-import java.util.LinkedList;
-import java.util.List;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.annotation.Nullable;
 
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.BindingMapping;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
-import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
@@ -37,13 +40,18 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Function;
 import com.google.common.base.Optional;
-import com.google.common.base.Supplier;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
@@ -59,7 +67,7 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
         this.bindingToLegacy = mappingService;
     }
 
-    public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toNormalized(
+    public org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier toNormalized(
             final InstanceIdentifier<? extends DataObject> binding) {
 
         // Used instance-identifier codec do not support serialization of last
@@ -73,31 +81,30 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
         return toNormalizedImpl(binding);
     }
 
-    public Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> toNormalizedNode(
+    public Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>> toNormalizedNode(
             final InstanceIdentifier<? extends DataObject> bindingPath, final DataObject bindingObject) {
-        return toNormalizedNode(toEntry(bindingPath, bindingObject));
+        return toNormalizedNode(toBindingEntry(bindingPath, bindingObject));
 
     }
 
-    public Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> toNormalizedNode(
+    public Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>> toNormalizedNode(
             final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> binding) {
-        Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> legacyEntry = bindingToLegacy
+        Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> legacyEntry = bindingToLegacy
                 .toDataDom(binding);
-        Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> normalizedEntry = legacyToNormalized
+        Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedEntry = legacyToNormalized
                 .toNormalized(legacyEntry);
         LOG.trace("Serialization of {}, Legacy Representation: {}, Normalized Representation: {}", binding,
                 legacyEntry, normalizedEntry);
-        if (Augmentation.class.isAssignableFrom(binding.getKey().getTargetType())) {
+        if (isAugmentation(binding.getKey().getTargetType())) {
 
             for (DataContainerChild<? extends PathArgument, ?> child : ((DataContainerNode<?>) normalizedEntry
                     .getValue()).getValue()) {
                 if (child instanceof AugmentationNode) {
                     ImmutableList<PathArgument> childArgs = ImmutableList.<PathArgument> builder()
-                            .addAll(normalizedEntry.getKey().getPath()).add(child.getIdentifier()).build();
-                    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier childPath = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(
-                            childArgs);
-                    return new SimpleEntry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>>(
-                            childPath, child);
+                            .addAll(normalizedEntry.getKey().getPathArguments()).add(child.getIdentifier()).build();
+                    org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier childPath = org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier
+                            .create(childArgs);
+                    return toDOMEntry(childPath, child);
                 }
             }
 
@@ -116,10 +123,10 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
      *
      */
     public Optional<InstanceIdentifier<? extends DataObject>> toBinding(
-            final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
-            throws DeserializationException {
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized)
+                    throws DeserializationException {
 
-        PathArgument lastArgument = Iterables.getLast(normalized.getPath());
+        PathArgument lastArgument = Iterables.getLast(normalized.getPathArguments());
         // Used instance-identifier codec do not support serialization of last
         // path
         // argument if it is AugmentationIdentifier (behaviour expected by old
@@ -133,8 +140,8 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
     }
 
     private Optional<InstanceIdentifier<? extends DataObject>> toBindingAugmented(
-            final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
-            throws DeserializationException {
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized)
+                    throws DeserializationException {
         Optional<InstanceIdentifier<? extends DataObject>> potential = toBindingImpl(normalized);
         // Shorthand check, if codec already supports deserialization
         // of AugmentationIdentifier we will return
@@ -143,7 +150,7 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
         }
 
         int normalizedCount = getAugmentationCount(normalized);
-        AugmentationIdentifier lastArgument = (AugmentationIdentifier) Iterables.getLast(normalized.getPath());
+        AugmentationIdentifier lastArgument = (AugmentationIdentifier) Iterables.getLast(normalized.getPathArguments());
 
         // Here we employ small trick - Binding-aware Codec injects an pointer
         // to augmentation class
@@ -151,9 +158,7 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
         // path.
         LOG.trace("Looking for candidates to match {}", normalized);
         for (QName child : lastArgument.getPossibleChildNames()) {
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier childPath = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(
-                    ImmutableList.<PathArgument> builder().addAll(normalized.getPath()).add(new NodeIdentifier(child))
-                            .build());
+            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier childPath = normalized.node(child);
             try {
                 if (isNotRepresentable(childPath)) {
                     LOG.trace("Path {} is not BI-representable, skipping it", childPath);
@@ -185,9 +190,9 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
     }
 
     private Optional<InstanceIdentifier<? extends DataObject>> toBindingImpl(
-            final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
-            throws DeserializationException {
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier legacyPath;
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized)
+                    throws DeserializationException {
+        org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier legacyPath;
 
         try {
             if (isNotRepresentable(normalized)) {
@@ -202,35 +207,41 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
         return Optional.<InstanceIdentifier<? extends DataObject>> of(bindingToLegacy.fromDataDom(legacyPath));
     }
 
-    private boolean isNotRepresentable(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
+    private boolean isNotRepresentable(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized)
             throws DataNormalizationException {
         DataNormalizationOperation<?> op = findNormalizationOperation(normalized);
-        ifop.isMixin() && op.getIdentifier() instanceof NodeIdentifier) {
+        if (op.isMixin() && op.getIdentifier() instanceof NodeIdentifier) {
             return true;
         }
-        if(op.isLeaf()) {
+        if (op.isLeaf()) {
             return true;
         }
         return false;
     }
 
     private DataNormalizationOperation<?> findNormalizationOperation(
-            final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
-            throws DataNormalizationException {
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized)
+                    throws DataNormalizationException {
         DataNormalizationOperation<?> current = legacyToNormalized.getRootOperation();
-        for (PathArgument arg : normalized.getPath()) {
+        for (PathArgument arg : normalized.getPathArguments()) {
             current = current.getChild(arg);
         }
         return current;
     }
 
-    private static final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> toEntry(
+    private static final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> toBindingEntry(
             final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> key,
             final DataObject value) {
         return new SimpleEntry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject>(
                 key, value);
     }
 
+    private static final Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>> toDOMEntry(
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier key, final NormalizedNode<?, ?> value) {
+        return new SimpleEntry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>>(key,
+                value);
+    }
+
     public DataObject toBinding(final InstanceIdentifier<?> path, final NormalizedNode<?, ?> normalizedNode)
             throws DeserializationException {
         CompositeNode legacy = null;
@@ -253,8 +264,8 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
     }
 
     public Optional<Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject>> toBinding(
-            final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, ? extends NormalizedNode<?, ?>> normalized)
-            throws DeserializationException {
+            final Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, ? extends NormalizedNode<?, ?>> normalized)
+                    throws DeserializationException {
         Optional<InstanceIdentifier<? extends DataObject>> potentialPath = toBinding(normalized.getKey());
         if (potentialPath.isPresent()) {
             InstanceIdentifier<? extends DataObject> bindingPath = potentialPath.get();
@@ -262,7 +273,7 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
             if (bindingData == null) {
                 LOG.warn("Failed to deserialize {} to Binding format. Binding path is: {}", normalized, bindingPath);
             }
-            return Optional.of(toEntry(bindingPath, bindingData));
+            return Optional.of(toBindingEntry(bindingPath, bindingData));
         } else {
             return Optional.absent();
         }
@@ -273,46 +284,173 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
         legacyToNormalized = new DataNormalizer(arg0);
     }
 
-    private org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toNormalizedAugmented(
+    private org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier toNormalizedAugmented(
             final InstanceIdentifier<?> augPath) {
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier processed = toNormalizedImpl(augPath);
+        org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier processed = toNormalizedImpl(augPath);
         // If used instance identifier codec added supports for deserialization
         // of last AugmentationIdentifier we will just reuse it
         if (isAugmentationIdentifier(processed)) {
             return processed;
         }
-        // Here we employ small trick - DataNormalizer injects augmentation
-        // identifier if child is
-        // also part of the path (since using a child we can safely identify
-        // augmentation)
-        // so, we scan augmentation for children add it to path
-        // and use original algorithm, then shorten it to last augmentation
-        for (@SuppressWarnings("rawtypes")
-        Class augChild : getAugmentationChildren(augPath.getTargetType())) {
+        Optional<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier> additionalSerialized;
+        additionalSerialized = toNormalizedAugmentedUsingChildContainers(augPath, processed);
+
+        if (additionalSerialized.isPresent()) {
+            return additionalSerialized.get();
+        }
+        additionalSerialized = toNormalizedAugmentedUsingChildLeafs(augPath, processed);
+        if (additionalSerialized.isPresent()) {
+            return additionalSerialized.get();
+        }
+        throw new IllegalStateException("Unabled to construct augmentation identfier for " + augPath);
+    }
+
+    /**
+     * Tries to find correct augmentation identifier using children leafs
+     *
+     * This method uses normalized Instance Identifier of parent node to fetch
+     * schema and {@link BindingReflections#getModuleInfo(Class)} to learn about
+     * augmentation namespace, specificly, in which module it was defined.
+     *
+     * Then it uses it to filter all available augmentations for parent by
+     * module. After that it walks augmentations in particular module and
+     * pick-up first which at least one leaf name matches supplied augmentation.
+     * We could do this safely since YANG explicitly states that no any existing
+     * augmentations must differ in leaf fully qualified names.
+     *
+     *
+     * @param augPath
+     *            Binding Aware Path which ends with augment
+     * @param parentPath
+     *            Processed path
+     * @return
+     */
+    private Optional<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier> toNormalizedAugmentedUsingChildLeafs(
+            final InstanceIdentifier<?> augPath,
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier parentPath) {
+        try {
+            DataNormalizationOperation<?> parentOp = legacyToNormalized.getOperation(parentPath);
+            if(!parentOp.getDataSchemaNode().isPresent()) {
+                return Optional.absent();
+            }
+            DataSchemaNode parentSchema = parentOp.getDataSchemaNode().get();
+            if (parentSchema instanceof AugmentationTarget) {
+                Set<AugmentationSchema> augmentations = ((AugmentationTarget) parentSchema).getAvailableAugmentations();
+                LOG.info("Augmentations for {}, {}", augPath, augmentations);
+                Optional<AugmentationSchema> schema = findAugmentation(augPath.getTargetType(), augmentations);
+                if (schema.isPresent()) {
+                    AugmentationIdentifier augmentationIdentifier = DataNormalizationOperation
+                            .augmentationIdentifierFrom(schema.get());
+                    return Optional.of(parentPath.node(augmentationIdentifier));
+                }
+            }
+        } catch (DataNormalizationException e) {
+            throw new IllegalArgumentException(e);
+        }
+        return Optional.absent();
+    }
+
+    /**
+     * Creates instance identifier for augmentation child, tries to serialize it
+     * Instance Identifier is then shortened to last augmentation.
+     *
+     * This is for situations, where underlying codec is implementing hydrogen
+     * style DOM APIs (which did not supported {@link AugmentationIdentifier}.)
+     *
+     * @param augPath
+     * @param parentPath
+     *            Path to parent node
+     * @return
+     */
+    @SuppressWarnings("rawtypes")
+    private Optional<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier> toNormalizedAugmentedUsingChildContainers(
+            final InstanceIdentifier<?> augPath,
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier parentPath) {
+        for (Class augChild : BindingReflections.getChildrenClasses(augPath.getTargetType())) {
             @SuppressWarnings("unchecked")
             InstanceIdentifier<?> childPath = augPath.child(augChild);
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized = toNormalizedImpl(childPath);
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier potentialDiscovered = shortenToLastAugmentation(normalized);
+            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized = toNormalizedImpl(childPath);
+            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier potentialDiscovered = shortenToLastAugmentation(
+                    normalized, parentPath);
             if (potentialDiscovered != null) {
-                return potentialDiscovered;
+                return Optional.of(potentialDiscovered);
             }
         }
-        return processed;
+        return Optional.absent();
+    }
+
+    private Optional<AugmentationSchema> findAugmentation(final Class<?> targetType,
+            final Set<AugmentationSchema> augmentations) {
+        YangModuleInfo moduleInfo;
+        try {
+            moduleInfo = BindingReflections.getModuleInfo(targetType);
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+        Iterable<AugmentationSchema> filtered = filteredByModuleInfo(augmentations,
+                BindingReflections.getModuleQName(moduleInfo).getModule());
+        filtered.toString();
+        Set<String> targetTypeGetters = getYangModeledGetters(targetType);
+        for (AugmentationSchema schema : filtered) {
+            for (DataSchemaNode child : schema.getChildNodes()) {
+                String getterName = "get" + BindingMapping.getClassName(child.getQName());
+                if (targetTypeGetters.contains(getterName)) {
+                    return Optional.of(schema);
+                }
+            }
+        }
+        return Optional.absent();
+    }
+
+    private static Iterable<AugmentationSchema> filteredByModuleInfo(final Iterable<AugmentationSchema> augmentations,
+            final QNameModule module) {
+        return Iterables.filter(augmentations, new Predicate<AugmentationSchema>() {
+            @Override
+            public boolean apply(final AugmentationSchema schema) {
+                final Collection<DataSchemaNode> childNodes = schema.getChildNodes();
+                return !childNodes.isEmpty() && module.equals(Iterables.get(childNodes, 0).getQName().getModule());
+            }
+        });
+    }
+
+    public static final Set<String> getYangModeledGetters(final Class<?> targetType) {
+        HashSet<String> ret = new HashSet<String>();
+        for (Method method : targetType.getMethods()) {
+            if (isYangModeledGetter(method)) {
+                ret.add(method.getName());
+            }
+        }
+        return ret;
     }
 
-    private org.opendaylight.yangtools.yang.data.api.InstanceIdentifier shortenToLastAugmentation(
-            final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized) {
+    /**
+     *
+     * Returns true if supplied method represent getter for YANG modeled value
+     *
+     * @param method
+     *            Method to be tested
+     * @return true if method represent getter for YANG Modeled value.
+     */
+    private static final boolean isYangModeledGetter(final Method method) {
+        return !method.getName().equals("getClass") && !method.getName().equals("getImplementedInterface")
+                && method.getName().startsWith("get") && method.getParameterTypes().length == 0;
+    }
+
+    private org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier shortenToLastAugmentation(
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized,
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier parentPath) {
+        int parentSize = Iterables.size(parentPath.getPathArguments());
         int position = 0;
         int foundPosition = -1;
-        for (PathArgument arg : normalized.getPath()) {
+        for (PathArgument arg : normalized.getPathArguments()) {
             position++;
             if (arg instanceof AugmentationIdentifier) {
                 foundPosition = position;
             }
         }
-        if (foundPosition > 0) {
-            return new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(normalized.getPath().subList(0,
-                    foundPosition));
+        if (foundPosition > 0 && foundPosition > parentSize) {
+            Iterable<PathArgument> shortened = Iterables.limit(normalized.getPathArguments(), foundPosition);
+            return org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.create(shortened);
         }
         return null;
     }
@@ -330,71 +468,15 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
         return InstanceIdentifier.create(Iterables.limit(binding.getPathArguments(), foundPosition));
     }
 
-    private org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toNormalizedImpl(
+    private org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier toNormalizedImpl(
             final InstanceIdentifier<? extends DataObject> binding) {
-        final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier legacyPath = bindingToLegacy
+        final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier legacyPath = bindingToLegacy
                 .toDataDom(binding);
-        final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized = legacyToNormalized
+        final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized = legacyToNormalized
                 .toNormalized(legacyPath);
         return normalized;
     }
 
-    @SuppressWarnings("unchecked")
-    private Iterable<Class<? extends DataObject>> getAugmentationChildren(final Class<?> targetType) {
-        List<Class<? extends DataObject>> ret = new LinkedList<>();
-        for (Method method : targetType.getMethods()) {
-            Class<?> entity = getYangModeledType(method);
-            if (entity != null) {
-                ret.add((Class<? extends DataObject>) entity);
-            }
-        }
-        return ret;
-    }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    private Class<? extends DataObject> getYangModeledType(final Method method) {
-        if (method.getName().equals("getClass") || !method.getName().startsWith("get")
-                || method.getParameterTypes().length > 0) {
-            return null;
-        }
-
-        Class<?> returnType = method.getReturnType();
-        if (DataContainer.class.isAssignableFrom(returnType)) {
-            return (Class) returnType;
-        } else if (List.class.isAssignableFrom(returnType)) {
-            try {
-                return ClassLoaderUtils.withClassLoader(method.getDeclaringClass().getClassLoader(),
-                        new Supplier<Class>() {
-                            @Override
-                            public Class get() {
-                                Type listResult = ClassLoaderUtils.getFirstGenericParameter(method
-                                        .getGenericReturnType());
-                                if (listResult instanceof Class
-                                        && DataObject.class.isAssignableFrom((Class) listResult)) {
-                                    return (Class<?>) listResult;
-                                }
-                                return null;
-                            }
-
-                        });
-            } catch (Exception e) {
-                LOG.debug("Could not get YANG modeled entity for {}", method, e);
-                return null;
-            }
-
-        }
-        return null;
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    private static InstanceIdentifier<?> toWildcarded(final InstanceIdentifier<?> orig) {
-        List<org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument> wildArgs = new LinkedList<>();
-        for (org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : orig.getPathArguments()) {
-            wildArgs.add(new Item(arg.getType()));
-        }
-        return InstanceIdentifier.create(wildArgs);
-    }
-
     private static boolean isAugmentation(final Class<? extends DataObject> type) {
         return Augmentation.class.isAssignableFrom(type);
     }
@@ -403,14 +485,14 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
         return Augmentation.class.isAssignableFrom(potential.getTargetType());
     }
 
-    private boolean isAugmentationIdentifier(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier processed) {
-        return Iterables.getLast(processed.getPath()) instanceof AugmentationIdentifier;
+    private boolean isAugmentationIdentifier(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier processed) {
+        return Iterables.getLast(processed.getPathArguments()) instanceof AugmentationIdentifier;
     }
 
     private static int getAugmentationCount(final InstanceIdentifier<?> potential) {
         int count = 0;
-        for(org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : potential.getPathArguments()) {
-            if(isAugmentation(arg.getType())) {
+        for (org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : potential.getPathArguments()) {
+            if (isAugmentation(arg.getType())) {
                 count++;
             }
 
@@ -418,13 +500,70 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
         return count;
     }
 
-    private static int getAugmentationCount(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier potential) {
+    private static int getAugmentationCount(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier potential) {
         int count = 0;
-        for(PathArgument arg : potential.getPath()) {
-            if(arg instanceof AugmentationIdentifier) {
+        for (PathArgument arg : potential.getPathArguments()) {
+            if (arg instanceof AugmentationIdentifier) {
                 count++;
             }
         }
         return count;
     }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public <T extends DataObject> Function<Optional<NormalizedNode<?, ?>>, Optional<T>>  deserializeFunction(final InstanceIdentifier<T> path) {
+        return new DeserializeFunction(this, path);
+    }
+
+    private static class DeserializeFunction<T extends DataObject> implements Function<Optional<NormalizedNode<?, ?>>, Optional<T>> {
+
+        private final BindingToNormalizedNodeCodec codec;
+        private final InstanceIdentifier<?> path;
+
+        public DeserializeFunction(final BindingToNormalizedNodeCodec codec, final InstanceIdentifier<?> path) {
+            super();
+            this.codec = Preconditions.checkNotNull(codec, "Codec must not be null");
+            this.path = Preconditions.checkNotNull(path, "Path must not be null");
+        }
+
+        @SuppressWarnings("rawtypes")
+        @Nullable
+        @Override
+        public Optional apply(@Nullable final Optional<NormalizedNode<?, ?>> normalizedNode) {
+            if (normalizedNode.isPresent()) {
+                final DataObject dataObject;
+                try {
+                    dataObject = codec.toBinding(path, normalizedNode.get());
+                } catch (DeserializationException e) {
+                    LOG.warn("Failed to create dataobject from node {}", normalizedNode.get(), e);
+                    throw new IllegalStateException("Failed to create dataobject", e);
+                }
+
+                if (dataObject != null) {
+                    return Optional.of(dataObject);
+                }
+            }
+            return Optional.absent();
+        }
+    }
+
+    /**
+     * Returns an default object according to YANG schema for supplied path.
+     *
+     * @param path DOM Path
+     * @return Node with defaults set on.
+     */
+    public NormalizedNode<?, ?> getDefaultNodeFor(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path) {
+        Iterator<PathArgument> iterator = path.getPathArguments().iterator();
+        DataNormalizationOperation<?> currentOp = legacyToNormalized.getRootOperation();
+        while (iterator.hasNext()) {
+            PathArgument currentArg = iterator.next();
+            try {
+                currentOp = currentOp.getChild(currentArg);
+            } catch (DataNormalizationException e) {
+                throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", path), e);
+            }
+        }
+        return currentOp.createDefault(path.getLastPathArgument());
+    }
 }
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingTranslatedTransactionChain.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingTranslatedTransactionChain.java
new file mode 100644 (file)
index 0000000..2d8e51c
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl;
+
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import javax.annotation.concurrent.GuardedBy;
+
+import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.yangtools.concepts.Delegator;
+
+import com.google.common.base.Preconditions;
+
+class BindingTranslatedTransactionChain implements BindingTransactionChain, Delegator<DOMTransactionChain> {
+
+    private final DOMTransactionChain delegate;
+
+    @GuardedBy("this")
+    private final Map<AsyncTransaction<?, ?>, AsyncTransaction<?, ?>> delegateTxToBindingTx = new WeakHashMap<>();
+    private final BindingToNormalizedNodeCodec codec;
+
+    public BindingTranslatedTransactionChain(final DOMDataBroker chainFactory,
+            final BindingToNormalizedNodeCodec codec, final TransactionChainListener listener) {
+        Preconditions.checkNotNull(chainFactory, "DOM Transaction chain factory must not be null");
+        this.delegate = chainFactory.createTransactionChain(new ListenerInvoker(listener));
+        this.codec = codec;
+    }
+
+    @Override
+    public DOMTransactionChain getDelegate() {
+        return delegate;
+    }
+
+    @Override
+    public ReadOnlyTransaction newReadOnlyTransaction() {
+        DOMDataReadOnlyTransaction delegateTx = delegate.newReadOnlyTransaction();
+        ReadOnlyTransaction bindingTx = new BindingDataReadTransactionImpl(delegateTx, codec);
+        putDelegateToBinding(delegateTx, bindingTx);
+        return bindingTx;
+    }
+
+    @Override
+    public ReadWriteTransaction newReadWriteTransaction() {
+        DOMDataReadWriteTransaction delegateTx = delegate.newReadWriteTransaction();
+        ReadWriteTransaction bindingTx = new BindingDataReadWriteTransactionImpl(delegateTx, codec);
+        putDelegateToBinding(delegateTx, bindingTx);
+        return bindingTx;
+    }
+
+    @Override
+    public WriteTransaction newWriteOnlyTransaction() {
+        DOMDataWriteTransaction delegateTx = delegate.newWriteOnlyTransaction();
+        WriteTransaction bindingTx = new BindingDataWriteTransactionImpl<>(delegateTx, codec);
+        putDelegateToBinding(delegateTx, bindingTx);
+        return bindingTx;
+    }
+
+    @Override
+    public void close() {
+        delegate.close();
+    }
+
+    private synchronized void putDelegateToBinding(final AsyncTransaction<?, ?> domTx,
+            final AsyncTransaction<?, ?> bindingTx) {
+        final Object previous = delegateTxToBindingTx.put(domTx, bindingTx);
+        Preconditions.checkState(previous == null, "DOM Transaction %s has already associated binding transation %s",domTx,previous);
+    }
+
+    private synchronized AsyncTransaction<?, ?> getBindingTransaction(final AsyncTransaction<?, ?> transaction) {
+        return delegateTxToBindingTx.get(transaction);
+    }
+
+    private final class ListenerInvoker implements TransactionChainListener {
+
+        private final TransactionChainListener listener;
+
+        public ListenerInvoker(final TransactionChainListener listener) {
+            this.listener = Preconditions.checkNotNull(listener, "Listener must not be null.");
+        }
+
+        @Override
+        public void onTransactionChainFailed(final TransactionChain<?, ?> chain,
+                final AsyncTransaction<?, ?> transaction, final Throwable cause) {
+            Preconditions.checkState(delegate.equals(chain),
+                    "Illegal state - listener for %s was invoked for incorrect chain %s.", delegate, chain);
+            AsyncTransaction<?, ?> bindingTx = getBindingTransaction(transaction);
+            listener.onTransactionChainFailed(chain, bindingTx, cause);
+        }
+
+        @Override
+        public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
+            Preconditions.checkState(delegate.equals(chain),
+                    "Illegal state - listener for %s was invoked for incorrect chain %s.", delegate, chain);
+            listener.onTransactionChainSuccessful(BindingTranslatedTransactionChain.this);
+        }
+    }
+
+}
index 49d04d04b3f7d58c1d1f1f5e250d918f91878f9e..c924b74a12bb0e7c6f080e98dffc09352faa16a7 100644 (file)
@@ -28,12 +28,12 @@ import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.Data
 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.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
 import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
 import org.opendaylight.yangtools.concepts.Delegator;
@@ -42,8 +42,8 @@ import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -55,6 +55,7 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 
+@SuppressWarnings("deprecation")
 public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDataBroker implements DataProviderService, AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(ForwardedBackwardsCompatibleDataBroker.class);
@@ -87,7 +88,7 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
     }
 
     @Override
-    public Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> registerCommitHandler(
+    public Registration registerCommitHandler(
             final InstanceIdentifier<? extends DataObject> path,
             final DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> commitHandler) {
 
@@ -122,7 +123,7 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
     }
 
     @Override
-    public Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> registerDataReader(
+    public Registration registerDataReader(
             final InstanceIdentifier<? extends DataObject> path,
             final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> reader) {
         throw new UnsupportedOperationException("Data reader contract is not supported.");
@@ -161,9 +162,9 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
             @Override
             public ListenableFuture<RpcResult<TransactionStatus>> apply(final Boolean requestCommitSuccess) throws Exception {
                 if(requestCommitSuccess) {
-                    return tx.getDelegate().commit();
+                    return AbstractDataTransaction.convertToLegacyCommitFuture(tx.getDelegate().submit());
                 }
-                return Futures.immediateFuture(Rpcs.getRpcResult(false, TransactionStatus.FAILED, Collections.<RpcError>emptySet()));
+                return Futures.immediateFuture(RpcResultBuilder.<TransactionStatus>failed().withResult(TransactionStatus.FAILED).build());
             }
         });
 
@@ -186,7 +187,7 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
     }
 
     private class ForwardedBackwardsCompatibleTransacion extends
-            AbstractForwardedTransaction<DOMDataReadWriteTransaction> implements DataModificationTransaction {
+            AbstractReadWriteTransaction implements DataModificationTransaction {
 
         private final ListenerRegistry<DataTransactionListener> listeners = ListenerRegistry.create();
         private final Map<InstanceIdentifier<? extends DataObject>, DataObject> updated = new HashMap<>();
@@ -213,10 +214,13 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
         @Override
         public void putOperationalData(final InstanceIdentifier<? extends DataObject> path, final DataObject data) {
             boolean previouslyRemoved = posponedRemovedOperational.remove(path);
+
+            @SuppressWarnings({ "rawtypes", "unchecked" })
+            final InstanceIdentifier<DataObject> castedPath = (InstanceIdentifier) path;
             if(previouslyRemoved) {
-                doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data);
+                put(LogicalDatastoreType.OPERATIONAL, castedPath, data,true);
             } else {
-                doMergeWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data);
+                merge(LogicalDatastoreType.OPERATIONAL, castedPath, data,true);
             }
         }
 
@@ -231,10 +235,12 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
                 created.put(path, data);
             }
             updated.put(path, data);
+            @SuppressWarnings({"rawtypes","unchecked"})
+            final InstanceIdentifier<DataObject> castedPath = (InstanceIdentifier) path;
             if(previouslyRemoved) {
-                doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data);
+                put(LogicalDatastoreType.CONFIGURATION, castedPath, data,true);
             } else {
-                doMergeWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data);
+                merge(LogicalDatastoreType.CONFIGURATION, castedPath, data,true);
             }
         }
 
@@ -308,11 +314,6 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
             }
         }
 
-        @Override
-        public Object getIdentifier() {
-            return getDelegate().getIdentifier();
-        }
-
         private void changeStatus(final TransactionStatus status) {
             LOG.trace("Transaction {} changed status to {}", getIdentifier(), status);
             this.status = status;
@@ -330,11 +331,11 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
         public ListenableFuture<RpcResult<TransactionStatus>> commit() {
 
             for(InstanceIdentifier<? extends DataObject> path : posponedRemovedConfiguration) {
-                doDelete(getDelegate(), LogicalDatastoreType.CONFIGURATION, path);
+                doDelete(LogicalDatastoreType.CONFIGURATION, path);
             }
 
             for(InstanceIdentifier<? extends DataObject> path : posponedRemovedOperational) {
-                doDelete(getDelegate(), LogicalDatastoreType.OPERATIONAL, path);
+                doDelete(LogicalDatastoreType.OPERATIONAL, path);
             }
 
             changeStatus(TransactionStatus.SUBMITED);
index 5b008ad4bc3c0fe87863bd5d968394bc0a38396d..6359b60684ef45e18d2185d1231b14b165497724 100644 (file)
@@ -8,27 +8,16 @@
 package org.opendaylight.controller.md.sal.binding.impl;
 
 
+import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.ListenableFuture;
-
 /**
  * The DataBrokerImpl simply defers to the DOMDataBroker for all its operations.
  * All transactions and listener registrations are wrapped by the DataBrokerImpl
@@ -37,9 +26,7 @@ import com.google.common.util.concurrent.ListenableFuture;
  * Besides this the DataBrokerImpl and it's collaborators also cache data that
  * is already transformed from the binding independent to binding aware format
  *
- * TODO : All references in this class to CompositeNode should be switched to
- * NormalizedNode once the MappingService is updated
- *
+
  */
 public class ForwardedBindingDataBroker extends AbstractForwardedDataBroker implements DataBroker {
 
@@ -60,90 +47,11 @@ public class ForwardedBindingDataBroker extends AbstractForwardedDataBroker impl
 
     @Override
     public WriteTransaction newWriteOnlyTransaction() {
-        return new BindingDataWriteTransactionImpl<DOMDataWriteTransaction>(getDelegate().newWriteOnlyTransaction(),getCodec());
-    }
-
-    private abstract class AbstractBindingTransaction<T extends AsyncTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>>>
-            extends AbstractForwardedTransaction<T> implements AsyncTransaction<InstanceIdentifier<?>, DataObject> {
-
-        protected AbstractBindingTransaction(final T delegate, final BindingToNormalizedNodeCodec codec) {
-            super(delegate, codec);
-        }
-
-        @Override
-        public Object getIdentifier() {
-            return getDelegate().getIdentifier();
-        }
-
-    }
-
-
-    private class BindingDataReadTransactionImpl extends AbstractBindingTransaction<DOMDataReadOnlyTransaction> implements
-            ReadOnlyTransaction {
-
-        protected BindingDataReadTransactionImpl(final DOMDataReadOnlyTransaction delegate,
-                final BindingToNormalizedNodeCodec codec) {
-            super(delegate, codec);
-        }
-
-        @Override
-        public ListenableFuture<Optional<DataObject>> read(final LogicalDatastoreType store,
-                final InstanceIdentifier<?> path) {
-            return doRead(getDelegate(), store, path);
-        }
-
-        @Override
-        public void close() {
-            getDelegate().close();
-        }
+        return new BindingDataWriteTransactionImpl<>(getDelegate().newWriteOnlyTransaction(),getCodec());
     }
 
-    private class BindingDataWriteTransactionImpl<T extends DOMDataWriteTransaction> extends
-            AbstractBindingTransaction<T> implements WriteTransaction {
-
-        protected BindingDataWriteTransactionImpl(final T delegate, final BindingToNormalizedNodeCodec codec) {
-            super(delegate, codec);
-
-        }
-
-        @Override
-        public boolean cancel() {
-            return doCancel(getDelegate());
-        }
-
-        @Override
-        public void put(final LogicalDatastoreType store, final InstanceIdentifier<?> path, final DataObject data) {
-            doPut(getDelegate(), store, path, data);
-        }
-
-        @Override
-        public void merge(final LogicalDatastoreType store, final InstanceIdentifier<?> path, final DataObject data) {
-            doMerge(getDelegate(), store, path, data);
-        }
-
-        @Override
-        public void delete(final LogicalDatastoreType store, final InstanceIdentifier<?> path) {
-            doDelete(getDelegate(), store, path);
-        }
-
-        @Override
-        public ListenableFuture<RpcResult<TransactionStatus>> commit() {
-            return doCommit(getDelegate());
-        }
-    }
-
-    private class BindingDataReadWriteTransactionImpl extends
-            BindingDataWriteTransactionImpl<DOMDataReadWriteTransaction> implements ReadWriteTransaction {
-
-        protected BindingDataReadWriteTransactionImpl(final DOMDataReadWriteTransaction delegate,
-                final BindingToNormalizedNodeCodec codec) {
-            super(delegate, codec);
-        }
-
-        @Override
-        public ListenableFuture<Optional<DataObject>> read(final LogicalDatastoreType store,
-                final InstanceIdentifier<?> path) {
-            return doRead(getDelegate(), store, path);
-        }
+    @Override
+    public BindingTransactionChain createTransactionChain(final TransactionChainListener listener) {
+        return new BindingTranslatedTransactionChain(getDelegate(), getCodec(), listener);
     }
 }
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RpcIsNotRoutedException.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RpcIsNotRoutedException.java
new file mode 100644 (file)
index 0000000..5317324
--- /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.sal.binding.codegen;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Exception is raised when supplied Bidning Aware
+ * RPCService class is not routed and was used in context
+ * where routed RPCs should only be used.
+ *
+ */
+public class RpcIsNotRoutedException extends IllegalStateException {
+
+    private static final long serialVersionUID = 1L;
+
+    public RpcIsNotRoutedException(final String message, final Throwable cause) {
+        super(Preconditions.checkNotNull(message), cause);
+    }
+
+    public RpcIsNotRoutedException(final String message) {
+        super(Preconditions.checkNotNull(message));
+    }
+}
index 9b7b8e28c90657aedc2f53c8c17d1697a0cd6e62..c7c5f10f71bd1073a9e6040ce62b23bbd39c0bc3 100644 (file)
@@ -84,8 +84,9 @@ public interface RuntimeCodeGenerator {
      *            - Subclass of RpcService for which Router is to be generated.
      * @return Instance of RpcService of provided serviceType which implements
      *         also {@link RpcRouter}<T> and {@link org.opendaylight.controller.sal.binding.spi.DelegateProxy}
+     * @throws RpcIsNotRoutedException
      */
-    <T extends RpcService> RpcRouter<T> getRouterFor(Class<T> serviceType,String name) throws IllegalArgumentException;
+    <T extends RpcService> RpcRouter<T> getRouterFor(Class<T> serviceType,String name) throws IllegalArgumentException, RpcIsNotRoutedException;
 
     NotificationInvokerFactory getInvokerFactory();
 }
index 9605a4d3723b6f21ccf8ce5810ad078ba3e3bbd6..1fa54be2005b06d0be70226ac4abd30625f8a8bb 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.controller.sal.binding.codegen.impl;
 
+import com.google.common.base.Supplier;
+
 import java.util.Map;
 import java.util.WeakHashMap;
 
@@ -19,16 +21,16 @@ import javax.annotation.concurrent.GuardedBy;
 
 import org.eclipse.xtext.xbase.lib.Extension;
 import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
+import org.opendaylight.controller.sal.binding.codegen.RpcIsNotRoutedException;
 import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
 import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
+import org.opendaylight.yangtools.yang.binding.BindingMapping;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext;
 import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils;
 
-import com.google.common.base.Supplier;
-
 abstract class AbstractRuntimeCodeGenerator implements org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator, NotificationInvokerFactory {
     @GuardedBy("this")
     private final Map<Class<? extends NotificationListener>, RuntimeGeneratedInvokerPrototype> invokerClasses = new WeakHashMap<>();
@@ -56,11 +58,11 @@ abstract class AbstractRuntimeCodeGenerator implements org.opendaylight.controll
     protected abstract <T extends RpcService> Supplier<T> directProxySupplier(final Class<T> serviceType);
     protected abstract <T extends RpcService> Supplier<T> routerSupplier(final Class<T> serviceType, RpcServiceMetadata metadata);
 
-    private RpcServiceMetadata getRpcMetadata(final CtClass iface) throws ClassNotFoundException, NotFoundException {
+    private RpcServiceMetadata getRpcMetadata(final CtClass iface) throws ClassNotFoundException, NotFoundException, RpcIsNotRoutedException {
         final RpcServiceMetadata metadata = new RpcServiceMetadata();
 
         for (CtMethod method : iface.getMethods()) {
-            if (iface.equals(method.getDeclaringClass()) && method.getParameterTypes().length == 1) {
+            if (isRpcMethodWithInput(iface, method)) {
                 final RpcMetadata routingPair = getRpcMetadata(method);
                 if (routingPair != null) {
                     metadata.addContext(routingPair.getContext());
@@ -81,6 +83,8 @@ abstract class AbstractRuntimeCodeGenerator implements org.opendaylight.controll
                      *        remains to be investigated.
                      */
                     Thread.currentThread().getContextClassLoader().loadClass(routingPair.getInputType().getName());
+                } else {
+                    throw new RpcIsNotRoutedException("RPC " + method.getName() + " from "+ iface.getName() +" is not routed");
                 }
             }
         }
@@ -88,6 +92,18 @@ abstract class AbstractRuntimeCodeGenerator implements org.opendaylight.controll
         return metadata;
     }
 
+
+    private boolean isRpcMethodWithInput(final CtClass iface, final CtMethod method) throws NotFoundException {
+        if(iface.equals(method.getDeclaringClass())
+                && method.getParameterTypes().length == 1) {
+            final CtClass onlyArg = method.getParameterTypes()[0];
+            if(onlyArg.isInterface() && onlyArg.getName().endsWith(BindingMapping.RPC_INPUT_SUFFIX)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private RpcMetadata getRpcMetadata(final CtMethod method) throws NotFoundException {
         final CtClass inputClass = method.getParameterTypes()[0];
         return rpcMethodMetadata(inputClass, inputClass, method.getName());
@@ -120,20 +136,17 @@ abstract class AbstractRuntimeCodeGenerator implements org.opendaylight.controll
             return invoker;
         }
 
-        utils.getLock().lock();
-        try {
+        synchronized (utils) {
             invoker = ClassLoaderUtils.withClassLoader(cls.getClassLoader(), new Supplier<RuntimeGeneratedInvokerPrototype>() {
                 @Override
                 public RuntimeGeneratedInvokerPrototype get() {
                     return generateListenerInvoker(cls);
                 }
             });
-
-            invokerClasses.put(cls, invoker);
-            return invoker;
-        } finally {
-            utils.getLock().unlock();
         }
+
+        invokerClasses.put(cls, invoker);
+        return invoker;
     }
 
     @Override
@@ -143,16 +156,13 @@ abstract class AbstractRuntimeCodeGenerator implements org.opendaylight.controll
 
     @Override
     public final <T extends RpcService> T getDirectProxyFor(final Class<T> serviceType) {
-        utils.getLock().lock();
-        try {
+        synchronized (utils) {
             return ClassLoaderUtils.withClassLoader(serviceType.getClassLoader(), directProxySupplier(serviceType));
-        } finally {
-            utils.getLock().unlock();
         }
     }
 
     @Override
-    public final <T extends RpcService> RpcRouter<T> getRouterFor(final Class<T> serviceType, final String name) {
+    public final <T extends RpcService> RpcRouter<T> getRouterFor(final Class<T> serviceType, final String name) throws RpcIsNotRoutedException {
         final RpcServiceMetadata metadata = ClassLoaderUtils.withClassLoader(serviceType.getClassLoader(), new Supplier<RpcServiceMetadata>() {
             @Override
             public RpcServiceMetadata get() {
@@ -164,12 +174,9 @@ abstract class AbstractRuntimeCodeGenerator implements org.opendaylight.controll
             }
         });
 
-        utils.getLock().lock();
-        try {
+        synchronized (utils) {
             final T instance = ClassLoaderUtils.withClassLoader(serviceType.getClassLoader(), routerSupplier(serviceType, metadata));
             return new RpcRouterCodegenInstance<T>(name, serviceType, instance, metadata.getContexts());
-        } finally {
-            utils.getLock().unlock();
         }
     }
 
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/BrokerImplClassLoader.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/BrokerImplClassLoader.java
deleted file mode 100644 (file)
index fdd9350..0000000
+++ /dev/null
@@ -1,27 +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.codegen.impl;
-
-public class BrokerImplClassLoader extends ClassLoader {
-    private final ClassLoader spiClassLoader;
-
-    public BrokerImplClassLoader(final ClassLoader model, final ClassLoader spi) {
-        super(model);
-        this.spiClassLoader = spi;
-    }
-
-    @Override
-    public Class<? extends Object> loadClass(final String name) throws ClassNotFoundException {
-        try {
-            return super.loadClass(name);
-        } catch (ClassNotFoundException e) {
-            return this.spiClassLoader.loadClass(name);
-        }
-    }
-}
index 052fd2169a523b955a427f036e2a0ab6b7a03bc4..709b62fee25247c09ec980c188acd504693d4e3e 100644 (file)
@@ -37,8 +37,6 @@ RpcRouter<T>, RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentif
 
     private static final Logger LOG = LoggerFactory.getLogger(RpcRouterCodegenInstance.class);
 
-    private T defaultService;
-
     private final Class<T> serviceType;
 
     private final T invocationProxy;
@@ -49,11 +47,8 @@ RpcRouter<T>, RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentif
 
     private final Map<Class<? extends BaseIdentity>, RpcRoutingTableImpl<? extends BaseIdentity, T>> routingTables;
 
-    private final String name;
-
     @SuppressWarnings("unchecked")
     public RpcRouterCodegenInstance(final String name,final Class<T> type, final T routerImpl, final Iterable<Class<? extends BaseIdentity>> contexts) {
-        this.name = name;
         this.listeners = ListenerRegistry.create();
         this.serviceType = type;
         this.invocationProxy = routerImpl;
@@ -90,7 +85,7 @@ RpcRouter<T>, RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentif
 
     @Override
     public T getDefaultService() {
-        return defaultService;
+        return RuntimeCodeHelper.getDelegate(invocationProxy);
     }
 
     @Override
@@ -125,11 +120,17 @@ RpcRouter<T>, RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentif
         return new RoutedRpcRegistrationImpl(service);
     }
 
+    public void removeDefaultImplementation(final T instance) {
+        RpcService current = RuntimeCodeHelper.getDelegate(invocationProxy);
+        if(instance == current) {
+            RuntimeCodeHelper.setDelegate(invocationProxy, null);
+        }
+    }
+
     @Override
     public RpcRegistration<T> registerDefaultService(final T service) {
-        // TODO Auto-generated method stub
         RuntimeCodeHelper.setDelegate(invocationProxy, service);
-        return null;
+        return new DefaultRpcImplementationRegistration(service);
     }
 
     private class RoutedRpcRegistrationImpl extends AbstractObjectRegistration<T> implements RoutedRpcRegistration<T> {
@@ -168,4 +169,24 @@ RpcRouter<T>, RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentif
 
         }
     }
+
+    private class DefaultRpcImplementationRegistration extends AbstractObjectRegistration<T> implements RpcRegistration<T> {
+
+
+        protected DefaultRpcImplementationRegistration(final T instance) {
+            super(instance);
+        }
+
+        @Override
+        protected void removeRegistration() {
+            removeDefaultImplementation(this.getInstance());
+        }
+
+        @Override
+        public Class<T> getServiceType() {
+            return serviceType;
+        }
+    }
+
+
 }
index 00c9f1eb91a14f7f1df97a73bc871cac9e918058..834eb4f5fb357b65ae7ed90b6e986ea7c2474a0e 100644 (file)
@@ -82,6 +82,12 @@ class RuntimeCodeGenerator extends AbstractRuntimeCodeGenerator {
                         val rpcMeta = metadata.getRpcMethod(name);
                         val bodyTmp = '''
                         {
+                            if($1 == null) {
+                                throw new IllegalArgumentException("RPC input must not be null and must contain a value for field «rpcMeta.inputRouteGetter.name»");
+                            }
+                            if($1.«rpcMeta.inputRouteGetter.name»() == null) {
+                                throw new IllegalArgumentException("Field «rpcMeta.inputRouteGetter.name» must not be null");
+                            }
                             final «InstanceIdentifier.name» identifier = $1.«rpcMeta.inputRouteGetter.name»()«IF rpcMeta.
                             routeEncapsulated».getValue()«ENDIF»;
                             «supertype.name» instance = («supertype.name») «rpcMeta.context.routingTableField».get(identifier);
index 9ede01b6a3e62ba3bdbd685b22309ab799b09ba7..d4cfb563f633cb1f21a0a6055010a9a98bfd19b7 100644 (file)
@@ -147,14 +147,14 @@ public class DataBrokerImpl extends
         }
 
         @Override
-        public Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> registerConfigurationReader(
+        public Registration registerConfigurationReader(
                 final InstanceIdentifier<? extends DataObject> path,
                 final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> reader) {
             throw new UnsupportedOperationException("Not supported");
         }
 
         @Override
-        public Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> registerOperationalReader(
+        public Registration registerOperationalReader(
                 final InstanceIdentifier<? extends DataObject> path,
                 final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> reader) {
             throw new UnsupportedOperationException("Not supported");
index 542dfa7e7bca61a0fc4ff33e31239c3c3872e73b..f2e467038f003cbc3acaa9dad3f4d108b0df691c 100644 (file)
@@ -7,6 +7,17 @@
  */
 package org.opendaylight.controller.sal.binding.impl;
 
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
 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;
@@ -16,6 +27,7 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistr
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
 import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
+import org.opendaylight.controller.sal.binding.codegen.RpcIsNotRoutedException;
 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;
@@ -28,24 +40,31 @@ import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.EventListener;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.WeakHashMap;
-
-import static com.google.common.base.Preconditions.checkState;
+import com.google.common.base.Throwables;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.util.concurrent.UncheckedExecutionException;
 
-public class RpcProviderRegistryImpl implements //
-        RpcProviderRegistry, //
-        RouteChangePublisher<RpcContextIdentifier, InstanceIdentifier<?>> {
+public class RpcProviderRegistryImpl implements RpcProviderRegistry, RouteChangePublisher<RpcContextIdentifier, InstanceIdentifier<?>> {
 
     private RuntimeCodeGenerator rpcFactory = SingletonHolder.RPC_GENERATOR_IMPL;
 
-    // publicProxies is a cache of proxy objects where each value in the map corresponds to a specific RpcService
-    private final Map<Class<? extends RpcService>, RpcService> publicProxies = new WeakHashMap<>();
-    private final Map<Class<? extends RpcService>, RpcRouter<?>> rpcRouters = new WeakHashMap<>();
+    // cache of proxy objects where each value in the map corresponds to a specific RpcService
+    private final LoadingCache<Class<? extends RpcService>, RpcService> publicProxies = CacheBuilder.newBuilder().weakKeys().
+            build(new CacheLoader<Class<? extends RpcService>, RpcService>() {
+                @Override
+                public RpcService load(final Class<? extends RpcService> type) {
+                    final RpcService proxy = rpcFactory.getDirectProxyFor(type);
+                    LOG.debug("Created {} as public proxy for {} in {}", proxy, type.getSimpleName(), this);
+                    return proxy;
+                }
+            });
+
+    private final Cache<Class<? extends RpcService>, RpcRouter<?>> rpcRouters = CacheBuilder.newBuilder().weakKeys()
+            .build();
+
     private final ListenerRegistry<RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> routeChangeListeners = ListenerRegistry
             .create();
     private final ListenerRegistry<RouterInstantiationListener> routerInstantiationListener = ListenerRegistry.create();
@@ -60,26 +79,34 @@ public class RpcProviderRegistryImpl implements //
         return name;
     }
 
-    public RpcProviderRegistryImpl(String name) {
+    public RpcProviderRegistryImpl(final String name) {
         super();
         this.name = name;
     }
 
     @Override
-    public final <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type,
-            T implementation) throws IllegalStateException {
+    public final <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(final Class<T> type,
+            final T implementation) throws IllegalStateException {
         return getRpcRouter(type).addRoutedRpcImplementation(implementation);
     }
 
     @Override
-    public final <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
+    public final <T extends RpcService> RpcRegistration<T> addRpcImplementation(final Class<T> type, final T implementation)
             throws IllegalStateException {
-        @SuppressWarnings("unchecked")
-        RpcRouter<T> potentialRouter = (RpcRouter<T>) rpcRouters.get(type);
-        if (potentialRouter != null) {
+
+        // FIXME: This should be well documented - addRpcImplementation for
+        // routed RPCs
+        try {
+            // Note: If RPC is really global, expected count of registrations
+            // of this method is really low.
+            RpcRouter<T> potentialRouter = getRpcRouter(type);
             checkState(potentialRouter.getDefaultService() == null,
-                    "Default service for routed RPC already registered.");
+                        "Default service for routed RPC already registered.");
             return potentialRouter.registerDefaultService(implementation);
+        } catch (RpcIsNotRoutedException e) {
+            // NOOP - we could safely continue, since RPC is not routed
+            // so we fallback to global routing.
+            LOG.debug("RPC is not routed. Using global registration.",e);
         }
         T publicProxy = getRpcService(type);
         RpcService currentDelegate = RuntimeCodeHelper.getDelegate(publicProxy);
@@ -92,55 +119,45 @@ public class RpcProviderRegistryImpl implements //
 
     @SuppressWarnings("unchecked")
     @Override
-    public final <T extends RpcService> T getRpcService(Class<T> type) {
-
-        T potentialProxy = (T) publicProxies.get(type);
-        if (potentialProxy != null) {
-            return potentialProxy;
-        }
-        synchronized (this) {
-            /**
-             * Potential proxy could be instantiated by other thread while we
-             * were waiting for the lock.
-             */
-
-            potentialProxy = (T) publicProxies.get(type);
-            if (potentialProxy != null) {
-                return potentialProxy;
-            }
-            T proxy = rpcFactory.getDirectProxyFor(type);
-            LOG.debug("Created {} as public proxy for {} in {}", proxy, type.getSimpleName(), this);
-            publicProxies.put(type, proxy);
-            return proxy;
-        }
+    public final <T extends RpcService> T getRpcService(final Class<T> type) {
+        return (T) publicProxies.getUnchecked(type);
     }
 
-    @SuppressWarnings("unchecked")
-    public <T extends RpcService> RpcRouter<T> getRpcRouter(Class<T> type) {
-        RpcRouter<?> potentialRouter = rpcRouters.get(type);
-        if (potentialRouter != null) {
-            return (RpcRouter<T>) potentialRouter;
-        }
-        synchronized (this) {
-            /**
-             * Potential Router could be instantiated by other thread while we
-             * were waiting for the lock.
-             */
-            potentialRouter = rpcRouters.get(type);
-            if (potentialRouter != null) {
-                return (RpcRouter<T>) potentialRouter;
+
+    public <T extends RpcService> RpcRouter<T> getRpcRouter(final Class<T> type) {
+        try {
+            final AtomicBoolean created = new AtomicBoolean(false);
+            @SuppressWarnings( "unchecked")
+            // LoadingCache is unsuitable for RpcRouter since we need to distinguish
+            // first creation of RPC Router, so that is why
+            // we are using normal cache with load API and shared AtomicBoolean
+            // for this call, which will be set to true if router was created.
+            RpcRouter<T> router = (RpcRouter<T>) rpcRouters.get(type,new Callable<RpcRouter<?>>() {
+
+                @Override
+                public org.opendaylight.controller.sal.binding.api.rpc.RpcRouter<?> call()  {
+                    RpcRouter<?> router = rpcFactory.getRouterFor(type, name);
+                    router.registerRouteChangeListener(new RouteChangeForwarder<T>(type));
+                    LOG.debug("Registering router {} as global implementation of {} in {}", router, type.getSimpleName(), this);
+                    RuntimeCodeHelper.setDelegate(getRpcService(type), router.getInvocationProxy());
+                    created.set(true);
+                    return router;
+                }
+            });
+            if(created.get()) {
+                notifyListenersRoutedCreated(router);
             }
-            RpcRouter<T> router = rpcFactory.getRouterFor(type, name);
-            router.registerRouteChangeListener(new RouteChangeForwarder(type));
-            LOG.debug("Registering router {} as global implementation of {} in {}", router, type.getSimpleName(), this);
-            RuntimeCodeHelper.setDelegate(getRpcService(type), router.getInvocationProxy());
-            rpcRouters.put(type, router);
-            notifyListenersRoutedCreated(router);
             return router;
+        } catch (ExecutionException | UncheckedExecutionException e) {
+            // We rethrow Runtime Exceptions which were wrapped by
+            // Execution Exceptions
+            // otherwise we throw IllegalStateException with original
+            Throwables.propagateIfPossible(e.getCause());
+            throw new IllegalStateException("Could not load RPC Router for "+type.getName(),e);
         }
     }
 
-    private void notifyGlobalRpcAdded(Class<? extends RpcService> type) {
+    private void notifyGlobalRpcAdded(final Class<? extends RpcService> type) {
         for(ListenerRegistration<GlobalRpcRegistrationListener> listener : globalRpcListeners) {
             try {
                 listener.getInstance().onGlobalRpcRegistered(type);
@@ -151,7 +168,7 @@ public class RpcProviderRegistryImpl implements //
 
     }
 
-    private void notifyListenersRoutedCreated(RpcRouter<?> router) {
+    private void notifyListenersRoutedCreated(final RpcRouter<?> router) {
 
         for (ListenerRegistration<RouterInstantiationListener> listener : routerInstantiationListener) {
             try {
@@ -164,10 +181,10 @@ public class RpcProviderRegistryImpl implements //
     }
 
     public ListenerRegistration<RouterInstantiationListener> registerRouterInstantiationListener(
-            RouterInstantiationListener listener) {
+            final RouterInstantiationListener listener) {
         ListenerRegistration<RouterInstantiationListener> reg = routerInstantiationListener.register(listener);
         try {
-            for (RpcRouter<?> router : rpcRouters.values()) {
+            for (RpcRouter<?> router : rpcRouters.asMap().values()) {
                 listener.onRpcRouterCreated(router);
             }
         } catch (Exception e) {
@@ -176,9 +193,10 @@ public class RpcProviderRegistryImpl implements //
         return reg;
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
-            L listener) {
+            final L listener) {
         return (ListenerRegistration<L>) routeChangeListeners.register(listener);
     }
 
@@ -186,7 +204,7 @@ public class RpcProviderRegistryImpl implements //
         return rpcFactory;
     }
 
-    public void setRpcFactory(RuntimeCodeGenerator rpcFactory) {
+    public void setRpcFactory(final RuntimeCodeGenerator rpcFactory) {
         this.rpcFactory = rpcFactory;
     }
 
@@ -194,7 +212,7 @@ public class RpcProviderRegistryImpl implements //
         void onRpcRouterCreated(RpcRouter<?> router);
     }
 
-    public ListenerRegistration<GlobalRpcRegistrationListener> registerGlobalRpcRegistrationListener(GlobalRpcRegistrationListener listener) {
+    public ListenerRegistration<GlobalRpcRegistrationListener> registerGlobalRpcRegistrationListener(final GlobalRpcRegistrationListener listener) {
         return globalRpcListeners.register(listener);
     }
 
@@ -204,17 +222,16 @@ public class RpcProviderRegistryImpl implements //
 
     }
 
-    private class RouteChangeForwarder<T extends RpcService> implements
-            RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentifier<?>> {
+    private class RouteChangeForwarder<T extends RpcService> implements RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentifier<?>> {
 
         private final Class<T> type;
 
-        public RouteChangeForwarder(Class<T> type) {
+        public RouteChangeForwarder(final Class<T> type) {
             this.type = type;
         }
 
         @Override
-        public void onRouteChange(RouteChange<Class<? extends BaseIdentity>, InstanceIdentifier<?>> change) {
+        public void onRouteChange(final RouteChange<Class<? extends BaseIdentity>, InstanceIdentifier<?>> change) {
             Map<RpcContextIdentifier, Set<InstanceIdentifier<?>>> announcements = new HashMap<>();
             for (Entry<Class<? extends BaseIdentity>, Set<InstanceIdentifier<?>>> entry : change.getAnnouncements()
                     .entrySet()) {
@@ -233,19 +250,18 @@ public class RpcProviderRegistryImpl implements //
                 try {
                     listener.getInstance().onRouteChange(toPublish);
                 } catch (Exception e) {
-                    e.printStackTrace();
+                    LOG.error("Unhandled exception during invoking listener",listener.getInstance(),e);
                 }
             }
         }
     }
 
-    public static class RpcProxyRegistration<T extends RpcService> extends AbstractObjectRegistration<T> implements
-            RpcRegistration<T> {
+    public static class RpcProxyRegistration<T extends RpcService> extends AbstractObjectRegistration<T> implements RpcRegistration<T> {
 
         private final Class<T> serviceType;
         private RpcProviderRegistryImpl registry;
 
-        public RpcProxyRegistration(Class<T> type, T service, RpcProviderRegistryImpl registry) {
+        public RpcProxyRegistration(final Class<T> type, final T service, final RpcProviderRegistryImpl registry) {
             super(service);
             this.serviceType = type;
             this.registry =  registry;
index d2472669fa39def5ae4862fb86be2fea5fa7b067..d00d8b7fa83894c6a4a1a2b19894ddfae2513d78 100644 (file)
  */
 package org.opendaylight.controller.sal.binding.impl.connect.dom;
 
-import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 
-import java.lang.ref.WeakReference;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
 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;
-import java.util.Set;
-import java.util.WeakHashMap;
-import java.util.concurrent.Callable;
+
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
 import org.opendaylight.controller.md.sal.binding.impl.AbstractForwardedDataBroker;
-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.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.NotificationProviderService;
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService.NotificationInterestListener;
 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.RpcContextIdentifier;
-import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
 import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
 import org.opendaylight.controller.sal.binding.impl.MountPointManagerImpl.BindingMountPointImpl;
 import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
-import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl.GlobalRpcRegistrationListener;
-import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl.RouterInstantiationListener;
-import org.opendaylight.controller.sal.common.util.CommitHandlerTransactions;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 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.Provider;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
-import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
 import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.Augmentable;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.BaseIdentity;
-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.Notification;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
-import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Function;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSet.Builder;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
 public class BindingIndependentConnector implements //
         RuntimeDataProvider, //
         Provider, //
         AutoCloseable {
 
-    private final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class);
-
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+    private static final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class);
+    private static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier
             .builder().toInstance();
 
-    private final static Method EQUALS_METHOD;
-
     private BindingIndependentMappingService mappingService;
-
     private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService;
-
     private DataProviderService baDataService;
 
-    private final ConcurrentMap<Object, BindingToDomTransaction> domOpenedTransactions = new ConcurrentHashMap<>();
-    private final ConcurrentMap<Object, DomToBindingTransaction> bindingOpenedTransactions = new ConcurrentHashMap<>();
-
-    private final BindingToDomCommitHandler bindingToDomCommitHandler = new BindingToDomCommitHandler();
-    private final DomToBindingCommitHandler domToBindingCommitHandler = new DomToBindingCommitHandler();
-
-    private Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> baCommitHandlerRegistration;
-
-    private Registration<DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode>> biCommitHandlerRegistration;
+    private final ConcurrentMap<Object, BindingToDomTransaction> domOpenedTransactions;
+    private final ConcurrentMap<Object, DomToBindingTransaction> bindingOpenedTransactions;
+    private final BindingToDomCommitHandler bindingToDomCommitHandler;
+    private final DomToBindingCommitHandler domToBindingCommitHandler;
 
+    private Registration biCommitHandlerRegistration;
     private RpcProvisionRegistry biRpcRegistry;
     private RpcProviderRegistry baRpcRegistry;
 
     private ListenerRegistration<DomToBindingRpcForwardingManager> domToBindingRpcManager;
-    // private ListenerRegistration<BindingToDomRpcForwardingManager>
-    // bindingToDomRpcManager;
 
-    private final Function<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> toDOMInstanceIdentifier = new Function<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier>() {
-
-        @Override
-        public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier apply(final InstanceIdentifier<?> input) {
-            return mappingService.toDataDom(input);
-        }
-
-    };
-
-    private boolean rpcForwarding = false;
-
-    private boolean dataForwarding = false;
-
-    private boolean notificationForwarding = false;
+    private boolean rpcForwarding;
+    private boolean dataForwarding;
+    private boolean notificationForwarding;
 
     private RpcProviderRegistryImpl baRpcRegistryImpl;
 
@@ -145,18 +74,21 @@ public class BindingIndependentConnector implements //
 
     private NotificationPublishService domNotificationService;
 
-    static {
-        try {
-            EQUALS_METHOD = Object.class.getMethod("equals", Object.class);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
+    public BindingIndependentConnector() {
+        domOpenedTransactions = new ConcurrentHashMap<>();
+        bindingOpenedTransactions = new ConcurrentHashMap<>();
+
+        bindingToDomCommitHandler = new BindingToDomCommitHandler(bindingOpenedTransactions, domOpenedTransactions);
+        domToBindingCommitHandler = new DomToBindingCommitHandler(bindingOpenedTransactions, domOpenedTransactions);
+        rpcForwarding = false;
+        dataForwarding = false;
+        notificationForwarding = false;
     }
 
     @Override
     public DataObject readOperationalData(final InstanceIdentifier<? extends DataObject> path) {
         try {
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
+            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier biPath = mappingService.toDataDom(path);
             CompositeNode result = biDataService.readOperationalData(biPath);
             return potentialAugmentationRead(path, biPath, result);
         } catch (DeserializationException e) {
@@ -165,7 +97,7 @@ public class BindingIndependentConnector implements //
     }
 
     private DataObject potentialAugmentationRead(InstanceIdentifier<? extends DataObject> path,
-            final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, final CompositeNode result)
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier biPath, final CompositeNode result)
             throws DeserializationException {
         Class<? extends DataObject> targetType = path.getTargetType();
         if (Augmentation.class.isAssignableFrom(targetType)) {
@@ -182,7 +114,7 @@ public class BindingIndependentConnector implements //
     @Override
     public DataObject readConfigurationData(final InstanceIdentifier<? extends DataObject> path) {
         try {
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
+            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier biPath = mappingService.toDataDom(path);
             CompositeNode result = biDataService.readConfigurationData(biPath);
             return potentialAugmentationRead(path, biPath, result);
         } catch (DeserializationException e) {
@@ -190,84 +122,6 @@ public class BindingIndependentConnector implements //
         }
     }
 
-    private DataModificationTransaction createBindingToDomTransaction(
-            final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> source) {
-        DataModificationTransaction target = biDataService.beginTransaction();
-        LOG.debug("Created DOM Transaction {} for {},", target.getIdentifier(), source.getIdentifier());
-        for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
-            target.removeConfigurationData(biEntry);
-            LOG.debug("Delete of Binding Configuration Data {} is translated to {}", entry, biEntry);
-        }
-        for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
-            target.removeOperationalData(biEntry);
-            LOG.debug("Delete of Binding Operational Data {} is translated to {}", entry, biEntry);
-        }
-        for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedConfigurationData()
-                .entrySet()) {
-            Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
-                    .toDataDom(entry);
-            target.putConfigurationData(biEntry.getKey(), biEntry.getValue());
-            LOG.debug("Update of Binding Configuration Data {} is translated to {}", entry, biEntry);
-        }
-        for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedOperationalData()
-                .entrySet()) {
-            Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
-                    .toDataDom(entry);
-            target.putOperationalData(biEntry.getKey(), biEntry.getValue());
-            LOG.debug("Update of Binding Operational Data {} is translated to {}", entry, biEntry);
-        }
-
-        return target;
-    }
-
-    private org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction createDomToBindingTransaction(
-            final DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> source) {
-        org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction target = baDataService
-                .beginTransaction();
-        for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedConfigurationData()) {
-            try {
-
-                InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
-                target.removeConfigurationData(baEntry);
-            } catch (DeserializationException e) {
-                LOG.error("Ommiting from BA transaction: {}.", entry, e);
-            }
-        }
-        for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedOperationalData()) {
-            try {
-
-                InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
-                target.removeOperationalData(baEntry);
-            } catch (DeserializationException e) {
-                LOG.error("Ommiting from BA transaction: {}.", entry, e);
-            }
-        }
-        for (Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> entry : source
-                .getUpdatedConfigurationData().entrySet()) {
-            try {
-                InstanceIdentifier<?> baKey = mappingService.fromDataDom(entry.getKey());
-                DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
-                target.putConfigurationData(baKey, baData);
-            } catch (DeserializationException e) {
-                LOG.error("Ommiting from BA transaction: {}.", entry.getKey(), e);
-            }
-        }
-        for (Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> entry : source
-                .getUpdatedOperationalData().entrySet()) {
-            try {
-
-                InstanceIdentifier<?> baKey = mappingService.fromDataDom(entry.getKey());
-                DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
-                target.putOperationalData(baKey, baData);
-            } catch (DeserializationException e) {
-                LOG.error("Ommiting from BA transaction: {}.", entry.getKey(), e);
-            }
-        }
-        return target;
-    }
-
     public org.opendaylight.controller.sal.core.api.data.DataProviderService getBiDataService() {
         return biDataService;
     }
@@ -275,6 +129,7 @@ public class BindingIndependentConnector implements //
     protected void setDomDataService(
             final org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
         this.biDataService = biDataService;
+        bindingToDomCommitHandler.setBindingIndependentDataService(this.biDataService);
     }
 
     public DataProviderService getBaDataService() {
@@ -283,6 +138,7 @@ public class BindingIndependentConnector implements //
 
     protected void setBindingDataService(final DataProviderService baDataService) {
         this.baDataService = baDataService;
+        domToBindingCommitHandler.setBindingAwareDataService(this.baDataService);
     }
 
     public RpcProviderRegistry getRpcRegistry() {
@@ -318,14 +174,20 @@ public class BindingIndependentConnector implements //
         dataForwarding = true;
     }
 
+    //WTF? - cycle references to biFwdManager - need to solve :-/
     public void startRpcForwarding() {
+        checkNotNull(mappingService, "Unable to start Rpc forwarding. Reason: Mapping Service is not initialized properly!");
         if (biRpcRegistry != null && baRpcRegistry instanceof RouteChangePublisher<?, ?>) {
             checkState(!rpcForwarding, "Connector is already forwarding RPCs");
-            domToBindingRpcManager = baRpcRegistry.registerRouteChangeListener(new DomToBindingRpcForwardingManager());
+            final DomToBindingRpcForwardingManager biFwdManager = new DomToBindingRpcForwardingManager(mappingService, biRpcRegistry, baRpcRegistry);
+
+            domToBindingRpcManager = baRpcRegistry.registerRouteChangeListener(biFwdManager);
+            biRpcRegistry.addRpcRegistrationListener(biFwdManager);
             if (baRpcRegistry instanceof RpcProviderRegistryImpl) {
                 baRpcRegistryImpl = (RpcProviderRegistryImpl) baRpcRegistry;
                 baRpcRegistryImpl.registerRouterInstantiationListener(domToBindingRpcManager.getInstance());
                 baRpcRegistryImpl.registerGlobalRpcRegistrationListener(domToBindingRpcManager.getInstance());
+                biFwdManager.setRegistryImpl(baRpcRegistryImpl);
             }
             rpcForwarding = true;
         }
@@ -333,15 +195,23 @@ public class BindingIndependentConnector implements //
 
     public void startNotificationForwarding() {
         checkState(!notificationForwarding, "Connector is already forwarding notifications.");
-        if (baNotifyService != null && domNotificationService != null) {
-            baNotifyService.registerInterestListener(new DomToBindingNotificationForwarder());
-
+        if (mappingService == null) {
+            LOG.warn("Unable to start Notification forwarding. Reason: Mapping Service is not initialized properly!");
+        } else if (baNotifyService == null) {
+            LOG.warn("Unable to start Notification forwarding. Reason: Binding Aware Notify Service is not initialized properly!");
+        } else if (domNotificationService == null) {
+            LOG.warn("Unable to start Notification forwarding. Reason: DOM Notification Service is not initialized properly!");
+        } else {
+            baNotifyService.registerInterestListener(
+                new DomToBindingNotificationForwarder(mappingService, baNotifyService, domNotificationService));
             notificationForwarding = true;
         }
     }
 
     protected void setMappingService(final BindingIndependentMappingService mappingService) {
         this.mappingService = mappingService;
+        bindingToDomCommitHandler.setMappingService(this.mappingService);
+        domToBindingCommitHandler.setMappingService(this.mappingService);
     }
 
     @Override
@@ -356,387 +226,15 @@ public class BindingIndependentConnector implements //
 
     }
 
-    public <T extends RpcService> void onRpcRouterCreated(final Class<T> serviceType, final RpcRouter<T> router) {
-
-    }
-
     public void setDomRpcRegistry(final RpcProvisionRegistry registry) {
         biRpcRegistry = registry;
     }
 
     @Override
     public void close() throws Exception {
-        if (baCommitHandlerRegistration != null) {
-            baCommitHandlerRegistration.close();
-        }
         if (biCommitHandlerRegistration != null) {
             biCommitHandlerRegistration.close();
         }
-
-    }
-
-    private class DomToBindingTransaction implements
-            DataCommitTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
-
-        private final org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing;
-        private final DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> modification;
-
-        public DomToBindingTransaction(
-                final org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing,
-                final DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> modification) {
-            super();
-            this.backing = backing;
-            this.modification = modification;
-            bindingOpenedTransactions.put(backing.getIdentifier(), this);
-        }
-
-        @Override
-        public DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getModification() {
-            return modification;
-        }
-
-        @Override
-        public RpcResult<Void> rollback() throws IllegalStateException {
-            // backing.cancel();
-            return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
-        }
-
-        @Override
-        public RpcResult<Void> finish() throws IllegalStateException {
-            Future<RpcResult<TransactionStatus>> result = backing.commit();
-            try {
-                RpcResult<TransactionStatus> baResult = result.get();
-                return Rpcs.<Void> getRpcResult(baResult.isSuccessful(), null, baResult.getErrors());
-            } catch (InterruptedException e) {
-                throw new IllegalStateException("", e);
-            } catch (ExecutionException e) {
-                throw new IllegalStateException("", e);
-            }
-        }
-    }
-
-    private class BindingToDomTransaction implements
-            DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
-
-        private final DataModificationTransaction backing;
-        private final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
-
-        public BindingToDomTransaction(final DataModificationTransaction backing,
-                final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
-            this.backing = backing;
-            this.modification = modification;
-            domOpenedTransactions.put(backing.getIdentifier(), this);
-        }
-
-        @Override
-        public DataModification<InstanceIdentifier<? extends DataObject>, DataObject> getModification() {
-            return modification;
-        }
-
-        @Override
-        public RpcResult<Void> finish() throws IllegalStateException {
-            Future<RpcResult<TransactionStatus>> result = backing.commit();
-            try {
-                RpcResult<TransactionStatus> biResult = result.get();
-                return Rpcs.<Void> getRpcResult(biResult.isSuccessful(), null, biResult.getErrors());
-            } catch (InterruptedException e) {
-                throw new IllegalStateException("", e);
-            } catch (ExecutionException e) {
-                throw new IllegalStateException("", e);
-            } finally {
-                domOpenedTransactions.remove(backing.getIdentifier());
-            }
-        }
-
-        @Override
-        public RpcResult<Void> rollback() throws IllegalStateException {
-            domOpenedTransactions.remove(backing.getIdentifier());
-            return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
-        }
-    }
-
-    private class BindingToDomCommitHandler implements
-            DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
-
-        @Override
-        public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
-                final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> bindingTransaction) {
-
-            /**
-             * Transaction was created as DOM transaction, in that case we do
-             * not need to forward it back.
-             */
-            if (bindingOpenedTransactions.containsKey(bindingTransaction.getIdentifier())) {
-
-                return CommitHandlerTransactions.allwaysSuccessfulTransaction(bindingTransaction);
-            }
-            DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction);
-            BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction);
-            LOG.trace("Forwarding Binding Transaction: {} as DOM Transaction: {} .",
-                    bindingTransaction.getIdentifier(), domTransaction.getIdentifier());
-            return wrapped;
-        }
-    }
-
-    private class DomToBindingCommitHandler implements //
-            RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject>>, //
-            DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
-
-        @Override
-        public void onRegister(
-                final DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject> registration) {
-
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(registration
-                    .getPath());
-
-        }
-
-        @Override
-        public void onUnregister(
-                final DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject> registration) {
-            // NOOP for now
-            // FIXME: do registration based on only active commit handlers.
-        }
-
-        @Override
-        public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> requestCommit(
-                final DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> domTransaction) {
-            Object identifier = domTransaction.getIdentifier();
-
-            /**
-             * We checks if the transcation was originated in this mapper. If it
-             * was originated in this mapper we are returing allways success
-             * commit hanlder to prevent creating loop in two-phase commit and
-             * duplicating data.
-             */
-            if (domOpenedTransactions.containsKey(identifier)) {
-                return CommitHandlerTransactions.allwaysSuccessfulTransaction(domTransaction);
-            }
-
-            org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction baTransaction = createDomToBindingTransaction(domTransaction);
-            DomToBindingTransaction forwardedTransaction = new DomToBindingTransaction(baTransaction, domTransaction);
-            LOG.trace("Forwarding DOM Transaction: {} as Binding Transaction: {}.", domTransaction.getIdentifier(),
-                    baTransaction.getIdentifier());
-            return forwardedTransaction;
-        }
-    }
-
-    /**
-     * Manager responsible for instantiating forwarders responsible for
-     * forwarding of RPC invocations from DOM Broker to Binding Aware Broker
-     *
-     */
-    private class DomToBindingRpcForwardingManager implements
-            RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>, RouterInstantiationListener,
-            GlobalRpcRegistrationListener {
-
-        private final Map<Class<? extends RpcService>, DomToBindingRpcForwarder> forwarders = new WeakHashMap<>();
-        private RpcProviderRegistryImpl registryImpl;
-
-        public RpcProviderRegistryImpl getRegistryImpl() {
-            return registryImpl;
-        }
-
-        public void setRegistryImpl(final RpcProviderRegistryImpl registryImpl) {
-            this.registryImpl = registryImpl;
-        }
-
-        @Override
-        public void onGlobalRpcRegistered(final Class<? extends RpcService> cls) {
-            getRpcForwarder(cls, null);
-        }
-
-        @Override
-        public void onGlobalRpcUnregistered(final Class<? extends RpcService> cls) {
-            // NOOP
-        }
-
-        @Override
-        public void onRpcRouterCreated(final RpcRouter<?> router) {
-            Class<? extends BaseIdentity> ctx = router.getContexts().iterator().next();
-            getRpcForwarder(router.getServiceType(), ctx);
-        }
-
-        @Override
-        public void onRouteChange(final RouteChange<RpcContextIdentifier, InstanceIdentifier<?>> change) {
-            for (Entry<RpcContextIdentifier, Set<InstanceIdentifier<?>>> entry : change.getAnnouncements().entrySet()) {
-                bindingRoutesAdded(entry);
-            }
-        }
-
-        private void bindingRoutesAdded(final Entry<RpcContextIdentifier, Set<InstanceIdentifier<?>>> entry) {
-            Class<? extends BaseIdentity> context = entry.getKey().getRoutingContext();
-            Class<? extends RpcService> service = entry.getKey().getRpcService();
-            if (context != null) {
-                getRpcForwarder(service, context).registerPaths(context, service, entry.getValue());
-            }
-        }
-
-        private DomToBindingRpcForwarder getRpcForwarder(final Class<? extends RpcService> service,
-                final Class<? extends BaseIdentity> context) {
-            DomToBindingRpcForwarder potential = forwarders.get(service);
-            if (potential != null) {
-                return potential;
-            }
-            if (context == null) {
-                potential = new DomToBindingRpcForwarder(service);
-            } else {
-                potential = new DomToBindingRpcForwarder(service, context);
-            }
-
-            forwarders.put(service, potential);
-            return potential;
-        }
-
-    }
-
-    private class DomToBindingRpcForwarder implements RpcImplementation, InvocationHandler {
-
-        private final Set<QName> supportedRpcs;
-        private final WeakReference<Class<? extends RpcService>> rpcServiceType;
-        private final Set<org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration> registrations;
-        private final Map<QName, RpcInvocationStrategy> strategiesByQName = new HashMap<>();
-        private final WeakHashMap<Method, RpcInvocationStrategy> strategiesByMethod = new WeakHashMap<>();
-
-        public DomToBindingRpcForwarder(final Class<? extends RpcService> service) {
-            this.rpcServiceType = new WeakReference<Class<? extends RpcService>>(service);
-            this.supportedRpcs = mappingService.getRpcQNamesFor(service);
-            try {
-                for (QName rpc : supportedRpcs) {
-                    RpcInvocationStrategy strategy = createInvocationStrategy(rpc, service);
-                    strategiesByMethod.put(strategy.targetMethod, strategy);
-                    strategiesByQName.put(rpc, strategy);
-                    biRpcRegistry.addRpcImplementation(rpc, this);
-                }
-
-            } catch (Exception e) {
-                LOG.error("Could not forward Rpcs of type {}", service.getName(), e);
-            }
-            registrations = ImmutableSet.of();
-        }
-
-        /**
-         * Constructor for Routed RPC Forwareder.
-         *
-         * @param service
-         * @param context
-         */
-        public DomToBindingRpcForwarder(final Class<? extends RpcService> service,
-                final Class<? extends BaseIdentity> context) {
-            this.rpcServiceType = new WeakReference<Class<? extends RpcService>>(service);
-            this.supportedRpcs = mappingService.getRpcQNamesFor(service);
-            Builder<RoutedRpcRegistration> registrationsBuilder = ImmutableSet
-                    .<org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration> builder();
-            try {
-                for (QName rpc : supportedRpcs) {
-                    RpcInvocationStrategy strategy = createInvocationStrategy(rpc, service);
-                    strategiesByMethod.put(strategy.targetMethod, strategy);
-                    strategiesByQName.put(rpc, strategy);
-                    registrationsBuilder.add(biRpcRegistry.addRoutedRpcImplementation(rpc, this));
-                }
-                createDefaultDomForwarder();
-            } catch (Exception e) {
-                LOG.error("Could not forward Rpcs of type {}", service.getName(), e);
-            }
-            registrations = registrationsBuilder.build();
-        }
-
-        public void registerPaths(final Class<? extends BaseIdentity> context,
-                final Class<? extends RpcService> service, final Set<InstanceIdentifier<?>> set) {
-            QName ctx = BindingReflections.findQName(context);
-            for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path : FluentIterable.from(set).transform(
-                    toDOMInstanceIdentifier)) {
-                for (org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration reg : registrations) {
-                    reg.registerPath(ctx, path);
-                }
-            }
-        }
-
-        @Override
-        public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
-            if (EQUALS_METHOD.equals(method)) {
-                return false;
-            }
-            RpcInvocationStrategy strategy = strategiesByMethod.get(method);
-            checkState(strategy != null);
-            checkArgument(args.length <= 2);
-            if (args.length == 1) {
-                checkArgument(args[0] instanceof DataObject);
-                return strategy.forwardToDomBroker((DataObject) args[0]);
-            }
-            return strategy.forwardToDomBroker(null);
-        }
-
-        public void removePaths(final Class<? extends BaseIdentity> context, final Class<? extends RpcService> service,
-                final Set<InstanceIdentifier<?>> set) {
-            QName ctx = BindingReflections.findQName(context);
-            for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path : FluentIterable.from(set).transform(
-                    toDOMInstanceIdentifier)) {
-                for (org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration reg : registrations) {
-                    reg.unregisterPath(ctx, path);
-                }
-            }
-        }
-
-        @Override
-        public Set<QName> getSupportedRpcs() {
-            return supportedRpcs;
-        }
-
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        public void createDefaultDomForwarder() {
-            if (baRpcRegistryImpl != null) {
-                Class<?> cls = rpcServiceType.get();
-                ClassLoader clsLoader = cls.getClassLoader();
-                RpcService proxy = (RpcService) Proxy.newProxyInstance(clsLoader, new Class<?>[] { cls }, this);
-
-                RpcRouter rpcRouter = baRpcRegistryImpl.getRpcRouter(rpcServiceType.get());
-                rpcRouter.registerDefaultService(proxy);
-            }
-        }
-
-        @Override
-        public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(final QName rpc, final CompositeNode domInput) {
-            checkArgument(rpc != null);
-            checkArgument(domInput != null);
-
-            Class<? extends RpcService> rpcType = rpcServiceType.get();
-            checkState(rpcType != null);
-            RpcService rpcService = baRpcRegistry.getRpcService(rpcType);
-            checkState(rpcService != null);
-            CompositeNode domUnwrappedInput = domInput.getFirstCompositeByName(QName.create(rpc, "input"));
-
-            try {
-                return Futures.immediateFuture(resolveInvocationStrategy(rpc).invokeOn(rpcService, domUnwrappedInput));
-            } catch (Exception e) {
-                return Futures.immediateFailedFuture(e);
-            }
-        }
-
-        private RpcInvocationStrategy resolveInvocationStrategy(final QName rpc) {
-            return strategiesByQName.get(rpc);
-        }
-
-        private RpcInvocationStrategy createInvocationStrategy(final QName rpc,
-                final Class<? extends RpcService> rpcType) throws Exception {
-            return ClassLoaderUtils.withClassLoader(rpcType.getClassLoader(), new Callable<RpcInvocationStrategy>() {
-                @Override
-                public RpcInvocationStrategy call() throws Exception {
-                    String methodName = BindingMapping.getMethodName(rpc);
-                    Method targetMethod = null;
-                    for (Method possibleMethod : rpcType.getMethods()) {
-                        if (possibleMethod.getName().equals(methodName)
-                                && BindingReflections.isRpcMethod(possibleMethod)) {
-                            targetMethod = possibleMethod;
-                            break;
-                        }
-                    }
-                    checkState(targetMethod != null, "Rpc method not found");
-                    return  new RpcInvocationStrategy(rpc,targetMethod, mappingService, biRpcRegistry);
-                }
-
-            });
-        }
     }
 
     public boolean isRpcForwarding() {
@@ -763,45 +261,4 @@ public class BindingIndependentConnector implements //
     public void setDomNotificationService(final NotificationPublishService domService) {
         this.domNotificationService = domService;
     }
-
-    private class DomToBindingNotificationForwarder implements NotificationInterestListener, NotificationListener {
-
-        private final ConcurrentMap<QName, WeakReference<Class<? extends Notification>>> notifications = new ConcurrentHashMap<>();
-        private final Set<QName> supportedNotifications = new HashSet<>();
-
-        @Override
-        public Set<QName> getSupportedNotifications() {
-            return Collections.unmodifiableSet(supportedNotifications);
-        }
-
-        @Override
-        public void onNotification(final CompositeNode notification) {
-            QName qname = notification.getNodeType();
-            WeakReference<Class<? extends Notification>> potential = notifications.get(qname);
-            if (potential != null) {
-                Class<? extends Notification> potentialClass = potential.get();
-                if (potentialClass != null) {
-                    final DataContainer baNotification = mappingService.dataObjectFromDataDom(potentialClass,
-                            notification);
-
-                    if (baNotification instanceof Notification) {
-                        baNotifyService.publish((Notification) baNotification);
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void onNotificationSubscribtion(final Class<? extends Notification> notificationType) {
-            QName qname = BindingReflections.findQName(notificationType);
-            if (qname != null) {
-                WeakReference<Class<? extends Notification>> already = notifications.putIfAbsent(qname,
-                        new WeakReference<Class<? extends Notification>>(notificationType));
-                if (already == null) {
-                    domNotificationService.addNotificationListener(qname, this);
-                    supportedNotifications.add(qname);
-                }
-            }
-        }
-    }
 }
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingToDomCommitHandler.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingToDomCommitHandler.java
new file mode 100644 (file)
index 0000000..44198bf
--- /dev/null
@@ -0,0 +1,104 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+
+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.common.util.CommitHandlerTransactions;
+import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @deprecated This is part of the legacy DataBrokerService
+ */
+@Deprecated
+class BindingToDomCommitHandler implements
+    DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+    private final Logger LOG = LoggerFactory.getLogger(BindingToDomCommitHandler.class);
+
+    private final ConcurrentMap<Object, DomToBindingTransaction> bindingOpenedTransactions;
+    private final ConcurrentMap<Object, BindingToDomTransaction> domOpenedTransactions;
+    private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService;
+    private BindingIndependentMappingService mappingService;
+
+    BindingToDomCommitHandler(final ConcurrentMap<Object, DomToBindingTransaction> bindingOpenedTransactions,
+        final ConcurrentMap<Object, BindingToDomTransaction> domOpenedTransactions) {
+        this.bindingOpenedTransactions = bindingOpenedTransactions;
+        this.domOpenedTransactions = domOpenedTransactions;
+    }
+
+    public void setBindingIndependentDataService(final DataProviderService biDataService) {
+        this.biDataService = biDataService;
+    }
+
+    public void setMappingService(final BindingIndependentMappingService mappingService) {
+        this.mappingService = mappingService;
+    }
+
+    @Override
+    public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
+        final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> bindingTransaction) {
+
+        /**
+         * Transaction was created as DOM transaction, in that case we do
+         * not need to forward it back.
+         */
+        if (bindingOpenedTransactions.containsKey(bindingTransaction.getIdentifier())) {
+            return CommitHandlerTransactions.allwaysSuccessfulTransaction(bindingTransaction);
+        }
+        DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction);
+        BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction, domOpenedTransactions);
+        LOG.trace("Forwarding Binding Transaction: {} as DOM Transaction: {} .",
+            bindingTransaction.getIdentifier(), domTransaction.getIdentifier());
+        return wrapped;
+    }
+
+    private DataModificationTransaction createBindingToDomTransaction(
+        final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> source) {
+        if (biDataService == null) {
+            final String msg = "Binding Independent Service is not initialized correctly! Binding to DOM Transaction cannot be created for ";
+            LOG.error(msg + "{}", source);
+            throw new IllegalStateException(msg + source);
+        }
+        if (mappingService == null) {
+            final String msg = "Mapping Service is not initialized correctly! Binding to DOM Transaction cannot be created for ";
+            LOG.error(msg + "{}", source);
+            throw new IllegalStateException(msg + source);
+        }
+        DataModificationTransaction target = biDataService.beginTransaction();
+        LOG.debug("Created DOM Transaction {} for {},", target.getIdentifier(), source.getIdentifier());
+        for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
+            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier biEntry = mappingService.toDataDom(entry);
+            target.removeConfigurationData(biEntry);
+            LOG.debug("Delete of Binding Configuration Data {} is translated to {}", entry, biEntry);
+        }
+        for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
+            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier biEntry = mappingService.toDataDom(entry);
+            target.removeOperationalData(biEntry);
+            LOG.debug("Delete of Binding Operational Data {} is translated to {}", entry, biEntry);
+        }
+        for (Map.Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedConfigurationData()
+            .entrySet()) {
+            Map.Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> biEntry = mappingService
+                .toDataDom(entry);
+            target.putConfigurationData(biEntry.getKey(), biEntry.getValue());
+            LOG.debug("Update of Binding Configuration Data {} is translated to {}", entry, biEntry);
+        }
+        for (Map.Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedOperationalData()
+            .entrySet()) {
+            Map.Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> biEntry = mappingService
+                .toDataDom(entry);
+            target.putOperationalData(biEntry.getKey(), biEntry.getValue());
+            LOG.debug("Update of Binding Operational Data {} is translated to {}", entry, biEntry);
+        }
+        return target;
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingToDomTransaction.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingToDomTransaction.java
new file mode 100644 (file)
index 0000000..081adb4
--- /dev/null
@@ -0,0 +1,59 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+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.core.api.data.DataModificationTransaction;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+class BindingToDomTransaction implements
+    DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+    private final DataModificationTransaction backing;
+    private final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
+    private final ConcurrentMap<Object, BindingToDomTransaction> domOpenedTransactions;
+
+    public BindingToDomTransaction(final DataModificationTransaction backing,
+        final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,
+        ConcurrentMap<Object, BindingToDomTransaction> domOpenedTransactions) {
+        this.backing = backing;
+        this.modification = modification;
+        this.domOpenedTransactions = domOpenedTransactions;
+        this.domOpenedTransactions.put(backing.getIdentifier(), this);
+    }
+
+    @Override
+    public DataModification<InstanceIdentifier<? extends DataObject>, DataObject> getModification() {
+        return modification;
+    }
+
+    @Override
+    public RpcResult<Void> finish() throws IllegalStateException {
+        Future<RpcResult<TransactionStatus>> result = backing.commit();
+        try {
+            RpcResult<TransactionStatus> biResult = result.get();
+            domOpenedTransactions.remove(backing.getIdentifier());
+            return RpcResultBuilder.<Void> status(biResult.isSuccessful())
+                                             .withRpcErrors(biResult.getErrors()).build();
+        } catch (InterruptedException e) {
+            throw new IllegalStateException("", e);
+        } catch (ExecutionException e) {
+            throw new IllegalStateException("", e);
+        } finally {
+            domOpenedTransactions.remove(backing.getIdentifier());
+        }
+    }
+
+    @Override
+    public RpcResult<Void> rollback() throws IllegalStateException {
+        domOpenedTransactions.remove(backing.getIdentifier());
+        return RpcResultBuilder.<Void> success().build();
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DataModificationTracker.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DataModificationTracker.java
deleted file mode 100644 (file)
index 8278b36..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.impl.connect.dom;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
-import org.opendaylight.yangtools.concepts.Path;
-
-public final class DataModificationTracker<P extends Path<P>,D> {
-    ConcurrentMap<Object, DataModification<P,D>> trackedTransactions = new ConcurrentHashMap<>();
-
-    public void startTrackingModification(DataModification<P,D> modification) {
-        trackedTransactions.putIfAbsent(modification.getIdentifier(), modification);
-    }
-
-    public boolean containsIdentifier(Object identifier) {
-        return trackedTransactions.containsKey(identifier);
-    }
-}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingCommitHandler.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingCommitHandler.java
new file mode 100644 (file)
index 0000000..43334f0
--- /dev/null
@@ -0,0 +1,140 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+
+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.DataModification;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.common.util.CommitHandlerTransactions;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @deprecated This is part of the legacy DataBrokerService
+ */
+@Deprecated
+class DomToBindingCommitHandler implements //
+    RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject>>, //
+    DataCommitHandler<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> {
+
+    private final Logger LOG = LoggerFactory.getLogger(DomToBindingCommitHandler.class);
+
+    private final ConcurrentMap<Object, DomToBindingTransaction> bindingOpenedTransactions;
+    private final ConcurrentMap<Object, BindingToDomTransaction> domOpenedTransactions;
+
+    DomToBindingCommitHandler(final ConcurrentMap<Object, DomToBindingTransaction> bindingOpenedTransactions,
+        final ConcurrentMap<Object, BindingToDomTransaction> domOpenedTransactions) {
+        this.bindingOpenedTransactions = bindingOpenedTransactions;
+        this.domOpenedTransactions = domOpenedTransactions;
+    }
+
+    private DataProviderService baDataService;
+    private BindingIndependentMappingService mappingService;
+
+    public void setBindingAwareDataService(final DataProviderService baDataService) {
+        this.baDataService = baDataService;
+    }
+
+    public void setMappingService(final BindingIndependentMappingService mappingService) {
+        this.mappingService = mappingService;
+    }
+
+    @Override
+    public void onRegister(final DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject> registration) {
+        mappingService.toDataDom(registration.getPath());
+    }
+
+    @Override
+    public void onUnregister(
+        final DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject> registration) {
+        // NOOP for now
+        // FIXME: do registration based on only active commit handlers.
+    }
+
+    @Override
+    public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> requestCommit(
+        final DataModification<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> domTransaction) {
+        Object identifier = domTransaction.getIdentifier();
+
+        /**
+         * We checks if the transcation was originated in this mapper. If it
+         * was originated in this mapper we are returing allways success
+         * commit hanlder to prevent creating loop in two-phase commit and
+         * duplicating data.
+         */
+        if (domOpenedTransactions.containsKey(identifier)) {
+            return CommitHandlerTransactions.allwaysSuccessfulTransaction(domTransaction);
+        }
+
+        org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction baTransaction = createDomToBindingTransaction(domTransaction);
+        DomToBindingTransaction forwardedTransaction = new DomToBindingTransaction(baTransaction, domTransaction, bindingOpenedTransactions);
+        LOG.trace("Forwarding DOM Transaction: {} as Binding Transaction: {}.", domTransaction.getIdentifier(),
+            baTransaction.getIdentifier());
+        return forwardedTransaction;
+    }
+
+    private org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction createDomToBindingTransaction(
+        final DataModification<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> source) {
+        if (baDataService == null) {
+            final String msg = "Binding Aware Service is not initialized correctly! DOM to Binding Transaction cannot be created for ";
+            LOG.error(msg + "{}", source);
+            throw new IllegalStateException(msg + source);
+        }
+        if (mappingService == null) {
+            final String msg = "Mapping Service is not initialized correctly! DOM to Binding Transaction cannot be created for ";
+            LOG.error(msg + "{}", source);
+            throw new IllegalStateException(msg + source);
+        }
+
+        org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction target = baDataService
+            .beginTransaction();
+        for (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier entry : source.getRemovedConfigurationData()) {
+            try {
+
+                InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
+                target.removeConfigurationData(baEntry);
+            } catch (DeserializationException e) {
+                LOG.error("Ommiting from BA transaction: {}.", entry, e);
+            }
+        }
+        for (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier entry : source.getRemovedOperationalData()) {
+            try {
+
+                InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
+                target.removeOperationalData(baEntry);
+            } catch (DeserializationException e) {
+                LOG.error("Ommiting from BA transaction: {}.", entry, e);
+            }
+        }
+        for (Map.Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> entry : source
+            .getUpdatedConfigurationData().entrySet()) {
+            try {
+                InstanceIdentifier<?> baKey = mappingService.fromDataDom(entry.getKey());
+                DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
+                target.putConfigurationData(baKey, baData);
+            } catch (DeserializationException e) {
+                LOG.error("Ommiting from BA transaction: {}.", entry.getKey(), e);
+            }
+        }
+        for (Map.Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> entry : source
+            .getUpdatedOperationalData().entrySet()) {
+            try {
+
+                InstanceIdentifier<?> baKey = mappingService.fromDataDom(entry.getKey());
+                DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
+                target.putOperationalData(baKey, baData);
+            } catch (DeserializationException e) {
+                LOG.error("Ommiting from BA transaction: {}.", entry.getKey(), e);
+            }
+        }
+        return target;
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingNotificationForwarder.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingNotificationForwarder.java
new file mode 100644 (file)
index 0000000..841ea55
--- /dev/null
@@ -0,0 +1,70 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.lang.ref.WeakReference;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.Notification;
+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.impl.codec.BindingIndependentMappingService;
+
+class DomToBindingNotificationForwarder implements NotificationProviderService.NotificationInterestListener,
+    NotificationListener {
+
+    private final ConcurrentMap<QName, WeakReference<Class<? extends Notification>>> notifications = new ConcurrentHashMap<>();
+    private final Set<QName> supportedNotifications = new HashSet<>();
+
+    private final BindingIndependentMappingService mappingService;
+    private final NotificationProviderService baNotifyService;
+    private final NotificationPublishService domNotificationService;
+
+    DomToBindingNotificationForwarder(final BindingIndependentMappingService mappingService, final NotificationProviderService baNotifyService,
+        final NotificationPublishService domNotificationService) {
+        this.mappingService = mappingService;
+        this.baNotifyService = baNotifyService;
+        this.domNotificationService = domNotificationService;
+    }
+
+    @Override
+    public Set<QName> getSupportedNotifications() {
+        return Collections.unmodifiableSet(supportedNotifications);
+    }
+
+    @Override
+    public void onNotification(final CompositeNode notification) {
+        QName qname = notification.getNodeType();
+        WeakReference<Class<? extends Notification>> potential = notifications.get(qname);
+        if (potential != null) {
+            Class<? extends Notification> potentialClass = potential.get();
+            if (potentialClass != null) {
+                final DataContainer baNotification = mappingService.dataObjectFromDataDom(potentialClass,
+                    notification);
+
+                if (baNotification instanceof Notification) {
+                    baNotifyService.publish((Notification) baNotification);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onNotificationSubscribtion(final Class<? extends Notification> notificationType) {
+        QName qname = BindingReflections.findQName(notificationType);
+        if (qname != null) {
+            WeakReference<Class<? extends Notification>> already = notifications.putIfAbsent(qname,
+                new WeakReference<Class<? extends Notification>>(notificationType));
+            if (already == null) {
+                domNotificationService.addNotificationListener(qname, this);
+                supportedNotifications.add(qname);
+            }
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingRpcForwarder.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingRpcForwarder.java
new file mode 100644 (file)
index 0000000..ab6d56c
--- /dev/null
@@ -0,0 +1,281 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.Callable;
+
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.yangtools.concepts.CompositeObjectRegistration;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.yang.binding.BaseIdentity;
+import org.opendaylight.yangtools.yang.binding.BindingMapping;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils;
+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.impl.codec.BindingIndependentMappingService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+class DomToBindingRpcForwarder implements RpcImplementation, InvocationHandler {
+
+    private final Logger LOG = LoggerFactory.getLogger(DomToBindingRpcForwarder.class);
+
+    private final Set<QName> supportedRpcs;
+    private final WeakReference<Class<? extends RpcService>> rpcServiceType;
+    private Set<org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration> registrations;
+    private final Map<QName, RpcInvocationStrategy> strategiesByQName = new HashMap<>();
+    private final WeakHashMap<Method, RpcInvocationStrategy> strategiesByMethod = new WeakHashMap<>();
+    private final RpcService proxy;
+    private ObjectRegistration<?> forwarderRegistration;
+    private boolean registrationInProgress = false;
+
+    private final RpcProvisionRegistry biRpcRegistry;
+    private final RpcProviderRegistry baRpcRegistry;
+    private final RpcProviderRegistryImpl baRpcRegistryImpl;
+
+    private final Function<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier> toDOMInstanceIdentifier;
+
+    private final static Method EQUALS_METHOD;
+
+    static {
+        try {
+            EQUALS_METHOD = Object.class.getMethod("equals", Object.class);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public DomToBindingRpcForwarder(final Class<? extends RpcService> service, final BindingIndependentMappingService mappingService,
+        final RpcProvisionRegistry biRpcRegistry, final RpcProviderRegistry baRpcRegistry, final RpcProviderRegistryImpl registryImpl) {
+        this.rpcServiceType = new WeakReference<Class<? extends RpcService>>(service);
+        this.supportedRpcs = mappingService.getRpcQNamesFor(service);
+
+        toDOMInstanceIdentifier = new Function<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier>() {
+
+            @Override
+            public org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier apply(final InstanceIdentifier<?> input) {
+                return mappingService.toDataDom(input);
+            }
+        };
+
+        this.biRpcRegistry = biRpcRegistry;
+        this.baRpcRegistry = baRpcRegistry;
+        this.baRpcRegistryImpl = registryImpl;
+
+        Class<?> cls = rpcServiceType.get();
+        ClassLoader clsLoader = cls.getClassLoader();
+        proxy =(RpcService) Proxy.newProxyInstance(clsLoader, new Class<?>[] { cls }, this);
+        createStrategies(mappingService);
+    }
+
+    /**
+     * Constructor for Routed RPC Forwareder.
+     *
+     * @param service
+     * @param context
+     * @param registryImpl
+     */
+    public DomToBindingRpcForwarder(final Class<? extends RpcService> service,
+        final Class<? extends BaseIdentity> context, final BindingIndependentMappingService mappingService,
+        final RpcProvisionRegistry biRpcRegistry, final RpcProviderRegistry baRpcRegistry, final RpcProviderRegistryImpl registryImpl) {
+        this(service, mappingService, biRpcRegistry, baRpcRegistry,registryImpl);
+
+        final ImmutableSet.Builder<Broker.RoutedRpcRegistration> registrationsBuilder = ImmutableSet.builder();
+        try {
+            for (QName rpc : supportedRpcs) {
+                registrationsBuilder.add(biRpcRegistry.addRoutedRpcImplementation(rpc, this));
+            }
+            createDefaultDomForwarder();
+        } catch (Exception e) {
+            LOG.error("Could not forward Rpcs of type {}", service.getName(), e);
+        }
+        registrations = registrationsBuilder.build();
+    }
+
+
+
+    private void createStrategies(final BindingIndependentMappingService mappingService) {
+        try {
+            for (QName rpc : supportedRpcs) {
+                RpcInvocationStrategy strategy = createInvocationStrategy(rpc, rpcServiceType.get(), mappingService);
+                strategiesByMethod.put(strategy.targetMethod, strategy);
+                strategiesByQName.put(rpc, strategy);
+            }
+        } catch (Exception e) {
+            LOG.error("Could not forward Rpcs of type {}", rpcServiceType.get(), e);
+        }
+
+    }
+
+    /**
+     * Registers RPC Forwarder to DOM Broker,
+     * this means Binding Aware Broker has implementation of RPC
+     * which is registered to it.
+     *
+     * If RPC Forwarder was previously registered to DOM Broker
+     * or to Bidning Broker this method is noop to prevent
+     * creating forwarding loop.
+     *
+     */
+    public void registerToDOMBroker() {
+        if(!registrationInProgress && forwarderRegistration == null) {
+            registrationInProgress = true;
+            CompositeObjectRegistration.CompositeObjectRegistrationBuilder<DomToBindingRpcForwarder> builder = CompositeObjectRegistration.builderFor(this);
+            try {
+                for (QName rpc : supportedRpcs) {
+                    builder.add(biRpcRegistry.addRpcImplementation(rpc, this));
+                }
+            } catch (Exception e) {
+                LOG.error("Could not forward Rpcs of type {}", rpcServiceType.get(), e);
+            }
+            this.forwarderRegistration = builder.toInstance();
+            registrationInProgress = false;
+        }
+    }
+
+
+    public void registerPaths(final Class<? extends BaseIdentity> context,
+        final Class<? extends RpcService> service, final Set<InstanceIdentifier<?>> set) {
+        QName ctx = BindingReflections.findQName(context);
+        for (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path : FluentIterable.from(set).transform(
+            toDOMInstanceIdentifier)) {
+            for (org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration reg : registrations) {
+                reg.registerPath(ctx, path);
+            }
+        }
+    }
+
+    @Override
+    public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+        if (EQUALS_METHOD.equals(method)) {
+            return false;
+        }
+        RpcInvocationStrategy strategy = strategiesByMethod.get(method);
+        checkState(strategy != null);
+        checkArgument(args.length <= 2);
+        if (args.length == 1) {
+            checkArgument(args[0] instanceof DataObject);
+            return strategy.forwardToDomBroker((DataObject) args[0]);
+        }
+        return strategy.forwardToDomBroker(null);
+    }
+
+    public void removePaths(final Class<? extends BaseIdentity> context, final Class<? extends RpcService> service,
+        final Set<InstanceIdentifier<?>> set) {
+        QName ctx = BindingReflections.findQName(context);
+        for (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path : FluentIterable.from(set).transform(
+            toDOMInstanceIdentifier)) {
+            for (org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration reg : registrations) {
+                reg.unregisterPath(ctx, path);
+            }
+        }
+    }
+
+    @Override
+    public Set<QName> getSupportedRpcs() {
+        return supportedRpcs;
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public void createDefaultDomForwarder() {
+        if (baRpcRegistryImpl != null) {
+            Class<?> cls = rpcServiceType.get();
+            ClassLoader clsLoader = cls.getClassLoader();
+            RpcService proxy = (RpcService) Proxy.newProxyInstance(clsLoader, new Class<?>[] { cls }, this);
+
+            RpcRouter rpcRouter = baRpcRegistryImpl.getRpcRouter(rpcServiceType.get());
+            rpcRouter.registerDefaultService(proxy);
+        }
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(final QName rpc, final CompositeNode domInput) {
+        checkArgument(rpc != null);
+        checkArgument(domInput != null);
+
+        Class<? extends RpcService> rpcType = rpcServiceType.get();
+        checkState(rpcType != null);
+        RpcService rpcService = baRpcRegistry.getRpcService(rpcType);
+        checkState(rpcService != null);
+        CompositeNode domUnwrappedInput = domInput.getFirstCompositeByName(QName.create(rpc, "input"));
+
+        try {
+            return Futures.immediateFuture(resolveInvocationStrategy(rpc).invokeOn(rpcService, domUnwrappedInput));
+        } catch (Exception e) {
+            return Futures.immediateFailedFuture(e);
+        }
+    }
+
+    private RpcInvocationStrategy resolveInvocationStrategy(final QName rpc) {
+        return strategiesByQName.get(rpc);
+    }
+
+    private RpcInvocationStrategy createInvocationStrategy(final QName rpc,
+        final Class<? extends RpcService> rpcType, final BindingIndependentMappingService mappingService) throws Exception {
+        return ClassLoaderUtils.withClassLoader(rpcType.getClassLoader(), new Callable<RpcInvocationStrategy>() {
+            @Override
+            public RpcInvocationStrategy call() throws Exception {
+                String methodName = BindingMapping.getMethodName(rpc);
+                Method targetMethod = null;
+                for (Method possibleMethod : rpcType.getMethods()) {
+                    if (possibleMethod.getName().equals(methodName)
+                        && BindingReflections.isRpcMethod(possibleMethod)) {
+                        targetMethod = possibleMethod;
+                        break;
+                    }
+                }
+                checkState(targetMethod != null, "Rpc method not found");
+                return new RpcInvocationStrategy(rpc, targetMethod, mappingService, biRpcRegistry);
+            }
+
+        });
+    }
+
+    /**
+     * Registers RPC Forwarder to Binding Broker,
+     * this means DOM Broekr has implementation of RPC
+     * which is registered to it.
+     *
+     * If RPC Forwarder was previously registered to DOM Broker
+     * or to Bidning Broker this method is noop to prevent
+     * creating forwarding loop.
+     *
+     */
+    public void registerToBindingBroker() {
+        if(!registrationInProgress && forwarderRegistration == null) {
+            try {
+                registrationInProgress = true;
+                this.forwarderRegistration = baRpcRegistry.addRpcImplementation((Class)rpcServiceType.get(), proxy);
+            } catch (Exception e) {
+                LOG.error("Unable to forward RPCs for {}",rpcServiceType.get(),e);
+            } finally {
+                registrationInProgress = false;
+            }
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingRpcForwardingManager.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingRpcForwardingManager.java
new file mode 100644 (file)
index 0000000..63d4b71
--- /dev/null
@@ -0,0 +1,115 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.yangtools.yang.binding.BaseIdentity;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+
+import com.google.common.base.Optional;
+
+/**
+ * Manager responsible for instantiating forwarders responsible for
+ * forwarding of RPC invocations from DOM Broker to Binding Aware Broker
+ *
+ */
+class DomToBindingRpcForwardingManager implements
+    RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>,
+    RpcProviderRegistryImpl.RouterInstantiationListener,
+    RpcProviderRegistryImpl.GlobalRpcRegistrationListener, RpcRegistrationListener {
+
+    private final Map<Class<? extends RpcService>, DomToBindingRpcForwarder> forwarders = new WeakHashMap<>();
+    private final BindingIndependentMappingService mappingService;
+    private final RpcProvisionRegistry biRpcRegistry;
+    private final RpcProviderRegistry baRpcRegistry;
+    private RpcProviderRegistryImpl registryImpl;
+
+    DomToBindingRpcForwardingManager(final BindingIndependentMappingService mappingService, final RpcProvisionRegistry biRpcRegistry,
+        final RpcProviderRegistry baRpcRegistry) {
+        this.mappingService = mappingService;
+        this.biRpcRegistry = biRpcRegistry;
+        this.baRpcRegistry = baRpcRegistry;
+    }
+
+    public RpcProviderRegistryImpl getRegistryImpl() {
+        return registryImpl;
+    }
+
+    public void setRegistryImpl(final RpcProviderRegistryImpl registryImpl) {
+        this.registryImpl = registryImpl;
+    }
+
+    @Override
+    public void onGlobalRpcRegistered(final Class<? extends RpcService> cls) {
+        getRpcForwarder(cls, null).registerToDOMBroker();
+    }
+
+    @Override
+    public void onGlobalRpcUnregistered(final Class<? extends RpcService> cls) {
+        // NOOP
+    }
+
+    @Override
+    public void onRpcRouterCreated(final RpcRouter<?> router) {
+        Class<? extends BaseIdentity> ctx = router.getContexts().iterator().next();
+        getRpcForwarder(router.getServiceType(), ctx);
+    }
+
+    @Override
+    public void onRouteChange(final RouteChange<RpcContextIdentifier, InstanceIdentifier<?>> change) {
+        for (Map.Entry<RpcContextIdentifier, Set<InstanceIdentifier<?>>> entry : change.getAnnouncements().entrySet()) {
+            bindingRoutesAdded(entry);
+        }
+    }
+
+    private void bindingRoutesAdded(final Map.Entry<RpcContextIdentifier, Set<InstanceIdentifier<?>>> entry) {
+        Class<? extends BaseIdentity> context = entry.getKey().getRoutingContext();
+        Class<? extends RpcService> service = entry.getKey().getRpcService();
+        if (context != null) {
+            getRpcForwarder(service, context).registerPaths(context, service, entry.getValue());
+        }
+    }
+
+    private DomToBindingRpcForwarder getRpcForwarder(final Class<? extends RpcService> service,
+        final Class<? extends BaseIdentity> context) {
+        DomToBindingRpcForwarder potential = forwarders.get(service);
+        if (potential != null) {
+            return potential;
+        }
+        if (context == null) {
+            potential = new DomToBindingRpcForwarder(service, mappingService, biRpcRegistry, baRpcRegistry,registryImpl);
+        } else {
+            potential = new DomToBindingRpcForwarder(service, context, mappingService, biRpcRegistry, baRpcRegistry,registryImpl);
+        }
+
+        forwarders.put(service, potential);
+        return potential;
+    }
+
+    @Override
+    public void onRpcImplementationAdded(final QName name) {
+
+        final Optional<Class<? extends RpcService>> rpcInterface = mappingService.getRpcServiceClassFor(
+            name.getNamespace().toString(), name.getFormattedRevision());
+        if (rpcInterface.isPresent()) {
+            getRpcForwarder(rpcInterface.get(), null).registerToBindingBroker();
+        }
+    }
+
+    @Override
+    public void onRpcImplementationRemoved(final QName name) {
+
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingTransaction.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingTransaction.java
new file mode 100644 (file)
index 0000000..a5a34da
--- /dev/null
@@ -0,0 +1,60 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+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.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+class DomToBindingTransaction implements
+    DataCommitHandler.DataCommitTransaction<YangInstanceIdentifier, CompositeNode> {
+
+    private final org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing;
+    private final DataModification<YangInstanceIdentifier, CompositeNode> modification;
+    private final ConcurrentMap<Object, DomToBindingTransaction> bindingOpenedTransactions;
+
+    public DomToBindingTransaction(
+    final org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing,
+    final DataModification<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> modification,
+        ConcurrentMap<Object, DomToBindingTransaction> bindingOpenedTransactions) {
+        super();
+        this.backing = backing;
+        this.modification = modification;
+        this.bindingOpenedTransactions = bindingOpenedTransactions;
+        this.bindingOpenedTransactions.put(backing.getIdentifier(), this);
+    }
+
+    @Override
+    public DataModification<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> getModification() {
+        return modification;
+    }
+
+    @Override
+    public RpcResult<Void> rollback() throws IllegalStateException {
+        bindingOpenedTransactions.remove(backing.getIdentifier());
+        return RpcResultBuilder.<Void> success().build();
+    }
+
+    @Override
+    public RpcResult<Void> finish() throws IllegalStateException {
+        Future<RpcResult<TransactionStatus>> result = backing.commit();
+        try {
+            RpcResult<TransactionStatus> baResult = result.get();
+            bindingOpenedTransactions.remove(backing.getIdentifier());
+            return RpcResultBuilder.<Void> status(baResult.isSuccessful())
+                                          .withRpcErrors(baResult.getErrors()).build();
+        } catch (InterruptedException e) {
+            throw new IllegalStateException("", e);
+        } catch (ExecutionException e) {
+            throw new IllegalStateException("", e);
+        } finally {
+            bindingOpenedTransactions.remove(backing.getIdentifier());
+        }
+    }
+}
index d08b217e71c547ea3cd2aa3dcb24a0b3374e9744..f03d07eb99c0fc2ae212cc358402ba67c17a4a74 100644 (file)
@@ -10,19 +10,17 @@ package org.opendaylight.controller.sal.binding.impl.connect.dom;
 
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Method;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.concurrent.Future;
 
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
@@ -89,7 +87,7 @@ public class RpcInvocationStrategy {
     public ListenableFuture<RpcResult<?>> forwardToDomBroker(final DataObject input) {
 
         if(biRpcRegistry == null) {
-            return Futures.<RpcResult<?>> immediateFuture(Rpcs.getRpcResult(false));
+            return Futures.<RpcResult<?>> immediateFuture(RpcResultBuilder.failed().build());
         }
 
         CompositeNode inputXml = null;
@@ -102,6 +100,7 @@ public class RpcInvocationStrategy {
 
         Function<RpcResult<CompositeNode>, RpcResult<?>> transformationFunction =
                                        new Function<RpcResult<CompositeNode>, RpcResult<?>>() {
+            @SuppressWarnings("rawtypes")
             @Override
             public RpcResult<?> apply(RpcResult<CompositeNode> result) {
 
@@ -114,7 +113,7 @@ public class RpcInvocationStrategy {
                     }
                 }
 
-                return Rpcs.getRpcResult(result.isSuccessful(), output, result.getErrors());
+                return RpcResultBuilder.from( (RpcResult)result ).withResult( output ).build();
             }
         };
 
@@ -135,22 +134,18 @@ public class RpcInvocationStrategy {
         }
 
         if (futureResult == null) {
-            return Rpcs.getRpcResult(false);
+            return RpcResultBuilder.<CompositeNode>failed().build();
         }
 
-        RpcResult<?> bindingResult = futureResult.get();
-
-        Collection<RpcError> errors = bindingResult.getErrors();
-        if( errors == null ) {
-            errors = Collections.<RpcError>emptySet();
-        }
+        @SuppressWarnings("rawtypes")
+        RpcResult bindingResult = futureResult.get();
 
         final Object resultObj = bindingResult.getResult();
-        CompositeNode output = null;
+        Object output = null;
         if (resultObj instanceof DataObject) {
             output = mappingService.toDataDom((DataObject)resultObj);
         }
-        return Rpcs.getRpcResult( bindingResult.isSuccessful(), output, errors);
+        return RpcResultBuilder.from( bindingResult ).withResult( output ).build();
     }
 
     public RpcResult<CompositeNode> invokeOn(final RpcService rpcService, final CompositeNode domInput) throws Exception {
index 8c74008990614ea07bba2499508c7d6143a15c4a..92836631a80c26e2a9cfd6807e77e74d75b5f418 100644 (file)
@@ -18,7 +18,7 @@ import org.opendaylight.yangtools.yang.data.impl.codec.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.controller.sal.core.api.mount.MountProvisionListener;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
@@ -33,7 +33,7 @@ public class DomForwardedBindingBrokerImpl extends RootBindingAwareBroker implem
     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 ConcurrentMap<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier> forwarded = new ConcurrentHashMap<>();
     private ListenerRegistration<MountProvisionListener> domListenerRegistration;
     private ListenerRegistration<org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener> baListenerRegistration;
 
@@ -89,8 +89,8 @@ public class DomForwardedBindingBrokerImpl extends RootBindingAwareBroker implem
     }
 
     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);
+            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier biPath) {
+        org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier previous = forwarded.putIfAbsent(baPath, biPath);
         if (previous != null) {
             return;
         }
@@ -111,7 +111,7 @@ public class DomForwardedBindingBrokerImpl extends RootBindingAwareBroker implem
         return mountConnector;
     }
 
-    public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) {
+    public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier domPath) {
         InstanceIdentifier<?> baPath;
         try {
             baPath = connector.getMappingService().fromDataDom(domPath);
@@ -130,7 +130,7 @@ public class DomForwardedBindingBrokerImpl extends RootBindingAwareBroker implem
         if (potentialConnector != null) {
             return;
         }
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = connector.getMappingService().toDataDom(baPath);
+        org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier domPath = connector.getMappingService().toDataDom(baPath);
         tryToDeployConnector(baPath, domPath);
     }
 
@@ -138,19 +138,19 @@ public class DomForwardedBindingBrokerImpl extends RootBindingAwareBroker implem
         // FIXME: Implement closeMountPoint
     }
 
-    public synchronized void undeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
+    public synchronized void undeployDomForwarder(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier biPath) {
         // FIXME: Implement closeMountPoint
     }
 
     private class DomMountPointForwardingManager implements MountProvisionListener {
 
         @Override
-        public void onMountPointCreated(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
+        public void onMountPointCreated(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path) {
             tryToDeployDomForwarder(path);
         }
 
         @Override
-        public void onMountPointRemoved(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
+        public void onMountPointRemoved(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path) {
             undeployDomForwarder(path);
         }
     }
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/package-info.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/package-info.java
deleted file mode 100644 (file)
index e5f26b9..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;
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/MapUtils.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/MapUtils.java
deleted file mode 100644 (file)
index aa6a9a2..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.binding.impl.util;
-
-import com.google.common.collect.Multimap;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map.Entry;
-import org.opendaylight.yangtools.concepts.Path;
-
-@SuppressWarnings("all")
-public class MapUtils {
-  public static <P extends Path<P>, V extends Object> Collection<Entry<? extends P,? extends V>> getAllChildren(final Multimap<? extends P,? extends V> map, final P path) {
-    HashSet<Entry<? extends P,? extends V>> _hashSet = new HashSet<Entry<? extends P, ? extends V>>();
-    final HashSet<Entry<? extends P,? extends V>> ret = _hashSet;
-    final Collection<? extends Entry<? extends P,? extends V>> entries = map.entries();
-    for (final Entry<? extends P,? extends V> entry : entries) {
-      {
-        final P currentPath = entry.getKey();
-        if (path.contains(currentPath)) {
-          ret.add(entry);
-        } else if (currentPath.contains(path)){
-            ret.add(entry);
-        }
-      }
-    }
-    return ret;
-  }
-}
-
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/DelegateProxy.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/DelegateProxy.java
deleted file mode 100644 (file)
index d22335e..0000000
+++ /dev/null
@@ -1,14 +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.spi;
-
-public interface DelegateProxy<T> {
-
-    void setDelegate(T delegate);
-    T getDelegate();
-}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/remote/RouteChangeListener.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/remote/RouteChangeListener.java
deleted file mode 100644 (file)
index 9e66fb8..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.spi.remote;
-
-import java.util.EventListener;
-
-import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
-import org.opendaylight.yangtools.yang.binding.BaseIdentity;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-public interface RouteChangeListener extends EventListener {
-
-    void onRouteChange(RouteChange<Class<? extends BaseIdentity>, InstanceIdentifier<?>> change);
-
-}
index 4456dea77f98fad1f4f43c79f67b224d9e44990e..cee4b1efb3a3107e27fa5325dd6d3f92cc937609 100644 (file)
@@ -105,7 +105,7 @@ module opendaylight-sal-binding-broker-impl {
             container data-broker {
                 uses config:service-ref {
                     refine type {
-                        mandatory true;
+                        mandatory false;
                         config:required-identity sal:binding-data-broker;
                     }
                 }
@@ -119,6 +119,15 @@ module opendaylight-sal-binding-broker-impl {
                     }
                 }
             }
+
+            container root-data-broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory false;
+                        config:required-identity sal:binding-async-data-broker;
+                    }
+                }
+            }
         }
     }
 
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/BindingNormalizedCodecTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/BindingNormalizedCodecTest.java
new file mode 100644 (file)
index 0000000..fd0a169
--- /dev/null
@@ -0,0 +1,58 @@
+package org.opendaylight.controller.md.sal.binding.impl.test;
+
+import static org.junit.Assert.assertTrue;
+import javassist.ClassPool;
+
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.md.sal.binding.test.AbstractSchemaAwareTest;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.TreeComplexUsesAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.TreeLeafOnlyAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.Top;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelListKey;
+import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class BindingNormalizedCodecTest extends AbstractSchemaAwareTest {
+
+    private static final TopLevelListKey TOP_FOO_KEY = new TopLevelListKey("foo");
+    private static final InstanceIdentifier<TopLevelList> BA_TOP_LEVEL_LIST = InstanceIdentifier
+            .builder(Top.class).child(TopLevelList.class, TOP_FOO_KEY).toInstance();
+    private static final InstanceIdentifier<TreeLeafOnlyAugment> BA_TREE_LEAF_ONLY = BA_TOP_LEVEL_LIST.augmentation(TreeLeafOnlyAugment.class);
+    private static final InstanceIdentifier<TreeComplexUsesAugment> BA_TREE_COMPLEX_USES = BA_TOP_LEVEL_LIST.augmentation(TreeComplexUsesAugment.class);
+    private static final QName SIMPLE_VALUE_QNAME = QName.create(TreeComplexUsesAugment.QNAME, "simple-value");
+
+
+    private RuntimeGeneratedMappingServiceImpl mappingService;
+    private BindingToNormalizedNodeCodec codec;
+
+    @Override
+    protected void setupWithSchema(final SchemaContext context) {
+        mappingService = new RuntimeGeneratedMappingServiceImpl(ClassPool.getDefault());
+        codec = new BindingToNormalizedNodeCodec(mappingService);
+        mappingService.onGlobalContextUpdated(context);
+        codec.onGlobalContextUpdated(context);
+    };
+
+    @Test
+    public void testComplexAugmentationSerialization() {
+
+        PathArgument lastArg = codec.toNormalized(BA_TREE_COMPLEX_USES).getLastPathArgument();
+        assertTrue(lastArg instanceof AugmentationIdentifier);
+    }
+
+
+    @Test
+    public void testLeafOnlyAugmentationSerialization() {
+
+        PathArgument leafOnlyLastArg = codec.toNormalized(BA_TREE_LEAF_ONLY).getLastPathArgument();
+        assertTrue(leafOnlyLastArg instanceof AugmentationIdentifier);
+        assertTrue(((AugmentationIdentifier) leafOnlyLastArg).getPossibleChildNames().contains(SIMPLE_VALUE_QNAME));
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1125RegressionTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1125RegressionTest.java
new file mode 100644 (file)
index 0000000..fb11535
--- /dev/null
@@ -0,0 +1,99 @@
+package org.opendaylight.controller.md.sal.binding.impl.test;
+
+import static org.opendaylight.controller.md.sal.binding.test.AssertCollections.assertContains;
+import static org.opendaylight.controller.md.sal.binding.test.AssertCollections.assertEmpty;
+import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.TOP_FOO_KEY;
+import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.path;
+import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.topLevelList;
+
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.binding.test.AbstractDataChangeListenerTest;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.TreeComplexUsesAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.TreeComplexUsesAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.complex.from.grouping.ContainerWithUsesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.Top;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.TopBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Regression test suite for Bug 1125 - Can't detect switch disconnection
+ * https://bugs.opendaylight.org/show_bug.cgi?id=1125
+ */
+public class Bug1125RegressionTest extends AbstractDataChangeListenerTest {
+
+    private static final InstanceIdentifier<Top> TOP_PATH = InstanceIdentifier
+            .create(Top.class);
+    private static final InstanceIdentifier<TopLevelList> TOP_FOO_PATH = TOP_PATH
+            .child(TopLevelList.class, TOP_FOO_KEY);
+
+    private static final InstanceIdentifier<TreeComplexUsesAugment> FOO_AUGMENT_PATH = TOP_FOO_PATH
+            .augmentation(TreeComplexUsesAugment.class);
+
+    private static final InstanceIdentifier<TreeComplexUsesAugment> WILDCARDED_AUGMENT_PATH = TOP_PATH
+            .child(TopLevelList.class).augmentation(
+                    TreeComplexUsesAugment.class);
+
+    private void writeInitialState() {
+        WriteTransaction initialTx = getDataBroker().newWriteOnlyTransaction();
+        initialTx.put(LogicalDatastoreType.OPERATIONAL, TOP_PATH,
+                new TopBuilder().build());
+        TreeComplexUsesAugment fooAugment = new TreeComplexUsesAugmentBuilder()
+                .setContainerWithUses(
+                        new ContainerWithUsesBuilder().setLeafFromGrouping(
+                                "foo").build()).build();
+        initialTx.put(LogicalDatastoreType.OPERATIONAL, path(TOP_FOO_KEY),
+                topLevelList(TOP_FOO_KEY, fooAugment));
+        assertCommit(initialTx.submit());
+    }
+
+    private void delete(final InstanceIdentifier<?> path) {
+        WriteTransaction tx = getDataBroker().newWriteOnlyTransaction();
+        tx.delete(LogicalDatastoreType.OPERATIONAL, path);
+        assertCommit(tx.submit());
+    }
+
+    private void verifyRemoved(
+            final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> event) {
+        assertEmpty(event.getCreatedData());
+        assertEmpty(event.getUpdatedData());
+        assertContains(event.getRemovedPaths(), FOO_AUGMENT_PATH);
+    }
+
+    private void deleteAndListenAugment(final DataChangeScope scope,
+            final InstanceIdentifier<?> path) {
+        writeInitialState();
+        TestListener listener = createListener(
+                LogicalDatastoreType.OPERATIONAL, WILDCARDED_AUGMENT_PATH,
+                scope);
+        delete(path);
+        verifyRemoved(listener.event());
+    }
+
+    @Test
+    public void deleteAndListenAugment() {
+
+        deleteAndListenAugment(DataChangeScope.ONE, TOP_PATH);
+
+        deleteAndListenAugment(DataChangeScope.BASE, TOP_PATH);
+
+        deleteAndListenAugment(DataChangeScope.SUBTREE, TOP_PATH);
+
+        deleteAndListenAugment(DataChangeScope.BASE, TOP_FOO_PATH);
+
+        deleteAndListenAugment(DataChangeScope.ONE, TOP_FOO_PATH);
+
+        deleteAndListenAugment(DataChangeScope.SUBTREE, TOP_FOO_PATH);
+
+        deleteAndListenAugment(DataChangeScope.BASE, FOO_AUGMENT_PATH);
+
+        deleteAndListenAugment(DataChangeScope.ONE, FOO_AUGMENT_PATH);
+
+        deleteAndListenAugment(DataChangeScope.SUBTREE, FOO_AUGMENT_PATH);
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ListInsertionDataChangeListenerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ListInsertionDataChangeListenerTest.java
new file mode 100644 (file)
index 0000000..5449330
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl.test;
+import static org.junit.Assert.assertFalse;
+import static org.opendaylight.controller.md.sal.binding.test.AssertCollections.assertContains;
+import static org.opendaylight.controller.md.sal.binding.test.AssertCollections.assertEmpty;
+import static org.opendaylight.controller.md.sal.binding.test.AssertCollections.assertNotContains;
+import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
+import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.TOP_BAR_KEY;
+import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.TOP_FOO_KEY;
+import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.top;
+import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.topLevelList;
+
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.binding.test.AbstractDataChangeListenerTest;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.Top;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ *
+ * This testsuite tests explanation for data change scope and data modifications
+ * which were described in
+ * https://lists.opendaylight.org/pipermail/controller-dev/2014-July/005541.html
+ *
+ *
+ */
+public class ListInsertionDataChangeListenerTest extends AbstractDataChangeListenerTest{
+
+    private static final InstanceIdentifier<Top> TOP = InstanceIdentifier.create(Top.class);
+    private static final InstanceIdentifier<TopLevelList> WILDCARDED = TOP.child(TopLevelList.class);
+    private static final InstanceIdentifier<TopLevelList> TOP_FOO = TOP.child(TopLevelList.class, TOP_FOO_KEY);
+    private static final InstanceIdentifier<TopLevelList> TOP_BAR = TOP.child(TopLevelList.class, TOP_BAR_KEY);
+
+
+    @Override
+    protected void setupWithDataBroker(final DataBroker dataBroker) {
+        WriteTransaction initialTx = dataBroker.newWriteOnlyTransaction();
+        initialTx.put(CONFIGURATION, TOP, top(topLevelList(TOP_FOO_KEY)));
+        assertCommit(initialTx.submit());
+    }
+
+    @Test
+    public void replaceTopNodeSubtreeListeners() {
+        TestListener topListener = createListener(CONFIGURATION, TOP, DataChangeScope.SUBTREE);
+        TestListener allListener = createListener(CONFIGURATION, WILDCARDED, DataChangeScope.SUBTREE);
+        TestListener fooListener = createListener(CONFIGURATION, TOP_FOO, DataChangeScope.SUBTREE);
+        TestListener barListener = createListener(CONFIGURATION, TOP_BAR, DataChangeScope.SUBTREE);
+
+        ReadWriteTransaction writeTx = getDataBroker().newReadWriteTransaction();
+        writeTx.put(CONFIGURATION, TOP, top(topLevelList(TOP_BAR_KEY)));
+        assertCommit(writeTx.submit());
+        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> top = topListener.event();
+        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> all = allListener.event();
+        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> foo = fooListener.event();
+        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> bar = barListener.event();
+
+        // Listener for TOP element
+        assertContains(top.getOriginalData(), TOP,TOP_FOO);
+        assertContains(top.getCreatedData(), TOP_BAR);
+        assertContains(top.getUpdatedData(), TOP);
+        assertContains(top.getRemovedPaths(), TOP_FOO);
+
+        /*
+         *  Listener for all list items
+         *
+         *  Updated should be empty, since no list item was
+         *  updated, items were only removed and added
+         */
+        assertContains(all.getOriginalData(), TOP_FOO);
+        assertContains(all.getCreatedData(), TOP_BAR);
+        assertEmpty(all.getUpdatedData());
+        assertContains(all.getRemovedPaths(), TOP_FOO);
+
+
+        /*
+         *  Listener for all Foo item
+         *
+         *  This one should see only Foo item removed
+         */
+        assertContains(foo.getOriginalData(), TOP_FOO);
+        assertEmpty(foo.getCreatedData());
+        assertEmpty(foo.getUpdatedData());
+        assertContains(foo.getRemovedPaths(), TOP_FOO);
+
+        /*
+         *  Listener for bar list items
+         *
+         *  Updated should be empty, since no list item was
+         *  updated, items were only removed and added
+         */
+        assertEmpty(bar.getOriginalData());
+        assertContains(bar.getCreatedData(), TOP_BAR);
+        assertEmpty(bar.getUpdatedData());
+        assertEmpty(bar.getRemovedPaths());
+    }
+
+    @Test
+    public void mergeTopNodeSubtreeListeners() {
+        TestListener topListener = createListener(CONFIGURATION, TOP, DataChangeScope.SUBTREE);
+        TestListener allListener = createListener(CONFIGURATION, WILDCARDED, DataChangeScope.SUBTREE);
+        TestListener fooListener = createListener(CONFIGURATION, TOP_FOO, DataChangeScope.SUBTREE);
+        TestListener barListener = createListener(CONFIGURATION, TOP_BAR, DataChangeScope.SUBTREE);
+
+        ReadWriteTransaction writeTx = getDataBroker().newReadWriteTransaction();
+        writeTx.merge(CONFIGURATION, TOP, top(topLevelList(TOP_BAR_KEY)));
+        assertCommit(writeTx.submit());
+
+        verifyBarOnlyAdded(topListener,allListener,fooListener,barListener);
+    }
+
+    @Test
+    public void putTopBarNodeSubtreeListeners() {
+        TestListener topListener = createListener(CONFIGURATION, TOP, DataChangeScope.SUBTREE);
+        TestListener allListener = createListener(CONFIGURATION, WILDCARDED, DataChangeScope.SUBTREE);
+        TestListener fooListener = createListener(CONFIGURATION, TOP_FOO, DataChangeScope.SUBTREE);
+        TestListener barListener = createListener(CONFIGURATION, TOP_BAR, DataChangeScope.SUBTREE);
+
+        ReadWriteTransaction writeTx = getDataBroker().newReadWriteTransaction();
+        writeTx.put(CONFIGURATION, TOP_BAR, topLevelList(TOP_BAR_KEY));
+        assertCommit(writeTx.submit());
+
+        verifyBarOnlyAdded(topListener,allListener,fooListener,barListener);
+    }
+
+    @Test
+    public void mergeTopBarNodeSubtreeListeners() {
+        TestListener topListener = createListener(CONFIGURATION, TOP, DataChangeScope.SUBTREE);
+        TestListener allListener = createListener(CONFIGURATION, WILDCARDED, DataChangeScope.SUBTREE);
+        TestListener fooListener = createListener(CONFIGURATION, TOP_FOO, DataChangeScope.SUBTREE);
+        TestListener barListener = createListener(CONFIGURATION, TOP_BAR, DataChangeScope.SUBTREE);
+
+        ReadWriteTransaction writeTx = getDataBroker().newReadWriteTransaction();
+        writeTx.merge(CONFIGURATION, TOP_BAR, topLevelList(TOP_BAR_KEY));
+        assertCommit(writeTx.submit());
+
+        verifyBarOnlyAdded(topListener,allListener,fooListener,barListener);
+    }
+
+    private void verifyBarOnlyAdded(final TestListener top, final TestListener all, final TestListener foo,
+            final TestListener bar) {
+
+        assertFalse(foo.hasEvent());
+
+        // Listener for TOP element
+        assertContains(top.event().getOriginalData(), TOP);
+        assertNotContains(top.event().getOriginalData(),TOP_FOO);
+        assertContains(top.event().getCreatedData(), TOP_BAR);
+        assertContains(top.event().getUpdatedData(), TOP);
+        assertEmpty(top.event().getRemovedPaths());
+
+        /*
+         *  Listener for all list items
+         *
+         *  Updated should be empty, since no list item was
+         *  updated, items were only removed and added
+         */
+        assertEmpty(all.event().getOriginalData());
+        assertContains(all.event().getCreatedData(), TOP_BAR);
+        assertEmpty(all.event().getUpdatedData());
+        assertEmpty(all.event().getRemovedPaths());
+
+        /*
+         *  Listener for all Foo item
+         *
+         *  Foo Listener should not have foo event
+         */
+        assertFalse(foo.hasEvent());
+
+        /*
+         *  Listener for bar list items
+         *
+         *  Updated should be empty, since no list item was
+         *  updated, items were only removed and added
+         */
+        assertEmpty(bar.event().getOriginalData());
+        assertContains(bar.event().getCreatedData(), TOP_BAR);
+        assertEmpty(bar.event().getUpdatedData());
+        assertEmpty(bar.event().getRemovedPaths());
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/RpcProviderRegistryTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/RpcProviderRegistryTest.java
new file mode 100644 (file)
index 0000000..8782046
--- /dev/null
@@ -0,0 +1,160 @@
+package org.opendaylight.controller.md.sal.binding.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.TOP_BAR_KEY;
+import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.TOP_FOO_KEY;
+import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.path;
+
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.binding.test.AssertCollections;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
+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.rpc.RpcContextIdentifier;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
+import org.opendaylight.controller.sal.binding.codegen.RpcIsNotRoutedException;
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.rpcservice.rev140701.OpendaylightTestRpcServiceService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.rpc.routing.rev140701.OpendaylightTestRoutedRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.rpc.routing.rev140701.TestContext;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.util.concurrent.SettableFuture;
+
+
+public class RpcProviderRegistryTest {
+
+    private static InstanceIdentifier<TopLevelList> FOO_PATH = path(TOP_FOO_KEY);
+    private static InstanceIdentifier<TopLevelList> BAR_PATH = path(TOP_BAR_KEY);
+    private static RpcContextIdentifier ROUTING_CONTEXT = RpcContextIdentifier.contextFor(OpendaylightTestRoutedRpcService.class, TestContext.class);
+
+    private RpcProviderRegistryImpl rpcRegistry;
+
+    @Before
+    public void setup() {
+        rpcRegistry = new RpcProviderRegistryImpl("test");
+    }
+
+    private static class TestListener implements RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>> {
+
+        final SettableFuture<RouteChange<RpcContextIdentifier, InstanceIdentifier<?>>> event = SettableFuture.create();
+        @Override
+        public void onRouteChange(
+                final RouteChange<RpcContextIdentifier, InstanceIdentifier<?>> change) {
+            event.set(change);
+        }
+    }
+
+    @Test
+    public void testGlobalRpcRegistrations() throws Exception {
+        OpendaylightTestRpcServiceService one = Mockito.mock(OpendaylightTestRpcServiceService.class);
+        OpendaylightTestRpcServiceService two = Mockito.mock(OpendaylightTestRpcServiceService.class);
+
+        RpcRegistration<OpendaylightTestRpcServiceService> regOne = rpcRegistry.addRpcImplementation(OpendaylightTestRpcServiceService.class, one);
+        assertNotNull(regOne);
+
+        try {
+            rpcRegistry.addRpcImplementation(OpendaylightTestRpcServiceService.class, two);
+        fail("Second call for registration of same RPC must throw IllegalStateException");
+        } catch (IllegalStateException e) {
+            assertNotNull(e.getMessage());
+        }
+
+        regOne.close();
+
+        RpcRegistration<OpendaylightTestRpcServiceService> regTwo = rpcRegistry.addRpcImplementation(OpendaylightTestRpcServiceService.class, two);
+        assertNotNull(regTwo);
+    }
+
+    @Test
+    public void routedRpcRegisteredUsingGlobalAsDefaultInstance() throws Exception {
+        OpendaylightTestRoutedRpcService def = Mockito.mock(OpendaylightTestRoutedRpcService.class);
+        rpcRegistry.addRpcImplementation(OpendaylightTestRoutedRpcService.class, def);
+        RpcRouter<OpendaylightTestRoutedRpcService> router = rpcRegistry.getRpcRouter(OpendaylightTestRoutedRpcService.class);
+        assertEquals(def, router.getDefaultService());
+    }
+
+    @Test
+    public void nonRoutedRegisteredAsRouted() {
+        OpendaylightTestRpcServiceService one = Mockito.mock(OpendaylightTestRpcServiceService.class);
+        try {
+            rpcRegistry.addRoutedRpcImplementation(OpendaylightTestRpcServiceService.class, one);
+            fail("RpcIsNotRoutedException should be thrown");
+        } catch (RpcIsNotRoutedException e) {
+            assertNotNull(e.getMessage());
+        } catch (Exception e) {
+            fail("RpcIsNotRoutedException should be thrown");
+        }
+
+    }
+
+    @Test
+    public void testRpcRouterInstance() throws Exception  {
+        OpendaylightTestRoutedRpcService def = Mockito.mock(OpendaylightTestRoutedRpcService.class);
+
+        RpcRouter<OpendaylightTestRoutedRpcService> router = rpcRegistry.getRpcRouter(OpendaylightTestRoutedRpcService.class);
+
+        assertEquals(OpendaylightTestRoutedRpcService.class, router.getServiceType());
+        assertNotNull(router.getInvocationProxy());
+        assertNull(router.getDefaultService());
+
+        AssertCollections.assertContains(router.getContexts(), TestContext.class);
+
+        RpcRegistration<OpendaylightTestRoutedRpcService> regDef = router.registerDefaultService(def);
+        assertNotNull(regDef);
+        assertEquals(OpendaylightTestRoutedRpcService.class,regDef.getServiceType());
+        assertEquals(def,regDef.getInstance());
+        assertEquals(def, router.getDefaultService());
+
+        regDef.close();
+        assertNull("Default instance should be null after closing registration",  router.getDefaultService());
+    }
+
+    @Test
+    public void testRoutedRpcPathChangeEvents() throws InterruptedException, TimeoutException, ExecutionException {
+        OpendaylightTestRoutedRpcService one = Mockito.mock(OpendaylightTestRoutedRpcService.class);
+        OpendaylightTestRoutedRpcService two = Mockito.mock(OpendaylightTestRoutedRpcService.class);
+        RoutedRpcRegistration<OpendaylightTestRoutedRpcService> regOne = rpcRegistry.addRoutedRpcImplementation(OpendaylightTestRoutedRpcService.class, one);
+        RoutedRpcRegistration<OpendaylightTestRoutedRpcService> regTwo = rpcRegistry.addRoutedRpcImplementation(OpendaylightTestRoutedRpcService.class, two);
+        assertNotNull(regOne);
+        assertNotNull(regTwo);
+
+        final TestListener addListener = new TestListener();
+        rpcRegistry.registerRouteChangeListener(addListener);
+        regOne.registerPath(TestContext.class, FOO_PATH);
+
+        RouteChange<RpcContextIdentifier, InstanceIdentifier<?>> fooAddEvent = addListener.event.get(500, TimeUnit.MILLISECONDS);
+        Set<InstanceIdentifier<?>> announce = fooAddEvent.getAnnouncements().get(ROUTING_CONTEXT);
+        assertNotNull(announce);
+        AssertCollections.assertContains(announce, FOO_PATH);
+        AssertCollections.assertNotContains(announce, BAR_PATH);
+
+
+
+        final TestListener removeListener = new TestListener();
+        rpcRegistry.registerRouteChangeListener(removeListener);
+
+        regOne.unregisterPath(TestContext.class, FOO_PATH);
+
+        RouteChange<RpcContextIdentifier, InstanceIdentifier<?>> fooRemoveEvent = removeListener.event.get(500, TimeUnit.MILLISECONDS);
+        Set<InstanceIdentifier<?>> removal = fooRemoveEvent.getRemovals().get(ROUTING_CONTEXT);
+        assertNotNull(removal);
+        AssertCollections.assertContains(removal, FOO_PATH);
+        AssertCollections.assertNotContains(removal, BAR_PATH);
+
+
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/WriteTransactionTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/WriteTransactionTest.java
new file mode 100644 (file)
index 0000000..b504837
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.ExecutionException;
+
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.Top;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.TopBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelListKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+
+
+public class WriteTransactionTest extends AbstractDataBrokerTest {
+
+    private static final InstanceIdentifier<Top> TOP_PATH = InstanceIdentifier.create(Top.class);
+    private static final TopLevelListKey TOP_LIST_KEY = new TopLevelListKey("foo");
+    private static final InstanceIdentifier<TopLevelList> NODE_PATH = TOP_PATH.child(TopLevelList.class, TOP_LIST_KEY);
+    private static final TopLevelList NODE = new TopLevelListBuilder().setKey(TOP_LIST_KEY).build();
+    @Test
+    public void test() throws InterruptedException, ExecutionException {
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, TOP_PATH, new TopBuilder().build());
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, NODE_PATH, NODE);
+        writeTx.submit().get();
+    }
+
+    @Test
+    public void testPutCreateParentsSuccess() throws TransactionCommitFailedException, InterruptedException, ExecutionException {
+
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, NODE_PATH, NODE,true);
+        writeTx.submit().checkedGet();
+
+        ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        Optional<Top> topNode = readTx.read(LogicalDatastoreType.OPERATIONAL, TOP_PATH).get();
+        assertTrue("Top node must exists after commit",topNode.isPresent());
+        Optional<TopLevelList> listNode = readTx.read(LogicalDatastoreType.OPERATIONAL, NODE_PATH).get();
+        assertTrue("List node must exists after commit",listNode.isPresent());
+    }
+
+    @Test
+    public void testMergeCreateParentsSuccess() throws TransactionCommitFailedException, InterruptedException, ExecutionException {
+
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.merge(LogicalDatastoreType.OPERATIONAL, NODE_PATH, NODE,true);
+        writeTx.submit().checkedGet();
+
+        ReadOnlyTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        Optional<Top> topNode = readTx.read(LogicalDatastoreType.OPERATIONAL, TOP_PATH).get();
+        assertTrue("Top node must exists after commit",topNode.isPresent());
+        Optional<TopLevelList> listNode = readTx.read(LogicalDatastoreType.OPERATIONAL, NODE_PATH).get();
+        assertTrue("List node must exists after commit",listNode.isPresent());
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataBrokerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataBrokerTest.java
new file mode 100644 (file)
index 0000000..5789270
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.test;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class AbstractDataBrokerTest extends AbstractSchemaAwareTest {
+
+    private DataBrokerTestCustomizer testCustomizer;
+    private DataBroker dataBroker;
+    private DOMDataBroker domBroker;
+
+
+    @Override
+    protected void setupWithSchema(final SchemaContext context) {
+        testCustomizer = createDataBrokerTestCustomizer();
+        dataBroker = testCustomizer.createDataBroker();
+        domBroker = testCustomizer.createDOMDataBroker();
+        testCustomizer.updateSchema(context);
+        setupWithDataBroker(dataBroker);
+    }
+
+    protected void setupWithDataBroker(final DataBroker dataBroker) {
+        // Intentionally left No-op, subclasses may customize it
+    }
+
+   protected DataBrokerTestCustomizer createDataBrokerTestCustomizer() {
+        return new DataBrokerTestCustomizer();
+    }
+
+    public DataBroker getDataBroker() {
+        return dataBroker;
+    }
+
+    public DOMDataBroker getDomBroker() {
+        return domBroker;
+    }
+
+    protected static final void assertCommit(final ListenableFuture<Void> commit) {
+        try {
+            commit.get(500, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException | ExecutionException | TimeoutException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataChangeListenerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataChangeListenerTest.java
new file mode 100644 (file)
index 0000000..7742f37
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.test;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.util.concurrent.SettableFuture;
+
+public abstract class AbstractDataChangeListenerTest extends AbstractDataBrokerTest {
+
+    protected static final class TestListener implements DataChangeListener {
+
+        private final SettableFuture<AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject>> event;
+        private boolean capture = false;
+
+        private TestListener() {
+            event = SettableFuture.create();
+        }
+
+        @Override
+        public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> arg) {
+            if (capture) {
+                event.set(arg);
+            }
+        }
+
+        public AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> event() {
+            try {
+                return event.get(500, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException | TimeoutException | ExecutionException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+
+        public boolean hasEvent() {
+            return event.isDone();
+        }
+
+        public void startCapture() {
+            this.capture = true;
+        }
+    }
+
+    protected final TestListener createListener(final LogicalDatastoreType store, final InstanceIdentifier<?> path,
+            final DataChangeScope scope) {
+        TestListener listener = new TestListener();
+        getDataBroker().registerDataChangeListener(store, path, listener, scope);
+        listener.startCapture();
+        return listener;
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractSchemaAwareTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractSchemaAwareTest.java
new file mode 100644 (file)
index 0000000..78febb5
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.test;
+
+import org.junit.Before;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public abstract class AbstractSchemaAwareTest  {
+
+    private Iterable<YangModuleInfo> moduleInfos;
+    private SchemaContext schemaContext;
+
+
+    protected Iterable<YangModuleInfo> getModuleInfos() {
+        return BindingReflections.loadModuleInfos();
+    }
+
+
+    @Before
+    public final void setup() {
+        moduleInfos = getModuleInfos();
+        ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create();
+        moduleContext.addModuleInfos(moduleInfos);
+        schemaContext = moduleContext.tryToCreateSchemaContext().get();
+        setupWithSchema(schemaContext);
+    }
+
+    /**
+     * Setups test with Schema context.
+     * This method is called before {@link #setupWithSchemaService(SchemaService)}
+     *
+     * @param context
+     */
+    protected abstract void setupWithSchema(SchemaContext context);
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AssertCollections.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AssertCollections.java
new file mode 100644 (file)
index 0000000..25b91bc
--- /dev/null
@@ -0,0 +1,42 @@
+package org.opendaylight.controller.md.sal.binding.test;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.junit.Assert;
+
+public class AssertCollections {
+
+    public static void assertEmpty(final Collection<?> set) {
+        Assert.assertTrue(set.isEmpty());
+    }
+
+    public static void assertEmpty(final Map<?,?> set) {
+        Assert.assertTrue(set.isEmpty());
+    }
+
+    public static void assertContains(final Collection<?> set, final Object... values) {
+        for (Object key : values) {
+            Assert.assertTrue(set.contains(key));
+        }
+
+    }
+
+    public static void assertNotContains(final Collection<?> set, final Object... values) {
+        for (Object key : values) {
+            Assert.assertFalse(set.contains(key));
+        }
+    }
+
+    public static void assertContains(final Map<?,?> map, final Object... values) {
+        for (Object key : values) {
+            Assert.assertTrue(map.containsKey(key));
+        }
+    }
+
+    public static void assertNotContains(final Map<?,?> map, final Object... values) {
+        for (Object key : values) {
+            Assert.assertFalse(map.containsKey(key));
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestCustomizer.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestCustomizer.java
new file mode 100644 (file)
index 0000000..79aa6b6
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.test;
+
+import javassist.ClassPool;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.ForwardedBindingDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMDataBrokerImpl;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.opendaylight.controller.sal.binding.test.util.MockSchemaService;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.core.spi.data.DOMStore;
+import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+public class DataBrokerTestCustomizer {
+
+    private DOMDataBroker domDataBroker;
+    private final RuntimeGeneratedMappingServiceImpl mappingService;
+    private final MockSchemaService schemaService;
+    private ImmutableMap<LogicalDatastoreType, DOMStore> datastores;
+
+    public ImmutableMap<LogicalDatastoreType, DOMStore> createDatastores() {
+        return ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
+                .put(LogicalDatastoreType.OPERATIONAL, createOperationalDatastore())
+                .put(LogicalDatastoreType.CONFIGURATION,createConfigurationDatastore())
+                .build();
+    }
+
+    public DataBrokerTestCustomizer() {
+        schemaService = new MockSchemaService();
+        mappingService = new RuntimeGeneratedMappingServiceImpl(ClassPool.getDefault());
+    }
+
+    public DOMStore createConfigurationDatastore() {
+        InMemoryDOMDataStore store = new InMemoryDOMDataStore("CFG", MoreExecutors.sameThreadExecutor());
+        schemaService.registerSchemaServiceListener(store);
+        return store;
+    }
+
+    public DOMStore createOperationalDatastore() {
+        InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER", MoreExecutors.sameThreadExecutor());
+        schemaService.registerSchemaServiceListener(store);
+        return store;
+    }
+
+    public DOMDataBroker createDOMDataBroker() {
+        return new DOMDataBrokerImpl(getDatastores(), getCommitCoordinatorExecutor());
+    }
+
+    public ListeningExecutorService getCommitCoordinatorExecutor() {
+        return MoreExecutors.sameThreadExecutor();
+    }
+
+    public DataBroker createDataBroker() {
+        return new ForwardedBindingDataBroker(getDOMDataBroker(), getMappingService(), getSchemaService());
+    }
+
+    private SchemaService getSchemaService() {
+        return schemaService;
+    }
+
+    private BindingIndependentMappingService getMappingService() {
+        return mappingService;
+    }
+
+    private DOMDataBroker getDOMDataBroker() {
+        if(domDataBroker == null) {
+            domDataBroker = createDOMDataBroker();
+        }
+        return domDataBroker;
+    }
+
+    private ImmutableMap<LogicalDatastoreType, DOMStore> getDatastores() {
+        if(datastores == null) {
+            datastores = createDatastores();
+        }
+        return datastores;
+    }
+
+    public void updateSchema(final SchemaContext ctx) {
+        schemaService.changeSchema(ctx);
+        mappingService.onGlobalContextUpdated(ctx);
+    }
+
+}
index c5aea8f2ab666cb5e777e3f20d808910ab3308c6..6977588a017265f003de2e9ac0f3bba29383cc2f 100644 (file)
@@ -25,13 +25,13 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 
@@ -96,9 +96,11 @@ public class RpcInvocationStrategyTest {
 
     private void setupForForwardToDom(boolean hasOutput, boolean hasInput, int expectedErrorSize) {
 
-        if (expectedErrorSize > 0)
+        if (expectedErrorSize > 0) {
             errors.add(rpcError);
-        RpcResult<CompositeNode> result = Rpcs.getRpcResult(true, invokeRpcResult, errors);
+        }
+        RpcResult<CompositeNode> result = RpcResultBuilder.<CompositeNode>success(invokeRpcResult)
+                                                            .withRpcErrors( errors ).build();
         futureCompNode = Futures.immediateFuture(result);
         if( hasInput )
         {
@@ -191,22 +193,28 @@ public class RpcInvocationStrategyTest {
      * invokeOn Tests
      */
     private void setupRpcResultsWithOutput(int expectedErrorSize) {
-        if (expectedErrorSize > 0)
+        if (expectedErrorSize > 0) {
             errors.add(rpcError);
-        RpcResult<CompositeNode> resultCompNode = Rpcs.getRpcResult(true, inputInvokeOn, errors);
+        }
+        RpcResult<CompositeNode> resultCompNode = RpcResultBuilder.<CompositeNode>success(inputInvokeOn)
+                                                                        .withRpcErrors(errors).build();
         futureCompNode = Futures.immediateFuture(resultCompNode);
-        RpcResult<DataObject> resultDataObj = Rpcs.getRpcResult(true, toDataDomInput, errors);
+        RpcResult<DataObject> resultDataObj = RpcResultBuilder.<DataObject>success(toDataDomInput)
+                                                                           .withRpcErrors(errors).build();
         futureDataObj = Futures.immediateFuture(resultDataObj);
 
         when(mockMappingService.toDataDom(toDataDomInput)).thenReturn(outputInvokeOn);
     }
 
     private void setupRpcResultsNoOutput(int expectedErrorSize) {
-        if (expectedErrorSize > 0)
+        if (expectedErrorSize > 0) {
             errors.add(rpcError);
-        RpcResult<CompositeNode> resultCompNode = Rpcs.getRpcResult(true, inputInvokeOn, errors);
+        }
+        RpcResult<CompositeNode> resultCompNode = RpcResultBuilder.<CompositeNode>success(inputInvokeOn)
+                                                                          .withRpcErrors(errors).build();
         futureCompNode = Futures.immediateFuture(resultCompNode);
-        RpcResult<DataObject> resultDataObj = Rpcs.getRpcResult(true, null, errors);
+        RpcResult<DataObject> resultDataObj = RpcResultBuilder.<DataObject>success()
+                                                                          .withRpcErrors(errors).build();
         futureDataObj = Futures.immediateFuture(resultDataObj);
     }
 
index 6c80f4d7394947cd34af1aa3eedb305dc2f99113..591e07d00440465f1bc6763d8ef4ef1508d9191c 100644 (file)
@@ -7,28 +7,21 @@
  */
 package org.opendaylight.controller.sal.binding.test;
 
-import org.junit.After;
 import org.junit.Before;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 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.data.DataStore;
-import org.opendaylight.controller.sal.dom.broker.impl.DataStoreStatsWrapper;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 
+@SuppressWarnings("deprecation")
 public abstract class AbstractDataServiceTest {
-    private static Logger log = LoggerFactory.getLogger(AbstractDataServiceTest.class);
 
     protected org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService;
     protected DataProviderService baDataService;
     protected BindingIndependentMappingService mappingService;
-    private DataStoreStatsWrapper dataStoreStats;
-    protected DataStore dataStore;
     protected BindingTestContext testContext;
 
     @Before
@@ -42,18 +35,10 @@ public abstract class AbstractDataServiceTest {
 
         baDataService = testContext.getBindingDataBroker();
         biDataService = testContext.getDomDataBroker();
-        dataStore = testContext.getDomDataStore();
         mappingService = testContext.getBindingToDomMappingService();
     }
 
     protected boolean getStartWithSchema() {
         return true;
     }
-
-    @After
-    public void afterTest() {
-
-        testContext.logDataStoreStatistics();
-
-    }
 }
index e6cd1aa1ad638716b474fa9570c7d3ace3d767a1..9ba65339710b50c5e3a1e453fa5b5ff3805484f3 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.controller.sal.binding.test;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
@@ -154,6 +155,31 @@ public class RuntimeCodeGeneratorTest {
 
         // We should have call to instance 1
         verify(service[1]).simple(instance_1_input[0]);
+
+        /*
+         * Generated RPC service should throw illegalArgumentException
+         * with message if rpc input is null.
+         */
+        try {
+            product.getInvocationProxy().simple(null);
+            fail("Generated RPC router should throw IllegalArgumentException on null input");
+        } catch (IllegalArgumentException e){
+            assertNotNull(e.getMessage());
+        }
+
+
+        /*
+         * Generated RPC service should throw illegalArgumentException
+         * with message if rpc route is null.
+         */
+        try {
+            SimpleInput withoutValue = new SimpleInputImpl(null);
+            product.getInvocationProxy().simple(withoutValue);
+            fail("Generated RPC router should throw IllegalArgumentException on null value for route");
+        } catch (IllegalArgumentException e){
+            assertNotNull(e.getMessage());
+        }
+
     }
 
     private InstanceIdentifier<?>[][] identifiers(final int serviceSize, final int instancesPerService) {
@@ -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.test.bugfix;
+package org.opendaylight.controller.sal.binding.test.compat;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -64,8 +64,8 @@ public class MultipleAugmentationPutsTest extends AbstractDataServiceTest implem
     private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA =
             NODES_INSTANCE_ID_BA.child(Node.class, NODE_KEY);
 
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
-    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+    private static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier NODE_INSTANCE_ID_BI = //
+    org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.builder() //
             .node(Nodes.QNAME) //
             .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
             .toInstance();
@@ -158,7 +158,7 @@ public class MultipleAugmentationPutsTest extends AbstractDataServiceTest implem
         return new AugmentationVerifier<Node>(readedNode);
     }
 
-    private void assertBindingIndependentVersion(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier nodeId) {
+    private void assertBindingIndependentVersion(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier nodeId) {
         CompositeNode node = biDataService.readOperationalData(nodeId);
         assertNotNull(node);
     }
@@ -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.test.bugfix;
+package org.opendaylight.controller.sal.binding.test.compat;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -5,11 +5,9 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.controller.sal.binding.test.bugfix;
-
-public class RpcRegistrationNullPointer {
-
-
-
-
-}
+/**
+ *
+ * Test suite targeting legacy Data APIs
+ *
+ */
+package org.opendaylight.controller.sal.binding.test.compat;
\ No newline at end of file
index 08c5d061dc832d47cdcffe991cacc2ddb25b6332..c58e258e8b64daa1151a88d1153aac3571d813ea 100644 (file)
@@ -11,10 +11,12 @@ import java.util.concurrent.ExecutorService;
 
 import javassist.ClassPool;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 
+@Beta
 public class BindingBrokerTestFactory {
 
     private static final ClassPool CLASS_POOL = ClassPool.getDefault();
index 623b2fdd6365c5f14d3948d2b567ab65c81435cd..e82c9d385d6592c55982f5a5e59fc3a5249ee749 100644 (file)
@@ -9,15 +9,14 @@ package org.opendaylight.controller.sal.binding.test.util;
 
 import static com.google.common.base.Preconditions.checkState;
 
-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.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.impl.ForwardedBackwardsCompatibleDataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.ForwardedBindingDataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.broker.impl.DOMDataBrokerImpl;
@@ -39,38 +38,36 @@ 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.spi.data.DOMStore;
 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.SchemaAwareDataStoreAdapter;
 import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
 import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 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.impl.codec.BindingIndependentMappingService;
-import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.reflections.Reflections;
-import org.reflections.scanners.ResourcesScanner;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Predicate;
+import com.google.common.annotations.Beta;
 import com.google.common.collect.ClassToInstanceMap;
 import com.google.common.collect.ImmutableClassToInstanceMap;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.MutableClassToInstanceMap;
 import com.google.common.util.concurrent.ListeningExecutorService;
 
+@Beta
 public class BindingTestContext implements AutoCloseable {
 
-    public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier TREE_ROOT = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+    public static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier TREE_ROOT = org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier
             .builder().toInstance();
 
     private static final Logger LOG = LoggerFactory.getLogger(BindingTestContext.class);
@@ -83,14 +80,9 @@ public class BindingTestContext implements AutoCloseable {
     private BindingIndependentConnector baConnectImpl;
 
     private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
+    @SuppressWarnings("deprecation")
     private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataLegacyBroker;
     private BrokerImpl biBrokerImpl;
-    private HashMapDataStore rawDataStore;
-    private SchemaAwareDataStoreAdapter schemaAwareDataStore;
-    private DataStoreStatsWrapper dataStoreStats;
-    private DataStore dataStore;
-
-    private final boolean dataStoreStatisticsEnabled = false;
 
     private final ListeningExecutorService executor;
     private final ClassPool classPool;
@@ -105,12 +97,15 @@ public class BindingTestContext implements AutoCloseable {
 
     private BackwardsCompatibleDataBroker biCompatibleBroker;
 
+    @SuppressWarnings("deprecation")
     private DataProviderService baData;
 
     private DOMDataBroker newDOMDataBroker;
 
     private final MockSchemaService mockSchemaService = new MockSchemaService();
 
+    private DataBroker dataBroker;
+
 
 
     public DOMDataBroker getDomAsyncDataBroker() {
@@ -123,25 +118,6 @@ public class BindingTestContext implements AutoCloseable {
         this.startWithSchema = startWithSchema;
     }
 
-    @Deprecated
-    public void startDomDataStore() {
-        checkState(dataStore == null, "DataStore already started.");
-        checkState(biDataImpl != null, "Dom Data Broker not present");
-        rawDataStore = new HashMapDataStore();
-        schemaAwareDataStore = new SchemaAwareDataStoreAdapter();
-        schemaAwareDataStore.changeDelegate(rawDataStore);
-        if (dataStoreStatisticsEnabled) {
-            dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore);
-            dataStore = dataStoreStats;
-        } else {
-            dataStore = schemaAwareDataStore;
-        }
-        mockSchemaService.registerSchemaServiceListener(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");
         biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl();
@@ -149,6 +125,12 @@ public class BindingTestContext implements AutoCloseable {
         biDataLegacyBroker = biDataImpl;
     }
 
+    public void startNewDataBroker() {
+        checkState(executor != null, "Executor needs to be set");
+        checkState(newDOMDataBroker != null, "DOM Data Broker must be set");
+        dataBroker = new ForwardedBindingDataBroker(newDOMDataBroker, mappingServiceImpl, mockSchemaService);
+    }
+
     public void startNewDomDataBroker() {
         checkState(executor != null, "Executor needs to be set");
         InMemoryDOMDataStore operStore = new InMemoryDOMDataStore("OPER", executor);
@@ -160,11 +142,10 @@ public class BindingTestContext implements AutoCloseable {
 
         newDOMDataBroker = new DOMDataBrokerImpl(newDatastores, executor);
 
-        biCompatibleBroker = new BackwardsCompatibleDataBroker(newDOMDataBroker);
+        biCompatibleBroker = new BackwardsCompatibleDataBroker(newDOMDataBroker,mockSchemaService);
 
         mockSchemaService.registerSchemaServiceListener(configStore);
         mockSchemaService.registerSchemaServiceListener(operStore);
-        mockSchemaService.registerSchemaServiceListener(biCompatibleBroker);
         biDataLegacyBroker = biCompatibleBroker;
     }
 
@@ -203,6 +184,7 @@ public class BindingTestContext implements AutoCloseable {
 
     private ProviderSession createMockContext() {
 
+        @SuppressWarnings("deprecation")
         final ClassToInstanceMap<BrokerService> domBrokerServices = ImmutableClassToInstanceMap
                 .<BrokerService> builder()
                 //
@@ -267,56 +249,24 @@ public class BindingTestContext implements AutoCloseable {
         mockSchemaService.registerSchemaServiceListener(mappingServiceImpl);
     }
 
-    public void updateYangSchema(final String[] files) {
-        mockSchemaService.changeSchema(getContext(files));
+    private void updateYangSchema(final ImmutableSet<YangModuleInfo> moduleInfos) {
+        mockSchemaService.changeSchema(getContext(moduleInfos));
     }
 
-    public static String[] getAllYangFilesOnClasspath() {
-        Predicate<String> predicate = new Predicate<String>() {
-            @Override
-            public boolean apply(final String input) {
-                return input.endsWith(".yang");
-            }
-        };
-        Reflections reflection = new Reflections("META-INF.yang", new ResourcesScanner());
-        Set<String> result = reflection.getResources(predicate);
-        return result.toArray(new String[result.size()]);
-    }
-
-    private static SchemaContext getContext(final String[] yangFiles) {
-        ClassLoader loader = BindingTestContext.class.getClassLoader();
-        List<InputStream> streams = new ArrayList<>();
-        for (String string : yangFiles) {
-            InputStream stream = loader.getResourceAsStream(string);
-            streams.add(stream);
-        }
-        YangParserImpl parser = new YangParserImpl();
-        Set<Module> modules = parser.parseYangModelsFromStreams(streams);
-        return parser.resolveSchemaContext(modules);
-    }
-
-    public void startLegacy() {
-        startBindingDataBroker();
-        startBindingNotificationBroker();
-        startBindingBroker();
-        startDomDataBroker();
-        startDomDataStore();
-        startDomBroker();
-        startDomMountPoint();
-        startBindingToDomMappingService();
-        startForwarding();
-        if (startWithSchema) {
-            loadYangSchemaFromClasspath();
-        }
+    private SchemaContext getContext(final ImmutableSet<YangModuleInfo> moduleInfos) {
+        ModuleInfoBackedContext ctx = ModuleInfoBackedContext.create();
+        ctx.addModuleInfos(moduleInfos);
+        return ctx.tryToCreateSchemaContext().get();
     }
 
     public void start() {
         startNewDomDataBroker();
+
         startDomBroker();
         startDomMountPoint();
         startBindingToDomMappingService();
+        startNewDataBroker();
         startNewBindingDataBroker();
-
         startBindingNotificationBroker();
         startBindingBroker();
 
@@ -338,8 +288,10 @@ public class BindingTestContext implements AutoCloseable {
 
     private void startDomBroker() {
         checkState(executor != null);
-        biBrokerImpl = new BrokerImpl();
-        biBrokerImpl.setRouter(new SchemaAwareRpcBroker("/", mockSchemaService));
+
+        SchemaAwareRpcBroker router = new SchemaAwareRpcBroker("/", mockSchemaService);
+        ClassToInstanceMap<BrokerService> services = MutableClassToInstanceMap.create();
+        biBrokerImpl = new BrokerImpl(router,services);
 
     }
 
@@ -350,44 +302,24 @@ public class BindingTestContext implements AutoCloseable {
     }
 
     public void loadYangSchemaFromClasspath() {
-        String[] files = getAllYangFilesOnClasspath();
-        updateYangSchema(files);
+        ImmutableSet<YangModuleInfo> moduleInfos = BindingReflections.loadModuleInfos();
+        updateYangSchema(moduleInfos);
     }
 
+    @SuppressWarnings("deprecation")
     public DataProviderService getBindingDataBroker() {
         return baData;
     }
 
+    @SuppressWarnings("deprecation")
     public org.opendaylight.controller.sal.core.api.data.DataProviderService getDomDataBroker() {
         return biDataLegacyBroker;
     }
 
-    public DataStore getDomDataStore() {
-        return dataStore;
-    }
-
     public BindingIndependentMappingService getBindingToDomMappingService() {
         return mappingServiceImpl;
     }
 
-    public void logDataStoreStatistics() {
-        if (dataStoreStats == null) {
-            return;
-        }
-
-        LOG.info("BIDataStore Statistics: Configuration Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
-                dataStoreStats.getConfigurationReadCount(), dataStoreStats.getConfigurationReadTotalTime(),
-                dataStoreStats.getConfigurationReadAverageTime());
-
-        LOG.info("BIDataStore Statistics: Operational Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
-                dataStoreStats.getOperationalReadCount(), dataStoreStats.getOperationalReadTotalTime(),
-                dataStoreStats.getOperationalReadAverageTime());
-
-        LOG.info("BIDataStore Statistics: Request Commit Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
-                dataStoreStats.getRequestCommitCount(), dataStoreStats.getRequestCommitTotalTime(),
-                dataStoreStats.getRequestCommitAverageTime());
-    }
-
     public RpcProviderRegistry getBindingRpcRegistry() {
         return baBrokerImpl.getRoot();
     }
@@ -416,5 +348,9 @@ public class BindingTestContext implements AutoCloseable {
         return biMountImpl;
     }
 
+    public DataBroker getDataBroker() {
+        return dataBroker;
+    }
+
 
 }
index fd5c5be18dc787c2bc6ae2237df3ce848b930ee7..42d5cfff65e755e29ef2f9198fb6478eabf783d6 100644 (file)
       <artifactId>pax-exam-container-native</artifactId>
       <scope>test</scope>
     </dependency>
-
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-simple</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-parser-impl</artifactId>
+      <scope>test</scope>
+    </dependency>
+      <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>sal-test-model</artifactId>
+          <version>1.1-SNAPSHOT</version>
+      </dependency>
   </dependencies>
   <build>
     <plugins>
           </execution>
         </executions>
       </plugin>
-      <plugin>
-        <groupId>org.opendaylight.yangtools</groupId>
-        <artifactId>yang-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>generate-sources</goal>
-            </goals>
-            <configuration>
-              <codeGenerators>
-                <generator>
-                  <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
-                  <outputBaseDir>${salGeneratorPath}</outputBaseDir>
-                </generator>
-              </codeGenerators>
-              <inspectDependencies>true</inspectDependencies>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
     </plugins>
   </build>
   <scm>
index c5dbdcecae747b7f4930b0f0f1119ec753f941e3..aefc53b124335b5801910faaed56adca6be32d46 100644 (file)
@@ -25,6 +25,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
+/*
+ * FIXME: THis test should be moved to sal-binding-broker and rewriten
+ * to use new DataBroker API
+ */
+@SuppressWarnings("deprecation")
 public class ConcurrentImplicitCreateTest extends AbstractDataServiceTest {
 
     private static final NodeKey NODE_FOO_KEY = new NodeKey(new NodeId("foo"));
index 667887ac805f3c8ea538df89da2d22d147b62ade..aa136451a19511de6d032674086c9e45d34c0224 100644 (file)
@@ -50,22 +50,20 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.ListenableFuture;
 
 /*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
+ * FIXME: THis test should be moved to sal-binding-broker and rewriten
+ * to use new DataBroker API
  */
+@SuppressWarnings("deprecation")
 public class ListProcessingAndOrderingTest extends AbstractDataServiceTest {
 
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier DOM_UNORDERED_LIST_PATH = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+    private static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier DOM_UNORDERED_LIST_PATH = org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier
             .builder(Lists.QNAME).node(UnorderedContainer.QNAME).node(UnorderedList.QNAME).build();
 
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier DOM_ORDERED_LIST_PATH = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+    private static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier DOM_ORDERED_LIST_PATH = org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier
             .builder(Lists.QNAME).node(OrderedContainer.QNAME).node(OrderedList.QNAME).build();
 
 
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier DOM_UNKEYED_LIST_PATH = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+    private static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier DOM_UNKEYED_LIST_PATH = org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier
             .builder(Lists.QNAME).node(UnkeyedContainer.QNAME).node(UnkeyedList.QNAME).build();
 
     private static final InstanceIdentifier<UnorderedContainer> UNORDERED_CONTAINER_PATH = InstanceIdentifier.builder(Lists.class).child(UnorderedContainer.class).build();
@@ -137,7 +135,7 @@ public class ListProcessingAndOrderingTest extends AbstractDataServiceTest {
     }
 
     private NormalizedNode<?, ?> resolveDataAsserted(
-            final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) {
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier domPath) {
 
         try (DOMDataReadOnlyTransaction readTx = testContext.getDomAsyncDataBroker().newReadOnlyTransaction()){
             ListenableFuture<Optional<NormalizedNode<?, ?>>> data = readTx.read(LogicalDatastoreType.OPERATIONAL, domPath);
@@ -171,10 +169,9 @@ public class ListProcessingAndOrderingTest extends AbstractDataServiceTest {
         assertEquals(TransactionStatus.COMMITED,result.getResult());
     }
 
-    @SuppressWarnings("deprecation")
     private void assertXmlRepresentation(final InstanceIdentifier<?> containerPath, final String... childNameValues) {
 
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = testContext.getBindingToDomMappingService().toDataDom(containerPath);
+        org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier domPath = testContext.getBindingToDomMappingService().toDataDom(containerPath);
         CompositeNode compositeNode = testContext.getDomDataBroker().readOperationalData(domPath);
         assertNotNull(compositeNode);
 
index 6b4cc5779806288d4f0cf26116d2ef3f7ca10ba1..2b5171369bb31a7195b029c1377201c76ba24849 100644 (file)
@@ -43,12 +43,10 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import com.google.common.util.concurrent.SettableFuture;
 
 /*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
+ * FIXME: THis test should be moved to compat test-suite and rewriten
+ * to use sal-test-model
  */
+@SuppressWarnings("deprecation")
 public class WildcardedDataChangeListenerTest extends AbstractDataServiceTest {
 
     private static final NodeKey NODE_0_KEY = new NodeKey(new NodeId("test:0"));
index 471935248506b9cf4c3cdf53d37e8ad43568b33b..34a71ac0c4bc2cee1f601d6f8346ddc100eba939 100644 (file)
@@ -14,7 +14,6 @@ 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.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -49,49 +48,29 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
-import com.google.common.collect.ImmutableMap;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 
+@SuppressWarnings("deprecation")
 public class DOMCodecBug01Test extends AbstractDataServiceTest {
 
-    private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
-    private static final QName FLOW_ID_QNAME = QName.create(Flow.QNAME, "id");
-    private static final QName FLOW_NODE_QNAME = QName.create(Flow.QNAME, "node");
     private static final long FLOW_ID = 1234;
     private static final String NODE_ID = "node:1";
 
     private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID));
 
-    private static final Map<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
-            NODE_ID);
-
     private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
             .child(Node.class, NODE_KEY).toInstance();
 
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
-    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
-            .node(Nodes.QNAME) //
-            .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
-            .toInstance();
     private static final NodeRef NODE_REF = new NodeRef(NODE_INSTANCE_ID_BA);
 
     private static final FlowKey FLOW_KEY = new FlowKey(FLOW_ID, NODE_REF);
 
-    private static final Map<QName, Object> FLOW_KEY_BI = //
-    ImmutableMap.<QName, Object> of(FLOW_ID_QNAME, FLOW_ID, FLOW_NODE_QNAME, NODE_INSTANCE_ID_BI);
-
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier FLOW_INSTANCE_ID_BI = //
-    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
-            .node(Flows.QNAME) //
-            .nodeWithKey(Flow.QNAME, FLOW_KEY_BI) //
-            .toInstance();
     private static final InstanceIdentifier<? extends DataObject> FLOW_INSTANCE_ID_BA = //
     InstanceIdentifier.builder(Flows.class) //
             .child(Flow.class, FLOW_KEY) //
@@ -243,7 +222,7 @@ public class DOMCodecBug01Test extends AbstractDataServiceTest {
     }
 
     private void verifyDataAreStoredProperly() {
-        CompositeNode biFlows = biDataService.readConfigurationData(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.of(Flows.QNAME));
+        CompositeNode biFlows = biDataService.readConfigurationData(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.of(Flows.QNAME));
         assertNotNull(biFlows);
         CompositeNode biFlow = biFlows.getFirstCompositeByName(Flow.QNAME);
         assertNotNull(biFlow);
index bc6f567c2bd01fd3346cc0c8d9769fd20f9cfdc8..bddbc4e95400965da7533b3d66dfee72fa6c3710 100644 (file)
@@ -11,7 +11,6 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
 import java.util.Collections;
-import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -22,47 +21,21 @@ import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
 import org.opendaylight.controller.sal.binding.test.util.BindingBrokerTestFactory;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 
+@SuppressWarnings("deprecation")
 public class DOMCodecBug02Test extends AbstractDataServiceTest {
 
-    private static final QName NODE_ID_QNAME = QName.create(Node.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<Nodes> NODES_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
             .toInstance();
 
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODES_INSTANCE_ID_BI = //
-    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
-            .node(Nodes.QNAME) //
-            .toInstance();
-
-    private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
-            .child(Node.class, NODE_KEY).toInstance();
-
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
-    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
-            .node(Nodes.QNAME) //
-            .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
-            .toInstance();
-    private static final NodeRef NODE_REF = new NodeRef(NODE_INSTANCE_ID_BA);
-
     /**
      * This test is ignored, till found out better way to test generation of
      * classes without leaking of instances from previous run
@@ -81,7 +54,6 @@ public class DOMCodecBug02Test extends AbstractDataServiceTest {
 
         baDataService = testContext.getBindingDataBroker();
         biDataService = testContext.getDomDataBroker();
-        dataStore = testContext.getDomDataStore();
         mappingService = testContext.getBindingToDomMappingService();
     };
 
index ccbd52fc77ea27711c19c934fb2109a3991343d6..c07125a5dcce9b2130c37e8f99feb646252e54ad 100644 (file)
@@ -46,6 +46,7 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 import com.google.common.util.concurrent.SettableFuture;
 
+@SuppressWarnings("deprecation")
 public class DOMCodecBug03Test extends AbstractDataServiceTest implements DataChangeListener {
 
     private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
@@ -71,16 +72,16 @@ public class DOMCodecBug03Test extends AbstractDataServiceTest implements DataCh
             .toInstance();
 
 
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
-    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+    private static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier NODE_INSTANCE_ID_BI = //
+    org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.builder() //
             .node(Nodes.QNAME) //
             .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
             .toInstance();
     private static final QName SUPPORTED_ACTIONS_QNAME = QName.create(FlowCapableNode.QNAME, SupportedActions.QNAME.getLocalName());
 
 
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier SUPPORTED_ACTIONS_INSTANCE_ID_BI = //
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+    private static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier SUPPORTED_ACTIONS_INSTANCE_ID_BI = //
+            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.builder() //
                     .node(Nodes.QNAME) //
                     .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
                     .node(SUPPORTED_ACTIONS_QNAME) //
@@ -205,7 +206,7 @@ public class DOMCodecBug03Test extends AbstractDataServiceTest implements DataCh
     }
 
     private void assertBindingIndependentVersion(
-            final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier nodeId) {
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier nodeId) {
         CompositeNode node = biDataService.readOperationalData(nodeId);
         assertNotNull(node);
     }
index c1eba3ee257abeb7bb864a810e8bad3b676ad529..735138a530ab801149adbaceb79e38c3b27d92b9 100644 (file)
@@ -24,12 +24,12 @@ 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.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 import com.google.common.util.concurrent.SettableFuture;
 
+@SuppressWarnings("deprecation")
 public class DeleteNestedAugmentationListenParentTest extends AbstractDataServiceTest {
 
     private static final NodeKey NODE_KEY = new NodeKey(new NodeId("foo"));
@@ -38,11 +38,6 @@ public class DeleteNestedAugmentationListenParentTest extends AbstractDataServic
 
     private static final FlowKey FLOW_KEY = new FlowKey(new FlowId("100"));
 
-    private static final InstanceIdentifier<FlowCapableNode> LISTENER_PATH = InstanceIdentifier.builder(Nodes.class) //
-            .child(Node.class)
-            .augmentation(FlowCapableNode.class).build();
-
-
     private static final InstanceIdentifier<FlowCapableNode> NODE_AUGMENT_PATH = InstanceIdentifier.builder(Nodes.class)
             .child(Node.class,NODE_KEY)
             .augmentation(FlowCapableNode.class)
@@ -63,7 +58,7 @@ public class DeleteNestedAugmentationListenParentTest extends AbstractDataServic
 
         final SettableFuture<DataChangeEvent<InstanceIdentifier<?>, DataObject>> event = SettableFuture.create();
 
-        ListenerRegistration<DataChangeListener> listenerReg = baDataService.registerDataChangeListener(FLOW_PATH, new DataChangeListener() {
+        baDataService.registerDataChangeListener(FLOW_PATH, new DataChangeListener() {
 
             @Override
             public void onDataChanged(final DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
@@ -83,13 +78,12 @@ public class DeleteNestedAugmentationListenParentTest extends AbstractDataServic
         FlowBuilder builder = new FlowBuilder()
             .setKey(FLOW_KEY)
             .addAugmentation(FlowStatisticsData.class,new FlowStatisticsDataBuilder()
-                    .setFlowStatistics(new FlowStatisticsBuilder()
-                        .setBarrier(true)
-                        .setMatch(new MatchBuilder()
-                            .build())
-                        .build())
+                    .setFlowStatistics(new FlowStatisticsBuilder().build())
                     .build())
-        ;//.build();
+            .setBarrier(true)
+            .setMatch(new MatchBuilder()
+            .build())
+        ;
         return builder.build();
     }
 
index 30c7af705f2ccba4a25e3b1d19f8261e3439386a..7143352c1f9c8ec625b4f29e93912d30db815414 100644 (file)
@@ -14,7 +14,6 @@ import static org.junit.Assert.assertNull;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
@@ -39,7 +38,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
@@ -54,11 +52,9 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 import com.google.common.collect.ImmutableSet;
 
+@SuppressWarnings("deprecation")
 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 String FLOW_ID = "1234";
     private static final short TABLE_ID = (short)0;
     private static final String NODE_ID = "node:1";
@@ -67,27 +63,9 @@ public class FlagsSerializationTest extends AbstractDataServiceTest {
     private static final FlowKey FLOW_KEY = new FlowKey(new FlowId(FLOW_ID));
     private static final TableKey TABLE_KEY = new TableKey(TABLE_ID);
 
-    private static final Map<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
-            NODE_ID);
-
     private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
             .child(Node.class, NODE_KEY).toInstance();
 
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
-    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
-            .node(Nodes.QNAME) //
-            .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
-            .toInstance();
-    private static final NodeRef NODE_REF = new NodeRef(NODE_INSTANCE_ID_BA);
-
-
-
-//    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier FLOW_INSTANCE_ID_BI = //
-//    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
-//
-//            .node(Flows.QNAME) //
-//            .nodeWithKey(Flow.QNAME, FLOW_KEY_BI) //
-//            .toInstance();
     private static final InstanceIdentifier<? extends DataObject> FLOW_INSTANCE_ID_BA = //
             NODE_INSTANCE_ID_BA.builder() //
             .augmentation(FlowCapableNode.class)
@@ -113,15 +91,13 @@ public class FlagsSerializationTest extends AbstractDataServiceTest {
         ImmutableSet<String> domAllTrueFlags = ImmutableSet.<String>of("CHECK_OVERLAP","NO_BYT_COUNTS", "NO_PKT_COUNTS", "RESET_COUNTS", "SEND_FLOW_REM");
         testFlags(allTrueFlags,domAllTrueFlags);
 
-        FlowModFlags nullFlags = null;
-        ImmutableSet<String> domNullFlags = null;
         testFlags(null,null);
 
 
 
     }
 
-    private void testFlags(FlowModFlags flagsToTest, ImmutableSet<String> domFlags) throws Exception {
+    private void testFlags(final FlowModFlags flagsToTest, final ImmutableSet<String> domFlags) throws Exception {
         Flow flow = createFlow(flagsToTest);
         assertNotNull(flow);
 
@@ -145,7 +121,7 @@ public class FlagsSerializationTest extends AbstractDataServiceTest {
 
     }
 
-    private Flow createFlow(FlowModFlags flagsToTest) throws Exception {
+    private Flow createFlow(final FlowModFlags flagsToTest) throws Exception {
 
         DataModificationTransaction modification = baDataService.beginTransaction();
 
index 7f1632081490003aa8921b14a8c37c6941df4c29..767ccaade304a711b7c54f4c958a8b4c2ea5ae5b 100644 (file)
@@ -27,7 +27,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.Fl
 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.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
@@ -45,6 +44,7 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 import com.google.common.util.concurrent.SettableFuture;
 
+@SuppressWarnings("deprecation")
 public class PutAugmentationTest extends AbstractDataServiceTest implements DataChangeListener {
 
     private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
@@ -62,31 +62,16 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data
             NODES_INSTANCE_ID_BA.builder() //
             .child(Node.class, NODE_KEY).toInstance();
 
-    private static final InstanceIdentifier<SupportedActions> SUPPORTED_ACTIONS_INSTANCE_ID_BA = //
-            NODES_INSTANCE_ID_BA.builder() //
-            .child(Node.class, NODE_KEY) //
-            .augmentation(FlowCapableNode.class) //
-            .child(SupportedActions.class).toInstance();
-
     private static final InstanceIdentifier<FlowCapableNode> ALL_FLOW_CAPABLE_NODES = //
             NODES_INSTANCE_ID_BA.builder() //
             .child(Node.class) //
             .augmentation(FlowCapableNode.class) //
             .build();
 
-    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 QName SUPPORTED_ACTIONS_QNAME = QName.create(FlowCapableNode.QNAME,
-            SupportedActions.QNAME.getLocalName());
-
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier SUPPORTED_ACTIONS_INSTANCE_ID_BI = //
-    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+    private static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier NODE_INSTANCE_ID_BI = //
+    org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.builder() //
             .node(Nodes.QNAME) //
             .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
-            .node(SUPPORTED_ACTIONS_QNAME) //
             .toInstance();
     private static final InstanceIdentifier<FlowCapableNode> FLOW_AUGMENTATION_PATH =
             NODE_INSTANCE_ID_BA.builder() //
@@ -231,31 +216,11 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data
         assertNull(node);
     }
 
-    private void verifyNodes(final Nodes nodes, final Node original) {
-        assertNotNull(nodes);
-        assertNotNull(nodes.getNode());
-        assertEquals(1, nodes.getNode().size());
-        Node readedNode = nodes.getNode().get(0);
-        assertEquals(original.getId(), readedNode.getId());
-        assertEquals(original.getKey(), readedNode.getKey());
-
-        FlowCapableNode fnu = original.getAugmentation(FlowCapableNode.class);
-        FlowCapableNode readedAugment = readedNode.getAugmentation(FlowCapableNode.class);
-        assertNotNull(fnu);
-        assertEquals(fnu.getDescription(), readedAugment.getDescription());
-        assertEquals(fnu.getSerialNumber(), readedAugment.getSerialNumber());
-
-    }
-
-    private void assertBindingIndependentVersion(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier nodeId) {
+    private void assertBindingIndependentVersion(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier nodeId) {
         CompositeNode node = biDataService.readOperationalData(nodeId);
         assertNotNull(node);
     }
 
-    private Nodes checkForNodes() {
-        return (Nodes) baDataService.readOperationalData(NODES_INSTANCE_ID_BA);
-    }
-
     @Override
     public void onDataChanged(final DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
         lastReceivedChangeEvent.set(change);
index cb31885f02673685342d35796d81e7bb3c38fa71..b09ba39a65e120f20c51801f2a699552f91132eb 100644 (file)
@@ -31,6 +31,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 import com.google.common.util.concurrent.SettableFuture;
 
+@SuppressWarnings("deprecation")
 public class WriteParentListenAugmentTest extends AbstractDataServiceTest {
 
     private static final String NODE_ID = "node:1";
index f7b81a44e9e2b685860b7269425c2630911b817b..ad02d9a6f6df31239c108352294a595452d43f7e 100644 (file)
@@ -40,6 +40,7 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 
 import com.google.common.collect.ImmutableList;
 
+@SuppressWarnings("deprecation")
 public class WriteParentReadChildTest extends AbstractDataServiceTest {
 
     private static final String FLOW_ID = "1234";
diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/package-info.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/package-info.java
new file mode 100644 (file)
index 0000000..84559d5
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+/**
+ * This testsuite test Hydrogen-level API and regression for most of it,
+ *
+ * FIXME: this testsuite needs to be refactored to use new DataBroker API,
+ * moved to sal-binding-broker-impl and uses models only from sal-test-model.
+ *
+ */
+package org.opendaylight.controller.sal.binding.test.bugfix;
\ No newline at end of file
index 6d0226849f3a81a02b143046ea8d092cfd755b5b..481a7ddfa2c42863b3cb17b17826d0a5748fa778 100644 (file)
@@ -11,16 +11,12 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
-
 import java.util.concurrent.Future;
 
-
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 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.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;
@@ -31,6 +27,8 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
+// FIXME: Migrate to use new Data Broker APIs
+@SuppressWarnings("deprecation")
 public class BrokerIntegrationTest extends AbstractDataServiceTest {
 
     @Test
@@ -105,14 +103,14 @@ public class BrokerIntegrationTest extends AbstractDataServiceTest {
         assertNull(readedData2);
     }
 
-    private static NodeRef createNodeRef(String string) {
+    private static NodeRef createNodeRef(final String string) {
         NodeKey key = new NodeKey(new NodeId(string));
         InstanceIdentifier<Node> path = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
                 .toInstance();
         return new NodeRef(path);
     }
 
-    private static Node createNode(String string) {
+    private static Node createNode(final String string) {
         NodeBuilder ret = new NodeBuilder();
         ret.setId(new NodeId(string));
         ret.setKey(new NodeKey(ret.getId()));
index 422b9ccee5c4cc9e1048d2812fe784d7a9a08075..a3b0819501c57ffdcf3764c243a20e680d8d9ecf 100644 (file)
@@ -45,7 +45,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
@@ -63,13 +62,14 @@ import org.slf4j.LoggerFactory;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.util.concurrent.SettableFuture;
 
+// FIXME: Migrate to use new Data Broker APIs
+@SuppressWarnings("deprecation")
 public class ChangeOriginatedInDomBrokerTest extends AbstractDataServiceTest {
 
     private static final Logger LOG = LoggerFactory.getLogger(ChangeOriginatedInDomBrokerTest.class);
 
     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";
@@ -87,21 +87,14 @@ public class ChangeOriginatedInDomBrokerTest extends AbstractDataServiceTest {
     private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
             .child(Node.class, NODE_KEY).toInstance();
 
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
-    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
-            .node(Nodes.QNAME) //
-            .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
-            .toInstance();
-    private static final NodeRef NODE_REF = new NodeRef(NODE_INSTANCE_ID_BA);
-
     private static final Map<QName, Object> FLOW_KEY_BI = //
     ImmutableMap.<QName, Object> of(FLOW_ID_QNAME, FLOW_ID.getValue());
 
     private static final Map<QName, Object> TABLE_KEY_BI = //
     ImmutableMap.<QName, Object> of(TABLE_ID_QNAME, TABLE_ID);;
 
-    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier FLOW_INSTANCE_ID_BI = //
-    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+    private static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier FLOW_INSTANCE_ID_BI = //
+    org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.builder() //
             .node(Nodes.QNAME) //
             .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
             .nodeWithKey(Table.QNAME, TABLE_KEY_BI) //
index 94570510ab0cd4d3c0fefe41ccd61e5670bf56d9..a79b0fd53eec2ecd677108757f38d9c4692197e0 100644 (file)
@@ -24,15 +24,12 @@ 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.tables.Table;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 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;
@@ -43,13 +40,10 @@ import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
 
 import com.google.common.util.concurrent.MoreExecutors;
 
+@SuppressWarnings("deprecation")
 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));
@@ -71,20 +65,18 @@ public class CrossBrokerMountPointTest {
     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() //
+    private static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier NODE_INSTANCE_ID_BI = //
+    org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.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
+    private static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier GROUP_STATISTICS_ID_BI = org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier
             //
             .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;
@@ -120,16 +112,16 @@ public class CrossBrokerMountPointTest {
         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>() {
+        DataReader<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> simpleReader = new DataReader<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode>() {
 
             @Override
-            public CompositeNode readConfigurationData(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier arg0) {
+            public CompositeNode readConfigurationData(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier arg0) {
                 return null;
             }
 
 
             @Override
-            public CompositeNode readOperationalData(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier arg0) {
+            public CompositeNode readOperationalData(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier arg0) {
                 if (arg0.equals(GROUP_STATISTICS_ID_BI)) {
                     ImmutableCompositeNode data = ImmutableCompositeNode
                             .builder()
index ca38ed0797e1f1d0433a2281a2763672d1d19300..4cc3780c6f0ebff8b25c0043c845034d3a15aba1 100644 (file)
@@ -23,7 +23,6 @@ import org.junit.Test;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.controller.sal.binding.test.util.BindingBrokerTestFactory;
 import org.opendaylight.controller.sal.binding.test.util.BindingTestContext;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.api.RpcImplementation;
 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
@@ -42,12 +41,11 @@ 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.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
 
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -74,10 +72,10 @@ public class CrossBrokerRpcTest {
     public static final InstanceIdentifier<Node> BA_NODE_C_ID = createBANodeIdentifier(NODE_C);
     public static final InstanceIdentifier<Node> BA_NODE_D_ID = createBANodeIdentifier(NODE_D);
 
-    public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier BI_NODE_A_ID = createBINodeIdentifier(NODE_A);
-    public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier BI_NODE_B_ID = createBINodeIdentifier(NODE_B);
-    public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier BI_NODE_C_ID = createBINodeIdentifier(NODE_C);
-    public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier BI_NODE_D_ID = createBINodeIdentifier(NODE_D);
+    public static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier BI_NODE_A_ID = createBINodeIdentifier(NODE_A);
+    public static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier BI_NODE_B_ID = createBINodeIdentifier(NODE_B);
+    public static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier BI_NODE_C_ID = createBINodeIdentifier(NODE_C);
+    public static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier BI_NODE_D_ID = createBINodeIdentifier(NODE_D);
 
 
 
@@ -136,7 +134,7 @@ public class CrossBrokerRpcTest {
             @Override
             public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
                 CompositeNode result = testContext.getBindingToDomMappingService().toDataDom(output);
-                return Futures.immediateFuture(Rpcs.getRpcResult(true, result, ImmutableList.<RpcError>of()));
+                return Futures.immediateFuture(RpcResultBuilder.<CompositeNode>success(result).build());
             }
         });
         registration.registerPath(NodeContext.QNAME, BI_NODE_C_ID);
@@ -160,15 +158,15 @@ public class CrossBrokerRpcTest {
         return InstanceIdentifier.builder(Nodes.class).child(Node.class, new NodeKey(node)).toInstance();
     }
 
-    private static org.opendaylight.yangtools.yang.data.api.InstanceIdentifier createBINodeIdentifier(NodeId node) {
-        return org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder().node(Nodes.QNAME)
+    private static org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier createBINodeIdentifier(NodeId node) {
+        return org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.builder().node(Nodes.QNAME)
                 .nodeWithKey(Node.QNAME, NODE_ID_QNAME, node.getValue()).toInstance();
     }
 
     private Future<RpcResult<AddFlowOutput>> addFlowResult(boolean success, long xid) {
         AddFlowOutput output = new AddFlowOutputBuilder() //
                 .setTransactionId(new TransactionId(BigInteger.valueOf(xid))).build();
-        RpcResult<AddFlowOutput> result = Rpcs.getRpcResult(success, output, ImmutableList.<RpcError> of());
+        RpcResult<AddFlowOutput> result = RpcResultBuilder.<AddFlowOutput>status(success).withResult(output).build();
         return Futures.immediateFuture(result);
     }
 
diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/DOMRpcServiceTestBugfix560.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/DOMRpcServiceTestBugfix560.java
new file mode 100644 (file)
index 0000000..6686a83
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.binding.test.connect.dom;
+
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+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.RpcImplementation;
+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.inventory.rev130819.NodeId;
+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.params.xml.ns.yang.controller.md.sal.test.bi.ba.rpcservice.rev140701.OpendaylightTestRpcServiceService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.rpcservice.rev140701.RockTheHouseInputBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+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.model.parser.api.YangContextParser;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+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.MoreExecutors;
+
+/**
+ * Test case for reported bug 560
+ *
+ * @author Lukas Sedlak
+ * @see <a
+ *      href="https://bugs.opendaylight.org/show_bug.cgi?id=560">https://bugs.opendaylight.org/show_bug.cgi?id=560</a>
+ */
+public class DOMRpcServiceTestBugfix560 {
+
+    private final static String RPC_SERVICE_NAMESPACE = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:bi:ba:rpcservice";
+    private final static String REVISION_DATE = "2014-07-01";
+    private final static QName RPC_NAME = QName.create(RPC_SERVICE_NAMESPACE,
+            REVISION_DATE, "rock-the-house");
+
+    private static final NodeId MOUNT_NODE = new NodeId("id");
+    private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
+
+    private static final InstanceIdentifier<Node> BA_MOUNT_ID = createBANodeIdentifier(MOUNT_NODE);
+    private static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier BI_MOUNT_ID = createBINodeIdentifier(MOUNT_NODE);
+
+    private BindingTestContext testContext;
+    private MountProvisionService domMountPointService;
+    private MountProviderService bindingMountPointService;
+    private SchemaContext schemaContext;
+
+    /**
+     * @throws java.lang.Exception
+     */
+    @Before
+    public void setUp() throws Exception {
+        BindingBrokerTestFactory testFactory = new BindingBrokerTestFactory();
+        testFactory.setExecutor(MoreExecutors.sameThreadExecutor());
+        testFactory.setStartWithParsedSchema(true);
+        testContext = testFactory.getTestContext();
+
+        testContext.start();
+        domMountPointService = testContext.getDomMountProviderService();
+        bindingMountPointService = testContext.getBindingMountProviderService();
+        assertNotNull(domMountPointService);
+
+        final YangContextParser parser = new YangParserImpl();
+        final InputStream moduleStream = BindingReflections.getModuleInfo(
+                OpendaylightTestRpcServiceService.class)
+                .getModuleSourceStream();
+
+        assertNotNull(moduleStream);
+        List<InputStream> rpcModels = Collections.singletonList(moduleStream);
+        @SuppressWarnings("deprecation")
+        Set<Module> modules = parser.parseYangModelsFromStreams(rpcModels);
+        @SuppressWarnings("deprecation")
+        SchemaContext mountSchemaContext = parser.resolveSchemaContext(modules);
+        schemaContext = mountSchemaContext;
+    }
+
+    private static org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier createBINodeIdentifier(
+            final NodeId mountNode) {
+        return org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier
+                .builder().node(Nodes.QNAME)
+                .nodeWithKey(Node.QNAME, NODE_ID_QNAME, mountNode.getValue())
+                .toInstance();
+    }
+
+    private static InstanceIdentifier<Node> createBANodeIdentifier(
+            final NodeId mountNode) {
+        return InstanceIdentifier.builder(Nodes.class)
+                .child(Node.class, new NodeKey(mountNode)).toInstance();
+    }
+
+    @SuppressWarnings("deprecation")
+    @Test
+    public void test() throws ExecutionException, InterruptedException {
+        // FIXME: This is made to only make sure instance identifier codec
+        // for path is instantiated.
+        testContext.getBindingDataBroker().readOperationalData(BA_MOUNT_ID);
+        final MountProvisionInstance mountPoint = domMountPointService
+                .createMountPoint(BI_MOUNT_ID);
+        mountPoint.setSchemaContext(schemaContext);
+        assertNotNull(mountPoint);
+
+        mountPoint.addRpcImplementation(RPC_NAME, new RpcImplementation() {
+
+            @Override
+            public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(
+                    final QName rpc, final CompositeNode input) {
+
+                return Futures.immediateFuture(RpcResultBuilder
+                        .<CompositeNode> success().build());
+            }
+
+            @Override
+            public Set<QName> getSupportedRpcs() {
+                return ImmutableSet.of(RPC_NAME);
+            }
+        });
+
+        final Set<QName> biSupportedRpcs = mountPoint.getSupportedRpcs();
+        assertNotNull(biSupportedRpcs);
+        assertTrue(!biSupportedRpcs.isEmpty());
+
+        MountProviderInstance mountInstance = bindingMountPointService
+                .getMountPoint(BA_MOUNT_ID);
+        assertNotNull(mountInstance);
+        final OpendaylightTestRpcServiceService rpcService = mountInstance
+                .getRpcService(OpendaylightTestRpcServiceService.class);
+        assertNotNull(rpcService);
+
+        try {
+            Future<RpcResult<Void>> result = rpcService
+                    .rockTheHouse(new RockTheHouseInputBuilder().build());
+            assertTrue(result.get().isSuccessful());
+        } catch (IllegalStateException ex) {
+            fail("OpendaylightTestRpcServiceService class doesn't contain rockTheHouse method!");
+        }
+    }
+
+    /**
+     * @throws java.lang.Exception
+     */
+    @After
+    public void teardown() throws Exception {
+        testContext.close();
+    }
+}
index 5ede600d9777917a0df963c01b5a08128057f722..c389618f2eb829f2dedb12ec58b0b365f7654ff0 100644 (file)
@@ -54,6 +54,7 @@ public class TestHelper {
                 mavenBundle("io.netty", "netty-transport").versionAsInProject(), //
 
                 mavenBundle(CONTROLLER, "config-manager").versionAsInProject(), // //
+                mavenBundle(CONTROLLER, "config-util").versionAsInProject(), // //
                 mavenBundle("commons-io", "commons-io").versionAsInProject(), //
                 mavenBundle(CONTROLLER, "config-manager").versionAsInProject(), //
                 mavenBundle(CONTROLLER, "yang-jmx-generator").versionAsInProject(), //
index e6bbaab2d9dec48c659ac1bbf38e646fc021662b..9ec5bcf6c29ea58114f58da3c1eba47999841a55 100644 (file)
@@ -33,7 +33,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Node
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 
@@ -43,8 +43,8 @@ public class NotificationTest extends AbstractTest {
     private final FlowListener listener1 = new FlowListener();
     private final FlowListener listener2 = new FlowListener();
 
-    private Registration<NotificationListener> listener1Reg;
-    private Registration<NotificationListener> listener2Reg;
+    private ListenerRegistration<NotificationListener> listener1Reg;
+    private ListenerRegistration<NotificationListener> listener2Reg;
 
     private NotificationProviderService notifyProviderService;
 
index 8f367de6c8976c687600a941b491aff4fcbfeb2f..830942f3377db22d9e7f431091aac3732b88bcef 100644 (file)
@@ -40,14 +40,14 @@ public abstract class AbstractBindingSalProviderInstance<D extends DataProviderS
     }
 
     @Override
-    public Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> registerDataReader(
+    public Registration 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(
+    public Registration registerCommitHandler(
             InstanceIdentifier<? extends DataObject> path,
             DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> commitHandler) {
         return getDataBrokerChecked().registerCommitHandler(path, commitHandler);
index 3df33ba377376182e3485f6506af70d4a5e932aa..49ac59fe95da5071aa7f9b59332ae2aef0b97113 100644 (file)
@@ -11,6 +11,14 @@ import org.opendaylight.controller.md.sal.common.api.data.DataReader;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
+/**
+ *
+ *
+ * @deprecated Use
+ *             {@link org.opendaylight.controller.md.sal.binding.api.ReadTransaction#read(org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType, InstanceIdentifier)}
+ *             instead.
+ */
+@Deprecated
 public final class TypeSafeDataReader {
 
     private final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate;
@@ -19,21 +27,25 @@ public final class TypeSafeDataReader {
         return delegate;
     }
 
-    public TypeSafeDataReader(DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
+    public TypeSafeDataReader(
+            final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
         this.delegate = delegate;
     }
 
     @SuppressWarnings("unchecked")
-    public <D extends DataObject> D readConfigurationData(InstanceIdentifier<D> path) {
+    public <D extends DataObject> D readConfigurationData(
+            final 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(
+            final InstanceIdentifier<D> path) {
         return (D) delegate.readOperationalData(path);
     }
 
-    public static TypeSafeDataReader forReader(DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
+    public static TypeSafeDataReader forReader(
+            final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
         return new TypeSafeDataReader(delegate);
     }
 }
index f088c0a0bdde1f29f5ff0bd4054d3b3137ab8f7e..3b3217db6ba8f5cde5dbc88c6ede86d8ea2a0147 100644 (file)
@@ -11,7 +11,7 @@ import java.util.EventListener;
 
 import org.opendaylight.yangtools.concepts.Registration;
 
-public interface RegistrationListener<T extends Registration<?>> extends EventListener {
+public interface RegistrationListener<T extends Registration> extends EventListener {
 
     void onRegister(T registration);
 
index 29c9bae31f76e2b1a1269116c2b3438cfa572172..ac4a0ffc331226504b47b5f1cf45b996b0522b5c 100644 (file)
@@ -101,7 +101,7 @@ public interface AsyncDataChangeEvent<P extends Path<P>, D> extends Immutable {
      *
      * @return map of paths and original state of updated and removed objects.
      */
-    Map<P, ? extends D> getOriginalData();
+    Map<P, D> getOriginalData();
 
     /**
      * Returns an immutable stable view of data state, which captures the state of
index dca5200d392687e25493876f945e347d3e394bf4..0bdaf7bf3766736aa76337a1e6e772e036ed0cb5 100644 (file)
@@ -41,9 +41,12 @@ public interface AsyncDataChangeListener<P extends Path<P>, D> extends EventList
      * This initial event will contain all preexisting data as created.
      *
      * <p>
-     * <b>Note</b> that this method may be invoked from a shared thread pool, so
-     * implementations SHOULD NOT perform CPU-intensive operations and they
-     * definitely MUST NOT invoke any potentially blocking operations.
+     * <b>Note</b>: This method may be invoked from a shared thread pool.
+     * <li>Implementations <b>SHOULD NOT</b> perform CPU-intensive operations on the calling thread.
+     * <li>Implementations <b>MUST NOT block the calling thread</b> - to do so could lead to deadlock
+     * scenarios.
+     *
+     *<br>
      *
      * @param change
      *            Data Change Event being delivered.
index 4beb5c62e335dcd2af46af1493a7ea8180d32f48..46c90b97560d440763d8b66f77ab10f998b6be7f 100644 (file)
@@ -10,12 +10,11 @@ package org.opendaylight.controller.md.sal.common.api.data;
 import org.opendaylight.yangtools.concepts.Path;
 
 /**
- * Read-only transaction, which provides stable view of data
- * and is {@link AutoCloseable} resource.
+ * Marker interface for a read-only view of the data tree.
  *
  * @see AsyncReadTransaction
  *
-* @param <P>
+ * @param <P>
  *            Type of path (subtree identifier), which represents location in
  *            tree
  * @param <D>
index e1cd4a712a0d9804ac1846a8e8bf4ad6f23dc8ca..afa86704ff7de0e17c12b3a15f401f9c88f06232 100644 (file)
@@ -9,12 +9,9 @@ package org.opendaylight.controller.md.sal.common.api.data;
 
 import org.opendaylight.yangtools.concepts.Path;
 
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.ListenableFuture;
-
 /**
  *
- * Provides a stateful read view of the data tree.
+ * Marker interface for stateful read view of the data tree.
  *
  * <p>
  * View of the data tree is a stable point-in-time snapshot of the current data tree state when
@@ -47,9 +44,9 @@ import com.google.common.util.concurrent.ListenableFuture;
  * <p>
  * <b>Note:</b> example contains blocking calls on future only to illustrate
  * that action happened after other asynchronous action. Use of blocking call
- * {@link ListenableFuture#get()} is discouraged for most uses and you should
- * use
- * {@link com.google.common.util.concurrent.Futures#addCallback(ListenableFuture, com.google.common.util.concurrent.FutureCallback)}
+ * {@link com.google.common.util.concurrent.ListenableFuture#get()} is discouraged for most
+ * uses and you should use
+ * {@link com.google.common.util.concurrent.Futures#addCallback(com.google.common.util.concurrent.ListenableFuture, com.google.common.util.concurrent.FutureCallback)}
  * or other functions from {@link com.google.common.util.concurrent.Futures} to
  * register more specific listeners.
  *
@@ -58,30 +55,10 @@ import com.google.common.util.concurrent.ListenableFuture;
  *            tree
  * @param <D>
  *            Type of data (payload), which represents data payload
+ *
+ * @see org.opendaylight.controller.md.sal.binding.api.ReadTransaction
+ * @see org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction
  */
 public interface AsyncReadTransaction<P extends Path<P>, D> extends AsyncTransaction<P, D> {
 
-    /**
-     *
-     * Reads data from provided logical data store located at the provided path.
-     *<p>
-     * If the target is a subtree, then the whole subtree is read (and will be
-     * accessible from the returned data object).
-     *
-     * @param store
-     *            Logical data store from which read should occur.
-     * @param path
-     *            Path which uniquely identifies subtree which client want to
-     *            read
-     * @return Listenable Future which contains read result
-     *         <ul>
-     *         <li>If data at supplied path exists the
-     *         {@link ListeblaFuture#get()} returns Optional object containing
-     *         data once read is done.
-     *         <li>If data at supplied path does not exists the
-     *         {@link ListenbleFuture#get()} returns {@link Optional#absent()}.
-     *         </ul>
-     */
-    ListenableFuture<Optional<D>> read(LogicalDatastoreType store, P path);
-
 }
index f7eae27320107ef6a90696ff73f2cf40b3c99fde..e47b54a0a1e6e138292530994a57b539501fc1bb 100644 (file)
@@ -11,6 +11,7 @@ import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.yangtools.concepts.Path;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
+import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.ListenableFuture;
 
 /**
@@ -26,15 +27,57 @@ import com.google.common.util.concurrent.ListenableFuture;
  * change for the data tree and it is not visible to any other concurrently running
  * transaction.
  * <p>
- * Applications publish the changes proposed in the transaction by calling {@link #commit}
- * on the transaction. This seals the transaction
+ * Applications make changes to the local data tree in the transaction by via the
+ * <b>put</b>, <b>merge</b>, and <b>delete</b> operations.
+ *
+ * <h2>Put operation</h2>
+ * Stores a piece of data at a specified path. This acts as an add / replace
+ * operation, which is to say that whole subtree will be replaced by the
+ * specified data.
+ * <p>
+ * Performing the following put operations:
+ *
+ * <pre>
+ * 1) container { list [ a ] }
+ * 2) container { list [ b ] }
+ * </pre>
+ *
+ * will result in the following data being present:
+ *
+ * <pre>
+ * container { list [ b ] }
+ * </pre>
+ * <h2>Merge operation</h2>
+ * Merges a piece of data with the existing data at a specified path. Any pre-existing data
+ * which is not explicitly overwritten will be preserved. This means that if you store a container,
+ * its child lists will be merged.
+ * <p>
+ * Performing the following merge operations:
+ *
+ * <pre>
+ * 1) container { list [ a ] }
+ * 2) container { list [ b ] }
+ * </pre>
+ *
+ * will result in the following data being present:
+ *
+ * <pre>
+ * container { list [ a, b ] }
+ * </pre>
+ *
+ * This also means that storing the container will preserve any
+ * augmentations which have been attached to it.
+ *
+ * <h2>Delete operation</h2>
+ * Removes a piece of data from a specified path.
+ * <p>
+ * After applying changes to the local data tree, applications publish the changes proposed in the
+ * transaction by calling {@link #submit} on the transaction. This seals the transaction
  * (preventing any further writes using this transaction) and submits it to be
  * processed and applied to global conceptual data tree.
  * <p>
  * The transaction commit may fail due to a concurrent transaction modifying and committing data in
- * an incompatible way. See {@link #commit()} for more concrete commit failure examples.
- *
- *
+ * an incompatible way. See {@link #submit} for more concrete commit failure examples.
  * <p>
  * <b>Implementation Note:</b> This interface is not intended to be implemented
  * by users of MD-SAL, but only to be consumed by them.
@@ -56,7 +99,7 @@ public interface AsyncWriteTransaction<P extends Path<P>, D> extends AsyncTransa
      * {@link TransactionStatus#CANCELED} will have no effect, and transaction
      * is considered cancelled.
      *
-     * Invoking cancel() on finished transaction  (future returned by {@link #commit()}
+     * Invoking cancel() on finished transaction  (future returned by {@link #submit()}
      * already completed with {@link TransactionStatus#COMMITED}) will always
      * fail (return false).
      *
@@ -65,77 +108,10 @@ public interface AsyncWriteTransaction<P extends Path<P>, D> extends AsyncTransa
      * <tt>true</tt> otherwise
      *
      */
-    public boolean cancel();
-
-    /**
-     * Store a piece of data at specified path. This acts as an add / replace
-     * operation, which is to say that whole subtree will be replaced by
-     * specified path. Performing the following put operations:
-     *
-     * <pre>
-     * 1) container { list [ a ] }
-     * 2) container { list [ b ] }
-     * </pre>
-     *
-     * will result in the following data being present:
-     *
-     * <pre>
-     * container { list [ b ] }
-     * </pre>
-     *
-     *
-     * If you need to make sure that a parent object exists, but you do not want modify
-     * its preexisting state by using put, consider using
-     * {@link #merge(LogicalDatastoreType, Path, Object)}
-     *
-     * @param store
-     *            Logical data store which should be modified
-     * @param path
-     *            Data object path
-     * @param data
-     *            Data object to be written to specified path
-     * @throws IllegalStateException
-     *             if the transaction is no longer {@link TransactionStatus#NEW}
-     */
-    public void put(LogicalDatastoreType store, P path, D data);
-
-    /**
-     * Store a piece of data at the specified path. This acts as a merge operation,
-     * which is to say that any pre-existing data which is not explicitly
-     * overwritten will be preserved. This means that if you store a container,
-     * its child lists will be merged. Performing the following merge
-     * operations:
-     *
-     * <pre>
-     * 1) container { list [ a ] }
-     * 2) container { list [ b ] }
-     * </pre>
-     *
-     * will result in the following data being present:
-     *
-     * <pre>
-     * container { list [ a, b ] }
-     * </pre>
-     *
-     * This also means that storing the container will preserve any
-     * augmentations which have been attached to it.
-     *<p>
-     * If you require an explicit replace operation, use
-     * {@link #put(LogicalDatastoreType, Path, Object)} instead.
-     *
-     * @param store
-     *            Logical data store which should be modified
-     * @param path
-     *            Data object path
-     * @param data
-     *            Data object to be written to specified path
-     * @throws IllegalStateException
-     *             if the transaction is no longer {@link TransactionStatus#NEW}
-     */
-    public void merge(LogicalDatastoreType store, P path, D data);
+    boolean cancel();
 
     /**
-     * Remove a piece of data from specified path. This operation does not fail
+     * Removes a piece of data from specified path. This operation does not fail
      * if the specified path does not exist.
      *
      * @param store
@@ -145,10 +121,14 @@ public interface AsyncWriteTransaction<P extends Path<P>, D> extends AsyncTransa
      * @throws IllegalStateException
      *             if the transaction is no longer {@link TransactionStatus#NEW}
      */
-    public void delete(LogicalDatastoreType store, P path);
+    void delete(LogicalDatastoreType store, P path);
 
     /**
-     * Submits transaction to be applied to update logical data tree.
+     * Submits this transaction to be asynchronously applied to update the logical data tree.
+     * The returned CheckedFuture conveys the result of applying the data changes.
+     * <p>
+     * <b>Note:</b> It is strongly recommended to process the CheckedFuture result in an asynchronous
+     * manner rather than using the blocking get() method. See example usage below.
      * <p>
      * This call logically seals the transaction, which prevents the client from
      * further changing data tree using this transaction. Any subsequent calls to
@@ -158,31 +138,65 @@ public interface AsyncWriteTransaction<P extends Path<P>, D> extends AsyncTransa
      * {@link IllegalStateException}.
      *
      * The transaction is marked as {@link TransactionStatus#SUBMITED} and
-     * enqueued into the data store backed for processing.
+     * enqueued into the data store back-end for processing.
      *
      * <p>
      * Whether or not the commit is successful is determined by versioning
-     * of data tree and validation of registered commit participants
-     * {@link AsyncConfigurationCommitHandler}
-     * if transaction changes {@link LogicalDatastoreType#CONFIGURATION} data tree.
-     *<p>
-     * The effects of successful commit of data depends on
-     * other data change listeners {@link AsyncDataChangeListener} and
-     * {@link AsyncConfigurationCommitHandler}, which was registered to the
-     * same {@link AsyncDataBroker}, to which this transaction belongs.
-     *
+     * of the data tree and validation of registered commit participants
+     * ({@link AsyncConfigurationCommitHandler})
+     * if the transaction changes the data tree.
+     * <p>
+     * The effects of a successful commit of data depends on data change listeners
+     * ({@link AsyncDataChangeListener}) and commit participants
+     * ({@link AsyncConfigurationCommitHandler}) that are registered with the data broker.
+     * <p>
+     * <h3>Example usage:</h3>
+     * <pre>
+     *  private void doWrite( final int tries ) {
+     *      WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
+     *
+     *      MyDataObject data = ...;
+     *      InstanceIdentifier<MyDataObject> path = ...;
+     *      writeTx.put( LogicalDatastoreType.OPERATIONAL, path, data );
+     *
+     *      Futures.addCallback( writeTx.submit(), new FutureCallback<Void>() {
+     *          public void onSuccess( Void result ) {
+     *              // succeeded
+     *          }
+     *
+     *          public void onFailure( Throwable t ) {
+     *              if( t instanceof OptimisticLockFailedException ) {
+     *                  if( ( tries - 1 ) > 0 ) {
+     *                      // do retry
+     *                      doWrite( tries - 1 );
+     *                  } else {
+     *                      // out of retries
+     *                  }
+     *              } else {
+     *                  // failed due to another type of TransactionCommitFailedException.
+     *              }
+     *          } );
+     * }
+     * ...
+     * doWrite( 2 );
+     * </pre>
      * <h2>Failure scenarios</h2>
      * <p>
      * Transaction may fail because of multiple reasons, such as
      * <ul>
-     * <li>Another transaction finished earlier and modified the same node in
-     * non-compatible way (see below). In this case the returned future will fail with
+     * <li>Another transaction finished earlier and modified the same node in a
+     * non-compatible way (see below). In this case the returned future will fail with an
      * {@link OptimisticLockFailedException}. It is the responsibility of the
      * caller to create a new transaction and submit the same modification again in
-     * order to update data tree.</li>
+     * order to update data tree. <i><b>Warning</b>: In most cases, retrying after an
+     * OptimisticLockFailedException will result in a high probability of success.
+     * However, there are scenarios, albeit unusual, where any number of retries will
+     * not succeed. Therefore it is strongly recommended to limit the number of retries (2 or 3)
+     * to avoid an endless loop.</i>
+     * </li>
      * <li>Data change introduced by this transaction did not pass validation by
      * commit handlers or data was incorrectly structured. Returned future will
-     * fail with {@link DataValidationFailedException}. User should not retry to
+     * fail with {@link DataValidationFailedException}. User should not retry to
      * create new transaction with same data, since it probably will fail again.
      * </li>
      * </ul>
@@ -273,8 +287,8 @@ public interface AsyncWriteTransaction<P extends Path<P>, D> extends AsyncTransa
      * txA.put(CONFIGURATION, PATH, A);    // writes to PATH value A
      * txB.put(CONFIGURATION, PATH, B)     // writes to PATH value B
      *
-     * ListenableFuture futureA = txA.commit(); // transaction A is sealed and committed
-     * ListenebleFuture futureB = txB.commit(); // transaction B is sealed and committed
+     * ListenableFuture futureA = txA.submit(); // transaction A is sealed and submitted
+     * ListenebleFuture futureB = txB.submit(); // transaction B is sealed and submitted
      * </pre>
      *
      * Commit of transaction A will be processed asynchronously and data tree
@@ -288,19 +302,21 @@ public interface AsyncWriteTransaction<P extends Path<P>, D> extends AsyncTransa
      * with {@link OptimisticLockFailedException} exception, which indicates to
      * client that concurrent transaction prevented the submitted transaction from being
      * applied.
-     *
-     * @return Result of the Commit, containing success information or list of
-     *         encountered errors, if commit was not successful. The Future
-     *         blocks until {@link TransactionStatus#COMMITED} is reached.
-     *         Future will fail with {@link TransactionCommitFailedException} if
-     *         Commit of this transaction failed. TODO: Usability: Consider
-     *         change from ListenableFuture to
-     *         {@link com.google.common.util.concurrent.CheckedFuture} which
-     *         will throw {@link TransactionCommitFailedException}.
+     * <br>
+     * @return a CheckFuture containing the result of the commit. The Future blocks until the
+     *         commit operation is complete. A successful commit returns nothing. On failure,
+     *         the Future will fail with a {@link TransactionCommitFailedException} or an exception
+     *         derived from TransactionCommitFailedException.
      *
      * @throws IllegalStateException
      *             if the transaction is not {@link TransactionStatus#NEW}
      */
-    public ListenableFuture<RpcResult<TransactionStatus>> commit();
+    CheckedFuture<Void,TransactionCommitFailedException> submit();
+
+    /**
+     * @deprecated Use {@link #submit()} instead.
+     */
+    @Deprecated
+    ListenableFuture<RpcResult<TransactionStatus>> commit();
 
 }
index 15d1daa1bbe882393f863e892728490c212f5e71..5e5ea0c1388da6b4ca85718a53fcef43feb8fb31 100644 (file)
@@ -10,6 +10,15 @@ package org.opendaylight.controller.md.sal.common.api.data;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.concepts.Path;
 
+/**
+ *
+ *
+ *
+ * @param <P>
+ * @param <D>
+ * @deprecated Replaced by {@link AsyncDataChangeEvent}
+ */
+@Deprecated
 public interface DataChangeEvent<P extends Path<P>,D> extends DataChange<P, D>, Immutable {
 
     /**
index 669baa8d9e96a6601bfe7cbe49cb99d2ffb00233..21006173f205603d481211db5a733475e50a7ee5 100644 (file)
@@ -10,7 +10,12 @@ package org.opendaylight.controller.md.sal.common.api.data;
 import java.util.EventListener;
 
 import org.opendaylight.yangtools.concepts.Path;
-
+/**
+ *
+ *
+ * @deprecated Replaced by {@link AsyncDataChangeEvent}
+ */
+@Deprecated
 public interface DataChangeListener<P extends Path<P>, D> extends EventListener {
     /**
      * Note that this method may be invoked from a shared thread pool, so
index 0c4c6d179ff84faf955fb6989d8ca900cbb8722e..222dba8eafc8e1be5bec4aab39ede6ca9187685d 100644 (file)
@@ -10,6 +10,11 @@ package org.opendaylight.controller.md.sal.common.api.data;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Path;
 
+/**
+ *
+ * @deprecated Replaced by {@link AsyncDataBroker}
+ */
+@Deprecated
 public interface DataChangePublisher<P extends Path<P>, D, L extends DataChangeListener<P,D>> {
 
     ListenerRegistration<L> registerDataChangeListener(P path, L listener);
index 22e95197bb4c2fb9c3886492cf7635cacf18c7d2..a9f02a8ee5ed13cac55a436311f1b556225703c0 100644 (file)
@@ -79,7 +79,9 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
  *
  * @param <P> Class representing a path
  * @param <D> Superclass from which all data objects are derived from.
+ * @deprecated Replaced by {@link AsyncConfigurationCommitHandler}
  */
+@Deprecated
 public interface DataCommitHandler<P extends Path<P>, D> {
 
 
index 86f1f9b13875ba4015e6bb5dbb111f693ba07b57..dceb3de5bf1af839a72c28ddb14ba0dfa0132a21 100644 (file)
@@ -10,7 +10,17 @@ package org.opendaylight.controller.md.sal.common.api.data;
 import org.opendaylight.yangtools.concepts.Path;
 import org.opendaylight.yangtools.concepts.Registration;
 
-public interface DataCommitHandlerRegistration<P extends Path<P>,D> extends Registration<DataCommitHandler<P, D>>{
+/**
+ *
+ *
+ * @deprecated THis was intended as Registration object, normal use of {@link org.opendaylight.yangtools.concepts.ObjectRegistration}
+ * is suffiecient, since {@link #getPath()} was implementation leak.
+ *
+ * @param <P>
+ * @param <D>
+ */
+@Deprecated
+public interface DataCommitHandlerRegistration<P extends Path<P>,D> extends Registration {
 
     P getPath();
 }
index 22c5fa0c1d25eb4a71e19b2b271a5a777dada2e3..630078dcedea1da1a45a279d3f2ed3e313858a69 100644 (file)
@@ -12,7 +12,11 @@ import java.util.concurrent.Future;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.yangtools.concepts.Path;
 import org.opendaylight.yangtools.yang.common.RpcResult;
-
+/**
+ *
+ * @deprecated Replaced by {@link AsyncWriteTransaction}
+ */
+@Deprecated
 public interface DataModification<P extends Path<P>, D> extends DataChange<P, D>, DataReader<P, D> {
     /**
      * Returns transaction identifier
index 34f6fe970dd2e0105e6a21d32ca7049815ea87e7..6a370b8cd168be3f196b779523e3a8cd8bb03ef9 100644 (file)
@@ -8,7 +8,11 @@
 package org.opendaylight.controller.md.sal.common.api.data;
 
 import org.opendaylight.yangtools.concepts.Path;
-
+/**
+ *
+ * @deprecated Replaced by {@link AsyncDataTransactionFactory}
+ */
+@Deprecated
 public interface DataModificationTransactionFactory<P extends Path<P> ,D> {
 
     DataModification<P, D> beginTransaction();
index dae9a1144b966a2e3c5e61884c1281e09a6229f3..fdeda2800bbd447ac028a028172347e5a30ce043 100644 (file)
@@ -9,6 +9,12 @@ package org.opendaylight.controller.md.sal.common.api.data;
 
 import org.opendaylight.yangtools.concepts.Path;
 
+/**
+ *
+ *
+ * @deprecated Replaced by org.opendaylight.controller.sal.core.spi.data.DOMStore contract.
+ */
+@Deprecated
 public interface DataProvider<P extends Path<P>, D> extends DataReader<P, D> {
 
 }
index da7efebdfeb1f7f02eda505d48a1f83be6a79b89..6c7166eaee01fc9557acf2ef8962a825ef9b12bd 100644 (file)
@@ -12,10 +12,15 @@ import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Path;
 import org.opendaylight.yangtools.concepts.Registration;
 
-
+/**
+ *
+ *
+ * @deprecated replaced by {@link AsyncDataBroker} and {@link AsyncConfigurationCommitCoordinator}
+ */
+@Deprecated
 public interface DataProvisionService<P extends Path<P> , D> {
 
-    public Registration<DataCommitHandler<P, D>> registerCommitHandler(P path, DataCommitHandler<P, D> commitHandler);
+    public Registration registerCommitHandler(P path, DataCommitHandler<P, D> commitHandler);
 
     public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<P, D>>>
         registerCommitHandlerListener(RegistrationListener<DataCommitHandlerRegistration<P, D>> commitHandlerListener);
index 14731d688c964adaf264d8909a4c3e90ccc4484e..2f657b8e5049dc196fbb5a04d3ddcc5f0a5a244a 100644 (file)
@@ -17,7 +17,9 @@ import org.opendaylight.yangtools.concepts.Path;
  *
  * @param <P> Path Type
  * @param <D> Data Type
+ * @deprecated Replaced by org.opendaylight.controller.sal.core.spi.data.DOMStore contract.
  */
+@Deprecated
 public interface DataReader<P extends Path<P> ,D> {
 
     /**
index 3520ba1819b42fb0ce37ae3548631cd80753334b..5688dd0988968b52a2957cd9998b0f98c8995e4a 100644 (file)
@@ -9,6 +9,11 @@ package org.opendaylight.controller.md.sal.common.api.data;
 
 import org.opendaylight.yangtools.concepts.Path;
 
+/**
+ *
+ * @deprecated Replaced by org.opendaylight.controller.sal.core.spi.data.DOMStore Contract.
+ */
+@Deprecated
 public interface DataStore<P extends Path<P>, D> extends //
         DataReader<P, D>, //
         DataModificationTransactionFactory<P, D> {
index c59c12ec5c3c59314d94094d421ab45c96deb4cb..d48bfc79fe8941935bbfa2b762d254d93f1da2d0 100644 (file)
@@ -8,6 +8,8 @@
 package org.opendaylight.controller.md.sal.common.api.data;
 
 import org.opendaylight.yangtools.concepts.Path;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 
 import com.google.common.base.Preconditions;
 
@@ -31,14 +33,17 @@ public class DataValidationFailedException extends TransactionCommitFailedExcept
 
     private Class<? extends Path<?>> pathType;
 
-    public <P extends Path<P>> DataValidationFailedException(final Class<P> pathType,final P path, final String message, final Throwable cause) {
-        super(message, cause);
+    public <P extends Path<P>> DataValidationFailedException(final Class<P> pathType,final P path,
+                                                             final String message, final Throwable cause) {
+        super(message, cause, RpcResultBuilder.newError(ErrorType.APPLICATION, "invalid-value", message, null,
+                                                        path != null ? path.toString() : null, cause));
         this.pathType = Preconditions.checkNotNull(pathType, "path type must not be null");
         this.path = Preconditions.checkNotNull(path,"path must not be null.");
     }
 
-    public  <P extends Path<P>> DataValidationFailedException(final Class<P> pathType,final P path,final String message) {
-        this(pathType,path,message,null);
+    public  <P extends Path<P>> DataValidationFailedException(final Class<P> pathType,final P path,
+                                                              final String message) {
+        this(pathType, path, message, null);
     }
 
     public final Path<?> getPath() {
index 222289ab6cb967396478a67869dbb11cf6689903..5ddec6b1edfcec9c76425d8587bc989abf3d897f 100644 (file)
@@ -1,5 +1,8 @@
 package org.opendaylight.controller.md.sal.common.api.data;
 
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+
 /**
 *
 * Failure of asynchronous transaction commit caused by failure
@@ -18,17 +21,13 @@ public class OptimisticLockFailedException extends TransactionCommitFailedExcept
 
     private static final long serialVersionUID = 1L;
 
-    protected OptimisticLockFailedException(final String message, final Throwable cause, final boolean enableSuppression,
-            final boolean writableStackTrace) {
-        super(message, cause, enableSuppression, writableStackTrace);
-    }
-
     public OptimisticLockFailedException(final String message, final Throwable cause) {
-        super(message, cause);
+        super(message, cause, RpcResultBuilder.newError(ErrorType.APPLICATION, "resource-denied",
+                                                        message, null, null, cause));
     }
 
     public OptimisticLockFailedException(final String message) {
-        super(message);
+        this(message, null);
     }
 
 }
index f3c2e1093cfbdacea1b2019f5df64f64ac54aeb9..18a857e1d5c4bd0816674a6af99070c2a9dc1e76 100644 (file)
@@ -7,6 +7,15 @@
  */
 package org.opendaylight.controller.md.sal.common.api.data;
 
+import java.util.Arrays;
+import java.util.List;
+
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+
+import com.google.common.collect.ImmutableList;
+
 /**
  *
  * Failed commit of asynchronous transaction
@@ -17,18 +26,39 @@ package org.opendaylight.controller.md.sal.common.api.data;
  */
 public class TransactionCommitFailedException extends Exception {
 
-    private static final long serialVersionUID = -6138306275373237068L;
+    private static final long serialVersionUID = 1L;
 
-    protected TransactionCommitFailedException(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) {
-        super(message, cause, enableSuppression, writableStackTrace);
+    private final List<RpcError> errorList;
+
+    public TransactionCommitFailedException(final String message, final RpcError... errors) {
+        this(message, null, errors);
     }
 
-    public TransactionCommitFailedException(final String message, final Throwable cause) {
+    public TransactionCommitFailedException(final String message, final Throwable cause,
+                                            final RpcError... errors) {
         super(message, cause);
+
+        if( errors != null && errors.length > 0 ) {
+            errorList = ImmutableList.<RpcError>builder().addAll( Arrays.asList( errors ) ).build();
+        }
+        else {
+            // Add a default RpcError.
+            errorList = ImmutableList.of(RpcResultBuilder.newError(ErrorType.APPLICATION, null,
+                    getMessage(), null, null, getCause()));
+        }
     }
 
-    public TransactionCommitFailedException(final String message) {
-        super(message);
+    /**
+     * Returns additional error information about this exception.
+     *
+     * @return a List of RpcErrors. There is always at least one RpcError.
+     */
+    public List<RpcError> getErrorList() {
+        return errorList;
     }
 
+    @Override
+    public String getMessage() {
+        return new StringBuilder( super.getMessage() ).append(", errors: ").append( errorList ).toString();
+    }
 }
index f5f03a106b36119b188ca489924d514f88b12f00..bb866f276e713151ccf18b0e57e589c65633647f 100644 (file)
@@ -9,9 +9,63 @@ package org.opendaylight.controller.md.sal.common.api.notify;
 
 import java.util.concurrent.ExecutorService;
 
+/**
+ * Interface for publishing YANG-modeled notifications.
+ * <p>
+ * Users of this interface can publish any YANG-modeled notification which will
+ * be delivered to all subscribed listeners.
+ * <p>
+ * Prefered way of publishing of notifications is done by invoking {@link #publish(Object)}.
+ *
+ * <p>You may consider using {@link #publish(Object, ExecutorService)} if and only if
+ * your use-case requires customized  execution policy or run-to-completion
+ * inside process.
+ *
+ * <p>
+ * The metadata required to deliver a notification to the correct listeners is
+ * extracted from the published notification.
+ *
+ *
+ * FIXME: Consider clarification of execution/delivery policy, how it will be
+ * affected by Actor model and cluster-wide notifications.
+ *
+ * @param <N>
+ *            the type of notifications
+ */
 public interface NotificationPublishService<N> {
 
+    /**
+     * Publishes a notification and notifies subscribed listeners. All listener
+     * notifications are done via a default executor.
+     * <p>
+     * <b>Note:</b> This call will block when the default executor is saturated
+     * and the notification queue for this executor is full.
+     *
+     * @param notification
+     *            the notification to publish.
+     */
     void publish(N notification);
 
-    void publish(N notification,ExecutorService executor);
+    /**
+     * Publishes a notification and notifies subscribed listeners. All listener
+     * notifications are done via the provided executor.
+     * <p>
+     * <b>Note:</b> Use only if ineccessary. Consider using
+     * {@link #publish(Object)} for most use-cases.
+     *
+     * <p>
+     * By using this method you could customize execution policy of listeners present
+     * inside process (e.g. using  single-threaded executor or even same-thread executor
+     * delivery.
+     *
+     * <p>
+     * This executor is used only for inside-process notification deliveries.
+     *
+     * @param notification
+     *            the notification to publish.
+     * @param executor
+     *            the executor that will be used to deliver notifications to
+     *            subscribed listeners.
+     */
+    void publish(N notification, ExecutorService executor);
 }
index bfca8f8bccf316d956dd8d621e0e868adf19b8f9..feccbbad92f694fb070af73c355376acbf26e928 100644 (file)
@@ -7,9 +7,11 @@
  */
 package org.opendaylight.controller.md.sal.common.api.notify;
 
-import org.opendaylight.yangtools.concepts.Registration;
+import java.util.EventListener;
 
-public interface NotificationSubscriptionService<T,N,L> {
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 
-    Registration<L> registerNotificationListener(T type,L listener);
+public interface NotificationSubscriptionService<T,N,L extends EventListener> {
+
+    ListenerRegistration<L> registerNotificationListener(T type,L listener);
 }
index 5f84ec579d7dd25bdc9580f785aca6d300c35a0a..0c04b936b668847d6914cefe522190751f10f733 100644 (file)
@@ -9,9 +9,36 @@ package org.opendaylight.controller.md.sal.common.api.routing;
 
 import java.util.Map;
 import java.util.Set;
-
+/**
+ * Event representing change in RPC routing table.
+ *
+ *
+ * @param <C> Type, which is used to represent Routing context.
+ * @param <P> Type of data tree path, which is used to identify route.
+ */
 public interface RouteChange<C,P> {
 
+    /**
+     *
+     * Returns a map of removed routes in associated routing contexts.
+     * <p>
+     * This map represents routes, which were withdrawn from broker local
+     * routing table and broker may need to forward RPC to other broker
+     * in order to process RPC request.
+     *
+     * @return Map of contexts and removed routes
+     */
     Map<C,Set<P>> getRemovals();
+    /**
+    *
+    * Returns a map of announced routes in associated routing contexts.
+    *
+    * This map represents routes, which were announced by broker
+    * and are present in broker's local routing table. This routes
+    * are processed by implementations which are registered
+    * to originating broker.
+    *
+    * @return Map of contexts and announced routes
+    */
     Map<C,Set<P>> getAnnouncements();
 }
index 62206013f816fea5a85885e1f5696d6b93603a4f..b3b6fe6ee93ba44a30abaf32028044c7c89d006f 100644 (file)
@@ -8,8 +8,23 @@
 package org.opendaylight.controller.md.sal.common.api.routing;
 
 import java.util.EventListener;
-
+/**
+ *
+ * Listener which is interested in receiving RouteChangeEvents
+ * for its local broker.
+ * <p>
+ * Listener is registerd via {@link RouteChangePublisher#registerRouteChangeListener(RouteChangeListener)}
+ *
+ *
+ * @param <C> Type, which is used to represent Routing context.
+ * @param <P> Type of data tree path, which is used to identify route.
+ */
 public interface RouteChangeListener<C,P> extends EventListener {
 
+    /**
+     * Callback which is invoked if there is an rpc routing table change.
+     *
+     * @param change Event representing change in local RPC routing table.
+     */
     void onRouteChange(RouteChange<C, P> change);
 }
index 7bf61fab0b726cd9ebc4f3fdcac428c447f74b26..dc6b6dd3b7d89c3d23a3ed6bf7e2157bd49bbc4c 100644 (file)
@@ -9,6 +9,12 @@ package org.opendaylight.controller.md.sal.common.api.routing;
 
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 
+/**
+ * Publishes changes in local RPC routing table to registered listener.
+ *
+ * @param <C> Type, which is used to represent Routing context.
+ * @param <P> Type of data tree path, which is used to identify route.
+ */
 public interface RouteChangePublisher<C,P> {
 
     <L extends RouteChangeListener<C,P>> ListenerRegistration<L> registerRouteChangeListener(L listener);
index 6ce7b5a5c7f990360ff1d5cb3d01e63989fc42da..7b1cdeae9f7dbc707b6b4aafe60cb02a773c7ca3 100644 (file)
@@ -10,9 +10,31 @@ package org.opendaylight.controller.md.sal.common.api.routing;
 import org.opendaylight.yangtools.concepts.Path;
 import org.opendaylight.yangtools.concepts.Registration;
 
-public interface RoutedRegistration<C, P extends Path<P>, S> extends Registration<S> {
+/**
+ * Base interface for a routed RPC RPC implementation registration.
+ *
+ * @param <C> the context type used for routing
+ * @param <P> the path identifier type
+ * @param <S> the RPC implementation type
+ */
+public interface RoutedRegistration<C, P extends Path<P>, S> extends Registration {
 
+    /**
+     * Registers the RPC implementation associated with this registration for the given path
+     * identifier and context.
+     *
+     * @param context the context used for routing RPCs to this implementation.
+     * @param path the path identifier for which to register.
+     */
     void registerPath(C context, P path);
+
+    /**
+     * Unregisters the RPC implementation associated with this registration for the given path
+     * identifier and context.
+     *
+     * @param context the context used for routing RPCs to this implementation.
+     * @param path the path identifier for which to unregister.
+     */
     void unregisterPath(C context, P path);
 
     @Override
index ee9af6cb80d91ccc4083a61e3e6a01604769a757..5dfb55ebd939615a10c6b0b0ceb4c4a6758c0940 100644 (file)
@@ -97,13 +97,13 @@ public abstract class AbstractDataReadRouter<P extends Path<P>, D> implements Da
      * @param reader Reader instance which is responsible for reading particular subpath.
      * @return
      */
-    public Registration<DataReader<P, D>> registerOperationalReader(P path, DataReader<P, D> reader) {
+    public Registration registerOperationalReader(P path, DataReader<P, D> reader) {
         OperationalDataReaderRegistration<P, D> ret = new OperationalDataReaderRegistration<>(path, reader);
         operationalReaders.put(path, ret);
         return ret;
     }
 
-    public Registration<DataReader<P, D>> registerConfigurationReader(P path, DataReader<P, D> reader) {
+    public Registration registerConfigurationReader(P path, DataReader<P, D> reader) {
         ConfigurationDataReaderRegistration<P, D> ret = new ConfigurationDataReaderRegistration<>(path, reader);
         configReaders.put(path, ret);
         return ret;
index d8bde3d41a623178e1e202b6ba1bc67aa7b49525..a732f2f1b96b72ee72a6987e2f2b94651656bf09 100644 (file)
@@ -230,7 +230,7 @@ public abstract class AbstractDataBroker<P extends Path<P>, D extends Object, DC
     }
 
     @Override
-    public final Registration<DataCommitHandler<P, D>> registerCommitHandler(final P path,
+    public final Registration registerCommitHandler(final P path,
             final DataCommitHandler<P, D> commitHandler) {
         synchronized (commitHandler) {
             final DataCommitHandlerRegistrationImpl<P, D> registration = new DataCommitHandlerRegistrationImpl<P, D>(
@@ -266,8 +266,8 @@ public abstract class AbstractDataBroker<P extends Path<P>, D extends Object, DC
     public final CompositeObjectRegistration<DataReader<P, D>> registerDataReader(final P path,
             final DataReader<P, D> reader) {
 
-        final Registration<DataReader<P, D>> confReg = getDataReadRouter().registerConfigurationReader(path, reader);
-        final Registration<DataReader<P, D>> dataReg = getDataReadRouter().registerOperationalReader(path, reader);
+        final Registration confReg = getDataReadRouter().registerConfigurationReader(path, reader);
+        final Registration dataReg = getDataReadRouter().registerOperationalReader(path, reader);
         return new CompositeObjectRegistration<DataReader<P, D>>(reader, Arrays.asList(confReg, dataReg));
     }
 
index b030e6cb5f84b8da49d1780ab51ec2e7ab425ede..d544c4b3710b06a12dac1bba3b11b5e13ced4f89 100644 (file)
@@ -11,13 +11,19 @@ import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.md.sal.common.impl.AbstractDataModification;
 import org.opendaylight.yangtools.concepts.Path;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
 
 public abstract class AbstractDataTransaction<P extends Path<P>, D extends Object> extends
         AbstractDataModification<P, D> {
@@ -83,18 +89,23 @@ public abstract class AbstractDataTransaction<P extends Path<P>, D extends Objec
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj)
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
+        }
         AbstractDataTransaction<?, ?> other = (AbstractDataTransaction<?, ?>) obj;
         if (identifier == null) {
-            if (other.identifier != null)
+            if (other.identifier != null) {
                 return false;
-        } else if (!identifier.equals(other.identifier))
+            }
+        } else if (!identifier.equals(other.identifier)) {
             return false;
+        }
         return true;
     }
 
@@ -122,4 +133,15 @@ public abstract class AbstractDataTransaction<P extends Path<P>, D extends Objec
         this.status = status;
         this.onStatusChange(status);
     }
+
+    public static ListenableFuture<RpcResult<TransactionStatus>> convertToLegacyCommitFuture(
+                                        CheckedFuture<Void,TransactionCommitFailedException> from ) {
+        return Futures.transform(from, new AsyncFunction<Void, RpcResult<TransactionStatus>>() {
+            @Override
+            public ListenableFuture<RpcResult<TransactionStatus>> apply(Void input) throws Exception {
+                return Futures.immediateFuture(RpcResultBuilder.<TransactionStatus>
+                                                              success(TransactionStatus.COMMITED).build());
+            }
+        } );
+    }
 }
index a51dc64816d0822778ff1b690bd10fdd19268afa..007122e41df26eaf6c3c9e803e2d3f75abcf8deb 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.md.sal.common.impl.service;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -21,10 +20,9 @@ import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
 import org.opendaylight.controller.md.sal.common.api.data.DataChangeListener;
 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.sal.common.util.Rpcs;
 import org.opendaylight.yangtools.concepts.Path;
-import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -68,8 +66,7 @@ public class TwoPhaseCommit<P extends Path<P>, D extends Object, DCL extends Dat
 
             log.trace("Transaction: {} Finished successfully (no effects).", transactionId);
 
-            return Rpcs.<TransactionStatus> getRpcResult(true, TransactionStatus.COMMITED,
-                    Collections.<RpcError> emptySet());
+            return RpcResultBuilder.<TransactionStatus> success( TransactionStatus.COMMITED ).build();
         }
 
         final ImmutableList.Builder<ListenerStateCapture<P, D, DCL>> listenersBuilder = ImmutableList.builder();
@@ -127,8 +124,7 @@ public class TwoPhaseCommit<P extends Path<P>, D extends Object, DCL extends Dat
         log.trace("Transaction: {} Notifying listeners.", transactionId);
 
         publishDataChangeEvent(listeners);
-        return Rpcs.<TransactionStatus> getRpcResult(true, TransactionStatus.COMMITED,
-                Collections.<RpcError> emptySet());
+        return RpcResultBuilder.<TransactionStatus> success(TransactionStatus.COMMITED).build();
     }
 
     private void captureInitialState(ImmutableList<ListenerStateCapture<P, D, DCL>> listeners) {
@@ -240,7 +236,6 @@ public class TwoPhaseCommit<P extends Path<P>, D extends Object, DCL extends Dat
         for (final DataCommitTransaction<P, D> transaction : transactions) {
             transaction.rollback();
         }
-        Set<RpcError> _emptySet = Collections.<RpcError> emptySet();
-        return Rpcs.<TransactionStatus> getRpcResult(false, TransactionStatus.FAILED, _emptySet);
+        return RpcResultBuilder.<TransactionStatus> failed().withResult(TransactionStatus.FAILED).build();
     }
 }
index 7ce475dd59ea1a056ac8d5a85d751a33f6d9a17f..b8dfca1604eb9e1ca82454f60f508abfffe01694 100644 (file)
@@ -10,10 +10,6 @@ package org.opendaylight.controller.md.sal.common.impl.util.compat;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -21,14 +17,15 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
@@ -50,19 +47,31 @@ 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.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 
 public abstract class DataNormalizationOperation<T extends PathArgument> implements Identifiable<T> {
 
     private final T identifier;
+    private final Optional<DataSchemaNode> dataSchemaNode;
 
     @Override
     public T getIdentifier() {
         return identifier;
     };
 
-    protected DataNormalizationOperation(final T identifier) {
+    protected DataNormalizationOperation(final T identifier, final SchemaNode schema) {
         super();
         this.identifier = identifier;
+        if(schema instanceof DataSchemaNode) {
+            this.dataSchemaNode = Optional.of((DataSchemaNode) schema);
+        } else {
+            this.dataSchemaNode = Optional.absent();
+        }
     }
 
     public boolean isMixin() {
@@ -86,10 +95,15 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
 
     public abstract boolean isLeaf();
 
+    public Optional<DataSchemaNode> getDataSchemaNode() {
+        // FIXME
+        return dataSchemaNode;
+    }
+
     private static abstract class SimpleTypeNormalization<T extends PathArgument> extends DataNormalizationOperation<T> {
 
-        protected SimpleTypeNormalization(final T identifier) {
-            super(identifier);
+        protected SimpleTypeNormalization(final T identifier, final DataSchemaNode potential) {
+            super(identifier,potential);
         }
 
         @Override
@@ -125,8 +139,8 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
 
     private static final class LeafNormalization extends SimpleTypeNormalization<NodeIdentifier> {
 
-        protected LeafNormalization(final NodeIdentifier identifier) {
-            super(identifier);
+        protected LeafNormalization(final LeafSchemaNode potential) {
+            super(new NodeIdentifier(potential.getQName()),potential);
         }
 
         @Override
@@ -139,7 +153,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
     private static final class LeafListEntryNormalization extends SimpleTypeNormalization<NodeWithValue> {
 
         public LeafListEntryNormalization(final LeafListSchemaNode potential) {
-            super(new NodeWithValue(potential.getQName(), null));
+            super(new NodeWithValue(potential.getQName(), null),potential);
         }
 
         @Override
@@ -156,10 +170,10 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
     }
 
     private static abstract class CompositeNodeNormalizationOperation<T extends PathArgument> extends
-            DataNormalizationOperation<T> {
+    DataNormalizationOperation<T> {
 
-        protected CompositeNodeNormalizationOperation(final T identifier) {
-            super(identifier);
+        protected CompositeNodeNormalizationOperation(final T identifier, final DataSchemaNode schema) {
+            super(identifier,schema);
         }
 
         @SuppressWarnings({ "rawtypes", "unchecked" })
@@ -218,14 +232,14 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
     }
 
     private static abstract class DataContainerNormalizationOperation<T extends PathArgument> extends
-            CompositeNodeNormalizationOperation<T> {
+    CompositeNodeNormalizationOperation<T> {
 
         private final DataNodeContainer schema;
         private final Map<QName, DataNormalizationOperation<?>> byQName;
         private final Map<PathArgument, DataNormalizationOperation<?>> byArg;
 
-        protected DataContainerNormalizationOperation(final T identifier, final DataNodeContainer schema) {
-            super(identifier);
+        protected DataContainerNormalizationOperation(final T identifier, final DataNodeContainer schema, final DataSchemaNode node) {
+            super(identifier,node);
             this.schema = schema;
             this.byArg = new ConcurrentHashMap<>();
             this.byQName = new ConcurrentHashMap<>();
@@ -276,12 +290,12 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
     }
 
     private static final class ListItemNormalization extends
-            DataContainerNormalizationOperation<NodeIdentifierWithPredicates> {
+    DataContainerNormalizationOperation<NodeIdentifierWithPredicates> {
 
         private final List<QName> keyDefinition;
 
         protected ListItemNormalization(final NodeIdentifierWithPredicates identifier, final ListSchemaNode schema) {
-            super(identifier, schema);
+            super(identifier, schema,schema);
             keyDefinition = schema.getKeyDefinition();
         }
 
@@ -322,7 +336,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
     private static final class UnkeyedListItemNormalization extends DataContainerNormalizationOperation<NodeIdentifier> {
 
         protected UnkeyedListItemNormalization(final ListSchemaNode schema) {
-            super(new NodeIdentifier(schema.getQName()), schema);
+            super(new NodeIdentifier(schema.getQName()), schema,schema);
         }
 
         @Override
@@ -340,7 +354,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
     private static final class ContainerNormalization extends DataContainerNormalizationOperation<NodeIdentifier> {
 
         protected ContainerNormalization(final ContainerSchemaNode schema) {
-            super(new NodeIdentifier(schema.getQName()), schema);
+            super(new NodeIdentifier(schema.getQName()),schema, schema);
         }
 
         @Override
@@ -356,10 +370,10 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
     }
 
     private static abstract class MixinNormalizationOp<T extends PathArgument> extends
-            CompositeNodeNormalizationOperation<T> {
+    CompositeNodeNormalizationOperation<T> {
 
-        protected MixinNormalizationOp(final T identifier) {
-            super(identifier);
+        protected MixinNormalizationOp(final T identifier, final DataSchemaNode schema) {
+            super(identifier,schema);
         }
 
         @Override
@@ -393,7 +407,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
         private final DataNormalizationOperation<?> innerOp;
 
         public UnorderedLeafListMixinNormalization(final LeafListSchemaNode potential) {
-            super(new NodeIdentifier(potential.getQName()));
+            super(new NodeIdentifier(potential.getQName()),potential);
             innerOp = new LeafListEntryNormalization(potential);
         }
 
@@ -428,7 +442,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
 
         public AugmentationNormalization(final AugmentationSchema augmentation, final DataNodeContainer schema) {
             //super();
-            super(augmentationIdentifierFrom(augmentation), augmentationProxy(augmentation,schema));
+            super(augmentationIdentifierFrom(augmentation), augmentationProxy(augmentation,schema),null);
         }
 
         @Override
@@ -477,7 +491,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
         private final ListItemNormalization innerNode;
 
         public UnorderedMapMixinNormalization(final ListSchemaNode list) {
-            super(new NodeIdentifier(list.getQName()));
+            super(new NodeIdentifier(list.getQName()),list);
             this.innerNode = new ListItemNormalization(new NodeIdentifierWithPredicates(list.getQName(),
                     Collections.<QName, Object> emptyMap()), list);
         }
@@ -517,7 +531,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
         private final UnkeyedListItemNormalization innerNode;
 
         public UnkeyedListMixinNormalization(final ListSchemaNode list) {
-            super(new NodeIdentifier(list.getQName()));
+            super(new NodeIdentifier(list.getQName()),list);
             this.innerNode = new UnkeyedListItemNormalization(list);
         }
 
@@ -575,7 +589,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
         private final ImmutableMap<PathArgument, DataNormalizationOperation<?>> byArg;
 
         protected ChoiceNodeNormalization(final org.opendaylight.yangtools.yang.model.api.ChoiceNode schema) {
-            super(new NodeIdentifier(schema.getQName()));
+            super(new NodeIdentifier(schema.getQName()),schema);
             ImmutableMap.Builder<QName, DataNormalizationOperation<?>> byQNameBuilder = ImmutableMap.builder();
             ImmutableMap.Builder<PathArgument, DataNormalizationOperation<?>> byArgBuilder = ImmutableMap.builder();
 
@@ -615,25 +629,25 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
 
     private static class AnyXmlNormalization extends DataNormalizationOperation<NodeIdentifier> {
 
-        protected AnyXmlNormalization( NodeIdentifier identifier ) {
-            super( identifier );
+        protected AnyXmlNormalization( final AnyXmlSchemaNode schema) {
+            super( new NodeIdentifier(schema.getQName()), schema);
         }
 
         @Override
-        public DataNormalizationOperation<?> getChild( PathArgument child ) throws DataNormalizationException {
+        public DataNormalizationOperation<?> getChild( final PathArgument child ) throws DataNormalizationException {
             return null;
         }
 
         @Override
-        public DataNormalizationOperation<?> getChild( QName child ) throws DataNormalizationException {
+        public DataNormalizationOperation<?> getChild( final QName child ) throws DataNormalizationException {
             return null;
         }
 
         @Override
-        public NormalizedNode<?, ?> normalize( Node<?> legacyData ) {
+        public NormalizedNode<?, ?> normalize( final Node<?> legacyData ) {
             NormalizedNodeAttrBuilder<NodeIdentifier, Node<?>, AnyXmlNode> builder =
                     Builders.anyXmlBuilder().withNodeIdentifier(
-                                                new NodeIdentifier( legacyData.getNodeType() ) );
+                            new NodeIdentifier( legacyData.getNodeType() ) );
             builder.withValue(legacyData);
             return builder.build();
         }
@@ -644,7 +658,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
         }
 
         @Override
-        public NormalizedNode<?, ?> createDefault( PathArgument currentArg ) {
+        public NormalizedNode<?, ?> createDefault( final PathArgument currentArg ) {
             return null;
         }
     }
@@ -694,7 +708,7 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
         for (DataSchemaNode child : augmentation.getChildNodes()) {
             potentialChildren.add(child.getQName());
         }
-        return new AugmentationIdentifier(null, potentialChildren.build());
+        return new AugmentationIdentifier(potentialChildren.build());
     }
 
     private static DataNodeContainer augmentationProxy(final AugmentationSchema augmentation, final DataNodeContainer schema) {
@@ -744,13 +758,13 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
 
             return fromListSchemaNode((ListSchemaNode) potential);
         } else if (potential instanceof LeafSchemaNode) {
-            return new LeafNormalization(new NodeIdentifier(potential.getQName()));
+            return new LeafNormalization((LeafSchemaNode) potential);
         } else if (potential instanceof org.opendaylight.yangtools.yang.model.api.ChoiceNode) {
             return new ChoiceNodeNormalization((org.opendaylight.yangtools.yang.model.api.ChoiceNode) potential);
         } else if (potential instanceof LeafListSchemaNode) {
             return fromLeafListSchemaNode((LeafListSchemaNode) potential);
         } else if (potential instanceof AnyXmlSchemaNode) {
-            return new AnyXmlNormalization( new NodeIdentifier(potential.getQName() ) );
+            return new AnyXmlNormalization( (AnyXmlSchemaNode) potential);
         }
         return null;
     }
index ec8ce6ecd5a96e628d2883ab38f24aaab383095a..3e14d5e4b7682abca507d1cc666bb9d19b09fd01 100644 (file)
@@ -9,20 +9,16 @@ package org.opendaylight.controller.md.sal.common.impl.util.compat;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicates;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
 import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.Map;
+
 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.InstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
@@ -36,6 +32,12 @@ import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
 import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicates;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
 public class DataNormalizer {
 
     private final DataNormalizationOperation<?> operation;
@@ -44,11 +46,11 @@ public class DataNormalizer {
         operation = DataNormalizationOperation.from(ctx);
     }
 
-    public InstanceIdentifier toNormalized(final InstanceIdentifier legacy) {
+    public YangInstanceIdentifier toNormalized(final YangInstanceIdentifier legacy) {
         ImmutableList.Builder<PathArgument> normalizedArgs = ImmutableList.builder();
 
         DataNormalizationOperation<?> currentOp = operation;
-        Iterator<PathArgument> arguments = legacy.getPath().iterator();
+        Iterator<PathArgument> arguments = legacy.getPathArguments().iterator();
 
         try {
             while (arguments.hasNext()) {
@@ -67,21 +69,31 @@ public class DataNormalizer {
             throw new IllegalArgumentException(String.format("Failed to normalize path %s", legacy), e);
         }
 
-        return new InstanceIdentifier(normalizedArgs.build());
+        return YangInstanceIdentifier.create(normalizedArgs.build());
+    }
+
+    public DataNormalizationOperation<?> getOperation(final YangInstanceIdentifier legacy) throws DataNormalizationException {
+        DataNormalizationOperation<?> currentOp = operation;
+        Iterator<PathArgument> arguments = legacy.getPathArguments().iterator();
+
+        while (arguments.hasNext()) {
+            currentOp = currentOp.getChild(arguments.next());
+        }
+        return currentOp;
     }
 
-    public Map.Entry<InstanceIdentifier, NormalizedNode<?, ?>> toNormalized(
-            final Map.Entry<InstanceIdentifier, CompositeNode> legacy) {
+    public Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> toNormalized(
+            final Map.Entry<YangInstanceIdentifier, CompositeNode> legacy) {
         return toNormalized(legacy.getKey(), legacy.getValue());
     }
 
-    public Map.Entry<InstanceIdentifier, NormalizedNode<?, ?>> toNormalized(final InstanceIdentifier legacyPath,
+    public Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> toNormalized(final YangInstanceIdentifier legacyPath,
             final CompositeNode legacyData) {
 
-        InstanceIdentifier normalizedPath = toNormalized(legacyPath);
+        YangInstanceIdentifier normalizedPath = toNormalized(legacyPath);
 
         DataNormalizationOperation<?> currentOp = operation;
-        for (PathArgument arg : normalizedPath.getPath()) {
+        for (PathArgument arg : normalizedPath.getPathArguments()) {
             try {
                 currentOp = currentOp.getChild(arg);
             } catch (DataNormalizationException e) {
@@ -103,39 +115,36 @@ public class DataNormalizer {
 
             if (potentialOp.getIdentifier() instanceof AugmentationIdentifier) {
                 currentOp = potentialOp;
-                ArrayList<PathArgument> reworkedArgs = new ArrayList<>(normalizedPath.getPath());
-                reworkedArgs.add(potentialOp.getIdentifier());
-                normalizedPath = new InstanceIdentifier(reworkedArgs);
+                normalizedPath = normalizedPath.node(potentialOp.getIdentifier());
             }
         }
 
         Preconditions.checkArgument(currentOp != null,
                 "Instance Identifier %s does not reference correct schema Node.", normalizedPath);
-        return new AbstractMap.SimpleEntry<InstanceIdentifier, NormalizedNode<?, ?>>(normalizedPath,
+        return new AbstractMap.SimpleEntry<YangInstanceIdentifier, NormalizedNode<?, ?>>(normalizedPath,
                 currentOp.normalize(legacyData));
     }
 
-    public InstanceIdentifier toLegacy(final InstanceIdentifier normalized) throws DataNormalizationException {
+    public YangInstanceIdentifier toLegacy(final YangInstanceIdentifier normalized) throws DataNormalizationException {
         ImmutableList.Builder<PathArgument> legacyArgs = ImmutableList.builder();
-        PathArgument previous = null;
         DataNormalizationOperation<?> currentOp = operation;
-        for (PathArgument normalizedArg : normalized.getPath()) {
+        for (PathArgument normalizedArg : normalized.getPathArguments()) {
             currentOp = currentOp.getChild(normalizedArg);
-            if(!currentOp.isMixin()) {
+            if (!currentOp.isMixin()) {
                 legacyArgs.add(normalizedArg);
             }
         }
-        return new InstanceIdentifier(legacyArgs.build());
+        return YangInstanceIdentifier.create(legacyArgs.build());
     }
 
-    public CompositeNode toLegacy(final InstanceIdentifier normalizedPath, final NormalizedNode<?, ?> normalizedData) {
+    public CompositeNode toLegacy(final YangInstanceIdentifier normalizedPath, final NormalizedNode<?, ?> normalizedData) {
         // Preconditions.checkArgument(normalizedData instanceof
         // DataContainerNode<?>,"Node object %s, %s should be of type DataContainerNode",normalizedPath,normalizedData);
         if (normalizedData instanceof DataContainerNode<?>) {
             return toLegacyFromDataContainer((DataContainerNode<?>) normalizedData);
         } else if (normalizedData instanceof AnyXmlNode) {
             Node<?> value = ((AnyXmlNode) normalizedData).getValue();
-            return value instanceof CompositeNode ? (CompositeNode)value : null;
+            return value instanceof CompositeNode ? (CompositeNode) value : null;
         }
         return null;
     }
@@ -170,7 +179,7 @@ public class DataNormalizer {
         for (NormalizedNode<?, ?> child : node.getValue()) {
             if (child instanceof MixinNode && child instanceof NormalizedNodeContainer<?, ?, ?>) {
                 builder.addAll(toLegacyNodesFromMixin((NormalizedNodeContainer) child));
-            } else ifchild instanceof UnkeyedListNode) {
+            } else if (child instanceof UnkeyedListNode) {
                 builder.addAll(toLegacyNodesFromUnkeyedList((UnkeyedListNode) child));
             } else {
                 addToBuilder(builder, toLegacy(child));
index ce861f7e7afbb4884fbf9ddbc8979eb0a1a3a64e..1595288608cfdbcd5166ccc8f780c1cb98a8e837 100644 (file)
@@ -14,9 +14,11 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
+
 import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -26,15 +28,16 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+
 import org.junit.Test;
 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.InstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
@@ -68,7 +71,7 @@ public class DataNormalizerTest {
         Class<?> nodeClass;
         Object nodeData; // List for a container, value Object for a leaf
 
-        NormalizedNodeData(PathArgument nodeID, Class<?> nodeClass, Object nodeData) {
+        NormalizedNodeData(final PathArgument nodeID, final Class<?> nodeClass, final Object nodeData) {
             this.nodeID = nodeID;
             this.nodeClass = nodeClass;
             this.nodeData = nodeData;
@@ -78,9 +81,9 @@ public class DataNormalizerTest {
     static class LegacyNodeData {
         QName nodeKey;
         Object nodeData; // List for a CompositeNode, value Object for a
-                         // SimpeNode
+        // SimpeNode
 
-        LegacyNodeData(QName nodeKey, Object nodeData) {
+        LegacyNodeData(final QName nodeKey, final Object nodeData) {
             this.nodeKey = nodeKey;
             this.nodeData = nodeData;
         }
@@ -100,8 +103,8 @@ public class DataNormalizerTest {
     static final QName NAME_QNAME = QName.create(TEST_QNAME, "name");
     static final QName VALUE_QNAME = QName.create(TEST_QNAME, "value");
 
-    static final InstanceIdentifier TEST_PATH = InstanceIdentifier.of(TEST_QNAME);
-    static final InstanceIdentifier OUTER_LIST_PATH = InstanceIdentifier.builder(TEST_PATH).node(OUTER_LIST_QNAME)
+    static final YangInstanceIdentifier TEST_PATH = YangInstanceIdentifier.of(TEST_QNAME);
+    static final YangInstanceIdentifier OUTER_LIST_PATH = YangInstanceIdentifier.builder(TEST_PATH).node(OUTER_LIST_QNAME)
             .build();
     static final QName ONE_QNAME = QName.create(TEST_QNAME, "one");
     static final QName TWO_QNAME = QName.create(TEST_QNAME, "two");
@@ -116,10 +119,10 @@ public class DataNormalizerTest {
 
     static final Short OUTER_LIST_ID = (short) 10;
 
-    static final InstanceIdentifier OUTER_LIST_PATH_LEGACY = InstanceIdentifier.builder(TEST_QNAME)
+    static final YangInstanceIdentifier OUTER_LIST_PATH_LEGACY = YangInstanceIdentifier.builder(TEST_QNAME)
             .nodeWithKey(OUTER_LIST_QNAME, ID_QNAME, OUTER_LIST_ID).build();
 
-    static final InstanceIdentifier LEAF_TWO_PATH_LEGACY = InstanceIdentifier.builder(OUTER_LIST_PATH_LEGACY)
+    static final YangInstanceIdentifier LEAF_TWO_PATH_LEGACY = YangInstanceIdentifier.builder(OUTER_LIST_PATH_LEGACY)
             .node(TWO_QNAME).build();
 
     static final QName ANY_XML_LEAF_QNAME = QName.create(TEST_QNAME, "leaf");;
@@ -138,19 +141,19 @@ public class DataNormalizerTest {
         SchemaContext testCtx = createTestContext();
         DataNormalizer normalizer = new DataNormalizer(testCtx);
 
-        InstanceIdentifier normalizedPath = normalizer.toNormalized(LEAF_TWO_PATH_LEGACY);
+        YangInstanceIdentifier normalizedPath = normalizer.toNormalized(LEAF_TWO_PATH_LEGACY);
 
         verifyNormalizedInstanceIdentifier(normalizedPath, TEST_QNAME, OUTER_LIST_QNAME, new Object[] {
                 OUTER_LIST_QNAME, ID_QNAME, OUTER_LIST_ID }, OUTER_CHOICE_QNAME, TWO_QNAME);
     }
 
-    private void verifyNormalizedInstanceIdentifier(InstanceIdentifier actual, Object... expPath) {
+    private void verifyNormalizedInstanceIdentifier(final YangInstanceIdentifier actual, final Object... expPath) {
 
         assertNotNull("Actual InstanceIdentifier is null", actual);
-        assertEquals("InstanceIdentifier path length", expPath.length, actual.getPath().size());
+        assertEquals("InstanceIdentifier path length", expPath.length, Iterables.size(actual.getPathArguments()));
 
         for (int i = 0; i < expPath.length; i++) {
-            PathArgument actualArg = actual.getPath().get(i);
+            PathArgument actualArg = Iterables.get(actual.getPathArguments(), i);
             if (expPath[i] instanceof Object[]) { // NodeIdentifierWithPredicates
                 Object[] exp = (Object[]) expPath[i];
                 assertEquals("Actual path arg " + (i + 1) + " class", NodeIdentifierWithPredicates.class,
@@ -178,11 +181,11 @@ public class DataNormalizerTest {
 
         DataNormalizer normalizer = new DataNormalizer(createTestContext());
 
-        InstanceIdentifier normalized = InstanceIdentifier.builder().node(TEST_QNAME).node(OUTER_LIST_QNAME)
+        YangInstanceIdentifier normalized = YangInstanceIdentifier.builder().node(TEST_QNAME).node(OUTER_LIST_QNAME)
                 .nodeWithKey(OUTER_LIST_QNAME, ID_QNAME, OUTER_LIST_ID).node(OUTER_CHOICE_QNAME).node(TWO_QNAME)
                 .build();
 
-        InstanceIdentifier legacy = normalizer.toLegacy(normalized);
+        YangInstanceIdentifier legacy = normalizer.toLegacy(normalized);
 
         assertEquals("Legacy InstanceIdentifier", LEAF_TWO_PATH_LEGACY, legacy);
     }
@@ -256,12 +259,12 @@ public class DataNormalizerTest {
                                 expectCompositeNode(INNER_LIST_QNAME, expectSimpleNode(NAME_QNAME, "inner-name1"),
                                         expectSimpleNode(VALUE_QNAME, "inner-value1")),
 
-                                expectCompositeNode(INNER_LIST_QNAME, expectSimpleNode(NAME_QNAME, "inner-name2"),
-                                        expectSimpleNode(VALUE_QNAME, "inner-value2"))),
-                        expectCompositeNode(OUTER_LIST_QNAME, expectSimpleNode(ID_QNAME, outerListID2),
-                                expectSimpleNode(ONE_QNAME, "one")),
-                        expectCompositeNode(UNKEYED_LIST_QNAME, expectSimpleNode(NAME_QNAME, "unkeyed1")),
-                        expectCompositeNode(UNKEYED_LIST_QNAME, expectSimpleNode(NAME_QNAME, "unkeyed2"))));
+                                        expectCompositeNode(INNER_LIST_QNAME, expectSimpleNode(NAME_QNAME, "inner-name2"),
+                                                expectSimpleNode(VALUE_QNAME, "inner-value2"))),
+                                                expectCompositeNode(OUTER_LIST_QNAME, expectSimpleNode(ID_QNAME, outerListID2),
+                                                        expectSimpleNode(ONE_QNAME, "one")),
+                                                        expectCompositeNode(UNKEYED_LIST_QNAME, expectSimpleNode(NAME_QNAME, "unkeyed1")),
+                                                        expectCompositeNode(UNKEYED_LIST_QNAME, expectSimpleNode(NAME_QNAME, "unkeyed2"))));
 
         // Conversion of Mixin type nodes is not supported.
 
@@ -292,7 +295,7 @@ public class DataNormalizerTest {
                 .withNodeIdentifier(new NodeIdentifier(TEST_QNAME)).withChild(testAnyXmlNode).build();
 
         DataNormalizer normalizer = new DataNormalizer(createTestContext());
-        Node<?> legacyNode = normalizer.toLegacy(InstanceIdentifier.builder(TEST_QNAME).build(), testContainerNode);
+        Node<?> legacyNode = normalizer.toLegacy(YangInstanceIdentifier.builder(TEST_QNAME).build(), testContainerNode);
 
         verifyLegacyNode(
                 legacyNode,
@@ -329,7 +332,7 @@ public class DataNormalizerTest {
 
         DataNormalizer normalizer = new DataNormalizer(createTestContext());
 
-        Node<?> legacyNode = normalizer.toLegacy(InstanceIdentifier.builder(TEST_QNAME).build(), testContainerNode);
+        Node<?> legacyNode = normalizer.toLegacy(YangInstanceIdentifier.builder(TEST_QNAME).build(), testContainerNode);
 
         verifyLegacyNode(
                 legacyNode,
@@ -356,7 +359,7 @@ public class DataNormalizerTest {
 
         DataNormalizer normalizer = new DataNormalizer(createTestContext());
 
-        Node<?> legacyNode = normalizer.toLegacy(InstanceIdentifier.builder(TEST_QNAME).build(), testContainerNode);
+        Node<?> legacyNode = normalizer.toLegacy(YangInstanceIdentifier.builder(TEST_QNAME).build(), testContainerNode);
 
         verifyLegacyNode(
                 legacyNode,
@@ -366,12 +369,12 @@ public class DataNormalizerTest {
                                 expectSimpleNode(AUGMENTED_LEAF_QNAME, "augmented-value"))));
     }
 
-    private boolean isOrdered(QName nodeName) {
+    private boolean isOrdered(final QName nodeName) {
         return ORDERED_LEAF_LIST_QNAME.equals(nodeName) || INNER_LIST_QNAME.equals(nodeName);
     }
 
     @SuppressWarnings("unchecked")
-    private void verifyLegacyNode(Node<?> actual, LegacyNodeData expNodeData) {
+    private void verifyLegacyNode(final Node<?> actual, final LegacyNodeData expNodeData) {
 
         assertNotNull("Actual Node is null", actual);
         assertTrue("Expected CompositeNode instance", actual instanceof CompositeNode);
@@ -390,7 +393,7 @@ public class DataNormalizerTest {
 
         Collections.sort(unorderdChildData, new Comparator<LegacyNodeData>() {
             @Override
-            public int compare(LegacyNodeData arg1, LegacyNodeData arg2) {
+            public int compare(final LegacyNodeData arg1, final LegacyNodeData arg2) {
                 if (!(arg1.nodeData instanceof List) && !(arg2.nodeData instanceof List)) {
                     // if neither is a list, just compare them
                     String str1 = arg1.nodeKey.getLocalName() + arg1.nodeData;
@@ -446,7 +449,7 @@ public class DataNormalizerTest {
 
         Collections.sort(unorderedChildNodes, new Comparator<Node<?>>() {
             @Override
-            public int compare(Node<?> n1, Node<?> n2) {
+            public int compare(final Node<?> n1, final Node<?> n2) {
                 if (n1 instanceof SimpleNode && n2 instanceof SimpleNode) {
                     // if they're SimpleNodes just compare their strings
                     String str1 = n1.getKey().getLocalName() + ((SimpleNode<?>)n1).getValue();
@@ -501,7 +504,7 @@ public class DataNormalizerTest {
             assertEquals("Child node QName", expData.nodeKey, actualChild.getKey());
 
             if (expData.nodeData instanceof List) { // List represents a
-                                                    // composite node
+                // composite node
                 verifyLegacyNode(actualChild, expData);
             } else { // else a simple node
                 assertTrue("Expected SimpleNode instance", actualChild instanceof SimpleNode);
@@ -515,11 +518,11 @@ public class DataNormalizerTest {
         }
     }
 
-    private LegacyNodeData expectCompositeNode(QName key, LegacyNodeData... childData) {
+    private LegacyNodeData expectCompositeNode(final QName key, final LegacyNodeData... childData) {
         return new LegacyNodeData(key, Lists.newArrayList(childData));
     }
 
-    private LegacyNodeData expectSimpleNode(QName key, Object value) {
+    private LegacyNodeData expectSimpleNode(final QName key, final Object value) {
         return new LegacyNodeData(key, value);
     }
 
@@ -560,8 +563,8 @@ public class DataNormalizerTest {
             testBuilder.add(unkeyedListBuilder.toInstance());
         }
 
-        Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
-                .toNormalized(new AbstractMap.SimpleEntry<InstanceIdentifier, CompositeNode>(new InstanceIdentifier(
+        Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
+                .toNormalized(new AbstractMap.SimpleEntry<YangInstanceIdentifier, CompositeNode>(YangInstanceIdentifier.create(
                         ImmutableList.<PathArgument> of(new NodeIdentifier(TEST_QNAME))), testBuilder.toInstance()));
 
         verifyNormalizedInstanceIdentifier(normalizedNodeEntry.getKey(), TEST_QNAME);
@@ -583,25 +586,25 @@ public class DataNormalizerTest {
                                                 expectMapEntryNode(INNER_LIST_QNAME, NAME_QNAME, "inner-name3",
                                                         expectLeafNode(NAME_QNAME, "inner-name3"),
                                                         expectLeafNode(VALUE_QNAME, "inner-value3")),
-                                                expectMapEntryNode(INNER_LIST_QNAME, NAME_QNAME, "inner-name2",
-                                                        expectLeafNode(NAME_QNAME, "inner-name2"),
-                                                        expectLeafNode(VALUE_QNAME, "inner-value2")),
-                                                expectMapEntryNode(INNER_LIST_QNAME, NAME_QNAME, "inner-name1",
-                                                        expectLeafNode(NAME_QNAME, "inner-name1"),
-                                                        expectLeafNode(VALUE_QNAME, "inner-value1")))),
-                                expectMapEntryNode(
-                                        OUTER_LIST_QNAME,
-                                        ID_QNAME,
-                                        20,
-                                        expectLeafNode(ID_QNAME, 20),
-                                        expectChoiceNode(OUTER_CHOICE_QNAME, expectLeafNode(TWO_QNAME, "two"),
-                                                expectLeafNode(THREE_QNAME, "three")))),
-                        expectUnkeyedListNode(
-                                UNKEYED_LIST_QNAME,
-                                expectUnkeyedListEntryNode(UNKEYED_LIST_QNAME,
-                                        expectLeafNode(NAME_QNAME, "unkeyed-name1")),
-                                expectUnkeyedListEntryNode(UNKEYED_LIST_QNAME,
-                                        expectLeafNode(NAME_QNAME, "unkeyed-name2")))));
+                                                        expectMapEntryNode(INNER_LIST_QNAME, NAME_QNAME, "inner-name2",
+                                                                expectLeafNode(NAME_QNAME, "inner-name2"),
+                                                                expectLeafNode(VALUE_QNAME, "inner-value2")),
+                                                                expectMapEntryNode(INNER_LIST_QNAME, NAME_QNAME, "inner-name1",
+                                                                        expectLeafNode(NAME_QNAME, "inner-name1"),
+                                                                        expectLeafNode(VALUE_QNAME, "inner-value1")))),
+                                                                        expectMapEntryNode(
+                                                                                OUTER_LIST_QNAME,
+                                                                                ID_QNAME,
+                                                                                20,
+                                                                                expectLeafNode(ID_QNAME, 20),
+                                                                                expectChoiceNode(OUTER_CHOICE_QNAME, expectLeafNode(TWO_QNAME, "two"),
+                                                                                        expectLeafNode(THREE_QNAME, "three")))),
+                                                                                        expectUnkeyedListNode(
+                                                                                                UNKEYED_LIST_QNAME,
+                                                                                                expectUnkeyedListEntryNode(UNKEYED_LIST_QNAME,
+                                                                                                        expectLeafNode(NAME_QNAME, "unkeyed-name1")),
+                                                                                                        expectUnkeyedListEntryNode(UNKEYED_LIST_QNAME,
+                                                                                                                expectLeafNode(NAME_QNAME, "unkeyed-name2")))));
     }
 
     @Test
@@ -624,8 +627,8 @@ public class DataNormalizerTest {
         CompositeNode anyXmlLegacy = anyXmlBuilder.toInstance();
         testBuilder.add(anyXmlLegacy);
 
-        Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
-                .toNormalized(new AbstractMap.SimpleEntry<InstanceIdentifier, CompositeNode>(new InstanceIdentifier(
+        Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
+                .toNormalized(new AbstractMap.SimpleEntry<YangInstanceIdentifier, CompositeNode>(YangInstanceIdentifier.create(
                         ImmutableList.<PathArgument> of(new NodeIdentifier(TEST_QNAME))), testBuilder.toInstance()));
 
         verifyNormalizedInstanceIdentifier(normalizedNodeEntry.getKey(), TEST_QNAME);
@@ -648,8 +651,8 @@ public class DataNormalizerTest {
 
         testBuilder.add(outerContBuilder.toInstance());
 
-        Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
-                .toNormalized(new AbstractMap.SimpleEntry<InstanceIdentifier, CompositeNode>(new InstanceIdentifier(
+        Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
+                .toNormalized(new AbstractMap.SimpleEntry<YangInstanceIdentifier, CompositeNode>(YangInstanceIdentifier.create(
                         ImmutableList.<PathArgument> of(new NodeIdentifier(TEST_QNAME))), testBuilder.toInstance()));
 
         verifyNormalizedInstanceIdentifier(normalizedNodeEntry.getKey(), TEST_QNAME);
@@ -660,8 +663,8 @@ public class DataNormalizerTest {
         verifyNormalizedNode(normalizedNodeEntry.getValue(),
                 expectContainerNode(TEST_QNAME, expectContainerNode(OUTER_CONTAINER_QNAME, expAugmentation)));
 
-        normalizedNodeEntry = normalizer.toNormalized(new AbstractMap.SimpleEntry<InstanceIdentifier, CompositeNode>(
-                new InstanceIdentifier(Lists.newArrayList(new NodeIdentifier(TEST_QNAME), new NodeIdentifier(
+        normalizedNodeEntry = normalizer.toNormalized(new AbstractMap.SimpleEntry<YangInstanceIdentifier, CompositeNode>(
+                YangInstanceIdentifier.create(Lists.newArrayList(new NodeIdentifier(TEST_QNAME), new NodeIdentifier(
                         OUTER_CONTAINER_QNAME))), outerContBuilder.toInstance()));
 
         verifyNormalizedInstanceIdentifier(normalizedNodeEntry.getKey(), TEST_QNAME, OUTER_CONTAINER_QNAME,
@@ -686,8 +689,8 @@ public class DataNormalizerTest {
             testBuilder.addLeaf(ORDERED_LEAF_LIST_QNAME, "ordered-value" + i);
         }
 
-        Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
-                .toNormalized(new AbstractMap.SimpleEntry<InstanceIdentifier, CompositeNode>(new InstanceIdentifier(
+        Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
+                .toNormalized(new AbstractMap.SimpleEntry<YangInstanceIdentifier, CompositeNode>(YangInstanceIdentifier.create(
                         ImmutableList.<PathArgument> of(new NodeIdentifier(TEST_QNAME))), testBuilder.toInstance()));
 
         verifyNormalizedInstanceIdentifier(normalizedNodeEntry.getKey(), TEST_QNAME);
@@ -700,14 +703,14 @@ public class DataNormalizerTest {
                                 expectLeafSetEntryNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value1"),
                                 expectLeafSetEntryNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value2"),
                                 expectLeafSetEntryNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value3")),
-                        expectOrderedLeafSetNode(ORDERED_LEAF_LIST_QNAME,
-                                expectLeafSetEntryNode(ORDERED_LEAF_LIST_QNAME, "ordered-value3"),
-                                expectLeafSetEntryNode(ORDERED_LEAF_LIST_QNAME, "ordered-value2"),
-                                expectLeafSetEntryNode(ORDERED_LEAF_LIST_QNAME, "ordered-value1"))));
+                                expectOrderedLeafSetNode(ORDERED_LEAF_LIST_QNAME,
+                                        expectLeafSetEntryNode(ORDERED_LEAF_LIST_QNAME, "ordered-value3"),
+                                        expectLeafSetEntryNode(ORDERED_LEAF_LIST_QNAME, "ordered-value2"),
+                                        expectLeafSetEntryNode(ORDERED_LEAF_LIST_QNAME, "ordered-value1"))));
     }
 
     @SuppressWarnings("unchecked")
-    private void verifyNormalizedNode(NormalizedNode<?, ?> actual, NormalizedNodeData expNodeData) {
+    private void verifyNormalizedNode(final NormalizedNode<?, ?> actual, final NormalizedNodeData expNodeData) {
 
         Class<?> expNodeClass = expNodeData.nodeClass;
         PathArgument expNodeID = expNodeData.nodeID;
@@ -743,18 +746,18 @@ public class DataNormalizerTest {
                 NormalizedNodeData expChildData = expNodeClass.equals(UnkeyedListNode.class) ? expChildDataList
                         .remove(0) : expChildDataMap.remove(actualChild.getIdentifier());
 
-                assertNotNull(
-                        "Unexpected child node " + actualChild.getClass() + " with identifier "
-                                + actualChild.getIdentifier() + " for parent node " + actual.getClass()
-                                + " with identifier " + actual.getIdentifier(), expChildData);
+                        assertNotNull(
+                                "Unexpected child node " + actualChild.getClass() + " with identifier "
+                                        + actualChild.getIdentifier() + " for parent node " + actual.getClass()
+                                        + " with identifier " + actual.getIdentifier(), expChildData);
 
-                if (orderingMap != null) {
-                    assertEquals("Order index for child node " + actualChild.getIdentifier(),
-                            orderingMap.get(actualChild.getIdentifier()), Integer.valueOf(i));
-                }
+                        if (orderingMap != null) {
+                            assertEquals("Order index for child node " + actualChild.getIdentifier(),
+                                    orderingMap.get(actualChild.getIdentifier()), Integer.valueOf(i));
+                        }
 
-                verifyNormalizedNode(actualChild, expChildData);
-                i++;
+                        verifyNormalizedNode(actualChild, expChildData);
+                        i++;
             }
 
             if (expNodeClass.equals(UnkeyedListNode.class)) {
@@ -771,62 +774,62 @@ public class DataNormalizerTest {
         }
     }
 
-    private NormalizedNodeData expectOrderedLeafSetNode(QName nodeName, NormalizedNodeData... childData) {
+    private NormalizedNodeData expectOrderedLeafSetNode(final QName nodeName, final NormalizedNodeData... childData) {
         return new NormalizedNodeData(new NodeIdentifier(nodeName), OrderedLeafSetNode.class,
                 Lists.newArrayList(childData));
     }
 
-    private NormalizedNodeData expectLeafSetNode(QName nodeName, NormalizedNodeData... childData) {
+    private NormalizedNodeData expectLeafSetNode(final QName nodeName, final NormalizedNodeData... childData) {
         return new NormalizedNodeData(new NodeIdentifier(nodeName), LeafSetNode.class, Lists.newArrayList(childData));
     }
 
-    private NormalizedNodeData expectLeafSetEntryNode(QName nodeName, Object value) {
+    private NormalizedNodeData expectLeafSetEntryNode(final QName nodeName, final Object value) {
         return new NormalizedNodeData(new NodeWithValue(nodeName, value), LeafSetEntryNode.class, value);
     }
 
-    private NormalizedNodeData expectUnkeyedListNode(QName nodeName, NormalizedNodeData... childData) {
+    private NormalizedNodeData expectUnkeyedListNode(final QName nodeName, final NormalizedNodeData... childData) {
         return new NormalizedNodeData(new NodeIdentifier(nodeName), UnkeyedListNode.class,
                 Lists.newArrayList(childData));
     }
 
-    private NormalizedNodeData expectUnkeyedListEntryNode(QName nodeName, NormalizedNodeData... childData) {
+    private NormalizedNodeData expectUnkeyedListEntryNode(final QName nodeName, final NormalizedNodeData... childData) {
         return new NormalizedNodeData(new NodeIdentifier(nodeName), UnkeyedListEntryNode.class,
                 Lists.newArrayList(childData));
     }
 
-    private NormalizedNodeData expectAugmentation(QName augmentedNodeName, NormalizedNodeData... childData) {
+    private NormalizedNodeData expectAugmentation(final QName augmentedNodeName, final NormalizedNodeData... childData) {
         return new NormalizedNodeData(new AugmentationIdentifier(Sets.newHashSet(augmentedNodeName)),
                 AugmentationNode.class, Lists.newArrayList(childData));
     }
 
-    private NormalizedNodeData expectAnyXmlNode(QName nodeName, Object value) {
+    private NormalizedNodeData expectAnyXmlNode(final QName nodeName, final Object value) {
         return new NormalizedNodeData(new NodeIdentifier(nodeName), AnyXmlNode.class, value);
     }
 
-    private NormalizedNodeData expectContainerNode(QName nodeName, NormalizedNodeData... childData) {
+    private NormalizedNodeData expectContainerNode(final QName nodeName, final NormalizedNodeData... childData) {
         return new NormalizedNodeData(new NodeIdentifier(nodeName), ContainerNode.class, Lists.newArrayList(childData));
     }
 
-    private NormalizedNodeData expectChoiceNode(QName nodeName, NormalizedNodeData... childData) {
+    private NormalizedNodeData expectChoiceNode(final QName nodeName, final NormalizedNodeData... childData) {
         return new NormalizedNodeData(new NodeIdentifier(nodeName), ChoiceNode.class, Lists.newArrayList(childData));
     }
 
-    private NormalizedNodeData expectLeafNode(QName nodeName, Object value) {
+    private NormalizedNodeData expectLeafNode(final QName nodeName, final Object value) {
         return new NormalizedNodeData(new NodeIdentifier(nodeName), LeafNode.class, value);
 
     }
 
-    private NormalizedNodeData expectMapEntryNode(QName nodeName, QName key, Object value,
-            NormalizedNodeData... childData) {
+    private NormalizedNodeData expectMapEntryNode(final QName nodeName, final QName key, final Object value,
+            final NormalizedNodeData... childData) {
         return new NormalizedNodeData(new NodeIdentifierWithPredicates(nodeName, key, value), MapEntryNode.class,
                 Lists.newArrayList(childData));
     }
 
-    private NormalizedNodeData expectMapNode(QName key, NormalizedNodeData... childData) {
+    private NormalizedNodeData expectMapNode(final QName key, final NormalizedNodeData... childData) {
         return new NormalizedNodeData(new NodeIdentifier(key), MapNode.class, Lists.newArrayList(childData));
     }
 
-    private NormalizedNodeData expectOrderedMapNode(QName key, NormalizedNodeData... childData) {
+    private NormalizedNodeData expectOrderedMapNode(final QName key, final NormalizedNodeData... childData) {
         return new NormalizedNodeData(new NodeIdentifier(key), OrderedMapNode.class, Lists.newArrayList(childData));
     }
 }
index 1af7ccc79ad2de55b1f26a3b53b11b6b44bfadea..9aacf1e0a8b8123d0c75360b7e9c9c88a73cb827 100644 (file)
@@ -7,13 +7,11 @@
  */
 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.yangtools.concepts.Path;
-import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 
 public class CommitHandlerTransactions {
 
@@ -26,11 +24,11 @@ public class CommitHandlerTransactions {
         }
         @Override
         public RpcResult<Void> rollback() throws IllegalStateException {
-            return Rpcs.<Void>getRpcResult(true, null, Collections.<RpcError>emptyList());
+            return RpcResultBuilder.<Void>success().build();
         }
         @Override
         public RpcResult<Void> finish() throws IllegalStateException {
-            return Rpcs.<Void>getRpcResult(true, null, Collections.<RpcError>emptyList());
+            return RpcResultBuilder.<Void>success().build();
         }
 
         @Override
index 4d41249b4d5600e7932d9b56dd34bbaaf80f8854..cacb167f6f54f962c4f7bb49b39452ed140186e1 100644 (file)
@@ -12,9 +12,9 @@ import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
 
 /**
- * @author mirehak
- *
+ * @deprecated Use {@link org.opendaylight.yangtools.yang.common.RpcResultBuilder}
  */
+@Deprecated
 public class RpcErrors {
 
     /**
index f30394187125153004e9b5c3a1b4d4cb2cc74886..69458b6a6d6e3492ed484c958bd3380e049bff0f 100644 (file)
@@ -16,6 +16,10 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 
 import com.google.common.collect.ImmutableList;
 
+/**
+ * @deprecated Use {@link org.opendaylight.yangtools.yang.common.RpcResultBuilder}
+ */
+@Deprecated
 public class Rpcs {
 
     public static <T> RpcResult<T> getRpcResult(boolean successful) {
diff --git a/opendaylight/md-sal/sal-compability/src/main/java/org/opendaylight/controller/sal/compability/ToSalPropertyClassUtils.java b/opendaylight/md-sal/sal-compability/src/main/java/org/opendaylight/controller/sal/compability/ToSalPropertyClassUtils.java
deleted file mode 100644 (file)
index 3894fbe..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.compability;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
-
-public class ToSalPropertyClassUtils {
-    public static Bandwidth salAdvertisedBandwidthFrom(NodeConnector nodeConnector) {
-        FlowCapableNodeConnector flowCapNodeConn = nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
-        PortFeatures portFeatures = flowCapNodeConn.getAdvertisedFeatures();
-        return new AdvertisedBandwidth(resolveBandwidth(portFeatures));
-    }
-
-    public static Bandwidth salPeerBandwidthFrom(NodeConnector nodeConnector) {
-        FlowCapableNodeConnector flowCapNodeConn = nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
-        PortFeatures portFeatures = flowCapNodeConn.getPeerFeatures();
-        return new PeerBandwidth(resolveBandwidth(portFeatures));
-    }
-
-    public static Bandwidth salSupportedBandwidthFrom(NodeConnector nodeConnector) {
-        FlowCapableNodeConnector flowCapNodeConn = nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
-        PortFeatures portFeatures = flowCapNodeConn.getSupported();
-        return new SupportedBandwidth(resolveBandwidth(portFeatures));
-    }
-
-    public static MacAddress salMacAddressFrom(NodeConnector nodeConnector) {
-        FlowCapableNodeConnector flowCapNodeConn = nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
-        String hwAddress = flowCapNodeConn.getHardwareAddress().getValue();
-        return new MacAddress(bytesFrom(hwAddress));
-    }
-
-
-    public static Name salNameFrom(NodeConnector nodeConnector) {
-        FlowCapableNodeConnector flowCapNodeConn = nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
-        return new Name(flowCapNodeConn.getName());
-    }
-
-
-
-    private static byte[] bytesFrom(String hwAddress) {
-        String[] mac = hwAddress.split(":");
-        byte[] macAddress = new byte[6]; // mac.length == 6 bytes
-        for (int i = 0; i < mac.length; i++) {
-            macAddress[i] = Integer.decode("0x" + mac[i]).byteValue();
-        }
-        return macAddress;
-    }
-
-    private static long resolveBandwidth(PortFeatures portFeatures) {
-        if (portFeatures.is_1tbFd()) {
-            return Bandwidth.BW1Tbps;
-        } else if (portFeatures.is_100gbFd()) {
-            return Bandwidth.BW100Gbps;
-        } else if (portFeatures.is_40gbFd()) {
-            return Bandwidth.BW40Gbps;
-        } else if (portFeatures.is_10gbFd()) {
-            return Bandwidth.BW10Gbps;
-        } else if (portFeatures.is_1gbHd() || portFeatures.is_1gbFd()) {
-            return Bandwidth.BW1Gbps;
-        } else if (portFeatures.is_100mbHd() || portFeatures.is_100mbFd()) {
-            return Bandwidth.BW100Mbps;
-        } else if (portFeatures.is_10mbHd() || portFeatures.is_10mbFd()) {
-            return Bandwidth.BW10Mbps;
-        } else {
-            return Bandwidth.BWUNK;
-        }
-    }
-
-}
index 519d21bf4fe6aea0fd3e0cdeda94132d7ce8b113..67fb6622d1772581d3ecec6133ab807bc6889ec2 100644 (file)
@@ -11,14 +11,14 @@ import java.util.Set;
 
 import org.opendaylight.controller.sal.core.api.RpcImplementation;
 import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 public interface Connector extends RpcImplementation, NotificationListener {
 
 
 
-    Set<InstanceIdentifier> getConfigurationPrefixes();
-    Set<InstanceIdentifier> getRuntimePrefixes();
+    Set<YangInstanceIdentifier> getConfigurationPrefixes();
+    Set<YangInstanceIdentifier> getRuntimePrefixes();
 
     void registerListener(ConnectorListener listener);
     void unregisterListener(ConnectorListener listener);
index ac9c893a0b9180c3de76a9f8e99cd7132bdbbb4f..935baba7a23540eddb71f732d5f9b8c8a9514cce 100644 (file)
@@ -9,11 +9,11 @@ package org.opendaylight.controller.sal.connector.api;
 
 import java.util.Set;
 
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 public interface ConnectorListener {
 
-    void onPrefixesAnnounced(Set<InstanceIdentifier> prefixes);
-    void onPrefixesWithdrawn(Set<InstanceIdentifier> prefixes);
+    void onPrefixesAnnounced(Set<YangInstanceIdentifier> prefixes);
+    void onPrefixesWithdrawn(Set<YangInstanceIdentifier> prefixes);
 
 }
index ea686d966ffa63b60e1cf3cb839db2f2eb034f1e..94c895dab385a92e3f547099ac83010cb7e517ec 100644 (file)
       <artifactId>sal-binding-config</artifactId>
     </dependency>
 
-    <!--
-      Adding a temporary dependency on the sal-broker-impl so that we can use InMemoryDOMDataStore
+      <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-data-api</artifactId>
+      </dependency>
+
+      <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-data-impl</artifactId>
+      </dependency>
 
-      InMemoryDOMDataStore needs to be moved into its own module and be wired up using config subsystem before
-      this bundle can use it
-    -->
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-broker-impl</artifactId>
+      <artifactId>sal-inmemory-datastore</artifactId>
+      <version>1.1-SNAPSHOT</version>
     </dependency>
 
     <dependency>
       <artifactId>scala-library</artifactId>
     </dependency>
 
+    <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>sal-protocolbuffer-encoding</artifactId>
+        <version>1.1-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>sal-akka-raft</artifactId>
+        <version>1.1-SNAPSHOT</version>
+    </dependency>
+
     <!-- Test Dependencies -->
     <dependency>
       <groupId>junit</groupId>
       <version>${slf4j.version}</version>
       <scope>test</scope>
     </dependency>
+
   </dependencies>
 
   <build>
             <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
             <Export-package></Export-package>
             <Private-Package></Private-Package>
+            <Import-Package>!*snappy;!org.jboss.*;*</Import-Package>
+            <Embed-Dependency>
+                sal-protocolbuffer-encoding;
+                sal-akka-raft;
+                !sal*;
+                !*config-api*;
+                !*testkit*;
+                akka*;
+                *leveldb*;
+                *config*;
+                *hawt*;
+                *protobuf*;
+                *netty*;
+                *uncommons*;
+                *scala*;
+            </Embed-Dependency>
+            <Embed-Transitive>true</Embed-Transitive>
           </instructions>
         </configuration>
       </plugin>
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/AbstractUntypedActor.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/AbstractUntypedActor.java
new file mode 100644 (file)
index 0000000..ce05160
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.UntypedActor;
+import akka.event.Logging;
+import akka.event.LoggingAdapter;
+import org.opendaylight.controller.cluster.datastore.messages.Monitor;
+
+public abstract class AbstractUntypedActor extends UntypedActor {
+    protected final LoggingAdapter LOG =
+        Logging.getLogger(getContext().system(), this);
+
+
+    public AbstractUntypedActor(){
+        LOG.debug("Actor created {}", getSelf());
+        getContext().
+            system().
+            actorSelection("user/termination-monitor").
+            tell(new Monitor(getSelf()), getSelf());
+    }
+
+    @Override public void onReceive(Object message) throws Exception {
+        LOG.debug("Received message {}", message.getClass().getSimpleName());
+        handleReceive(message);
+        LOG.debug("Done handling message {}", message.getClass().getSimpleName());
+    }
+
+    protected abstract void handleReceive(Object message) throws Exception;
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ActorSystemFactory.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ActorSystemFactory.java
new file mode 100644 (file)
index 0000000..baf04fe
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.ActorSystem;
+import akka.actor.Props;
+import com.google.common.base.Function;
+import com.typesafe.config.ConfigFactory;
+
+import javax.annotation.Nullable;
+
+public class ActorSystemFactory {
+    private static final ActorSystem actorSystem = (new Function<Void, ActorSystem>(){
+
+        @Nullable @Override public ActorSystem apply(@Nullable Void aVoid) {
+                ActorSystem system =
+                    ActorSystem.create("opendaylight-cluster", ConfigFactory
+                        .load().getConfig("ODLCluster"));
+                system.actorOf(Props.create(TerminationMonitor.class), "termination-monitor");
+                return system;
+        }
+    }).apply(null);
+
+    public static final ActorSystem getInstance(){
+        return actorSystem;
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ClusterWrapper.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ClusterWrapper.java
new file mode 100644 (file)
index 0000000..2eac240
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.ActorRef;
+
+public interface ClusterWrapper {
+    void subscribeToMemberEvents(ActorRef actorRef);
+    String getCurrentMemberName();
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ClusterWrapperImpl.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ClusterWrapperImpl.java
new file mode 100644 (file)
index 0000000..142aacd
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.cluster.Cluster;
+import akka.cluster.ClusterEvent;
+
+public class ClusterWrapperImpl implements ClusterWrapper {
+    private final Cluster cluster;
+    private final String currentMemberName;
+
+    public ClusterWrapperImpl(ActorSystem actorSystem){
+        cluster = Cluster.get(actorSystem);
+        currentMemberName = (String) cluster.getSelfRoles().toArray()[0];
+
+    }
+
+    public void subscribeToMemberEvents(ActorRef actorRef){
+        cluster.subscribe(actorRef, ClusterEvent.initialStateAsEvents(),
+            ClusterEvent.MemberEvent.class,
+            ClusterEvent.UnreachableMember.class);
+    }
+
+    public String getCurrentMemberName() {
+        return currentMemberName;
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/CompositeModificationPayload.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/CompositeModificationPayload.java
new file mode 100644 (file)
index 0000000..955e4bb
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore;
+
+import com.google.common.base.Preconditions;
+import com.google.protobuf.GeneratedMessage;
+import org.opendaylight.controller.cluster.example.protobuff.messages.KeyValueMessages;
+import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
+import org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages;
+import org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+public class CompositeModificationPayload extends Payload implements
+    Serializable {
+
+    private final PersistentMessages.CompositeModification modification;
+
+    public CompositeModificationPayload(){
+        modification = null;
+    }
+    public CompositeModificationPayload(Object modification){
+        this.modification = (PersistentMessages.CompositeModification) modification;
+    }
+
+    @Override public Map<GeneratedMessage.GeneratedExtension, PersistentMessages.CompositeModification> encode() {
+        Preconditions.checkState(modification!=null);
+        Map<GeneratedMessage.GeneratedExtension, PersistentMessages.CompositeModification> map = new HashMap<>();
+        map.put(org.opendaylight.controller.mdsal.CompositeModificationPayload.modification, this.modification);
+        return map;
+    }
+
+    @Override public Payload decode(
+        AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload payload) {
+        PersistentMessages.CompositeModification modification = payload
+            .getExtension(
+                org.opendaylight.controller.mdsal.CompositeModificationPayload.modification);
+        payload.getExtension(KeyValueMessages.value);
+        return new CompositeModificationPayload(modification);
+    }
+
+    public Object getModification(){
+        return this.modification;
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Configuration.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Configuration.java
new file mode 100644 (file)
index 0000000..3423907
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategy;
+
+import java.util.List;
+import java.util.Map;
+
+public interface Configuration {
+
+    /**
+     * Given a memberName find all the shards that belong on that member and
+     * return the names of those shards
+     *
+     * @param memberName
+     * @return
+     */
+    List<String> getMemberShardNames(String memberName);
+
+    /**
+     * Given a module namespace return the name of a module
+     * @param nameSpace
+     * @return
+     */
+    Optional<String> getModuleNameFromNameSpace(String nameSpace);
+
+    /**
+     * Get a mapping of the module names to it's corresponding ShardStrategy
+     * @return
+     */
+    Map<String, ShardStrategy> getModuleNameToShardStrategyMap();
+
+    /**
+     * Given a module name find all the shardNames corresponding to it
+     * @param moduleName
+     * @return
+     */
+    List<String> getShardNamesFromModuleName(String moduleName);
+
+    /**
+     * Given a shardName find all the members on which it belongs
+     *
+     * @param shardName
+     * @return
+     */
+    List<String> getMembersFromShardName(String shardName);
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ConfigurationImpl.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ConfigurationImpl.java
new file mode 100644 (file)
index 0000000..3459002
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore;
+
+import com.google.common.base.Optional;
+import com.typesafe.config.Config;
+import com.typesafe.config.ConfigFactory;
+import com.typesafe.config.ConfigObject;
+import org.opendaylight.controller.cluster.datastore.shardstrategy.DefaultShardStrategy;
+import org.opendaylight.controller.cluster.datastore.shardstrategy.ModuleShardStrategy;
+import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ConfigurationImpl implements Configuration {
+
+    private final List<ModuleShard> moduleShards = new ArrayList<>();
+
+    private final List<Module> modules = new ArrayList<>();
+
+    private static final Logger
+        LOG = LoggerFactory.getLogger(DistributedDataStore.class);
+
+
+    public ConfigurationImpl(String moduleShardsConfigPath,
+
+        String modulesConfigPath){
+
+        File moduleShardsFile = new File("./configuration/initial/" + moduleShardsConfigPath);
+        File modulesFile = new File("./configuration/initial/" + modulesConfigPath);
+
+        Config moduleShardsConfig = null;
+        if(moduleShardsFile.exists()) {
+            LOG.info("module shards config file exists - reading config from it");
+            moduleShardsConfig = ConfigFactory.parseFile(moduleShardsFile);
+        } else {
+            LOG.warn("module shards configuration read from resource");
+            moduleShardsConfig = ConfigFactory.load(moduleShardsConfigPath);
+        }
+
+        Config modulesConfig = null;
+        if(modulesFile.exists()) {
+            LOG.info("modules config file exists - reading config from it");
+            modulesConfig = ConfigFactory.parseFile(modulesFile);
+        } else {
+            LOG.warn("modules configuration read from resource");
+            modulesConfig = ConfigFactory.load(modulesConfigPath);
+        }
+
+        readModuleShards(moduleShardsConfig);
+
+        readModules(modulesConfig);
+    }
+
+    @Override public List<String> getMemberShardNames(String memberName){
+        List<String> shards = new ArrayList();
+        for(ModuleShard ms : moduleShards){
+            for(Shard s : ms.getShards()){
+                for(String m : s.getReplicas()){
+                    if(memberName.equals(m)){
+                        shards.add(s.getName());
+                    }
+                }
+            }
+        }
+        return shards;
+
+    }
+
+    @Override public Optional<String> getModuleNameFromNameSpace(String nameSpace) {
+        for(Module m : modules){
+            if(m.getNameSpace().equals(nameSpace)){
+                return Optional.of(m.getName());
+            }
+        }
+        return Optional.absent();
+    }
+
+    @Override public Map<String, ShardStrategy> getModuleNameToShardStrategyMap() {
+        Map<String, ShardStrategy> map = new HashMap<>();
+        for(Module m : modules){
+            map.put(m.getName(), m.getShardStrategy());
+        }
+        return map;
+    }
+
+    @Override public List<String> getShardNamesFromModuleName(String moduleName) {
+        for(ModuleShard m : moduleShards){
+            if(m.getModuleName().equals(moduleName)){
+                List<String> l = new ArrayList<>();
+                for(Shard s : m.getShards()){
+                    l.add(s.getName());
+                }
+                return l;
+            }
+        }
+
+        return Collections.EMPTY_LIST;
+    }
+
+    @Override public List<String> getMembersFromShardName(String shardName) {
+        List<String> shards = new ArrayList();
+        for(ModuleShard ms : moduleShards){
+            for(Shard s : ms.getShards()) {
+                if(s.getName().equals(shardName)){
+                    return s.getReplicas();
+                }
+            }
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+
+
+    private void readModules(Config modulesConfig) {
+        List<? extends ConfigObject> modulesConfigObjectList =
+            modulesConfig.getObjectList("modules");
+
+        for(ConfigObject o : modulesConfigObjectList){
+            ConfigObjectWrapper w = new ConfigObjectWrapper(o);
+            modules.add(new Module(w.stringValue("name"), w.stringValue(
+                "namespace"), w.stringValue("shard-strategy")));
+        }
+    }
+
+    private void readModuleShards(Config moduleShardsConfig) {
+        List<? extends ConfigObject> moduleShardsConfigObjectList =
+            moduleShardsConfig.getObjectList("module-shards");
+
+        for(ConfigObject moduleShardConfigObject : moduleShardsConfigObjectList){
+
+            String moduleName = moduleShardConfigObject.get("name").unwrapped().toString();
+
+            List<? extends ConfigObject> shardsConfigObjectList =
+                moduleShardConfigObject.toConfig().getObjectList("shards");
+
+            List<Shard> shards = new ArrayList<>();
+
+            for(ConfigObject shard : shardsConfigObjectList){
+                String shardName = shard.get("name").unwrapped().toString();
+                List<String> replicas = shard.toConfig().getStringList("replicas");
+                shards.add(new Shard(shardName, replicas));
+            }
+
+            this.moduleShards.add(new ModuleShard(moduleName, shards));
+        }
+    }
+
+
+    private class ModuleShard {
+        private final String moduleName;
+        private final List<Shard> shards;
+
+        public ModuleShard(String moduleName, List<Shard> shards) {
+            this.moduleName = moduleName;
+            this.shards = shards;
+        }
+
+        public String getModuleName() {
+            return moduleName;
+        }
+
+        public List<Shard> getShards() {
+            return shards;
+        }
+    }
+
+    private class Shard {
+        private final String name;
+        private final List<String> replicas;
+
+        Shard(String name, List<String> replicas) {
+            this.name = name;
+            this.replicas = replicas;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public List<String> getReplicas() {
+            return replicas;
+        }
+    }
+
+    private class Module {
+
+        private final String name;
+        private final String nameSpace;
+        private final ShardStrategy shardStrategy;
+
+        Module(String name, String nameSpace, String shardStrategy) {
+            this.name = name;
+            this.nameSpace = nameSpace;
+            if(ModuleShardStrategy.NAME.equals(shardStrategy)){
+                this.shardStrategy = new ModuleShardStrategy(name, ConfigurationImpl.this);
+            } else {
+                this.shardStrategy = new DefaultShardStrategy();
+            }
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public String getNameSpace() {
+            return nameSpace;
+        }
+
+        public ShardStrategy getShardStrategy() {
+            return shardStrategy;
+        }
+    }
+
+
+    private static class ConfigObjectWrapper{
+
+        private final ConfigObject configObject;
+
+        ConfigObjectWrapper(ConfigObject configObject){
+            this.configObject = configObject;
+        }
+
+        public String stringValue(String name){
+            return configObject.get(name).unwrapped().toString();
+        }
+    }
+}
index ba09d0402530921667915eae11103302cfcfb2ea..3af6f56a2c78fe40ddd9cfa60ac5fe7bd60348c9 100644 (file)
@@ -9,19 +9,46 @@
 package org.opendaylight.controller.cluster.datastore;
 
 import akka.actor.Props;
-import akka.actor.UntypedActor;
 import akka.japi.Creator;
+import org.opendaylight.controller.cluster.datastore.messages.DataChanged;
+import org.opendaylight.controller.cluster.datastore.messages.DataChangedReply;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-public class DataChangeListener extends UntypedActor {
-    @Override public void onReceive(Object message) throws Exception {
-        throw new UnsupportedOperationException("onReceive");
+public class DataChangeListener extends AbstractUntypedActor {
+    private final AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> listener;
+    private final SchemaContext schemaContext;
+    private final YangInstanceIdentifier pathId;
+
+    public DataChangeListener(SchemaContext schemaContext,
+                              AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> listener, YangInstanceIdentifier pathId) {
+        this.listener = listener;
+        this.schemaContext = schemaContext;
+        this.pathId  = pathId;
+    }
+
+    @Override public void handleReceive(Object message) throws Exception {
+        if(message.getClass().equals(DataChanged.SERIALIZABLE_CLASS)){
+            DataChanged reply = DataChanged.fromSerialize(schemaContext,message, pathId);
+            AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>>
+                change = reply.getChange();
+            this.listener.onDataChanged(change);
+
+            if(getSender() != null){
+                getSender().tell(new DataChangedReply().toSerializable(), getSelf());
+            }
+
+        }
     }
 
-    public static Props props() {
+    public static Props props(final SchemaContext schemaContext, final AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> listener, final YangInstanceIdentifier pathId) {
         return Props.create(new Creator<DataChangeListener>() {
             @Override
             public DataChangeListener create() throws Exception {
-                return new DataChangeListener();
+                return new DataChangeListener(schemaContext,listener,pathId );
             }
 
         });
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxy.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxy.java
new file mode 100644 (file)
index 0000000..cd9c330
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.ActorSelection;
+import org.opendaylight.controller.cluster.datastore.messages.DataChanged;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * DataChangeListenerProxy represents a single remote DataChangeListener
+ */
+public class DataChangeListenerProxy implements AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>{
+    private final ActorSelection dataChangeListenerActor;
+    private final SchemaContext schemaContext;
+
+    public DataChangeListenerProxy(SchemaContext schemaContext,ActorSelection dataChangeListenerActor) {
+        this.dataChangeListenerActor = dataChangeListenerActor;
+        this.schemaContext = schemaContext;
+    }
+
+    @Override public void onDataChanged(
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
+        dataChangeListenerActor.tell(new DataChanged(schemaContext,change).toSerializable(), null);
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistration.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistration.java
new file mode 100644 (file)
index 0000000..9e50b5b
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.PoisonPill;
+import akka.actor.Props;
+import akka.japi.Creator;
+import org.opendaylight.controller.cluster.datastore.messages.CloseDataChangeListenerRegistration;
+import org.opendaylight.controller.cluster.datastore.messages.CloseDataChangeListenerRegistrationReply;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class DataChangeListenerRegistration extends AbstractUntypedActor {
+
+    private final org.opendaylight.yangtools.concepts.ListenerRegistration<AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>>
+        registration;
+
+    public DataChangeListenerRegistration(
+        org.opendaylight.yangtools.concepts.ListenerRegistration<AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>> registration) {
+        this.registration = registration;
+    }
+
+    @Override
+    public void handleReceive(Object message) throws Exception {
+        if (message.getClass().equals(CloseDataChangeListenerRegistration.SERIALIZABLE_CLASS)) {
+            closeListenerRegistration(
+                new CloseDataChangeListenerRegistration());
+        }
+    }
+
+    public static Props props(
+        final org.opendaylight.yangtools.concepts.ListenerRegistration<AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>> registration) {
+        return Props.create(new Creator<DataChangeListenerRegistration>() {
+
+            @Override
+            public DataChangeListenerRegistration create() throws Exception {
+                return new DataChangeListenerRegistration(registration);
+            }
+        });
+    }
+
+    private void closeListenerRegistration(
+        CloseDataChangeListenerRegistration message) {
+        registration.close();
+        getSender()
+            .tell(new CloseDataChangeListenerRegistrationReply().toSerializable(), getSelf());
+        getSelf().tell(PoisonPill.getInstance(), getSelf());
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationProxy.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationProxy.java
new file mode 100644 (file)
index 0000000..e3cdbb4
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSelection;
+import akka.actor.PoisonPill;
+import org.opendaylight.controller.cluster.datastore.messages.CloseDataChangeListenerRegistration;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * ListenerRegistrationProxy acts as a proxy for a ListenerRegistration that was done on a remote shard
+ * <p>
+ * Registering a DataChangeListener on the Data Store creates a new instance of the ListenerRegistrationProxy
+ * The ListenerRegistrationProxy talks to a remote ListenerRegistration actor.
+ * </p>
+ */
+public class DataChangeListenerRegistrationProxy implements ListenerRegistration {
+    private final ActorSelection listenerRegistrationActor;
+    private final AsyncDataChangeListener listener;
+    private final ActorRef dataChangeListenerActor;
+
+    public <L extends AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>>
+    DataChangeListenerRegistrationProxy(
+        ActorSelection listenerRegistrationActor,
+        L listener, ActorRef dataChangeListenerActor) {
+        this.listenerRegistrationActor = listenerRegistrationActor;
+        this.listener = listener;
+        this.dataChangeListenerActor = dataChangeListenerActor;
+    }
+
+    @Override
+    public Object getInstance() {
+        return listener;
+    }
+
+    @Override
+    public void close() {
+        listenerRegistrationActor.tell(new CloseDataChangeListenerRegistration().toSerializable(), null);
+        dataChangeListenerActor.tell(PoisonPill.getInstance(), null);
+    }
+}
index f64c6f1a8669888726f30bfe4099aa628365ccbb..2ef8e5f449f8df564ae42943c6597224b832bcb4 100644 (file)
@@ -13,6 +13,7 @@ import akka.actor.ActorSystem;
 import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListener;
 import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListenerReply;
 import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
+import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategyFactory;
 import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
@@ -22,17 +23,20 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransactio
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
 /**
  *
  */
-public class DistributedDataStore implements DOMStore, SchemaContextListener {
+public class DistributedDataStore implements DOMStore, SchemaContextListener, AutoCloseable {
 
     private static final Logger
         LOG = LoggerFactory.getLogger(DistributedDataStore.class);
@@ -41,8 +45,25 @@ public class DistributedDataStore implements DOMStore, SchemaContextListener {
     private final String type;
     private final ActorContext actorContext;
 
-    public DistributedDataStore(ActorSystem actorSystem, String type) {
-        this(new ActorContext(actorSystem, actorSystem.actorOf(ShardManager.props(type))), type);
+    private SchemaContext schemaContext;
+
+
+
+    /**
+     * Executor used to run FutureTask's
+     *
+     * This is typically used when we need to make a request to an actor and
+     * wait for it's response and the consumer needs to be provided a Future.
+     *
+     * FIXME : Make the thread pool configurable
+     */
+    private final ExecutorService executor =
+        Executors.newFixedThreadPool(10);
+
+    public DistributedDataStore(ActorSystem actorSystem, String type, ClusterWrapper cluster, Configuration configuration) {
+        this(new ActorContext(actorSystem, actorSystem
+            .actorOf(ShardManager.props(type, cluster, configuration),
+                "shardmanager-" + type), cluster, configuration), type);
     }
 
     public DistributedDataStore(ActorContext actorContext, String type) {
@@ -52,44 +73,58 @@ public class DistributedDataStore implements DOMStore, SchemaContextListener {
 
 
     @Override
-    public <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> ListenerRegistration<L> registerChangeListener(
-        InstanceIdentifier path, L listener,
+    public <L extends AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>> ListenerRegistration<L> registerChangeListener(
+        YangInstanceIdentifier path, L listener,
         AsyncDataBroker.DataChangeScope scope) {
 
-        ActorRef dataChangeListenerActor = actorContext.getActorSystem().actorOf(DataChangeListener.props());
+        ActorRef dataChangeListenerActor = actorContext.getActorSystem().actorOf(
+            DataChangeListener.props(schemaContext,listener,path ));
 
-        Object result = actorContext.executeShardOperation(Shard.DEFAULT_NAME,
+        String shardName = ShardStrategyFactory.getStrategy(path).findShard(path);
+
+        Object result = actorContext.executeShardOperation(shardName,
             new RegisterChangeListener(path, dataChangeListenerActor.path(),
-                AsyncDataBroker.DataChangeScope.BASE),
-            ActorContext.ASK_DURATION);
+                scope).toSerializable(),
+            ActorContext.ASK_DURATION
+        );
 
-        RegisterChangeListenerReply reply = (RegisterChangeListenerReply) result;
-        return new ListenerRegistrationProxy(reply.getListenerRegistrationPath());
+        RegisterChangeListenerReply reply = RegisterChangeListenerReply.fromSerializable(actorContext.getActorSystem(),result);
+        return new DataChangeListenerRegistrationProxy(actorContext.actorSelection(reply.getListenerRegistrationPath()), listener, dataChangeListenerActor);
     }
 
 
 
     @Override
     public DOMStoreTransactionChain createTransactionChain() {
-        return new TransactionChainProxy(actorContext);
+        return new TransactionChainProxy(actorContext, executor, schemaContext);
     }
 
     @Override
     public DOMStoreReadTransaction newReadOnlyTransaction() {
-        return new TransactionProxy(actorContext, TransactionProxy.TransactionType.READ_ONLY);
+        return new TransactionProxy(actorContext, TransactionProxy.TransactionType.READ_ONLY,
+            executor, schemaContext);
     }
 
     @Override
     public DOMStoreWriteTransaction newWriteOnlyTransaction() {
-        return new TransactionProxy(actorContext, TransactionProxy.TransactionType.WRITE_ONLY);
+        return new TransactionProxy(actorContext, TransactionProxy.TransactionType.WRITE_ONLY,
+            executor, schemaContext);
     }
 
     @Override
     public DOMStoreReadWriteTransaction newReadWriteTransaction() {
-        return new TransactionProxy(actorContext, TransactionProxy.TransactionType.READ_WRITE);
+        return new TransactionProxy(actorContext, TransactionProxy.TransactionType.READ_WRITE,
+            executor, schemaContext);
     }
 
     @Override public void onGlobalContextUpdated(SchemaContext schemaContext) {
-        actorContext.getShardManager().tell(new UpdateSchemaContext(schemaContext), null);
+        this.schemaContext = schemaContext;
+        actorContext.getShardManager().tell(
+            new UpdateSchemaContext(schemaContext), null);
+    }
+
+    @Override public void close() throws Exception {
+        actorContext.shutdown();
+
     }
 }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreFactory.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreFactory.java
new file mode 100644 (file)
index 0000000..692d1b4
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.ActorSystem;
+import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategyFactory;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+
+public class DistributedDataStoreFactory {
+    public static DistributedDataStore createInstance(String name, SchemaService schemaService){
+        ActorSystem actorSystem = ActorSystemFactory.getInstance();
+        Configuration config = new ConfigurationImpl("module-shards.conf", "modules.conf");
+        final DistributedDataStore dataStore =
+            new DistributedDataStore(actorSystem, name, new ClusterWrapperImpl(actorSystem),config );
+       ShardStrategyFactory.setConfiguration(config);
+        schemaService
+            .registerSchemaServiceListener(dataStore);
+        return dataStore;
+
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ListenerProxy.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ListenerProxy.java
deleted file mode 100644 (file)
index 7c38ee5..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.cluster.datastore;
-
-import akka.actor.ActorSelection;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public class ListenerProxy implements AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>{
-    private final ActorSelection listenerRegistrationActor;
-
-    public ListenerProxy(ActorSelection listenerRegistrationActor) {
-        this.listenerRegistrationActor = listenerRegistrationActor;
-    }
-
-    @Override public void onDataChanged(
-        AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> change) {
-        throw new UnsupportedOperationException("onDataChanged");
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ListenerRegistration.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ListenerRegistration.java
deleted file mode 100644 (file)
index fda429f..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.cluster.datastore;
-
-import akka.actor.Props;
-import akka.actor.UntypedActor;
-import akka.japi.Creator;
-import org.opendaylight.controller.cluster.datastore.messages.CloseListenerRegistration;
-import org.opendaylight.controller.cluster.datastore.messages.CloseListenerRegistrationReply;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public class ListenerRegistration extends UntypedActor{
-
-  private final org.opendaylight.yangtools.concepts.ListenerRegistration<AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> registration;
-
-  public ListenerRegistration(org.opendaylight.yangtools.concepts.ListenerRegistration<AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> registration) {
-    this.registration = registration;
-  }
-
-  @Override
-  public void onReceive(Object message) throws Exception {
-    if(message instanceof CloseListenerRegistration){
-      closeListenerRegistration((CloseListenerRegistration) message);
-    }
-  }
-
-  public static Props props(final org.opendaylight.yangtools.concepts.ListenerRegistration<AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> registration){
-    return Props.create(new Creator<ListenerRegistration>(){
-
-      @Override
-      public ListenerRegistration create() throws Exception {
-        return new ListenerRegistration(registration);
-      }
-    });
-  }
-
-  private void closeListenerRegistration(CloseListenerRegistration message){
-    registration.close();
-    getSender().tell(new CloseListenerRegistrationReply(), getSelf());
-  }
-}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ListenerRegistrationProxy.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ListenerRegistrationProxy.java
deleted file mode 100644 (file)
index a548a88..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.cluster.datastore;
-
-import akka.actor.ActorPath;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-
-/**
- * ListenerRegistrationProxy acts as a proxy for a ListenerRegistration that was done on a remote shard
- *
- * Registering a DataChangeListener on the Data Store creates a new instance of the ListenerRegistrationProxy
- * The ListenerRegistrationProxy talks to a remote ListenerRegistration actor.
- */
-public class ListenerRegistrationProxy implements ListenerRegistration {
-    private final ActorPath listenerRegistrationPath;
-
-    public ListenerRegistrationProxy(ActorPath listenerRegistrationPath) {
-
-        this.listenerRegistrationPath = listenerRegistrationPath;
-    }
-
-    @Override
-    public Object getInstance() {
-        throw new UnsupportedOperationException("getInstance");
-    }
-
-    @Override
-    public void close() {
-        throw new UnsupportedOperationException("close");
-    }
-}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/NoOpCohort.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/NoOpCohort.java
new file mode 100644 (file)
index 0000000..eb28159
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.UntypedActor;
+import org.opendaylight.controller.cluster.datastore.messages.AbortTransaction;
+import org.opendaylight.controller.cluster.datastore.messages.AbortTransactionReply;
+import org.opendaylight.controller.cluster.datastore.messages.CanCommitTransaction;
+import org.opendaylight.controller.cluster.datastore.messages.CanCommitTransactionReply;
+import org.opendaylight.controller.cluster.datastore.messages.CommitTransaction;
+import org.opendaylight.controller.cluster.datastore.messages.CommitTransactionReply;
+import org.opendaylight.controller.cluster.datastore.messages.PreCommitTransaction;
+import org.opendaylight.controller.cluster.datastore.messages.PreCommitTransactionReply;
+
+public class NoOpCohort extends UntypedActor {
+
+    @Override public void onReceive(Object message) throws Exception {
+        if (message.getClass().equals(CanCommitTransaction.SERIALIZABLE_CLASS)) {
+            getSender().tell(new CanCommitTransactionReply(false).toSerializable(), getSelf());
+        } else if (message.getClass().equals(PreCommitTransaction.SERIALIZABLE_CLASS)) {
+            getSender().tell(
+                new PreCommitTransactionReply().toSerializable(),
+                getSelf());
+        } else if (message.getClass().equals(CommitTransaction.SERIALIZABLE_CLASS)) {
+            getSender().tell(new CommitTransactionReply().toSerializable(), getSelf());
+        } else if (message.getClass().equals(AbortTransaction.SERIALIZABLE_CLASS)) {
+            getSender().tell(new AbortTransactionReply().toSerializable(), getSelf());
+        } else {
+            throw new Exception ("Not recognized message received,message="+message);
+        }
+
+    }
+}
+
index 5b4f7ef8989711dffdf4cdd8fbe7d483165f23a7..999d0f8bafca9639baa70ea7c893656f87704ae7 100644 (file)
@@ -14,25 +14,33 @@ import akka.actor.Props;
 import akka.event.Logging;
 import akka.event.LoggingAdapter;
 import akka.japi.Creator;
-import akka.persistence.Persistent;
-import akka.persistence.UntypedProcessor;
+import akka.serialization.Serialization;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
+import org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard.ShardMBeanFactory;
+import org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard.ShardStats;
 import org.opendaylight.controller.cluster.datastore.messages.CommitTransactionReply;
+import org.opendaylight.controller.cluster.datastore.messages.CreateTransaction;
 import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionChain;
 import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionChainReply;
+import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionReply;
 import org.opendaylight.controller.cluster.datastore.messages.ForwardedCommitTransaction;
+import org.opendaylight.controller.cluster.datastore.messages.PeerAddressResolved;
 import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListener;
 import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListenerReply;
 import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
 import org.opendaylight.controller.cluster.datastore.modification.Modification;
+import org.opendaylight.controller.cluster.datastore.modification.MutableCompositeModification;
+import org.opendaylight.controller.cluster.raft.RaftActor;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -45,7 +53,7 @@ import java.util.concurrent.Executors;
  * Our Shard uses InMemoryDataStore as it's internal representation and delegates all requests it
  * </p>
  */
-public class Shard extends UntypedProcessor {
+public class Shard extends RaftActor {
 
     public static final String DEFAULT_NAME = "default";
 
@@ -54,105 +62,208 @@ public class Shard extends UntypedProcessor {
 
     private final InMemoryDOMDataStore store;
 
-    private final Map<Modification, DOMStoreThreePhaseCommitCohort>
+    private final Map<Object, DOMStoreThreePhaseCommitCohort>
         modificationToCohort = new HashMap<>();
 
-    private final LoggingAdapter log =
+    private final LoggingAdapter LOG =
         Logging.getLogger(getContext().system(), this);
 
-    private Shard(String name) {
+    // By default persistent will be true and can be turned off using the system
+    // property persistent
+    private final boolean persistent;
+
+    private final String name;
+
+    private SchemaContext schemaContext;
+
+    private final ShardStats shardMBean;
+
+    private Shard(String name, Map<String, String> peerAddresses) {
+        super(name, peerAddresses);
+
+        this.name = name;
+
+        String setting = System.getProperty("shard.persistent");
+
+        this.persistent = !"false".equals(setting);
+
+        LOG.info("Creating shard : {} persistent : {}", name, persistent);
+
         store = new InMemoryDOMDataStore(name, storeExecutor);
+
+        shardMBean = ShardMBeanFactory.getShardStatsMBean(name);
+
     }
 
-    public static Props props(final String name) {
+    public static Props props(final String name, final Map<String, String> peerAddresses) {
         return Props.create(new Creator<Shard>() {
 
             @Override
             public Shard create() throws Exception {
-                return new Shard(name);
+                return new Shard(name, peerAddresses);
             }
 
         });
     }
 
-    @Override
-    public void onReceive(Object message) throws Exception {
-        if (message instanceof CreateTransactionChain) {
-            createTransactionChain();
-        } else if (message instanceof RegisterChangeListener) {
-            registerChangeListener((RegisterChangeListener) message);
+
+    @Override public void onReceiveCommand(Object message){
+        LOG.debug("Received message {} from {}", message.getClass().toString(), getSender());
+
+        if (message.getClass().equals(CreateTransactionChain.SERIALIZABLE_CLASS)) {
+            if(isLeader()) {
+                createTransactionChain();
+            } else if(getLeader() != null){
+                getLeader().forward(message, getContext());
+            }
+        } else if (message.getClass().equals(RegisterChangeListener.SERIALIZABLE_CLASS)) {
+            registerChangeListener(RegisterChangeListener.fromSerializable(getContext().system(), message));
         } else if (message instanceof UpdateSchemaContext) {
             updateSchemaContext((UpdateSchemaContext) message);
         } else if (message instanceof ForwardedCommitTransaction) {
             handleForwardedCommit((ForwardedCommitTransaction) message);
-        } else if (message instanceof Persistent) {
-            commit((Persistent) message);
+        } else if (message.getClass().equals(CreateTransaction.SERIALIZABLE_CLASS)) {
+            if(isLeader()) {
+                createTransaction(CreateTransaction.fromSerializable(message));
+            } else if(getLeader() != null){
+                getLeader().forward(message, getContext());
+            }
+        } else if (message instanceof PeerAddressResolved){
+            PeerAddressResolved resolved = (PeerAddressResolved) message;
+            setPeerAddress(resolved.getPeerId(), resolved.getPeerAddress());
+        } else {
+          super.onReceiveCommand(message);
         }
     }
 
-    private void commit(Persistent message) {
-        Modification modification = (Modification) message.payload();
+    private void createTransaction(CreateTransaction createTransaction) {
+        DOMStoreReadWriteTransaction transaction =
+            store.newReadWriteTransaction();
+        String transactionId = "shard-" + createTransaction.getTransactionId();
+        LOG.info("Creating transaction : {} " , transactionId);
+        ActorRef transactionActor = getContext().actorOf(
+            ShardTransaction.props(transaction, getSelf(), schemaContext), transactionId);
+
+        getSender()
+            .tell(new CreateTransactionReply(Serialization.serializedActorPath(transactionActor), createTransaction.getTransactionId()).toSerializable(),
+                getSelf());
+    }
+
+    private void commit(final ActorRef sender, Object serialized) {
+        Modification modification = MutableCompositeModification.fromSerializable(serialized, schemaContext);
         DOMStoreThreePhaseCommitCohort cohort =
-            modificationToCohort.remove(modification);
+            modificationToCohort.remove(serialized);
         if (cohort == null) {
-            log.error(
+            LOG.error(
                 "Could not find cohort for modification : " + modification);
+            LOG.info("Writing modification using a new transaction");
+            modification.apply(store.newReadWriteTransaction());
             return;
         }
+
         final ListenableFuture<Void> future = cohort.commit();
-        final ActorRef sender = getSender();
+        shardMBean.incrementCommittedTransactionCount();
         final ActorRef self = getSelf();
         future.addListener(new Runnable() {
             @Override
             public void run() {
                 try {
                     future.get();
-                    sender.tell(new CommitTransactionReply(), self);
+
+                    if(sender != null) {
+                        sender
+                            .tell(new CommitTransactionReply().toSerializable(),
+                                self);
+                    } else {
+                        LOG.error("sender is null ???");
+                    }
                 } catch (InterruptedException | ExecutionException e) {
-                    log.error(e, "An exception happened when committing");
+                    // FIXME : Handle this properly
+                    LOG.error(e, "An exception happened when committing");
                 }
             }
         }, getContext().dispatcher());
     }
 
     private void handleForwardedCommit(ForwardedCommitTransaction message) {
-        log.info("received forwarded transaction");
+        Object serializedModification = message.getModification().toSerializable();
+
         modificationToCohort
-            .put(message.getModification(), message.getCohort());
-        getSelf().forward(Persistent.create(message.getModification()),
-            getContext());
+            .put(serializedModification , message.getCohort());
+
+        if(persistent) {
+            this.persistData(getSender(), "identifier", new CompositeModificationPayload(serializedModification));
+        } else {
+            this.commit(getSender(), serializedModification);
+        }
     }
 
     private void updateSchemaContext(UpdateSchemaContext message) {
+        this.schemaContext = message.getSchemaContext();
         store.onGlobalContextUpdated(message.getSchemaContext());
     }
 
     private void registerChangeListener(
         RegisterChangeListener registerChangeListener) {
 
-        ActorSelection listenerRegistrationActor = getContext()
-            .system().actorSelection(registerChangeListener.getDataChangeListenerPath());
+        LOG.debug("registerDataChangeListener for " + registerChangeListener.getPath());
 
-        AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>
-            listener = new ListenerProxy(listenerRegistrationActor);
 
-        org.opendaylight.yangtools.concepts.ListenerRegistration<AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>>
+        ActorSelection dataChangeListenerPath = getContext()
+            .system().actorSelection(
+                registerChangeListener.getDataChangeListenerPath());
+
+        AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>
+            listener = new DataChangeListenerProxy(schemaContext,dataChangeListenerPath);
+
+        org.opendaylight.yangtools.concepts.ListenerRegistration<AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>>
             registration =
             store.registerChangeListener(registerChangeListener.getPath(),
                 listener, registerChangeListener.getScope());
         ActorRef listenerRegistration =
-            getContext().actorOf(ListenerRegistration.props(registration));
+            getContext().actorOf(
+                DataChangeListenerRegistration.props(registration));
+
+        LOG.debug("registerDataChangeListener sending reply, listenerRegistrationPath = " + listenerRegistration.path().toString());
+
         getSender()
-            .tell(new RegisterChangeListenerReply(listenerRegistration.path()),
+            .tell(new RegisterChangeListenerReply(listenerRegistration.path()).toSerializable(),
                 getSelf());
     }
 
     private void createTransactionChain() {
         DOMStoreTransactionChain chain = store.createTransactionChain();
         ActorRef transactionChain =
-            getContext().actorOf(ShardTransactionChain.props(chain));
+            getContext().actorOf(
+                ShardTransactionChain.props(chain, schemaContext));
         getSender()
-            .tell(new CreateTransactionChainReply(transactionChain.path()),
+            .tell(new CreateTransactionChainReply(transactionChain.path())
+                .toSerializable(),
                 getSelf());
     }
+
+    @Override protected void applyState(ActorRef clientActor, String identifier,
+        Object data) {
+
+        if(data instanceof CompositeModificationPayload){
+            Object modification =
+                ((CompositeModificationPayload) data).getModification();
+            commit(clientActor, modification);
+        } else {
+            LOG.error("Unknown state received {}", data);
+        }
+
+    }
+
+    @Override protected Object createSnapshot() {
+        throw new UnsupportedOperationException("createSnapshot");
+    }
+
+    @Override protected void applySnapshot(Object snapshot) {
+        throw new UnsupportedOperationException("applySnapshot");
+    }
+
+    @Override public String persistenceId() {
+        return this.name;
+    }
 }
index 4e2369d3758596bd1217670f8f3ec5a2438db36d..5fbce4cd98900be65053939ca7a51d4f7a929a98 100644 (file)
@@ -11,15 +11,19 @@ package org.opendaylight.controller.cluster.datastore;
 import akka.actor.ActorPath;
 import akka.actor.ActorRef;
 import akka.actor.Address;
+import akka.actor.OneForOneStrategy;
 import akka.actor.Props;
-import akka.actor.UntypedActor;
-import akka.event.Logging;
-import akka.event.LoggingAdapter;
+import akka.actor.SupervisorStrategy;
+import akka.cluster.ClusterEvent;
 import akka.japi.Creator;
+import akka.japi.Function;
+import com.google.common.base.Preconditions;
 import org.opendaylight.controller.cluster.datastore.messages.FindPrimary;
+import org.opendaylight.controller.cluster.datastore.messages.PeerAddressResolved;
 import org.opendaylight.controller.cluster.datastore.messages.PrimaryFound;
 import org.opendaylight.controller.cluster.datastore.messages.PrimaryNotFound;
 import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
+import scala.concurrent.duration.Duration;
 
 import java.util.HashMap;
 import java.util.List;
@@ -48,56 +52,244 @@ import java.util.Map;
  * <li> When a local shard replica comes alive
  * </p>
  */
-public class ShardManager extends UntypedActor {
-
-  // Stores a mapping between a shard name and the address of the current primary
-  private final Map<String, Address> shardNameToPrimaryAddress = new HashMap<>();
-
-  // Stores a mapping between a member name and the address of the member
-  private final Map<String, Address> memberNameToAddress = new HashMap<>();
-
-  // Stores a mapping between the shard name and all the members on which a replica of that shard are available
-  private final Map<String, List<String>> shardNameToMembers = new HashMap<>();
-
-  private final LoggingAdapter log = Logging.getLogger(getContext().system(), this);
-
-  private final ActorPath defaultShardPath;
-
-  /**
-   *
-   * @param type defines the kind of data that goes into shards created by this shard manager. Examples of type would be
-   *             configuration or operational
-   */
-  private ShardManager(String type){
-    ActorRef actor = getContext().actorOf(Shard.props(Shard.DEFAULT_NAME + "-" + type));
-    defaultShardPath = actor.path();
-  }
-
-  public static Props props(final String type){
-    return Props.create(new Creator<ShardManager>(){
-
-      @Override
-      public ShardManager create() throws Exception {
-        return new ShardManager(type);
-      }
-    });
-  }
-
-  @Override
-  public void onReceive(Object message) throws Exception {
-    if (message instanceof FindPrimary) {
-      FindPrimary msg = ((FindPrimary) message);
-      String shardName = msg.getShardName();
-      if(Shard.DEFAULT_NAME.equals(shardName)){
-        getSender().tell(new PrimaryFound(defaultShardPath.toString()), getSelf());
-      } else {
-        getSender().tell(new PrimaryNotFound(shardName), getSelf());
-      }
-    } else if(message instanceof UpdateSchemaContext){
-        // FIXME : Notify all local shards of a context change
-        getContext().system().actorSelection(defaultShardPath).forward(message, getContext());
+public class ShardManager extends AbstractUntypedActor {
+
+    // Stores a mapping between a member name and the address of the member
+    private final Map<String, Address> memberNameToAddress = new HashMap<>();
+
+    private final Map<String, ShardInformation> localShards = new HashMap<>();
+
+
+    private final String type;
+
+    private final ClusterWrapper cluster;
+
+    private final Configuration configuration;
+
+    /**
+     * @param type defines the kind of data that goes into shards created by this shard manager. Examples of type would be
+     *             configuration or operational
+     */
+    private ShardManager(String type, ClusterWrapper cluster, Configuration configuration) {
+
+        this.type = Preconditions.checkNotNull(type, "type should not be null");
+        this.cluster = Preconditions.checkNotNull(cluster, "cluster should not be null");
+        this.configuration = Preconditions.checkNotNull(configuration, "configuration should not be null");
+
+        // Subscribe this actor to cluster member events
+        cluster.subscribeToMemberEvents(getSelf());
+
+        // Create all the local Shards and make them a child of the ShardManager
+        // TODO: This may need to be initiated when we first get the schema context
+        createLocalShards();
+    }
+
+    public static Props props(final String type,
+        final ClusterWrapper cluster,
+        final Configuration configuration) {
+        return Props.create(new Creator<ShardManager>() {
+
+            @Override
+            public ShardManager create() throws Exception {
+                return new ShardManager(type, cluster, configuration);
+            }
+        });
+    }
+
+
+    @Override
+    public void handleReceive(Object message) throws Exception {
+        if (message.getClass().equals(FindPrimary.SERIALIZABLE_CLASS)) {
+            findPrimary(
+                FindPrimary.fromSerializable(message));
+
+        } else if (message instanceof UpdateSchemaContext) {
+            updateSchemaContext(message);
+        } else if (message instanceof ClusterEvent.MemberUp){
+            memberUp((ClusterEvent.MemberUp) message);
+        } else if(message instanceof ClusterEvent.MemberRemoved) {
+            memberRemoved((ClusterEvent.MemberRemoved) message);
+        } else if(message instanceof ClusterEvent.UnreachableMember) {
+            ignoreMessage(message);
+        } else{
+          throw new Exception ("Not recognized message received, message="+message);
+        }
+
+    }
+
+    private void ignoreMessage(Object message){
+        LOG.debug("Unhandled message : " + message);
+    }
+
+    private void memberRemoved(ClusterEvent.MemberRemoved message) {
+        memberNameToAddress.remove(message.member().roles().head());
+    }
+
+    private void memberUp(ClusterEvent.MemberUp message) {
+        String memberName = message.member().roles().head();
+
+        memberNameToAddress.put(memberName , message.member().address());
+
+        for(ShardInformation info : localShards.values()){
+            String shardName = info.getShardName();
+            info.updatePeerAddress(getShardActorName(memberName, shardName),
+                getShardActorPath(shardName, memberName));
+        }
+    }
+
+    private void updateSchemaContext(Object message) {
+        for(ShardInformation info : localShards.values()){
+            info.getActor().tell(message,getSelf());
+        }
     }
-  }
 
+    private void findPrimary(FindPrimary message) {
+        String shardName = message.getShardName();
 
+        List<String> members =
+            configuration.getMembersFromShardName(shardName);
+
+        // First see if the there is a local replica for the shard
+        ShardInformation info = localShards.get(shardName);
+        if(info != null) {
+            ActorPath shardPath = info.getActorPath();
+            if (shardPath != null) {
+                getSender()
+                    .tell(
+                        new PrimaryFound(shardPath.toString()).toSerializable(),
+                        getSelf());
+                return;
+            }
+        }
+
+        if(cluster.getCurrentMemberName() != null) {
+            members.remove(cluster.getCurrentMemberName());
+        }
+
+        // There is no way for us to figure out the primary (for now) so assume
+        // that one of the remote nodes is a primary
+        for(String memberName : members) {
+            Address address = memberNameToAddress.get(memberName);
+            if(address != null){
+                String path =
+                    getShardActorPath(shardName, memberName);
+                getSender().tell(new PrimaryFound(path).toSerializable(), getSelf());
+                return;
+            }
+        }
+        getSender().tell(new PrimaryNotFound(shardName).toSerializable(), getSelf());
+    }
+
+    private String
+
+
+    getShardActorPath(String shardName, String memberName) {
+        Address address = memberNameToAddress.get(memberName);
+        if(address != null) {
+            return address.toString() + "/user/shardmanager-" + this.type + "/"
+                + getShardActorName(
+                memberName, shardName);
+        }
+        return null;
+    }
+
+    private String getShardActorName(String memberName, String shardName){
+        return memberName + "-shard-" + shardName + "-" + this.type;
+    }
+
+    // Create the shards that are local to this member
+    private void createLocalShards() {
+        String memberName = this.cluster.getCurrentMemberName();
+        List<String> memberShardNames =
+            this.configuration.getMemberShardNames(memberName);
+
+        for(String shardName : memberShardNames){
+            String shardActorName = getShardActorName(memberName, shardName);
+            Map<String, String> peerAddresses = getPeerAddresses(shardName);
+            ActorRef actor = getContext()
+                .actorOf(Shard.props(shardActorName, peerAddresses),
+                    shardActorName);
+            localShards.put(shardName, new ShardInformation(shardName, actor, peerAddresses));
+        }
+
+    }
+
+    private Map<String, String> getPeerAddresses(String shardName){
+
+        Map<String, String> peerAddresses = new HashMap<>();
+
+        List<String> members =
+            this.configuration.getMembersFromShardName(shardName);
+
+        String currentMemberName = this.cluster.getCurrentMemberName();
+
+        for(String memberName : members){
+            if(!currentMemberName.equals(memberName)){
+                String shardActorName = getShardActorName(memberName, shardName);
+                String path =
+                    getShardActorPath(shardName, currentMemberName);
+                peerAddresses.put(shardActorName, path);
+            }
+        }
+        return peerAddresses;
+    }
+
+
+    @Override
+    public SupervisorStrategy supervisorStrategy() {
+        return new OneForOneStrategy(10, Duration.create("1 minute"),
+            new Function<Throwable, SupervisorStrategy.Directive>() {
+                @Override
+                public SupervisorStrategy.Directive apply(Throwable t) {
+                    return SupervisorStrategy.resume();
+                }
+            }
+        );
+
+    }
+
+    private class ShardInformation {
+        private final String shardName;
+        private final ActorRef actor;
+        private final ActorPath actorPath;
+        private final Map<String, String> peerAddresses;
+
+        private ShardInformation(String shardName, ActorRef actor,
+            Map<String, String> peerAddresses) {
+            this.shardName = shardName;
+            this.actor = actor;
+            this.actorPath = actor.path();
+            this.peerAddresses = peerAddresses;
+        }
+
+        public String getShardName() {
+            return shardName;
+        }
+
+        public ActorRef getActor(){
+            return actor;
+        }
+
+        public ActorPath getActorPath() {
+            return actorPath;
+        }
+
+        public Map<String, String> getPeerAddresses() {
+            return peerAddresses;
+        }
+
+        public void updatePeerAddress(String peerId, String peerAddress){
+            LOG.info("updatePeerAddress for peer {} with address {}", peerId, peerAddress);
+            if(peerAddresses.containsKey(peerId)){
+                peerAddresses.put(peerId, peerAddress);
+
+                LOG.info("Sending PeerAddressResolved for peer {} with address {} to {}", peerId, peerAddress, actor.path());
+
+                actor
+                    .tell(new PeerAddressResolved(peerId, peerAddress),
+                        getSelf());
+
+            }
+        }
+    }
 }
index 75744cad5b920b942efda865d0fa6ed29c41f3d7..737f57bf5d7314536f5fc20b1cbc45167f1b6e97 100644 (file)
@@ -9,8 +9,8 @@
 package org.opendaylight.controller.cluster.datastore;
 
 import akka.actor.ActorRef;
+import akka.actor.PoisonPill;
 import akka.actor.Props;
-import akka.actor.UntypedActor;
 import akka.event.Logging;
 import akka.event.LoggingAdapter;
 import akka.japi.Creator;
@@ -36,23 +36,25 @@ import org.opendaylight.controller.cluster.datastore.modification.MutableComposi
 import org.opendaylight.controller.cluster.datastore.modification.WriteModification;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 import java.util.concurrent.ExecutionException;
 
 /**
  * The ShardTransaction Actor represents a remote transaction
- *<p>
+ * <p>
  * The ShardTransaction Actor delegates all actions to DOMDataReadWriteTransaction
- *</p>
- *<p>
+ * </p>
+ * <p>
  * Even though the DOMStore and the DOMStoreTransactionChain implement multiple types of transactions
  * the ShardTransaction Actor only works with read-write transactions. This is just to keep the logic simple. At this
  * time there are no known advantages for creating a read-only or write-only transaction which may change over time
  * at which point we can optimize things in the distributed store as well.
- *</p>
- *<p>
+ * </p>
+ * <p>
  * Handles Messages <br/>
  * ---------------- <br/>
  * <li> {@link org.opendaylight.controller.cluster.datastore.messages.ReadData}
@@ -63,125 +65,170 @@ import java.util.concurrent.ExecutionException;
  * <li> {@link org.opendaylight.controller.cluster.datastore.messages.CloseTransaction}
  * </p>
  */
-public class ShardTransaction extends UntypedActor {
-
-  private final ActorRef shardActor;
-
-  private final DOMStoreReadWriteTransaction transaction;
-
-  private final MutableCompositeModification modification = new MutableCompositeModification();
-
-  private final LoggingAdapter log = Logging.getLogger(getContext().system(), this);
-
-  public ShardTransaction(DOMStoreReadWriteTransaction transaction, ActorRef shardActor) {
-    this.transaction = transaction;
-    this.shardActor = shardActor;
-  }
-
-
-  public static Props props(final DOMStoreReadWriteTransaction transaction, final ActorRef shardActor){
-    return Props.create(new Creator<ShardTransaction>(){
-
-      @Override
-      public ShardTransaction create() throws Exception {
-        return new ShardTransaction(transaction, shardActor);
-      }
-    });
-  }
-
-  @Override
-  public void onReceive(Object message) throws Exception {
-    if(message instanceof ReadData){
-      readData((ReadData) message);
-    } else if(message instanceof WriteData){
-      writeData((WriteData) message);
-    } else if(message instanceof MergeData){
-      mergeData((MergeData) message);
-    } else if(message instanceof DeleteData){
-      deleteData((DeleteData) message);
-    } else if(message instanceof ReadyTransaction){
-      readyTransaction((ReadyTransaction) message);
-    } else if(message instanceof CloseTransaction){
-      closeTransaction((CloseTransaction) message);
-    } else if(message instanceof GetCompositedModification){
-      // This is here for testing only
-      getSender().tell(new GetCompositeModificationReply(new ImmutableCompositeModification(modification)), getSelf());
+public class ShardTransaction extends AbstractUntypedActor {
+
+    private final ActorRef shardActor;
+    private final SchemaContext schemaContext;
+
+    // FIXME : see below
+    // If transactionChain is not null then this transaction is part of a
+    // transactionChain. Not really clear as to what that buys us
+    private final DOMStoreTransactionChain transactionChain;
+
+    private final DOMStoreReadWriteTransaction transaction;
+
+    private final MutableCompositeModification modification =
+        new MutableCompositeModification();
+
+    private final LoggingAdapter log =
+        Logging.getLogger(getContext().system(), this);
+
+    public ShardTransaction(DOMStoreReadWriteTransaction transaction,
+        ActorRef shardActor, SchemaContext schemaContext) {
+        this(null, transaction, shardActor, schemaContext);
     }
-  }
-
-  private void readData(ReadData message) {
-    final ActorRef sender = getSender();
-    final ActorRef self = getSelf();
-    final InstanceIdentifier path = message.getPath();
-    final ListenableFuture<Optional<NormalizedNode<?, ?>>> future = transaction.read(path);
-
-    future.addListener(new Runnable() {
-      @Override
-      public void run() {
-        try {
-          Optional<NormalizedNode<?, ?>> optional = future.get();
-          if(optional.isPresent()){
-            sender.tell(new ReadDataReply(optional.get()), self);
-          } else {
-            //TODO : Need to decide what to do here
-          }
-        } catch (InterruptedException | ExecutionException e) {
-          log.error(e, "An exception happened when reading data from path : " + path.toString());
-        }
 
-      }
-    }, getContext().dispatcher());
-  }
+    public ShardTransaction(DOMStoreTransactionChain transactionChain, DOMStoreReadWriteTransaction transaction,
+        ActorRef shardActor, SchemaContext schemaContext) {
+        this.transactionChain = transactionChain;
+        this.transaction = transaction;
+        this.shardActor = shardActor;
+        this.schemaContext = schemaContext;
+    }
 
 
-  private void writeData(WriteData message){
-    modification.addModification(new WriteModification(message.getPath(), message.getData()));
-    transaction.write(message.getPath(), message.getData());
-    getSender().tell(new WriteDataReply(), getSelf());
-  }
 
-  private void mergeData(MergeData message){
-    modification.addModification(new MergeModification(message.getPath(), message.getData()));
-    transaction.merge(message.getPath(), message.getData());
-    getSender().tell(new MergeDataReply(), getSelf());
-  }
+    public static Props props(final DOMStoreReadWriteTransaction transaction,
+        final ActorRef shardActor, final SchemaContext schemaContext) {
+        return Props.create(new Creator<ShardTransaction>() {
 
-  private void deleteData(DeleteData message){
-    modification.addModification(new DeleteModification(message.getPath()));
-    transaction.delete(message.getPath());
-    getSender().tell(new DeleteDataReply(), getSelf());
-  }
+            @Override
+            public ShardTransaction create() throws Exception {
+                return new ShardTransaction(transaction, shardActor, schemaContext);
+            }
+        });
+    }
 
-  private void readyTransaction(ReadyTransaction message){
-    DOMStoreThreePhaseCommitCohort cohort = transaction.ready();
-    ActorRef cohortActor = getContext().actorOf(ThreePhaseCommitCohort.props(cohort, shardActor, modification));
-    getSender().tell(new ReadyTransactionReply(cohortActor.path()), getSelf());
+    public static Props props(final DOMStoreTransactionChain transactionChain, final DOMStoreReadWriteTransaction transaction,
+        final ActorRef shardActor, final SchemaContext schemaContext) {
+        return Props.create(new Creator<ShardTransaction>() {
 
-  }
+            @Override
+            public ShardTransaction create() throws Exception {
+                return new ShardTransaction(transactionChain, transaction, shardActor, schemaContext);
+            }
+        });
+    }
 
-  private void closeTransaction(CloseTransaction message){
-    transaction.close();
-    getSender().tell(new CloseTransactionReply(), getSelf());
-  }
 
+    @Override
+    public void handleReceive(Object message) throws Exception {
+        if (ReadData.SERIALIZABLE_CLASS.equals(message.getClass())) {
+            readData(ReadData.fromSerializable(message));
+        } else if (WriteData.SERIALIZABLE_CLASS.equals(message.getClass())) {
+            writeData(WriteData.fromSerializable(message, schemaContext));
+        } else if (MergeData.SERIALIZABLE_CLASS.equals(message.getClass())) {
+            mergeData(MergeData.fromSerializable(message, schemaContext));
+        } else if (DeleteData.SERIALIZABLE_CLASS.equals(message.getClass())) {
+            deleteData(DeleteData.fromSerizalizable(message));
+        } else if (ReadyTransaction.SERIALIZABLE_CLASS.equals(message.getClass())) {
+            readyTransaction(new ReadyTransaction());
+        } else if (message.getClass().equals(CloseTransaction.SERIALIZABLE_CLASS)) {
+            closeTransaction(new CloseTransaction());
+        } else if (message instanceof GetCompositedModification) {
+            // This is here for testing only
+            getSender().tell(new GetCompositeModificationReply(
+                new ImmutableCompositeModification(modification)), getSelf());
+        }else{
+          throw new Exception ("Shard:handleRecieve received an unknown message"+message);
+        }
+    }
 
-  // These classes are in here for test purposes only
+    private void readData(ReadData message) {
+        final ActorRef sender = getSender();
+        final ActorRef self = getSelf();
+        final YangInstanceIdentifier path = message.getPath();
+        final ListenableFuture<Optional<NormalizedNode<?, ?>>> future =
+            transaction.read(path);
+
+        future.addListener(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Optional<NormalizedNode<?, ?>> optional = future.get();
+                    if (optional.isPresent()) {
+                        sender.tell(new ReadDataReply(schemaContext,optional.get()).toSerializable(), self);
+                    } else {
+                        sender.tell(new ReadDataReply(schemaContext,null).toSerializable(), self);
+                    }
+                } catch (InterruptedException | ExecutionException e) {
+                    log.error(e,
+                        "An exception happened when reading data from path : "
+                            + path.toString());
+                }
+
+            }
+        }, getContext().dispatcher());
+    }
 
-  static class GetCompositedModification {
 
-  }
+    private void writeData(WriteData message) {
+        modification.addModification(
+            new WriteModification(message.getPath(), message.getData(),schemaContext));
+        LOG.debug("writeData at path : " + message.getPath().toString());
+        transaction.write(message.getPath(), message.getData());
+        getSender().tell(new WriteDataReply().toSerializable(), getSelf());
+    }
 
-  static class GetCompositeModificationReply {
-    private final CompositeModification modification;
+    private void mergeData(MergeData message) {
+        modification.addModification(
+            new MergeModification(message.getPath(), message.getData(), schemaContext));
+        LOG.debug("mergeData at path : " + message.getPath().toString());
+        transaction.merge(message.getPath(), message.getData());
+        getSender().tell(new MergeDataReply().toSerializable(), getSelf());
+    }
 
+    private void deleteData(DeleteData message) {
+        modification.addModification(new DeleteModification(message.getPath()));
+        transaction.delete(message.getPath());
+        getSender().tell(new DeleteDataReply().toSerializable(), getSelf());
+    }
+
+    private void readyTransaction(ReadyTransaction message) {
+        DOMStoreThreePhaseCommitCohort cohort = transaction.ready();
+        ActorRef cohortActor = getContext().actorOf(
+            ThreePhaseCommitCohort.props(cohort, shardActor, modification), "cohort");
+        getSender()
+            .tell(new ReadyTransactionReply(cohortActor.path()).toSerializable(), getSelf());
+
+    }
+
+    private void closeTransaction(CloseTransaction message) {
+        transaction.close();
+        getSender().tell(new CloseTransactionReply().toSerializable(), getSelf());
+        getSelf().tell(PoisonPill.getInstance(), getSelf());
+    }
+
+
+    // These classes are in here for test purposes only
+
+
+    static class GetCompositedModification {
 
-    GetCompositeModificationReply(CompositeModification modification) {
-      this.modification = modification;
     }
 
 
-    public CompositeModification getModification() {
-      return modification;
+    static class GetCompositeModificationReply {
+        private final CompositeModification modification;
+
+
+        GetCompositeModificationReply(CompositeModification modification) {
+            this.modification = modification;
+        }
+
+
+        public CompositeModification getModification() {
+            return modification;
+        }
     }
-  }
 }
index 79aaa86b28baaa71f161dceca0d56f59528d94a1..50042411b17eeb0b0428963535008e8a777ca915 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.controller.cluster.datastore;
 
 import akka.actor.ActorRef;
 import akka.actor.Props;
-import akka.actor.UntypedActor;
 import akka.japi.Creator;
 import org.opendaylight.controller.cluster.datastore.messages.CloseTransactionChain;
 import org.opendaylight.controller.cluster.datastore.messages.CloseTransactionChainReply;
@@ -18,37 +17,51 @@ import org.opendaylight.controller.cluster.datastore.messages.CreateTransaction;
 import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionReply;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 /**
  * The ShardTransactionChain Actor represents a remote TransactionChain
  */
-public class ShardTransactionChain extends UntypedActor{
-
-  private final DOMStoreTransactionChain chain;
-
-  public ShardTransactionChain(DOMStoreTransactionChain chain) {
-    this.chain = chain;
-  }
-
-  @Override
-  public void onReceive(Object message) throws Exception {
-    if(message instanceof CreateTransaction){
-      DOMStoreReadWriteTransaction transaction = chain.newReadWriteTransaction();
-      ActorRef transactionActor = getContext().actorOf(ShardTransaction.props(transaction, getContext().parent()));
-      getSender().tell(new CreateTransactionReply(transactionActor.path()), getSelf());
-    } else if (message instanceof CloseTransactionChain){
-      chain.close();
-      getSender().tell(new CloseTransactionChainReply(), getSelf());
+public class ShardTransactionChain extends AbstractUntypedActor {
+
+    private final DOMStoreTransactionChain chain;
+    private final SchemaContext schemaContext;
+
+    public ShardTransactionChain(DOMStoreTransactionChain chain, SchemaContext schemaContext) {
+        this.chain = chain;
+        this.schemaContext = schemaContext;
     }
-  }
 
-  public static Props props(final DOMStoreTransactionChain chain){
-    return Props.create(new Creator<ShardTransactionChain>(){
+    @Override
+    public void handleReceive(Object message) throws Exception {
+        if (message.getClass().equals(CreateTransaction.SERIALIZABLE_CLASS)) {
+            CreateTransaction createTransaction = CreateTransaction.fromSerializable( message);
+            createTransaction(createTransaction);
+        } else if (message.getClass().equals(CloseTransactionChain.SERIALIZABLE_CLASS)) {
+            chain.close();
+            getSender().tell(new CloseTransactionChainReply().toSerializable(), getSelf());
+        }else{
+          throw new Exception("Not recognized message recieved="+message);
+        }
+    }
 
-      @Override
-      public ShardTransactionChain create() throws Exception {
-        return new ShardTransactionChain(chain);
-      }
-    });
-  }
+    private void createTransaction(CreateTransaction createTransaction) {
+        DOMStoreReadWriteTransaction transaction =
+            chain.newReadWriteTransaction();
+        ActorRef transactionActor = getContext().actorOf(ShardTransaction
+            .props(chain, transaction, getContext().parent(), schemaContext), "shard-" + createTransaction.getTransactionId());
+        getSender()
+            .tell(new CreateTransactionReply(transactionActor.path().toString(),createTransaction.getTransactionId()).toSerializable(),
+                getSelf());
+    }
+
+    public static Props props(final DOMStoreTransactionChain chain, final SchemaContext schemaContext) {
+        return Props.create(new Creator<ShardTransactionChain>() {
+
+            @Override
+            public ShardTransactionChain create() throws Exception {
+                return new ShardTransactionChain(chain, schemaContext);
+            }
+        });
+    }
 }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TerminationMonitor.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/TerminationMonitor.java
new file mode 100644 (file)
index 0000000..e6ac7f8
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.Terminated;
+import akka.actor.UntypedActor;
+import akka.event.Logging;
+import akka.event.LoggingAdapter;
+import org.opendaylight.controller.cluster.datastore.messages.Monitor;
+
+public class TerminationMonitor extends UntypedActor{
+    protected final LoggingAdapter LOG =
+        Logging.getLogger(getContext().system(), this);
+
+    public TerminationMonitor(){
+        LOG.info("Created TerminationMonitor");
+    }
+
+    @Override public void onReceive(Object message) throws Exception {
+        if(message instanceof Terminated){
+            Terminated terminated = (Terminated) message;
+            LOG.debug("Actor terminated : {}", terminated.actor());
+        } else if(message instanceof Monitor){
+            Monitor monitor = (Monitor) message;
+            getContext().watch(monitor.getActorRef());
+        }
+    }
+}
index 61baf1ab64421e04f76d52ec684709ca33f38d25..a8deb0153a400eefbf28fd4269892c86ea61ef35 100644 (file)
@@ -9,8 +9,8 @@
 package org.opendaylight.controller.cluster.datastore;
 
 import akka.actor.ActorRef;
+import akka.actor.PoisonPill;
 import akka.actor.Props;
-import akka.actor.UntypedActor;
 import akka.event.Logging;
 import akka.event.LoggingAdapter;
 import akka.japi.Creator;
@@ -28,101 +28,112 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCoh
 
 import java.util.concurrent.ExecutionException;
 
-public class ThreePhaseCommitCohort extends UntypedActor{
-  private final DOMStoreThreePhaseCommitCohort cohort;
-  private final ActorRef shardActor;
-  private final CompositeModification modification;
-
-  public ThreePhaseCommitCohort(DOMStoreThreePhaseCommitCohort cohort, ActorRef shardActor, CompositeModification modification) {
-    this.cohort = cohort;
-    this.shardActor = shardActor;
-    this.modification = modification;
-  }
-
-  private final LoggingAdapter log = Logging.getLogger(getContext().system(), this);
-
-  public static Props props(final DOMStoreThreePhaseCommitCohort cohort, final ActorRef shardActor, final CompositeModification modification) {
-    return Props.create(new Creator<ThreePhaseCommitCohort>(){
-      @Override
-      public ThreePhaseCommitCohort create() throws Exception {
-        return new ThreePhaseCommitCohort(cohort, shardActor, modification);
-      }
-    });
-  }
-
-  @Override
-  public void onReceive(Object message) throws Exception {
-    if(message instanceof CanCommitTransaction){
-      canCommit((CanCommitTransaction) message);
-    } else if(message instanceof PreCommitTransaction) {
-      preCommit((PreCommitTransaction) message);
-    } else if(message instanceof CommitTransaction){
-      commit((CommitTransaction) message);
-    } else if (message instanceof AbortTransaction){
-      abort((AbortTransaction) message);
+public class ThreePhaseCommitCohort extends AbstractUntypedActor {
+    private final DOMStoreThreePhaseCommitCohort cohort;
+    private final ActorRef shardActor;
+    private final CompositeModification modification;
+
+    public ThreePhaseCommitCohort(DOMStoreThreePhaseCommitCohort cohort,
+        ActorRef shardActor, CompositeModification modification) {
+
+        this.cohort = cohort;
+        this.shardActor = shardActor;
+        this.modification = modification;
     }
-  }
-
-  private void abort(AbortTransaction message) {
-    final ListenableFuture<Void> future = cohort.abort();
-    final ActorRef sender = getSender();
-    final ActorRef self = getSelf();
-
-    future.addListener(new Runnable() {
-      @Override
-      public void run() {
-        try {
-          future.get();
-          sender.tell(new AbortTransactionReply(), self);
-        } catch (InterruptedException | ExecutionException e) {
-          log.error(e, "An exception happened when aborting");
-        }
-      }
-    }, getContext().dispatcher());
-  }
-
-  private void commit(CommitTransaction message) {
-    // Forward the commit to the shard
-    log.info("Commit transaction now + " + shardActor);
-    shardActor.forward(new ForwardedCommitTransaction(cohort, modification), getContext());
-
-  }
-
-  private void preCommit(PreCommitTransaction message) {
-    final ListenableFuture<Void> future = cohort.preCommit();
-    final ActorRef sender = getSender();
-    final ActorRef self = getSelf();
-
-    future.addListener(new Runnable() {
-      @Override
-      public void run() {
-        try {
-          future.get();
-          sender.tell(new PreCommitTransactionReply(), self);
-        } catch (InterruptedException | ExecutionException e) {
-          log.error(e, "An exception happened when preCommitting");
-        }
-      }
-    }, getContext().dispatcher());
-
-  }
-
-  private void canCommit(CanCommitTransaction message) {
-    final ListenableFuture<Boolean> future = cohort.canCommit();
-    final ActorRef sender = getSender();
-    final ActorRef self = getSelf();
-
-    future.addListener(new Runnable() {
-      @Override
-      public void run() {
-        try {
-          Boolean canCommit = future.get();
-          sender.tell(new CanCommitTransactionReply(canCommit), self);
-        } catch (InterruptedException | ExecutionException e) {
-          log.error(e, "An exception happened when aborting");
+
+    private final LoggingAdapter log =
+        Logging.getLogger(getContext().system(), this);
+
+    public static Props props(final DOMStoreThreePhaseCommitCohort cohort,
+        final ActorRef shardActor, final CompositeModification modification) {
+        return Props.create(new Creator<ThreePhaseCommitCohort>() {
+            @Override
+            public ThreePhaseCommitCohort create() throws Exception {
+                return new ThreePhaseCommitCohort(cohort, shardActor,
+                    modification);
+            }
+        });
+    }
+
+
+    @Override
+    public void handleReceive(Object message) throws Exception {
+        if (message.getClass().equals(CanCommitTransaction.SERIALIZABLE_CLASS)) {
+            canCommit(new CanCommitTransaction());
+        } else if (message.getClass().equals(PreCommitTransaction.SERIALIZABLE_CLASS)) {
+            preCommit(new PreCommitTransaction());
+        } else if (message.getClass().equals(CommitTransaction.SERIALIZABLE_CLASS)) {
+            commit(new CommitTransaction());
+        } else if (message.getClass().equals(AbortTransaction.SERIALIZABLE_CLASS)) {
+            abort(new AbortTransaction());
+        } else {
+          throw new Exception ("Not recognized message received,message="+message);
         }
-      }
-    }, getContext().dispatcher());
+    }
+
+    private void abort(AbortTransaction message) {
+        final ListenableFuture<Void> future = cohort.abort();
+        final ActorRef sender = getSender();
+        final ActorRef self = getSelf();
+
+        future.addListener(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    future.get();
+                    sender.tell(new AbortTransactionReply().toSerializable(), self);
+                } catch (InterruptedException | ExecutionException e) {
+                    log.error(e, "An exception happened when aborting");
+                }
+            }
+        }, getContext().dispatcher());
+    }
+
+    private void commit(CommitTransaction message) {
+        // Forward the commit to the shard
+        log.debug("Forward commit transaction to Shard {} ", shardActor);
+        shardActor.forward(new ForwardedCommitTransaction(cohort, modification),
+            getContext());
+
+        getContext().parent().tell(PoisonPill.getInstance(), getSelf());
+
+    }
 
-  }
+    private void preCommit(PreCommitTransaction message) {
+        final ListenableFuture<Void> future = cohort.preCommit();
+        final ActorRef sender = getSender();
+        final ActorRef self = getSelf();
+
+        future.addListener(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    future.get();
+                    sender.tell(new PreCommitTransactionReply().toSerializable(), self);
+                } catch (InterruptedException | ExecutionException e) {
+                    log.error(e, "An exception happened when preCommitting");
+                }
+            }
+        }, getContext().dispatcher());
+
+    }
+
+    private void canCommit(CanCommitTransaction message) {
+        final ListenableFuture<Boolean> future = cohort.canCommit();
+        final ActorRef sender = getSender();
+        final ActorRef self = getSelf();
+
+        future.addListener(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Boolean canCommit = future.get();
+                    sender.tell(new CanCommitTransactionReply(canCommit).toSerializable(), self);
+                } catch (InterruptedException | ExecutionException e) {
+                    log.error(e, "An exception happened when aborting");
+                }
+            }
+        }, getContext().dispatcher());
+
+    }
 }
index 197b3b70cefa292e3829b776560b4cd2ae99967f..b56dc9432f0b28067ca2daaba1cd95f936cb816e 100644 (file)
@@ -9,11 +9,27 @@
 package org.opendaylight.controller.cluster.datastore;
 
 import akka.actor.ActorPath;
+import akka.actor.ActorSelection;
 import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListenableFutureTask;
+import org.opendaylight.controller.cluster.datastore.exceptions.TimeoutException;
+import org.opendaylight.controller.cluster.datastore.messages.AbortTransaction;
+import org.opendaylight.controller.cluster.datastore.messages.AbortTransactionReply;
+import org.opendaylight.controller.cluster.datastore.messages.CanCommitTransaction;
+import org.opendaylight.controller.cluster.datastore.messages.CanCommitTransactionReply;
+import org.opendaylight.controller.cluster.datastore.messages.CommitTransaction;
+import org.opendaylight.controller.cluster.datastore.messages.CommitTransactionReply;
+import org.opendaylight.controller.cluster.datastore.messages.PreCommitTransaction;
+import org.opendaylight.controller.cluster.datastore.messages.PreCommitTransactionReply;
+import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
 
 /**
  * ThreePhaseCommitCohortProxy represents a set of remote cohort proxies
@@ -21,27 +37,114 @@ import java.util.List;
 public class ThreePhaseCommitCohortProxy implements
     DOMStoreThreePhaseCommitCohort{
 
+    private static final Logger
+        LOG = LoggerFactory.getLogger(DistributedDataStore.class);
+
+    private final ActorContext actorContext;
     private final List<ActorPath> cohortPaths;
+    private final ExecutorService executor;
+    private final String transactionId;
+
 
-    public ThreePhaseCommitCohortProxy(List<ActorPath> cohortPaths) {
+    public ThreePhaseCommitCohortProxy(ActorContext actorContext,
+        List<ActorPath> cohortPaths,
+        String transactionId,
+        ExecutorService executor) {
 
+        this.actorContext = actorContext;
         this.cohortPaths = cohortPaths;
+        this.transactionId = transactionId;
+        this.executor = executor;
     }
 
     @Override public ListenableFuture<Boolean> canCommit() {
-        throw new UnsupportedOperationException("canCommit");
+        Callable<Boolean> call = new Callable() {
+
+            @Override public Boolean call() throws Exception {
+            for(ActorPath actorPath : cohortPaths){
+                ActorSelection cohort = actorContext.actorSelection(actorPath);
+
+                try {
+                    Object response =
+                        actorContext.executeRemoteOperation(cohort,
+                            new CanCommitTransaction().toSerializable(),
+                            ActorContext.ASK_DURATION);
+
+                    if (response.getClass().equals(CanCommitTransactionReply.SERIALIZABLE_CLASS)) {
+                        CanCommitTransactionReply reply =
+                            CanCommitTransactionReply.fromSerializable(response);
+                        if (!reply.getCanCommit()) {
+                            return false;
+                        }
+                    }
+                } catch(RuntimeException e){
+                    LOG.error("Unexpected Exception", e);
+                    return false;
+                }
+
+
+            }
+            return true;
+            }
+        };
+
+        ListenableFutureTask<Boolean>
+            future = ListenableFutureTask.create(call);
+
+        executor.submit(future);
+
+        return future;
     }
 
     @Override public ListenableFuture<Void> preCommit() {
-        throw new UnsupportedOperationException("preCommit");
+        return voidOperation(new PreCommitTransaction().toSerializable(), PreCommitTransactionReply.SERIALIZABLE_CLASS);
     }
 
     @Override public ListenableFuture<Void> abort() {
-        throw new UnsupportedOperationException("abort");
+        return voidOperation(new AbortTransaction().toSerializable(), AbortTransactionReply.SERIALIZABLE_CLASS);
     }
 
     @Override public ListenableFuture<Void> commit() {
-        throw new UnsupportedOperationException("commit");
+        return voidOperation(new CommitTransaction().toSerializable(), CommitTransactionReply.SERIALIZABLE_CLASS);
+    }
+
+    private ListenableFuture<Void> voidOperation(final Object message, final Class expectedResponseClass){
+        Callable<Void> call = new Callable<Void>() {
+
+            @Override public Void call() throws Exception {
+                for(ActorPath actorPath : cohortPaths){
+                    ActorSelection cohort = actorContext.actorSelection(actorPath);
+
+                    try {
+                        Object response =
+                            actorContext.executeRemoteOperation(cohort,
+                                message,
+                                ActorContext.ASK_DURATION);
+
+                        if (response != null && !response.getClass()
+                            .equals(expectedResponseClass)) {
+                            throw new RuntimeException(
+                                String.format(
+                                    "did not get the expected response \n\t\t expected : %s \n\t\t actual   : %s",
+                                    expectedResponseClass.toString(),
+                                    response.getClass().toString())
+                            );
+                        }
+                    } catch(TimeoutException e){
+                        LOG.error(String.format("A timeout occurred when processing operation : %s", message));
+                    }
+                }
+                return null;
+            }
+        };
+
+        ListenableFutureTask<Void>
+            future = ListenableFutureTask.create(call);
+
+        executor.submit(future);
+
+        return future;
+
     }
 
     public List<ActorPath> getCohortPaths() {
index 837ffc1b51dd8c5b2a80a3cf2f71a1076406648d..2e8538d07768479e336bfbcc877778e3c4872277 100644 (file)
@@ -13,37 +13,45 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import java.util.concurrent.ExecutorService;
 
 /**
  * TransactionChainProxy acts as a proxy for a DOMStoreTransactionChain created on a remote shard
  */
 public class TransactionChainProxy implements DOMStoreTransactionChain{
     private final ActorContext actorContext;
+    private final ExecutorService transactionExecutor;
+    private final SchemaContext schemaContext;
 
-    public TransactionChainProxy(ActorContext actorContext) {
+    public TransactionChainProxy(ActorContext actorContext, ExecutorService transactionExecutor, SchemaContext schemaContext) {
         this.actorContext = actorContext;
+        this.transactionExecutor = transactionExecutor;
+        this.schemaContext = schemaContext;
     }
 
     @Override
     public DOMStoreReadTransaction newReadOnlyTransaction() {
         return new TransactionProxy(actorContext,
-            TransactionProxy.TransactionType.READ_ONLY);
+            TransactionProxy.TransactionType.READ_ONLY, transactionExecutor, schemaContext);
     }
 
     @Override
     public DOMStoreReadWriteTransaction newReadWriteTransaction() {
         return new TransactionProxy(actorContext,
-            TransactionProxy.TransactionType.WRITE_ONLY);
+            TransactionProxy.TransactionType.WRITE_ONLY, transactionExecutor, schemaContext);
     }
 
     @Override
     public DOMStoreWriteTransaction newWriteOnlyTransaction() {
         return new TransactionProxy(actorContext,
-            TransactionProxy.TransactionType.READ_WRITE);
+            TransactionProxy.TransactionType.READ_WRITE, transactionExecutor, schemaContext);
     }
 
     @Override
     public void close() {
+        // FIXME : The problem here is don't know which shard the transaction chain is to be created on ???
         throw new UnsupportedOperationException("close - not sure what to do here?");
     }
 }
index 32bb7d0951964975b850c8a1a685ce7d95c03f47..c85d32012fed9ee036a96b2e3663c061eabd0385 100644 (file)
@@ -9,10 +9,14 @@
 package org.opendaylight.controller.cluster.datastore;
 
 import akka.actor.ActorPath;
+import akka.actor.ActorRef;
 import akka.actor.ActorSelection;
+import akka.actor.Props;
 import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListenableFutureTask;
+import org.opendaylight.controller.cluster.datastore.exceptions.TimeoutException;
 import org.opendaylight.controller.cluster.datastore.messages.CloseTransaction;
 import org.opendaylight.controller.cluster.datastore.messages.CreateTransaction;
 import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionReply;
@@ -23,18 +27,22 @@ import org.opendaylight.controller.cluster.datastore.messages.ReadDataReply;
 import org.opendaylight.controller.cluster.datastore.messages.ReadyTransaction;
 import org.opendaylight.controller.cluster.datastore.messages.ReadyTransactionReply;
 import org.opendaylight.controller.cluster.datastore.messages.WriteData;
+import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategyFactory;
 import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
-import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
 import java.util.concurrent.atomic.AtomicLong;
 
 /**
@@ -50,7 +58,6 @@ import java.util.concurrent.atomic.AtomicLong;
  * </p>
  */
 public class TransactionProxy implements DOMStoreReadWriteTransaction {
-
     public enum TransactionType {
         READ_ONLY,
         WRITE_ONLY,
@@ -59,90 +66,81 @@ public class TransactionProxy implements DOMStoreReadWriteTransaction {
 
     private static final AtomicLong counter = new AtomicLong();
 
-    private final TransactionType readOnly;
+    private static final Logger
+        LOG = LoggerFactory.getLogger(TransactionProxy.class);
+
+
+    private final TransactionType transactionType;
     private final ActorContext actorContext;
-    private final Map<String, ActorSelection> remoteTransactionPaths = new HashMap<>();
+    private final Map<String, TransactionContext> remoteTransactionPaths = new HashMap<>();
     private final String identifier;
+    private final ExecutorService executor;
+    private final SchemaContext schemaContext;
 
     public TransactionProxy(
         ActorContext actorContext,
-        TransactionType readOnly) {
+        TransactionType transactionType,
+        ExecutorService executor,
+        SchemaContext schemaContext
+    ) {
 
-        this.identifier = "transaction-" + counter.getAndIncrement();
-        this.readOnly = readOnly;
+        this.identifier = actorContext.getCurrentMemberName() + "-txn-" + counter.getAndIncrement();
+        this.transactionType = transactionType;
         this.actorContext = actorContext;
+        this.executor = executor;
+        this.schemaContext = schemaContext;
+
 
-        Object response = actorContext.executeShardOperation(Shard.DEFAULT_NAME, new CreateTransaction(), ActorContext.ASK_DURATION);
-        if(response instanceof CreateTransactionReply){
-            CreateTransactionReply reply = (CreateTransactionReply) response;
-            remoteTransactionPaths.put(Shard.DEFAULT_NAME, actorContext.actorSelection(reply.getTransactionPath()));
-        }
     }
 
     @Override
-    public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final InstanceIdentifier path) {
-        final ActorSelection remoteTransaction = remoteTransactionFromIdentifier(path);
-
-        Callable<Optional<NormalizedNode<?,?>>> call = new Callable() {
-
-            @Override public Optional<NormalizedNode<?,?>> call() throws Exception {
-                Object response = actorContext
-                    .executeRemoteOperation(remoteTransaction, new ReadData(path),
-                        ActorContext.ASK_DURATION);
-                if(response instanceof ReadDataReply){
-                    ReadDataReply reply = (ReadDataReply) response;
-                    //FIXME : A cast should not be required here ???
-                    return (Optional<NormalizedNode<?, ?>>) Optional.of(reply.getNormalizedNode());
-                }
+    public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final YangInstanceIdentifier path) {
 
-                return Optional.absent();
-            }
-        };
+        createTransactionIfMissing(actorContext, path);
 
-        ListenableFutureTask<Optional<NormalizedNode<?, ?>>>
-            future = ListenableFutureTask.create(call);
-
-        //FIXME : Use a thread pool here
-        Executors.newSingleThreadExecutor().submit(future);
-
-        return future;
+        return transactionContext(path).readData(path);
     }
 
     @Override
-    public void write(InstanceIdentifier path, NormalizedNode<?, ?> data) {
-        final ActorSelection remoteTransaction = remoteTransactionFromIdentifier(path);
-        remoteTransaction.tell(new WriteData(path, data), null);
+    public void write(YangInstanceIdentifier path, NormalizedNode<?, ?> data) {
+
+        createTransactionIfMissing(actorContext, path);
+
+        transactionContext(path).writeData(path, data);
     }
 
     @Override
-    public void merge(InstanceIdentifier path, NormalizedNode<?, ?> data) {
-        final ActorSelection remoteTransaction = remoteTransactionFromIdentifier(path);
-        remoteTransaction.tell(new MergeData(path, data), null);
+    public void merge(YangInstanceIdentifier path, NormalizedNode<?, ?> data) {
+
+        createTransactionIfMissing(actorContext, path);
+
+        transactionContext(path).mergeData(path, data);
     }
 
     @Override
-    public void delete(InstanceIdentifier path) {
-        final ActorSelection remoteTransaction = remoteTransactionFromIdentifier(path);
-        remoteTransaction.tell(new DeleteData(path), null);
+    public void delete(YangInstanceIdentifier path) {
+
+        createTransactionIfMissing(actorContext, path);
+
+        transactionContext(path).deleteData(path);
     }
 
     @Override
     public DOMStoreThreePhaseCommitCohort ready() {
         List<ActorPath> cohortPaths = new ArrayList<>();
 
-        for(ActorSelection remoteTransaction : remoteTransactionPaths.values()) {
-            Object result = actorContext.executeRemoteOperation(remoteTransaction,
-                new ReadyTransaction(),
-                ActorContext.ASK_DURATION
-            );
+        for(TransactionContext transactionContext : remoteTransactionPaths.values()) {
+            Object result = transactionContext.readyTransaction();
 
-            if(result instanceof ReadyTransactionReply){
-                ReadyTransactionReply reply = (ReadyTransactionReply) result;
-                cohortPaths.add(reply.getCohortPath());
+            if(result.getClass().equals(ReadyTransactionReply.SERIALIZABLE_CLASS)){
+                ReadyTransactionReply reply = ReadyTransactionReply.fromSerializable(actorContext.getActorSystem(),result);
+                String resolvedCohortPath = transactionContext
+                    .getResolvedCohortPath(reply.getCohortPath().toString());
+                cohortPaths.add(actorContext.actorFor(resolvedCohortPath));
             }
         }
 
-        return new ThreePhaseCommitCohortProxy(cohortPaths);
+        return new ThreePhaseCommitCohortProxy(actorContext, cohortPaths, identifier, executor);
     }
 
     @Override
@@ -152,17 +150,211 @@ public class TransactionProxy implements DOMStoreReadWriteTransaction {
 
     @Override
     public void close() {
-        for(ActorSelection remoteTransaction : remoteTransactionPaths.values()) {
-            remoteTransaction.tell(new CloseTransaction(), null);
+        for(TransactionContext transactionContext : remoteTransactionPaths.values()) {
+            transactionContext.closeTransaction();
         }
     }
 
-    private ActorSelection remoteTransactionFromIdentifier(InstanceIdentifier path){
+    private TransactionContext transactionContext(YangInstanceIdentifier path){
         String shardName = shardNameFromIdentifier(path);
         return remoteTransactionPaths.get(shardName);
     }
 
-    private String shardNameFromIdentifier(InstanceIdentifier path){
-        return Shard.DEFAULT_NAME;
+    private String shardNameFromIdentifier(YangInstanceIdentifier path){
+        return ShardStrategyFactory.getStrategy(path).findShard(path);
+    }
+
+    private void createTransactionIfMissing(ActorContext actorContext, YangInstanceIdentifier path) {
+        String shardName = ShardStrategyFactory.getStrategy(path).findShard(path);
+
+        TransactionContext transactionContext =
+            remoteTransactionPaths.get(shardName);
+
+        if(transactionContext != null){
+            // A transaction already exists with that shard
+            return;
+        }
+
+        try {
+            Object response = actorContext.executeShardOperation(shardName,
+                new CreateTransaction(identifier).toSerializable(),
+                ActorContext.ASK_DURATION);
+            if (response.getClass()
+                .equals(CreateTransactionReply.SERIALIZABLE_CLASS)) {
+                CreateTransactionReply reply =
+                    CreateTransactionReply.fromSerializable(response);
+
+                String transactionPath = reply.getTransactionPath();
+
+                LOG.info("Received transaction path = {}"  , transactionPath );
+
+                ActorSelection transactionActor =
+                    actorContext.actorSelection(transactionPath);
+                transactionContext =
+                    new TransactionContextImpl(shardName, transactionPath,
+                        transactionActor);
+
+                remoteTransactionPaths.put(shardName, transactionContext);
+            }
+        } catch(TimeoutException e){
+            remoteTransactionPaths.put(shardName, new NoOpTransactionContext(shardName));
+        }
+    }
+
+    private interface TransactionContext {
+        String getShardName();
+
+        String getResolvedCohortPath(String cohortPath);
+
+        public void closeTransaction();
+
+        public Object readyTransaction();
+
+        void deleteData(YangInstanceIdentifier path);
+
+        void mergeData(YangInstanceIdentifier path, NormalizedNode<?, ?> data);
+
+        ListenableFuture<Optional<NormalizedNode<?, ?>>> readData(final YangInstanceIdentifier path);
+
+        void writeData(YangInstanceIdentifier path, NormalizedNode<?, ?> data);
     }
+
+
+    private class TransactionContextImpl implements TransactionContext{
+        private final String shardName;
+        private final String actorPath;
+        private final ActorSelection  actor;
+
+
+        private TransactionContextImpl(String shardName, String actorPath,
+            ActorSelection actor) {
+            this.shardName = shardName;
+            this.actorPath = actorPath;
+            this.actor = actor;
+        }
+
+        @Override public String getShardName() {
+            return shardName;
+        }
+
+        private ActorSelection getActor() {
+            return actor;
+        }
+
+        @Override public String getResolvedCohortPath(String cohortPath){
+            return actorContext.resolvePath(actorPath, cohortPath);
+        }
+
+        @Override public void closeTransaction() {
+            getActor().tell(
+                new CloseTransaction().toSerializable(), null);
+        }
+
+        @Override public Object readyTransaction() {
+            return actorContext.executeRemoteOperation(getActor(),
+                new ReadyTransaction().toSerializable(),
+                ActorContext.ASK_DURATION
+            );
+
+        }
+
+        @Override public void deleteData(YangInstanceIdentifier path) {
+            getActor().tell(new DeleteData(path).toSerializable(), null);
+        }
+
+        @Override public void mergeData(YangInstanceIdentifier path, NormalizedNode<?, ?> data){
+            getActor().tell(new MergeData(path, data, schemaContext).toSerializable(), null);
+        }
+
+        @Override public ListenableFuture<Optional<NormalizedNode<?, ?>>> readData(final YangInstanceIdentifier path) {
+
+            Callable<Optional<NormalizedNode<?,?>>> call = new Callable() {
+
+                @Override public Optional<NormalizedNode<?,?>> call() throws Exception {
+                    Object response = actorContext
+                        .executeRemoteOperation(getActor(), new ReadData(path).toSerializable(),
+                            ActorContext.ASK_DURATION);
+                    if(response.getClass().equals(ReadDataReply.SERIALIZABLE_CLASS)){
+                        ReadDataReply reply = ReadDataReply.fromSerializable(schemaContext,path, response);
+                        if(reply.getNormalizedNode() == null){
+                            return Optional.absent();
+                        }
+                        //FIXME : A cast should not be required here ???
+                        return (Optional<NormalizedNode<?, ?>>) Optional.of(reply.getNormalizedNode());
+                    }
+
+                    return Optional.absent();
+                }
+            };
+
+            ListenableFutureTask<Optional<NormalizedNode<?, ?>>>
+                future = ListenableFutureTask.create(call);
+
+            executor.submit(future);
+
+            return future;
+        }
+
+        @Override public void writeData(YangInstanceIdentifier path, NormalizedNode<?, ?> data) {
+            getActor().tell(new WriteData(path, data, schemaContext).toSerializable(), null);
+        }
+
+    }
+
+    private class NoOpTransactionContext implements TransactionContext {
+
+        private final Logger
+            LOG = LoggerFactory.getLogger(NoOpTransactionContext.class);
+
+        private final String shardName;
+
+        private ActorRef cohort;
+
+        public NoOpTransactionContext(String shardName){
+            this.shardName = shardName;
+        }
+        @Override public String getShardName() {
+            return  shardName;
+
+        }
+
+        @Override public String getResolvedCohortPath(String cohortPath) {
+            return cohort.path().toString();
+        }
+
+        @Override public void closeTransaction() {
+            LOG.error("closeTransaction called");
+        }
+
+        @Override public Object readyTransaction() {
+            LOG.error("readyTransaction called");
+            cohort = actorContext.getActorSystem().actorOf(Props.create(NoOpCohort.class));
+            return new ReadyTransactionReply(cohort.path()).toSerializable();
+        }
+
+        @Override public void deleteData(YangInstanceIdentifier path) {
+            LOG.error("deleteData called path = {}", path);
+        }
+
+        @Override public void mergeData(YangInstanceIdentifier path,
+            NormalizedNode<?, ?> data) {
+            LOG.error("mergeData called path = {}", path);
+        }
+
+        @Override
+        public ListenableFuture<Optional<NormalizedNode<?, ?>>> readData(
+            YangInstanceIdentifier path) {
+            LOG.error("readData called path = {}", path);
+            return Futures.immediateFuture(
+                Optional.<NormalizedNode<?, ?>>absent());
+        }
+
+        @Override public void writeData(YangInstanceIdentifier path,
+            NormalizedNode<?, ?> data) {
+            LOG.error("writeData called path = {}", path);
+        }
+    }
+
+
+
 }
@@ -5,8 +5,11 @@
  * 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.connect.dom;
 
-public class Constants {
-    public static final Class<byte[]> BYTES_CLASS = byte[].class;
+package org.opendaylight.controller.cluster.datastore.exceptions;
+
+public class PrimaryNotFoundException extends RuntimeException {
+    public PrimaryNotFoundException(String message){
+        super(message);
+    }
 }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/exceptions/TimeoutException.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/exceptions/TimeoutException.java
new file mode 100644 (file)
index 0000000..472cd38
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.exceptions;
+
+public class TimeoutException extends RuntimeException {
+    public TimeoutException(String message, Exception e){
+        super(message, e);
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/AbstractBaseMBean.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/AbstractBaseMBean.java
new file mode 100644 (file)
index 0000000..de1ac18
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+
+package org.opendaylight.controller.cluster.datastore.jmx.mbeans;
+
+
+import com.google.common.base.Preconditions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import java.lang.management.ManagementFactory;
+
+/**
+ * All MBeans should extend this class that help in registering and
+ * unregistering the MBeans.
+ *
+ */
+
+
+public abstract class AbstractBaseMBean {
+
+
+  public static String BASE_JMX_PREFIX = "org.opendaylight.controller:";
+  public static String JMX_TYPE_DISTRIBUTED_DATASTORE = "DistributedDatastore";
+  public static String JMX_CATEGORY_SHARD = "Shard";
+
+  private static final Logger LOG = LoggerFactory
+      .getLogger(AbstractBaseMBean.class);
+
+  MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+  /**
+   * gets the MBean ObjectName
+   *
+   * @return Object name of the MBean
+   * @throws MalformedObjectNameException - The bean name does not have the right format.
+   * @throws NullPointerException - The bean name is null
+   */
+  protected ObjectName getMBeanObjectName()
+      throws MalformedObjectNameException, NullPointerException {
+    String name = BASE_JMX_PREFIX + "type="+getMBeanType()+",Category="+
+                                   getMBeanCategory() + ",name="+
+                                   getMBeanName();
+
+
+    return new ObjectName(name);
+  }
+
+  public boolean registerMBean() {
+    boolean registered = false;
+    try {
+      // Object to identify MBean
+      final ObjectName mbeanName = this.getMBeanObjectName();
+
+      Preconditions.checkArgument(mbeanName != null,
+          "Object name of the MBean cannot be null");
+
+      LOG.debug("Register MBean {}", mbeanName);
+
+      // unregistered if already registered
+      if (server.isRegistered(mbeanName)) {
+
+        LOG.debug("MBean {} found to be already registered", mbeanName);
+
+        try {
+          unregisterMBean(mbeanName);
+        } catch (Exception e) {
+
+          LOG.warn("unregister mbean {} resulted in exception {} ", mbeanName,
+              e);
+        }
+      }
+      server.registerMBean(this, mbeanName);
+
+      LOG.debug("MBean {} registered successfully",
+          mbeanName.getCanonicalName());
+      registered = true;
+    } catch (Exception e) {
+
+      LOG.error("registration failed {}", e);
+
+    }
+    return registered;
+  }
+
+
+  public boolean unregisterMBean() {
+    boolean unregister = false;
+    try {
+      ObjectName mbeanName = this.getMBeanObjectName();
+      unregister = true;
+      unregisterMBean(mbeanName);
+    } catch (Exception e) {
+
+      LOG.error("Failed when unregistering MBean {}", e);
+    }
+    return unregister;
+  }
+
+  private void unregisterMBean(ObjectName mbeanName)
+      throws MBeanRegistrationException, InstanceNotFoundException {
+
+    server.unregisterMBean(mbeanName);
+
+  }
+
+
+  /**
+   * @return name of bean
+   */
+  protected abstract String getMBeanName();
+
+  /**
+   * @return type of the MBean
+   */
+  protected abstract String getMBeanType();
+
+
+  /**
+   * @return Category name of teh bean
+   */
+  protected abstract String getMBeanCategory();
+
+  //require for test cases
+  public MBeanServer getMBeanServer() {
+    return server;
+  }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardMBeanFactory.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardMBeanFactory.java
new file mode 100644 (file)
index 0000000..a335908
--- /dev/null
@@ -0,0 +1,26 @@
+package org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author: syedbahm
+ * Date: 7/16/14
+ */
+public class ShardMBeanFactory {
+  private static Map<String,ShardStats> shardMBeans= new HashMap<String,ShardStats>();
+
+  public static ShardStats getShardStatsMBean(String shardName){
+       if(shardMBeans.containsKey(shardName)){
+            return shardMBeans.get(shardName);
+       }else {
+         ShardStats shardStatsMBeanImpl = new ShardStats(shardName);
+
+         if(shardStatsMBeanImpl.registerMBean()) {
+           shardMBeans.put(shardName, shardStatsMBeanImpl);
+         }
+         return shardStatsMBeanImpl;
+       }
+  }
+
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStats.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStats.java
new file mode 100644 (file)
index 0000000..2da6aae
--- /dev/null
@@ -0,0 +1,70 @@
+package org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard;
+
+import org.opendaylight.controller.cluster.datastore.jmx.mbeans.AbstractBaseMBean;
+
+/**
+ * @author: syedbahm
+ */
+public class ShardStats extends AbstractBaseMBean implements ShardStatsMBean {
+  private  Long committedTransactionsCount;
+  private Long journalMessagesCount;
+  final private String shardName;
+
+  ShardStats(String shardName){
+    this.shardName = shardName;
+    committedTransactionsCount =0L;
+    journalMessagesCount = 0L;
+  };
+
+
+  @Override
+  public String getShardName() {
+    return shardName;
+  }
+
+  @Override
+  public Long getCommittedTransactionsCount() {
+    return committedTransactionsCount;
+  }
+
+  @Override
+  public Long getJournalMessagesCount() {
+    //FIXME: this will be populated once after integration with Raft stuff
+    return journalMessagesCount;
+  }
+
+
+  public Long incrementCommittedTransactionCount() {
+    return committedTransactionsCount++;
+  }
+
+
+  public void updateCommittedTransactionsCount(long currentCount){
+     committedTransactionsCount = currentCount;
+
+  }
+
+  public void updateJournalMessagesCount(long currentCount){
+    journalMessagesCount  = currentCount;
+
+  }
+
+
+
+  @Override
+  protected String getMBeanName() {
+    return  shardName;
+  }
+
+  @Override
+  protected String getMBeanType() {
+    return JMX_TYPE_DISTRIBUTED_DATASTORE;
+  }
+
+  @Override
+  protected String getMBeanCategory() {
+    return JMX_CATEGORY_SHARD;
+  }
+
+
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStatsMBean.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStatsMBean.java
new file mode 100644 (file)
index 0000000..c107e49
--- /dev/null
@@ -0,0 +1,11 @@
+package org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard;
+
+/**
+ * @author: syedbahm
+ */
+public interface ShardStatsMBean {
+   String getShardName();
+   Long getCommittedTransactionsCount();
+   Long getJournalMessagesCount();
+
+}
index 4cf713a0b3efa0a16aa68a9230af81bf568aa0ad..4515bd70427a6eca892bb61115817941684d0a1c 100644 (file)
@@ -8,5 +8,13 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class AbortTransaction {
+import org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages;
+
+public class AbortTransaction implements SerializableMessage {
+  public static Class SERIALIZABLE_CLASS = ThreePhaseCommitCohortMessages.AbortTransaction.class;
+
+  @Override
+  public Object toSerializable() {
+    return ThreePhaseCommitCohortMessages.AbortTransaction.newBuilder().build();
+  }
 }
index 84234e58075203a4adb39c46a961718509464dfb..31a06fe4c51f66329dd2b85dc49bad38afeb7b25 100644 (file)
@@ -8,5 +8,14 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class AbortTransactionReply {
+import org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages;
+
+public class AbortTransactionReply implements SerializableMessage {
+  public static Class SERIALIZABLE_CLASS = ThreePhaseCommitCohortMessages.AbortTransactionReply.class;
+
+
+  @Override
+  public Object toSerializable() {
+    return ThreePhaseCommitCohortMessages.AbortTransactionReply.newBuilder().build();
+  }
 }
index 526d60fc75b2571616b9c911d218faaba612b8f2..2c032aff65ea569567b09595f76b9b52a1108124 100644 (file)
@@ -8,5 +8,13 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class CanCommitTransaction {
+import org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages;
+
+public class CanCommitTransaction implements SerializableMessage {
+  public static Class SERIALIZABLE_CLASS = ThreePhaseCommitCohortMessages.CanCommitTransaction.class;
+
+  @Override
+  public Object toSerializable() {
+    return  ThreePhaseCommitCohortMessages.CanCommitTransaction.newBuilder().build();
+  }
 }
index d143c14b3bd491147d5dabc42301878601f4a99f..bbcd4de03facf583db5e9def54d9512bde2ebb1b 100644 (file)
@@ -8,7 +8,10 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class CanCommitTransactionReply {
+import org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages;
+
+public class CanCommitTransactionReply implements SerializableMessage {
+  public static Class SERIALIZABLE_CLASS = ThreePhaseCommitCohortMessages.CanCommitTransactionReply.class;
   private final Boolean canCommit;
 
   public CanCommitTransactionReply(Boolean canCommit) {
@@ -18,4 +21,14 @@ public class CanCommitTransactionReply {
   public Boolean getCanCommit() {
     return canCommit;
   }
+
+  @Override
+  public Object toSerializable() {
+    return  ThreePhaseCommitCohortMessages.CanCommitTransactionReply.newBuilder().setCanCommit(canCommit).build();
+  }
+
+
+  public static CanCommitTransactionReply fromSerializable(Object message) {
+    return  new CanCommitTransactionReply(((ThreePhaseCommitCohortMessages.CanCommitTransactionReply)message).getCanCommit());
+  }
 }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CloseDataChangeListenerRegistration.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CloseDataChangeListenerRegistration.java
new file mode 100644 (file)
index 0000000..57237bc
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.messages;
+
+import org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages;
+
+public class CloseDataChangeListenerRegistration implements SerializableMessage {
+  public static Class SERIALIZABLE_CLASS = ListenerRegistrationMessages.CloseDataChangeListenerRegistration.class;
+  @Override
+  public Object toSerializable() {
+    return ListenerRegistrationMessages.CloseDataChangeListenerRegistration.newBuilder().build();
+  }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CloseDataChangeListenerRegistrationReply.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/CloseDataChangeListenerRegistrationReply.java
new file mode 100644 (file)
index 0000000..faf73c8
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.messages;
+
+import org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages;
+
+public class CloseDataChangeListenerRegistrationReply implements SerializableMessage{
+  public static Class SERIALIZABLE_CLASS = ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply.class;
+
+  @Override
+  public Object toSerializable() {
+    return ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply.newBuilder().build();
+  }
+
+}
index 6809f4b1357c1e7140ad7366b40dfb1511934180..451e39cf6a75d2ac0777c60d25de969c0d0fd2ef 100644 (file)
@@ -8,5 +8,12 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class CloseTransaction {
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
+
+public class CloseTransaction implements SerializableMessage{
+  public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.CloseTransaction.class;
+  @Override
+  public Object toSerializable() {
+    return ShardTransactionMessages.CloseTransaction.newBuilder().build();
+  }
 }
index 04c422b68e0909decec335b298d478a89417b308..efa51fde2090c3762f8d32e5d75b2a4a50c77757 100644 (file)
@@ -8,5 +8,12 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class CloseTransactionChain {
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages;
+
+public class CloseTransactionChain implements SerializableMessage{
+  public static final Class SERIALIZABLE_CLASS = ShardTransactionChainMessages.CloseTransactionChain.class;
+  @Override
+  public Object toSerializable() {
+    return ShardTransactionChainMessages.CloseTransactionChain.newBuilder().build();
+  }
 }
index 89fa93bf9ac16ce201391f0adf82815034ed4dee..23699b7be6c64cb103241329ad9fa72a585cf10b 100644 (file)
@@ -8,5 +8,13 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class CloseTransactionChainReply {
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages;
+
+public class CloseTransactionChainReply implements SerializableMessage {
+  public static final Class SERIALIZABLE_CLASS = ShardTransactionChainMessages.CloseTransactionChainReply.class;
+  @Override
+  public Object toSerializable() {
+    return ShardTransactionChainMessages.CloseTransactionChainReply.newBuilder().build();
+  }
+
 }
index 4910a3ea0e57316075fd1dd65cae3b831eb732f9..666d182aaff24c9e3d7a8da86a5de061dc4e0999 100644 (file)
@@ -8,5 +8,12 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class CloseTransactionReply {
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
+
+public class CloseTransactionReply implements SerializableMessage {
+  public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.CloseTransactionReply.class;
+  @Override
+  public Object toSerializable() {
+    return ShardTransactionMessages.CloseTransactionReply.newBuilder().build();
+  }
 }
index d7b210fd0307f019b537e6420a5a3001bb8cd234..14187139aafefd1758dd0dff444882b1ae4c54c9 100644 (file)
@@ -8,5 +8,13 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class CommitTransaction {
+import org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages;
+
+public class CommitTransaction implements SerializableMessage {
+  public static Class SERIALIZABLE_CLASS = ThreePhaseCommitCohortMessages.CommitTransaction.class;
+
+  @Override
+  public Object toSerializable() {
+    return  ThreePhaseCommitCohortMessages.CommitTransaction.newBuilder().build();
+  }
 }
index a0e5e895d2d6d4af282949fb77be0daee93c4ce8..afeba298797ea2aead2879ec98d4100bde0996cd 100644 (file)
@@ -8,5 +8,14 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class CommitTransactionReply {
+import org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages;
+
+public class CommitTransactionReply implements SerializableMessage {
+
+  public static Class SERIALIZABLE_CLASS = ThreePhaseCommitCohortMessages.CommitTransactionReply.class;
+
+  @Override
+  public Object toSerializable() {
+    return  ThreePhaseCommitCohortMessages.CommitTransactionReply.newBuilder().build();
+  }
 }
index e0cdd3cc2b6876ff1e34a155b9e4f18336f0de7a..795131fdbf6400f0b53c98f91d167bf31f45d493 100644 (file)
@@ -8,6 +8,30 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class CreateTransaction {
+
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
+
+
+public class CreateTransaction implements SerializableMessage {
+  public static Class SERIALIZABLE_CLASS = ShardTransactionMessages.CreateTransaction.class;
+  private final String transactionId;
+
+  public CreateTransaction(String transactionId){
+
+    this.transactionId = transactionId;
+  }
+
+  public String getTransactionId() {
+    return transactionId;
+  }
+
+  @Override
+  public Object toSerializable() {
+    return  ShardTransactionMessages.CreateTransaction.newBuilder().setTransactionId(transactionId).build();
+  }
+
+  public static CreateTransaction fromSerializable(Object message){
+    return new CreateTransaction(((ShardTransactionMessages.CreateTransaction)message).getTransactionId());
+  }
 
 }
index cdad3324ab0db6ca08aff0455931fd45fbd5bf2a..6339749f7bb298f27238493dfa999035f48d70ad 100644 (file)
@@ -8,6 +8,13 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class CreateTransactionChain {
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages;
 
+public class CreateTransactionChain implements SerializableMessage{
+  public static Class SERIALIZABLE_CLASS = ShardTransactionChainMessages.CreateTransactionChain.class;
+
+  @Override
+  public Object toSerializable() {
+    return  ShardTransactionChainMessages.CreateTransactionChain.newBuilder().build();
+  }
 }
index 49dd9b63d2d6d96f991f63c4e82a380870adfdce..4a497622fc1934978b172b60556a00409beb382e 100644 (file)
@@ -9,8 +9,11 @@
 package org.opendaylight.controller.cluster.datastore.messages;
 
 import akka.actor.ActorPath;
+import akka.actor.ActorSystem;
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages;
 
-public class CreateTransactionChainReply {
+public class CreateTransactionChainReply implements SerializableMessage {
+  public static final Class SERIALIZABLE_CLASS = ShardTransactionChainMessages.CreateTransactionChainReply.class;
   private final ActorPath transactionChainPath;
 
   public CreateTransactionChainReply(ActorPath transactionChainPath) {
@@ -20,4 +23,17 @@ public class CreateTransactionChainReply {
   public ActorPath getTransactionChainPath() {
     return transactionChainPath;
   }
+
+  @Override
+  public ShardTransactionChainMessages.CreateTransactionChainReply toSerializable() {
+    return ShardTransactionChainMessages.CreateTransactionChainReply.newBuilder()
+        .setTransactionChainPath(transactionChainPath.toString()).build();
+  }
+
+  public static CreateTransactionChainReply fromSerializable(ActorSystem actorSystem,Object serializable){
+    ShardTransactionChainMessages.CreateTransactionChainReply o = (ShardTransactionChainMessages.CreateTransactionChainReply) serializable;
+    return new CreateTransactionChainReply(
+        actorSystem.actorFor(o.getTransactionChainPath()).path());
+  }
+
 }
index 4faf9d370d56a4dc4bb3edf97de469fb33f95362..096d131d5a5517821ae2e228aa4c4332315a37a9 100644 (file)
@@ -8,16 +8,38 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-import akka.actor.ActorPath;
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
 
-public class CreateTransactionReply {
-  private final ActorPath transactionPath;
+public class CreateTransactionReply implements SerializableMessage {
 
-  public CreateTransactionReply(ActorPath transactionPath) {
-    this.transactionPath = transactionPath;
-  }
+    public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.CreateTransactionReply.class;
+    private final String transactionPath;
+    private final String transactionId;
+
+    public CreateTransactionReply(String transactionPath,
+        String transactionId) {
+        this.transactionPath = transactionPath;
+        this.transactionId = transactionId;
+    }
+
+    public String getTransactionPath() {
+        return transactionPath;
+    }
+
+    public String getTransactionId() {
+        return transactionId;
+    }
+
+    public Object toSerializable(){
+        return ShardTransactionMessages.CreateTransactionReply.newBuilder()
+            .setTransactionActorPath(transactionPath)
+            .setTransactionId(transactionId)
+            .build();
+    }
+
+    public static CreateTransactionReply fromSerializable(Object serializable){
+        ShardTransactionMessages.CreateTransactionReply o = (ShardTransactionMessages.CreateTransactionReply) serializable;
+        return new CreateTransactionReply(o.getTransactionActorPath(), o.getTransactionId());
+    }
 
-  public ActorPath getTransactionPath() {
-    return transactionPath;
-  }
 }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/DataChanged.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/DataChanged.java
new file mode 100644 (file)
index 0000000..a8827be
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.messages;
+
+import org.opendaylight.controller.cluster.datastore.node.NormalizedNodeToNodeCodec;
+import org.opendaylight.controller.cluster.datastore.utils.InstanceIdentifierUtils;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class DataChanged implements SerializableMessage {
+    public static final Class SERIALIZABLE_CLASS =
+        DataChangeListenerMessages.DataChanged.class;
+    final private SchemaContext schemaContext;
+    private final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>>
+        change;
+
+
+
+    public DataChanged(SchemaContext schemaContext,
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
+        this.change = change;
+        this.schemaContext = schemaContext;
+    }
+
+
+    public AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> getChange() {
+        return change;
+    }
+
+
+    private NormalizedNodeMessages.Node convertToNodeTree(
+        NormalizedNode<?, ?> normalizedNode) {
+
+        return new NormalizedNodeToNodeCodec(schemaContext)
+            .encode(YangInstanceIdentifier.builder().build(), normalizedNode)
+            .getNormalizedNode();
+
+    }
+
+    private Iterable<NormalizedNodeMessages.InstanceIdentifier> convertToRemovePaths(
+        Set<YangInstanceIdentifier> removedPaths) {
+        final Set<NormalizedNodeMessages.InstanceIdentifier> removedPathInstanceIds = new HashSet<>();
+        for (YangInstanceIdentifier id : removedPaths) {
+            removedPathInstanceIds.add(InstanceIdentifierUtils.toSerializable(id));
+        }
+        return new Iterable<NormalizedNodeMessages.InstanceIdentifier>() {
+            public Iterator<NormalizedNodeMessages.InstanceIdentifier> iterator() {
+                return removedPathInstanceIds.iterator();
+            }
+        };
+
+    }
+
+    private NormalizedNodeMessages.NodeMap convertToNodeMap(
+        Map<YangInstanceIdentifier, NormalizedNode<?, ?>> data) {
+        NormalizedNodeToNodeCodec normalizedNodeToNodeCodec =
+            new NormalizedNodeToNodeCodec(schemaContext);
+        NormalizedNodeMessages.NodeMap.Builder nodeMapBuilder =
+            NormalizedNodeMessages.NodeMap.newBuilder();
+        NormalizedNodeMessages.NodeMapEntry.Builder builder =
+            NormalizedNodeMessages.NodeMapEntry.newBuilder();
+        for (Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry : data
+            .entrySet()) {
+
+
+            NormalizedNodeMessages.InstanceIdentifier instanceIdentifier =
+                InstanceIdentifierUtils.toSerializable(entry.getKey());
+
+            builder.setInstanceIdentifierPath(instanceIdentifier)
+                .setNormalizedNode(normalizedNodeToNodeCodec
+                    .encode(entry.getKey(), entry.getValue())
+                    .getNormalizedNode());
+            nodeMapBuilder.addMapEntries(builder.build());
+        }
+        return nodeMapBuilder.build();
+    }
+
+
+    @Override
+    public Object toSerializable() {
+        return DataChangeListenerMessages.DataChanged.newBuilder()
+            .addAllRemovedPaths(convertToRemovePaths(change.getRemovedPaths()))
+            .setCreatedData(convertToNodeMap(change.getCreatedData()))
+            .setOriginalData(convertToNodeMap(change.getOriginalData()))
+            .setUpdatedData(convertToNodeMap(change.getUpdatedData()))
+            .setOriginalSubTree(convertToNodeTree(change.getOriginalSubtree()))
+            .setUpdatedSubTree(convertToNodeTree(change.getUpdatedSubtree()))
+            .build();
+    }
+
+    public static DataChanged fromSerialize(SchemaContext sc, Object message,
+        YangInstanceIdentifier pathId) {
+        DataChangeListenerMessages.DataChanged dataChanged =
+            (DataChangeListenerMessages.DataChanged) message;
+        DataChangedEvent event = new DataChangedEvent(sc);
+        if (dataChanged.getCreatedData() != null && dataChanged.getCreatedData()
+            .isInitialized()) {
+            event.setCreatedData(dataChanged.getCreatedData());
+        }
+        if (dataChanged.getOriginalData() != null && dataChanged
+            .getOriginalData().isInitialized()) {
+            event.setOriginalData(dataChanged.getOriginalData());
+        }
+
+        if (dataChanged.getUpdatedData() != null && dataChanged.getUpdatedData()
+            .isInitialized()) {
+            event.setUpdateData(dataChanged.getUpdatedData());
+        }
+
+        if (dataChanged.getOriginalSubTree() != null && dataChanged
+            .getOriginalSubTree().isInitialized()) {
+            event.setOriginalSubtree(dataChanged.getOriginalSubTree(), pathId);
+        }
+
+        if (dataChanged.getUpdatedSubTree() != null && dataChanged
+            .getUpdatedSubTree().isInitialized()) {
+            event.setUpdatedSubtree(dataChanged.getOriginalSubTree(), pathId);
+        }
+
+        if (dataChanged.getRemovedPathsList() != null && !dataChanged
+            .getRemovedPathsList().isEmpty()) {
+            event.setRemovedPaths(dataChanged.getRemovedPathsList());
+        }
+
+        return new DataChanged(sc, event);
+
+    }
+
+    static class DataChangedEvent implements
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> {
+        private final SchemaContext schemaContext;
+        private Map<YangInstanceIdentifier, NormalizedNode<?, ?>> createdData;
+        private final NormalizedNodeToNodeCodec nodeCodec;
+        private Map<YangInstanceIdentifier, NormalizedNode<?, ?>> updatedData;
+        private Map<YangInstanceIdentifier, NormalizedNode<?, ?>> originalData;
+        private NormalizedNode<?, ?> originalSubTree;
+        private NormalizedNode<?, ?> updatedSubTree;
+        private Set<YangInstanceIdentifier> removedPathIds;
+
+        DataChangedEvent(SchemaContext schemaContext) {
+            this.schemaContext = schemaContext;
+            nodeCodec = new NormalizedNodeToNodeCodec(schemaContext);
+        }
+
+        @Override
+        public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getCreatedData() {
+            if(createdData == null){
+                return Collections.emptyMap();
+            }
+            return createdData;
+        }
+
+        DataChangedEvent setCreatedData(
+            NormalizedNodeMessages.NodeMap nodeMap) {
+            this.createdData = convertNodeMapToMap(nodeMap);
+            return this;
+        }
+
+        private Map<YangInstanceIdentifier, NormalizedNode<?, ?>> convertNodeMapToMap(
+            NormalizedNodeMessages.NodeMap nodeMap) {
+            Map<YangInstanceIdentifier, NormalizedNode<?, ?>> mapEntries =
+                new HashMap<YangInstanceIdentifier, NormalizedNode<?, ?>>();
+            for (NormalizedNodeMessages.NodeMapEntry nodeMapEntry : nodeMap
+                .getMapEntriesList()) {
+                YangInstanceIdentifier id = InstanceIdentifierUtils
+                    .fromSerializable(nodeMapEntry.getInstanceIdentifierPath());
+                mapEntries.put(id,
+                    nodeCodec.decode(id, nodeMapEntry.getNormalizedNode()));
+            }
+            return mapEntries;
+        }
+
+
+        @Override
+        public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getUpdatedData() {
+            if(updatedData == null){
+                return Collections.emptyMap();
+            }
+            return updatedData;
+        }
+
+        DataChangedEvent setUpdateData(NormalizedNodeMessages.NodeMap nodeMap) {
+            this.updatedData = convertNodeMapToMap(nodeMap);
+            return this;
+        }
+
+        @Override
+        public Set<YangInstanceIdentifier> getRemovedPaths() {
+            if (removedPathIds == null) {
+                return Collections.emptySet();
+            }
+            return removedPathIds;
+        }
+
+        public DataChangedEvent setRemovedPaths(List<NormalizedNodeMessages.InstanceIdentifier> removedPaths) {
+            Set<YangInstanceIdentifier> removedIds = new HashSet<>();
+            for (NormalizedNodeMessages.InstanceIdentifier path : removedPaths) {
+                removedIds.add(InstanceIdentifierUtils.fromSerializable(path));
+            }
+            this.removedPathIds = removedIds;
+            return this;
+        }
+
+        @Override
+        public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getOriginalData() {
+            if (originalData == null) {
+                Collections.emptyMap();
+            }
+            return originalData;
+        }
+
+        DataChangedEvent setOriginalData(
+            NormalizedNodeMessages.NodeMap nodeMap) {
+            this.originalData = convertNodeMapToMap(nodeMap);
+            return this;
+        }
+
+        @Override
+        public NormalizedNode<?, ?> getOriginalSubtree() {
+            return originalSubTree;
+        }
+
+        DataChangedEvent setOriginalSubtree(NormalizedNodeMessages.Node node,
+            YangInstanceIdentifier instanceIdentifierPath) {
+            originalSubTree = nodeCodec.decode(instanceIdentifierPath, node);
+            return this;
+        }
+
+        @Override
+        public NormalizedNode<?, ?> getUpdatedSubtree() {
+            return updatedSubTree;
+        }
+
+        DataChangedEvent setUpdatedSubtree(NormalizedNodeMessages.Node node,
+            YangInstanceIdentifier instanceIdentifierPath) {
+            updatedSubTree = nodeCodec.decode(instanceIdentifierPath, node);
+            return this;
+        }
+
+
+    }
+
+
+
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/DataChangedReply.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/DataChangedReply.java
new file mode 100644 (file)
index 0000000..cffe985
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.messages;
+
+import org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages;
+
+public class DataChangedReply implements SerializableMessage {
+  public static final Class SERIALIZABLE_CLASS = DataChangeListenerMessages.DataChangedReply.class;
+  @Override
+  public Object toSerializable() {
+    return DataChangeListenerMessages.DataChangedReply.newBuilder().build();
+  }
+}
index 384e75ae7e6a11a7073ef3142586aeb68f59a4c0..17861a5a68b0e7da27f7b7996ddb2c87cdcd22ad 100644 (file)
@@ -8,16 +8,31 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.controller.cluster.datastore.utils.InstanceIdentifierUtils;
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
-public class DeleteData {
-  private final InstanceIdentifier path;
+public class DeleteData implements SerializableMessage {
 
-  public DeleteData(InstanceIdentifier path) {
-    this.path = path;
-  }
+    public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.DeleteData.class;
 
-  public InstanceIdentifier getPath() {
-    return path;
-  }
+    private final YangInstanceIdentifier path;
+
+    public DeleteData(YangInstanceIdentifier path) {
+        this.path = path;
+    }
+
+    public YangInstanceIdentifier getPath() {
+        return path;
+    }
+
+    @Override public Object toSerializable() {
+        return ShardTransactionMessages.DeleteData.newBuilder()
+            .setInstanceIdentifierPathArguments(InstanceIdentifierUtils.toSerializable(path)).build();
+    }
+
+    public static DeleteData fromSerizalizable(Object serializable){
+        ShardTransactionMessages.DeleteData o = (ShardTransactionMessages.DeleteData) serializable;
+        return new DeleteData(InstanceIdentifierUtils.fromSerializable(o.getInstanceIdentifierPathArguments()));
+    }
 }
index a3c73056858d5a8d339151d57fe2dd4047649e4f..8e2a7b72951a27b5d2b1fe039ed619db5ac62ffd 100644 (file)
@@ -8,5 +8,12 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class DeleteDataReply {
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
+
+public class DeleteDataReply implements SerializableMessage{
+  public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.DeleteDataReply.class;
+  @Override
+  public Object toSerializable() {
+    return ShardTransactionMessages.DeleteDataReply.newBuilder().build();
+  }
 }
index f2497e6517f376e4d7173efdbd4aeb21596d3990..f584467ee91b37f2b0866cb9a39556eba3c9ace8 100644 (file)
@@ -9,13 +9,14 @@
 package org.opendaylight.controller.cluster.datastore.messages;
 
 import com.google.common.base.Preconditions;
+import org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages;
 
 /**
  * The FindPrimary message is used to locate the primary of any given shard
  *
- * TODO : Make this serializable
  */
-public class FindPrimary{
+public class FindPrimary implements SerializableMessage{
+  public static final Class SERIALIZABLE_CLASS = ShardManagerMessages.FindPrimary.class;
     private final String shardName;
 
     public FindPrimary(String shardName){
@@ -28,4 +29,13 @@ public class FindPrimary{
     public String getShardName() {
         return shardName;
     }
+
+  @Override
+  public Object toSerializable() {
+    return ShardManagerMessages.FindPrimary.newBuilder().setShardName(shardName).build();
+  }
+
+  public static FindPrimary fromSerializable(Object message){
+    return new FindPrimary(((ShardManagerMessages.FindPrimary)message).getShardName());
+  }
 }
index 75d1e95c1e715c28f1e9b6d53758c8cad9722bd4..ba790816c4aefa72d5db0e97b392af205e979f4b 100644 (file)
@@ -8,11 +8,41 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.controller.cluster.datastore.node.NormalizedNodeToNodeCodec;
+import org.opendaylight.controller.cluster.datastore.utils.InstanceIdentifierUtils;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-public class MergeData extends ModifyData {
-  public MergeData(InstanceIdentifier path, NormalizedNode<?, ?> data) {
-    super(path, data);
-  }
+public class MergeData extends ModifyData{
+
+    public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.MergeData.class;
+
+    public MergeData(YangInstanceIdentifier path, NormalizedNode<?, ?> data,
+        SchemaContext context) {
+        super(path, data, context);
+    }
+
+    @Override public Object toSerializable() {
+
+        NormalizedNodeMessages.Node normalizedNode =
+            new NormalizedNodeToNodeCodec(schemaContext).encode(path, data)
+                .getNormalizedNode();
+        return ShardTransactionMessages.MergeData.newBuilder()
+            .setInstanceIdentifierPathArguments(InstanceIdentifierUtils.toSerializable(path))
+            .setNormalizedNode(normalizedNode).build();
+    }
+
+    public static MergeData fromSerializable(Object serializable, SchemaContext schemaContext){
+        ShardTransactionMessages.MergeData o = (ShardTransactionMessages.MergeData) serializable;
+        YangInstanceIdentifier identifier = InstanceIdentifierUtils.fromSerializable(o.getInstanceIdentifierPathArguments());
+
+        NormalizedNode<?, ?> normalizedNode =
+            new NormalizedNodeToNodeCodec(schemaContext)
+                .decode(identifier, o.getNormalizedNode());
+
+        return new MergeData(identifier, normalizedNode, schemaContext);
+    }
 }
index 8e90972f87ef33f7e34f29008cb346340291a62e..81b1c3bbb1e3dab609b903ed5b40f57e8da07523 100644 (file)
@@ -8,5 +8,13 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class MergeDataReply {
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
+
+public class MergeDataReply implements SerializableMessage{
+  public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.MergeDataReply.class;
+
+  @Override
+  public Object toSerializable() {
+    return ShardTransactionMessages.MergeDataReply.newBuilder().build();
+  }
 }
index da8608876e4d7b53a2113e6140b9e8bb26bf22e9..b5c39d1c3fa630a674efb1302d3441f8dd8403ed 100644 (file)
@@ -8,24 +8,33 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-public abstract class ModifyData {
-  private final InstanceIdentifier path;
-  private final NormalizedNode<?,?> data;
+public abstract class ModifyData implements SerializableMessage {
+    protected final YangInstanceIdentifier path;
+    protected final NormalizedNode<?, ?> data;
+    protected final SchemaContext schemaContext;
 
-  public ModifyData(InstanceIdentifier path, NormalizedNode<?, ?> data) {
-    this.path = path;
-    this.data = data;
-  }
+    public ModifyData(YangInstanceIdentifier path, NormalizedNode<?, ?> data,
+        SchemaContext context) {
+        Preconditions.checkNotNull(context,
+            "Cannot serialize an object which does not have a schema schemaContext");
 
-  public InstanceIdentifier getPath() {
-    return path;
-  }
 
-  public NormalizedNode<?, ?> getData() {
-    return data;
-  }
+        this.path = path;
+        this.data = data;
+        this.schemaContext = context;
+    }
+
+    public YangInstanceIdentifier getPath() {
+        return path;
+    }
+
+    public NormalizedNode<?, ?> getData() {
+        return data;
+    }
 
 }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/Monitor.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/Monitor.java
new file mode 100644 (file)
index 0000000..567f14a
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.messages;
+
+import akka.actor.ActorRef;
+
+public class Monitor {
+    private final ActorRef actorRef;
+
+    public Monitor(ActorRef actorRef){
+
+        this.actorRef = actorRef;
+    }
+
+    public ActorRef getActorRef() {
+        return actorRef;
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/NonPersistent.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/NonPersistent.java
new file mode 100644 (file)
index 0000000..a779ed0
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.messages;
+
+/**
+ * A NonPersistent message is to be used when we want to trigger state update
+ * for an actor without actually persisting the data to disk. This could be
+ * useful for test purposes.
+ */
+public class NonPersistent {
+    private final Object payload;
+
+    public NonPersistent(Object payload){
+        this.payload = payload;
+    }
+
+    public Object payload() {
+        return payload;
+    }
+
+    public static NonPersistent create(Object payload){
+        return new NonPersistent(payload);
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/PeerAddressResolved.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/PeerAddressResolved.java
new file mode 100644 (file)
index 0000000..8c2543e
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.messages;
+
+public class PeerAddressResolved {
+    private final String peerId;
+    private final String peerAddress;
+
+    public PeerAddressResolved(String peerId, String peerAddress) {
+        this.peerId = peerId;
+        this.peerAddress = peerAddress;
+    }
+
+    public String getPeerId() {
+        return peerId;
+    }
+
+    public String getPeerAddress() {
+        return peerAddress;
+    }
+}
index 87a9c77a4fcf3486db1cabc83db52ce0bbb4b53c..1e5a05329b72c38b72637a6ceaeee3002741b64e 100644 (file)
@@ -8,5 +8,14 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class PreCommitTransaction {
+import org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages;
+
+public class PreCommitTransaction implements SerializableMessage{
+
+  public static Class SERIALIZABLE_CLASS = ThreePhaseCommitCohortMessages.PreCommitTransaction.class;
+
+  @Override
+  public Object toSerializable() {
+    return  ThreePhaseCommitCohortMessages.PreCommitTransaction.newBuilder().build();
+  }
 }
index f499c720d234f817c1d7254cb5e164d4e4b2c5f4..1aedae3ae72fb51b0794e12ee338c0ca478c97f4 100644 (file)
@@ -8,5 +8,14 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class PreCommitTransactionReply {
+import org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages;
+
+public class PreCommitTransactionReply implements SerializableMessage{
+
+  public static Class SERIALIZABLE_CLASS = ThreePhaseCommitCohortMessages.PreCommitTransactionReply.class;
+
+  @Override
+  public Object toSerializable() {
+    return  ThreePhaseCommitCohortMessages.PreCommitTransactionReply.newBuilder().build();
+  }
 }
index d6aae3786fc3e4f1e08eda17c168345c83073dc9..69502837bcc6c114a1daa98986006ed0bd206aab 100644 (file)
@@ -8,7 +8,10 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class PrimaryFound {
+import org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages;
+
+public class PrimaryFound implements SerializableMessage {
+  public static final Class SERIALIZABLE_CLASS = ShardManagerMessages.PrimaryFound.class;
   private final String primaryPath;
 
   public PrimaryFound(String primaryPath) {
@@ -44,4 +47,12 @@ public class PrimaryFound {
   }
 
 
+  @Override
+  public Object toSerializable() {
+    return  ShardManagerMessages.PrimaryFound.newBuilder().setPrimaryPath(primaryPath).build();
+  }
+
+  public static PrimaryFound fromSerializable(Object message){
+    return new PrimaryFound(((ShardManagerMessages.PrimaryFound)message).getPrimaryPath());
+  }
 }
index c66e12cb395d4850392716644644d91dc830da4b..057028c469416df2767a067ef5e36e4256babd35 100644 (file)
@@ -9,8 +9,10 @@
 package org.opendaylight.controller.cluster.datastore.messages;
 
 import com.google.common.base.Preconditions;
+import org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages;
 
-public class PrimaryNotFound {
+public class PrimaryNotFound implements SerializableMessage {
+  public static final Class SERIALIZABLE_CLASS = ShardManagerMessages.PrimaryNotFound.class;
 
     private final String shardName;
 
@@ -37,4 +39,13 @@ public class PrimaryNotFound {
     public int hashCode() {
         return shardName != null ? shardName.hashCode() : 0;
     }
+
+  @Override
+  public Object toSerializable() {
+    return ShardManagerMessages.PrimaryNotFound.newBuilder().setShardName(shardName).build();
+  }
+
+  public static PrimaryNotFound fromSerializable(Object message){
+    return new PrimaryNotFound(((ShardManagerMessages.PrimaryNotFound)message).getShardName());
+  }
 }
index 2f56a9740b2d4872a116dbccc31ceeb33e6425f1..a698f4634797116875871d20bf5d68d90ffb1ff7 100644 (file)
@@ -8,16 +8,30 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.controller.cluster.datastore.utils.InstanceIdentifierUtils;
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 public class ReadData {
-  private final InstanceIdentifier path;
+  public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.ReadData.class;
+  private final YangInstanceIdentifier path;
 
-  public ReadData(InstanceIdentifier path) {
+  public ReadData(YangInstanceIdentifier path) {
     this.path = path;
   }
 
-  public InstanceIdentifier getPath() {
+  public YangInstanceIdentifier getPath() {
     return path;
   }
+
+  public Object toSerializable(){
+    return ShardTransactionMessages.ReadData.newBuilder()
+        .setInstanceIdentifierPathArguments(InstanceIdentifierUtils.toSerializable(path))
+        .build();
+  }
+
+  public static ReadData fromSerializable(Object serializable){
+    ShardTransactionMessages.ReadData o = (ShardTransactionMessages.ReadData) serializable;
+    return new ReadData(InstanceIdentifierUtils.fromSerializable(o.getInstanceIdentifierPathArguments()));
+  }
 }
index 52e2c29249704fc2831b1db0d97ad1a4f9b2ecdc..c5498ca228b3f846b5fd528b2da4dd2a4afef7a2 100644 (file)
@@ -8,17 +8,42 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
+import org.opendaylight.controller.cluster.datastore.node.NormalizedNodeToNodeCodec;
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-public class ReadDataReply {
-  private final NormalizedNode<?, ?> normalizedNode;
+public class ReadDataReply implements SerializableMessage{
 
-  public ReadDataReply(NormalizedNode<?, ?> normalizedNode){
+  private final NormalizedNode<?, ?> normalizedNode;
+  private final SchemaContext schemaContext;
+  public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.ReadDataReply.class;
+  public ReadDataReply(SchemaContext context,NormalizedNode<?, ?> normalizedNode){
 
     this.normalizedNode = normalizedNode;
+    this.schemaContext = context;
   }
 
   public NormalizedNode<?, ?> getNormalizedNode() {
     return normalizedNode;
   }
+
+  public Object toSerializable(){
+    if(normalizedNode != null) {
+      return ShardTransactionMessages.ReadDataReply.newBuilder()
+          .setNormalizedNode(new NormalizedNodeToNodeCodec(schemaContext)
+                  .encode(YangInstanceIdentifier.builder().build(), normalizedNode).getNormalizedNode()
+          ).build();
+    }else{
+      return ShardTransactionMessages.ReadDataReply.newBuilder().build();
+
+    }
+
+  }
+
+  public static ReadDataReply fromSerializable(SchemaContext schemaContext,YangInstanceIdentifier id,Object serializable){
+    ShardTransactionMessages.ReadDataReply o = (ShardTransactionMessages.ReadDataReply) serializable;
+    return new ReadDataReply(schemaContext,new NormalizedNodeToNodeCodec(schemaContext).decode(id, o.getNormalizedNode()));
+  }
 }
index 58eef66fc75a156a823e2fad00ad8f1b4ef0b128..3a51d9850b78ae1272fb419bbec7068bfd81bbea 100644 (file)
@@ -8,5 +8,14 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class ReadyTransaction {
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
+
+public class ReadyTransaction implements SerializableMessage{
+  public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.ReadyTransaction.class;
+
+  @Override
+  public Object toSerializable() {
+    return ShardTransactionMessages.ReadyTransaction.newBuilder().build();
+  }
+
 }
index 32d31bf84db44e87a4ebbbd6328c97c3898fd9ae..5273dc247925608326f9756e5dcbb061b106e5e2 100644 (file)
@@ -9,8 +9,11 @@
 package org.opendaylight.controller.cluster.datastore.messages;
 
 import akka.actor.ActorPath;
+import akka.actor.ActorSystem;
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
 
-public class ReadyTransactionReply {
+public class ReadyTransactionReply implements SerializableMessage {
+  public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.ReadyTransactionReply.class;
   private final ActorPath cohortPath;
 
   public ReadyTransactionReply(ActorPath cohortPath) {
@@ -21,4 +24,16 @@ public class ReadyTransactionReply {
   public ActorPath getCohortPath() {
     return cohortPath;
   }
+
+  @Override
+  public ShardTransactionMessages.ReadyTransactionReply toSerializable() {
+    return ShardTransactionMessages.ReadyTransactionReply.newBuilder()
+        .setActorPath(cohortPath.toString()).build();
+  }
+
+  public static ReadyTransactionReply fromSerializable(ActorSystem actorSystem,Object serializable){
+    ShardTransactionMessages.ReadyTransactionReply o = (ShardTransactionMessages.ReadyTransactionReply) serializable;
+    return new ReadyTransactionReply(
+        actorSystem.actorFor(o.getActorPath()).path());
+  }
 }
index 7c9e4f0665a2710e2ed4b28f4792e6a043a48800..c1ec0a87cba2c64db745879fa08211cea9821b2c 100644 (file)
@@ -9,16 +9,20 @@
 package org.opendaylight.controller.cluster.datastore.messages;
 
 import akka.actor.ActorPath;
+import akka.actor.ActorSystem;
+import org.opendaylight.controller.cluster.datastore.utils.InstanceIdentifierUtils;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
-public class RegisterChangeListener {
-    private final InstanceIdentifier path;
+public class RegisterChangeListener implements SerializableMessage {
+  public static final Class SERIALIZABLE_CLASS = ListenerRegistrationMessages.RegisterChangeListener.class;
+    private final YangInstanceIdentifier path;
     private final ActorPath dataChangeListenerPath;
     private final AsyncDataBroker.DataChangeScope scope;
 
 
-    public RegisterChangeListener(InstanceIdentifier path,
+    public RegisterChangeListener(YangInstanceIdentifier path,
         ActorPath dataChangeListenerPath,
         AsyncDataBroker.DataChangeScope scope) {
         this.path = path;
@@ -26,7 +30,7 @@ public class RegisterChangeListener {
         this.scope = scope;
     }
 
-    public InstanceIdentifier getPath() {
+    public YangInstanceIdentifier getPath() {
         return path;
     }
 
@@ -38,4 +42,22 @@ public class RegisterChangeListener {
     public ActorPath getDataChangeListenerPath() {
         return dataChangeListenerPath;
     }
+
+
+    @Override
+    public ListenerRegistrationMessages.RegisterChangeListener toSerializable() {
+      return ListenerRegistrationMessages.RegisterChangeListener.newBuilder()
+          .setInstanceIdentifierPath(InstanceIdentifierUtils.toSerializable(path))
+          .setDataChangeListenerActorPath(dataChangeListenerPath.toString())
+          .setDataChangeScope(scope.ordinal()).build();
+    }
+
+  public static RegisterChangeListener fromSerializable(ActorSystem actorSystem,Object serializable){
+    ListenerRegistrationMessages.RegisterChangeListener o = (ListenerRegistrationMessages.RegisterChangeListener) serializable;
+    return new RegisterChangeListener(InstanceIdentifierUtils.fromSerializable(o.getInstanceIdentifierPath()),
+                                                actorSystem.actorFor(o.getDataChangeListenerActorPath()).path(),
+                                              AsyncDataBroker.DataChangeScope.values()[o.getDataChangeScope()]);
+  }
+
+
 }
index ae8bbbd75adf2717a3a50d579bd7f179a31841b5..8d980d283db9c9187733e44c4f685287c83a97ea 100644 (file)
@@ -9,8 +9,11 @@
 package org.opendaylight.controller.cluster.datastore.messages;
 
 import akka.actor.ActorPath;
+import akka.actor.ActorSystem;
+import org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages;
 
-public class RegisterChangeListenerReply {
+public class RegisterChangeListenerReply implements SerializableMessage{
+  public static final Class SERIALIZABLE_CLASS = ListenerRegistrationMessages.RegisterChangeListenerReply.class;
   private final ActorPath listenerRegistrationPath;
 
   public RegisterChangeListenerReply(ActorPath listenerRegistrationPath) {
@@ -20,4 +23,17 @@ public class RegisterChangeListenerReply {
   public ActorPath getListenerRegistrationPath() {
     return listenerRegistrationPath;
   }
+
+  @Override
+  public ListenerRegistrationMessages.RegisterChangeListenerReply toSerializable() {
+    return ListenerRegistrationMessages.RegisterChangeListenerReply.newBuilder()
+            .setListenerRegistrationPath(listenerRegistrationPath.toString()).build();
+  }
+
+  public static RegisterChangeListenerReply fromSerializable(ActorSystem actorSystem,Object serializable){
+    ListenerRegistrationMessages.RegisterChangeListenerReply o = (ListenerRegistrationMessages.RegisterChangeListenerReply) serializable;
+    return new RegisterChangeListenerReply(
+        actorSystem.actorFor(o.getListenerRegistrationPath()).path()
+        );
+  }
 }
index 1348e65aa30679cbdb8ae539eb0aa91d4d54594c..87fa010b373d679eae58ff306a262de406c9c148 100644 (file)
@@ -8,12 +8,42 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.controller.cluster.datastore.node.NormalizedNodeToNodeCodec;
+import org.opendaylight.controller.cluster.datastore.utils.InstanceIdentifierUtils;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public class WriteData extends ModifyData{
 
-  public WriteData(InstanceIdentifier path, NormalizedNode<?, ?> data) {
-    super(path, data);
+  public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.WriteData.class;
+
+  public WriteData(YangInstanceIdentifier path, NormalizedNode<?, ?> data, SchemaContext schemaContext) {
+    super(path, data, schemaContext);
   }
+
+    @Override public Object toSerializable() {
+
+        NormalizedNodeMessages.Node normalizedNode =
+            new NormalizedNodeToNodeCodec(schemaContext).encode(path, data)
+                .getNormalizedNode();
+        return ShardTransactionMessages.WriteData.newBuilder()
+            .setInstanceIdentifierPathArguments(InstanceIdentifierUtils.toSerializable(path))
+            .setNormalizedNode(normalizedNode).build();
+
+    }
+
+    public static WriteData fromSerializable(Object serializable, SchemaContext schemaContext){
+        ShardTransactionMessages.WriteData o = (ShardTransactionMessages.WriteData) serializable;
+        YangInstanceIdentifier identifier = InstanceIdentifierUtils.fromSerializable(o.getInstanceIdentifierPathArguments());
+
+        NormalizedNode<?, ?> normalizedNode =
+            new NormalizedNodeToNodeCodec(schemaContext)
+                .decode(identifier, o.getNormalizedNode());
+
+        return new WriteData(identifier, normalizedNode, schemaContext);
+    }
+
 }
index 2a2b4ed25d2587eab787430f0ccc509596b6656b..5404fb65103557235ae8e56f95eebd645ea11b9d 100644 (file)
@@ -8,5 +8,12 @@
 
 package org.opendaylight.controller.cluster.datastore.messages;
 
-public class WriteDataReply {
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages;
+
+public class WriteDataReply implements SerializableMessage{
+  public static final Class SERIALIZABLE_CLASS = ShardTransactionMessages.WriteDataReply.class;
+  @Override
+  public Object toSerializable() {
+    return ShardTransactionMessages.WriteDataReply.newBuilder().build();
+  }
 }
index 5d9f96277ddcba65b05801ea328c8e80333744f3..169397bf877168cee54be4fd013870e158c17b0c 100644 (file)
@@ -9,7 +9,7 @@
 package org.opendaylight.controller.cluster.datastore.modification;
 
 
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 import java.io.Serializable;
 
@@ -21,9 +21,9 @@ public abstract class AbstractModification implements Modification,
 
     private static final long serialVersionUID = 1638042650152084457L;
 
-    protected final InstanceIdentifier path;
+    protected final YangInstanceIdentifier path;
 
-    protected AbstractModification(InstanceIdentifier path) {
+    protected AbstractModification(YangInstanceIdentifier path) {
         this.path = path;
     }
 }
index 063ec3e1fcc34ca96192bd4e0c90e40c604c43a6..593f458afa314f458ad314e6af22701160810c35 100644 (file)
@@ -8,14 +8,16 @@
 
 package org.opendaylight.controller.cluster.datastore.modification;
 
+import org.opendaylight.controller.cluster.datastore.utils.InstanceIdentifierUtils;
+import org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 /**
  * DeleteModification store all the parameters required to delete a path from the data tree
  */
 public class DeleteModification extends AbstractModification {
-  public DeleteModification(InstanceIdentifier path) {
+  public DeleteModification(YangInstanceIdentifier path) {
     super(path);
   }
 
@@ -23,4 +25,16 @@ public class DeleteModification extends AbstractModification {
   public void apply(DOMStoreWriteTransaction transaction) {
     transaction.delete(path);
   }
+
+    @Override public Object toSerializable() {
+        return PersistentMessages.Modification.newBuilder()
+            .setType(this.getClass().toString())
+            .setPath(InstanceIdentifierUtils.toSerializable(this.path))
+            .build();
+    }
+
+    public static DeleteModification fromSerializable(Object serializable){
+        PersistentMessages.Modification o = (PersistentMessages.Modification) serializable;
+        return new DeleteModification(InstanceIdentifierUtils.fromSerializable(o.getPath()));
+    }
 }
index 5a15d76d27b0f34c270063438e8da41db853cc85..2d11500eb7e44369ce428bab44a057723df83036 100644 (file)
@@ -8,25 +8,39 @@
 
 package org.opendaylight.controller.cluster.datastore.modification;
 
+import org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
 
 import java.util.List;
 
-public class ImmutableCompositeModification implements CompositeModification{
+public class ImmutableCompositeModification implements CompositeModification {
 
-  private final CompositeModification modification;
+    private final CompositeModification modification;
 
-  public ImmutableCompositeModification(CompositeModification modification){
-    this.modification = modification;
-  }
+    public ImmutableCompositeModification(CompositeModification modification) {
+        this.modification = modification;
+    }
 
-  @Override
-  public List<Modification> getModifications() {
-    return modification.getModifications();
-  }
+    @Override
+    public List<Modification> getModifications() {
+        return modification.getModifications();
+    }
 
-  @Override
-  public void apply(DOMStoreWriteTransaction transaction) {
-    modification.apply(transaction);
-  }
+    @Override
+    public void apply(DOMStoreWriteTransaction transaction) {
+        modification.apply(transaction);
+    }
+
+    @Override public Object toSerializable() {
+
+        PersistentMessages.CompositeModification.Builder builder =
+            PersistentMessages.CompositeModification.newBuilder();
+
+        for (Modification m : modification.getModifications()) {
+            builder.addModification(
+                (PersistentMessages.Modification) m.toSerializable());
+        }
+
+        return builder.build();
+    }
 }
index 0457a7828029b2cb820f48499941f9809edb7126..f06adcf96f9ff7c16f1842187bbc98119b53152c 100644 (file)
@@ -8,24 +8,58 @@
 
 package org.opendaylight.controller.cluster.datastore.modification;
 
+import org.opendaylight.controller.cluster.datastore.node.NormalizedNodeToNodeCodec;
+import org.opendaylight.controller.cluster.datastore.utils.InstanceIdentifierUtils;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 /**
  * MergeModification stores all the parameters required to merge data into the specified path
  */
-public class MergeModification extends AbstractModification{
-  private final NormalizedNode data;
+public class MergeModification extends AbstractModification {
+    private final NormalizedNode data;
+    private final SchemaContext schemaContext;
 
 
-  public MergeModification(InstanceIdentifier path, NormalizedNode data) {
-    super(path);
-    this.data = data;
-  }
+    public MergeModification(YangInstanceIdentifier path, NormalizedNode data,
+        SchemaContext schemaContext) {
+        super(path);
+        this.data = data;
+        this.schemaContext = schemaContext;
+    }
+
+    @Override
+    public void apply(DOMStoreWriteTransaction transaction) {
+        transaction.merge(path, data);
+    }
+
+    @Override public Object toSerializable() {
+        NormalizedNodeMessages.Container encode =
+            new NormalizedNodeToNodeCodec(schemaContext).encode(
+                path, data);
+
+        return PersistentMessages.Modification.newBuilder()
+            .setType(this.getClass().toString())
+            .setPath(InstanceIdentifierUtils.toSerializable(this.path))
+            .setData(encode.getNormalizedNode())
+            .build();
+
+    }
+
+    public static MergeModification fromSerializable(
+        Object serializable,
+        SchemaContext schemaContext) {
+        PersistentMessages.Modification o = (PersistentMessages.Modification) serializable;
+
+        YangInstanceIdentifier path = InstanceIdentifierUtils.fromSerializable(o.getPath());
+        NormalizedNode data = new NormalizedNodeToNodeCodec(schemaContext).decode(
+            path, o.getData());
+
+        return new MergeModification(path, data, schemaContext);
+    }
 
-  @Override
-  public void apply(DOMStoreWriteTransaction transaction) {
-    transaction.merge(path, data);
-  }
 }
index 60dbf0f4b17e06131db9c0939f257a2af76a31fb..ed9b1fe3b9548f9b529b4e1e9ce6929e41fcda11 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.cluster.datastore.modification;
 
+import org.opendaylight.controller.cluster.datastore.messages.SerializableMessage;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
 
 /**
@@ -24,7 +25,7 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
  * which can then be applied to a write transaction
  * </p>
  */
-public interface Modification {
+public interface Modification extends SerializableMessage {
   /**
    * Apply the modification to the specified transaction
    * @param transaction
index 9f37ba42d3c97076af0dfff3146c61338036968d..1a005d856e30ceb3b9cd359b5fd14ef42bc14cf0 100644 (file)
@@ -8,9 +8,10 @@
 
 package org.opendaylight.controller.cluster.datastore.modification;
 
+import org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -20,7 +21,7 @@ import java.util.List;
  * CompositeModification {@link org.opendaylight.controller.cluster.datastore.modification.MutableCompositeModification#addModification(Modification)}
  */
 public class MutableCompositeModification
-    implements CompositeModification, Serializable {
+    implements CompositeModification {
 
     private static final long serialVersionUID = 1163377899140186790L;
 
@@ -46,4 +47,33 @@ public class MutableCompositeModification
     public List<Modification> getModifications() {
         return Collections.unmodifiableList(modifications);
     }
+
+    @Override public Object toSerializable() {
+        PersistentMessages.CompositeModification.Builder builder =
+            PersistentMessages.CompositeModification.newBuilder();
+
+        for (Modification m : modifications) {
+            builder.addModification(
+                (PersistentMessages.Modification) m.toSerializable());
+        }
+
+        return builder.build();
+    }
+
+    public static MutableCompositeModification fromSerializable(Object serializable, SchemaContext schemaContext){
+        PersistentMessages.CompositeModification o = (PersistentMessages.CompositeModification) serializable;
+        MutableCompositeModification compositeModification = new MutableCompositeModification();
+
+        for(PersistentMessages.Modification m : o.getModificationList()){
+            if(m.getType().equals(DeleteModification.class.toString())){
+                compositeModification.addModification(DeleteModification.fromSerializable(m));
+            } else if(m.getType().equals(WriteModification.class.toString())){
+                compositeModification.addModification(WriteModification.fromSerializable(m, schemaContext));
+            } else if(m.getType().equals(MergeModification.class.toString())){
+                compositeModification.addModification(MergeModification.fromSerializable(m, schemaContext));
+            }
+        }
+
+        return compositeModification;
+    }
 }
index 1b2a87f42bb0cbfc61852534b1a9d65419491741..b4a7dd62d00121debd5cde36c358e02f4c264df8 100644 (file)
@@ -8,9 +8,14 @@
 
 package org.opendaylight.controller.cluster.datastore.modification;
 
+import org.opendaylight.controller.cluster.datastore.node.NormalizedNodeToNodeCodec;
+import org.opendaylight.controller.cluster.datastore.utils.InstanceIdentifierUtils;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 /**
  * WriteModification stores all the parameters required to write data to the specified path
@@ -18,15 +23,42 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 public class WriteModification extends AbstractModification {
 
   private final NormalizedNode data;
+    private final SchemaContext schemaContext;
 
-  public WriteModification(InstanceIdentifier path, NormalizedNode data) {
+    public WriteModification(YangInstanceIdentifier path, NormalizedNode data, SchemaContext schemaContext) {
     super(path);
     this.data = data;
-  }
+        this.schemaContext = schemaContext;
+    }
 
   @Override
   public void apply(DOMStoreWriteTransaction transaction) {
     transaction.write(path, data);
   }
 
+    @Override public Object toSerializable() {
+        NormalizedNodeMessages.Container encode =
+            new NormalizedNodeToNodeCodec(schemaContext).encode(
+                path, data);
+
+
+        return PersistentMessages.Modification.newBuilder()
+            .setType(this.getClass().toString())
+            .setPath(InstanceIdentifierUtils.toSerializable(this.path))
+            .setData(encode.getNormalizedNode())
+            .build();
+
+    }
+
+    public static WriteModification fromSerializable(
+        Object serializable,
+        SchemaContext schemaContext) {
+        PersistentMessages.Modification o = (PersistentMessages.Modification) serializable;
+
+        YangInstanceIdentifier path = InstanceIdentifierUtils.fromSerializable(o.getPath());
+        NormalizedNode data = new NormalizedNodeToNodeCodec(schemaContext).decode(
+            path, o.getData());
+
+        return new WriteModification(path, data, schemaContext);
+    }
 }
index a8ab5c4bd390ea3567613b8a9075c1cd430b0066..55c682b86000187e10e2376b3f69e94a87772d73 100644 (file)
@@ -8,7 +8,7 @@
 
 package org.opendaylight.controller.cluster.datastore.shardstrategy;
 
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 /**
  * The DefaultShardStrategy basically puts all data into the default Shard
@@ -22,7 +22,7 @@ public class DefaultShardStrategy implements ShardStrategy{
   public static final String DEFAULT_SHARD = "default";
 
   @Override
-  public String findShard(InstanceIdentifier path) {
+  public String findShard(YangInstanceIdentifier path) {
     return DEFAULT_SHARD;
   }
 }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ModuleShardStrategy.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ModuleShardStrategy.java
new file mode 100644 (file)
index 0000000..6f4b65a
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.shardstrategy;
+
+import org.opendaylight.controller.cluster.datastore.Configuration;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public class ModuleShardStrategy implements ShardStrategy {
+
+    public static final String NAME = "module";
+
+    private final String moduleName;
+    private final Configuration configuration;
+
+    public ModuleShardStrategy(String moduleName, Configuration configuration){
+        this.moduleName = moduleName;
+
+        this.configuration = configuration;
+    }
+
+    @Override public String findShard(YangInstanceIdentifier path) {
+        return configuration.getShardNamesFromModuleName(moduleName).get(0);
+    }
+}
index f75eb2d863e65a636397b254d66607af588134c5..2df945edd5e9b9c16ed454e55859611afe8a66e0 100644 (file)
@@ -8,7 +8,7 @@
 
 package org.opendaylight.controller.cluster.datastore.shardstrategy;
 
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 /**
  * The role of ShardStrategy is to figure out which Shards a given piece of data belongs to
@@ -20,5 +20,5 @@ public interface ShardStrategy {
    * @param path The location of the data in the logical tree
    * @return
    */
-  String findShard(InstanceIdentifier path);
+  String findShard(YangInstanceIdentifier path);
 }
index 210537925b151a0b0c140433d4d1f009fa90acf6..f4ab8fab6f768e84bd48c15ebc83e862315e09eb 100644 (file)
@@ -8,41 +8,52 @@
 
 package org.opendaylight.controller.cluster.datastore.shardstrategy;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.controller.cluster.datastore.Configuration;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 public class ShardStrategyFactory {
-  private static final Map<String, ShardStrategy> moduleNameToStrategyMap = new ConcurrentHashMap();
+    private static Map<String, ShardStrategy> moduleNameToStrategyMap =
+        new ConcurrentHashMap();
 
-  private static final String UNKNOWN_MODULE_NAME = "unknown";
+    private static final String UNKNOWN_MODULE_NAME = "unknown";
+    private static Configuration configuration;
 
-  public static ShardStrategy getStrategy(InstanceIdentifier path){
-    Preconditions.checkNotNull(path, "path should not be null");
 
-    String moduleName = getModuleName(path);
-    ShardStrategy shardStrategy = moduleNameToStrategyMap.get(moduleName);
-    if(shardStrategy == null){
-      return new DefaultShardStrategy();
+    public static void setConfiguration(Configuration configuration){
+        ShardStrategyFactory.configuration = configuration;
+        moduleNameToStrategyMap = configuration.getModuleNameToShardStrategyMap();
     }
 
-    return shardStrategy;
-  }
+    public static ShardStrategy getStrategy(YangInstanceIdentifier path) {
+        Preconditions.checkState(configuration != null, "configuration should not be missing");
+        Preconditions.checkNotNull(path, "path should not be null");
 
 
-  private static String getModuleName(InstanceIdentifier path){
-    return UNKNOWN_MODULE_NAME;
-  }
+        String moduleName = getModuleName(path);
+        ShardStrategy shardStrategy = moduleNameToStrategyMap.get(moduleName);
+        if (shardStrategy == null) {
+            return new DefaultShardStrategy();
+        }
 
-  /**
-   * This is to be used in the future to register a custom shard strategy
-   *
-   * @param moduleName
-   * @param shardStrategy
-   */
-  public static void registerShardStrategy(String moduleName, ShardStrategy shardStrategy){
-    throw new UnsupportedOperationException("registering a custom shard strategy not supported yet");
-  }
+        return shardStrategy;
+    }
+
+
+    private static String getModuleName(YangInstanceIdentifier path) {
+        String namespace = path.getPathArguments().iterator().next().getNodeType().getNamespace().toASCIIString();
+
+        Optional<String> optional =
+            configuration.getModuleNameFromNameSpace(namespace);
+
+        if(!optional.isPresent()){
+            return UNKNOWN_MODULE_NAME;
+        }
+
+        return optional.get();
+    }
 }
index ba4d4de6bfaeed985bf1e70c626c4a3bd365a0b1..ac0893da5ad157c230fad2aab7401b27d0054751 100644 (file)
@@ -12,9 +12,15 @@ import akka.actor.ActorPath;
 import akka.actor.ActorRef;
 import akka.actor.ActorSelection;
 import akka.actor.ActorSystem;
+import akka.actor.PoisonPill;
 import akka.util.Timeout;
+import org.opendaylight.controller.cluster.datastore.ClusterWrapper;
+import org.opendaylight.controller.cluster.datastore.Configuration;
+import org.opendaylight.controller.cluster.datastore.exceptions.PrimaryNotFoundException;
+import org.opendaylight.controller.cluster.datastore.exceptions.TimeoutException;
 import org.opendaylight.controller.cluster.datastore.messages.FindPrimary;
 import org.opendaylight.controller.cluster.datastore.messages.PrimaryFound;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import scala.concurrent.Await;
@@ -36,15 +42,25 @@ public class ActorContext {
     private static final Logger
         LOG = LoggerFactory.getLogger(ActorContext.class);
 
-    public static final FiniteDuration ASK_DURATION = Duration.create(5, TimeUnit.SECONDS);
-    public static final Duration AWAIT_DURATION = Duration.create(5, TimeUnit.SECONDS);
+    public static final FiniteDuration ASK_DURATION =
+        Duration.create(5, TimeUnit.SECONDS);
+    public static final Duration AWAIT_DURATION =
+        Duration.create(5, TimeUnit.SECONDS);
 
     private final ActorSystem actorSystem;
     private final ActorRef shardManager;
+    private final ClusterWrapper clusterWrapper;
+    private final Configuration configuration;
 
-    public ActorContext(ActorSystem actorSystem, ActorRef shardManager){
+    private SchemaContext schemaContext = null;
+
+    public ActorContext(ActorSystem actorSystem, ActorRef shardManager,
+        ClusterWrapper clusterWrapper,
+        Configuration configuration) {
         this.actorSystem = actorSystem;
         this.shardManager = shardManager;
+        this.clusterWrapper = clusterWrapper;
+        this.configuration = configuration;
     }
 
     public ActorSystem getActorSystem() {
@@ -55,11 +71,11 @@ public class ActorContext {
         return shardManager;
     }
 
-    public ActorSelection actorSelection(String actorPath){
+    public ActorSelection actorSelection(String actorPath) {
         return actorSystem.actorSelection(actorPath);
     }
 
-    public ActorSelection actorSelection(ActorPath actorPath){
+    public ActorSelection actorSelection(ActorPath actorPath) {
         return actorSystem.actorSelection(actorPath);
     }
 
@@ -71,74 +87,124 @@ public class ActorContext {
      * @return
      */
     public ActorSelection findPrimary(String shardName) {
+        String path = findPrimaryPath(shardName);
+        return actorSystem.actorSelection(path);
+    }
+
+    public String findPrimaryPath(String shardName) {
         Object result = executeLocalOperation(shardManager,
-            new FindPrimary(shardName), ASK_DURATION);
+            new FindPrimary(shardName).toSerializable(), ASK_DURATION);
 
-        if(result instanceof PrimaryFound){
-            PrimaryFound found = (PrimaryFound) result;
+        if (result.getClass().equals(PrimaryFound.SERIALIZABLE_CLASS)) {
+            PrimaryFound found = PrimaryFound.fromSerializable(result);
 
-            LOG.error("Primary found {}", found.getPrimaryPath());
+            LOG.debug("Primary found {}", found.getPrimaryPath());
 
-            return actorSystem.actorSelection(found.getPrimaryPath());
+            return found.getPrimaryPath();
         }
-        throw new RuntimeException("primary was not found");
+        throw new PrimaryNotFoundException("Could not find primary for shardName " + shardName);
     }
 
+
     /**
      * Executes an operation on a local actor and wait for it's response
+     *
      * @param actor
      * @param message
      * @param duration
      * @return The response of the operation
      */
     public Object executeLocalOperation(ActorRef actor, Object message,
-        FiniteDuration duration){
+        FiniteDuration duration) {
         Future<Object> future =
             ask(actor, message, new Timeout(duration));
 
         try {
             return Await.result(future, AWAIT_DURATION);
         } catch (Exception e) {
-            throw new RuntimeException(e);
+            throw new TimeoutException("Sending message " + message.getClass().toString() + " to actor " + actor.toString() + " failed" , e);
         }
     }
 
     /**
      * Execute an operation on a remote actor and wait for it's response
+     *
      * @param actor
      * @param message
      * @param duration
      * @return
      */
     public Object executeRemoteOperation(ActorSelection actor, Object message,
-        FiniteDuration duration){
+        FiniteDuration duration) {
+
+        LOG.debug("Sending remote message {} to {}", message.getClass().toString(), actor.toString());
+
         Future<Object> future =
             ask(actor, message, new Timeout(duration));
 
         try {
             return Await.result(future, AWAIT_DURATION);
         } catch (Exception e) {
-            throw new RuntimeException(e);
+            throw new TimeoutException("Sending message " + message.getClass().toString() + " to actor " + actor.toString() + " failed" , e);
         }
     }
 
     /**
      * Execute an operation on the primary for a given shard
      * <p>
-     *     This method first finds the primary for a given shard ,then sends
-     *     the message to the remote shard and waits for a response
+     * This method first finds the primary for a given shard ,then sends
+     * the message to the remote shard and waits for a response
      * </p>
+     *
      * @param shardName
      * @param message
      * @param duration
-     * @throws java.lang.RuntimeException when a primary is not found or if the message to the remote shard fails or times out
-     *
      * @return
+     * @throws org.opendaylight.controller.cluster.datastore.exceptions.TimeoutException         if the message to the remote shard times out
+     * @throws org.opendaylight.controller.cluster.datastore.exceptions.PrimaryNotFoundException if the primary shard is not found
      */
-    public Object executeShardOperation(String shardName, Object message, FiniteDuration duration){
+    public Object executeShardOperation(String shardName, Object message,
+        FiniteDuration duration) {
         ActorSelection primary = findPrimary(shardName);
 
         return executeRemoteOperation(primary, message, duration);
     }
 
+    public void shutdown() {
+        shardManager.tell(PoisonPill.getInstance(), null);
+        actorSystem.shutdown();
+    }
+
+    /**
+     * @deprecated Need to stop using this method. There are ways to send a
+     * remote ActorRef as a string which should be used instead of this hack
+     *
+     * @param primaryPath
+     * @param localPathOfRemoteActor
+     * @return
+     */
+    @Deprecated
+    public String resolvePath(final String primaryPath,
+        final String localPathOfRemoteActor) {
+        StringBuilder builder = new StringBuilder();
+        String[] primaryPathElements = primaryPath.split("/");
+        builder.append(primaryPathElements[0]).append("//")
+            .append(primaryPathElements[1]).append(primaryPathElements[2]);
+        String[] remotePathElements = localPathOfRemoteActor.split("/");
+        for (int i = 3; i < remotePathElements.length; i++) {
+            builder.append("/").append(remotePathElements[i]);
+        }
+
+        return builder.toString();
+
+    }
+
+    public ActorPath actorFor(String path){
+        return actorSystem.actorFor(path).path();
+    }
+
+    public String getCurrentMemberName(){
+        return clusterWrapper.getCurrentMemberName();
+    }
+
 }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/utils/InstanceIdentifierUtils.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/utils/InstanceIdentifierUtils.java
new file mode 100644 (file)
index 0000000..20268a6
--- /dev/null
@@ -0,0 +1,72 @@
+package org.opendaylight.controller.cluster.datastore.utils;
+
+import org.opendaylight.controller.cluster.datastore.node.utils.NodeIdentifierFactory;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author: syedbahm
+ */
+public class InstanceIdentifierUtils {
+
+    protected static final Logger logger = LoggerFactory
+        .getLogger(InstanceIdentifierUtils.class);
+
+    public static String getParentPath(String currentElementPath) {
+        String parentPath = "";
+
+        if (currentElementPath != null) {
+            String[] parentPaths = currentElementPath.split("/");
+            if (parentPaths.length > 2) {
+                for (int i = 0; i < parentPaths.length - 1; i++) {
+                    if (parentPaths[i].length() > 0) {
+                        parentPath += "/" + parentPaths[i];
+                    }
+                }
+            }
+        }
+        return parentPath;
+    }
+
+    @Deprecated
+    public static YangInstanceIdentifier from(String path) {
+        String[] ids = path.split("/");
+
+        List<YangInstanceIdentifier.PathArgument> pathArguments =
+            new ArrayList<>();
+        for (String nodeId : ids) {
+            if (!"".equals(nodeId)) {
+                pathArguments
+                    .add(NodeIdentifierFactory.getArgument(nodeId));
+            }
+        }
+        final YangInstanceIdentifier instanceIdentifier =
+            YangInstanceIdentifier.create(pathArguments);
+        return instanceIdentifier;
+    }
+
+    /**
+     * @deprecated Use {@link org.opendaylight.controller.cluster.datastore.util.InstanceIdentifierUtils} instead
+     * @param path
+     * @return
+     */
+    @Deprecated
+    public static NormalizedNodeMessages.InstanceIdentifier toSerializable(YangInstanceIdentifier path){
+        return org.opendaylight.controller.cluster.datastore.util.InstanceIdentifierUtils.toSerializable(path);
+    }
+
+    /**
+     * @deprecated Use {@link org.opendaylight.controller.cluster.datastore.util.InstanceIdentifierUtils} instead
+     * @param path
+     * @return
+     */
+    @Deprecated
+    public static YangInstanceIdentifier fromSerializable(NormalizedNodeMessages.InstanceIdentifier path){
+        return org.opendaylight.controller.cluster.datastore.util.InstanceIdentifierUtils.fromSerializable(path);
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java
new file mode 100644 (file)
index 0000000..039446b
--- /dev/null
@@ -0,0 +1,32 @@
+package org.opendaylight.controller.config.yang.config.distributed_datastore_provider;
+
+import org.opendaylight.controller.cluster.datastore.DistributedDataStoreFactory;
+
+public class DistributedConfigDataStoreProviderModule extends
+    org.opendaylight.controller.config.yang.config.distributed_datastore_provider.AbstractDistributedConfigDataStoreProviderModule {
+    public DistributedConfigDataStoreProviderModule(
+        org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+        org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public DistributedConfigDataStoreProviderModule(
+        org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+        org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+        org.opendaylight.controller.config.yang.config.distributed_datastore_provider.DistributedConfigDataStoreProviderModule oldModule,
+        java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        return DistributedDataStoreFactory
+            .createInstance("config", getSchemaServiceDependency());
+    }
+
+}
@@ -1,13 +1,13 @@
 /*
 * Generated file
 *
-* Generated from: yang module name: distributed-datastore-provider yang module local name: distributed-datastore-provider
+* Generated from: yang module name: distributed-datastore-provider yang module local name: distributed-config-datastore-provider
 * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Thu Jun 12 15:23:43 PDT 2014
+* Generated at: Tue Jun 24 17:14:50 PDT 2014
 *
 * Do not modify this file unless it is present under src/main directory
 */
 package org.opendaylight.controller.config.yang.config.distributed_datastore_provider;
-public class DistributedDataStoreProviderModuleFactory extends org.opendaylight.controller.config.yang.config.distributed_datastore_provider.AbstractDistributedDataStoreProviderModuleFactory {
+public class DistributedConfigDataStoreProviderModuleFactory extends org.opendaylight.controller.config.yang.config.distributed_datastore_provider.AbstractDistributedConfigDataStoreProviderModuleFactory {
 
 }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedDataStoreProviderModule.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedDataStoreProviderModule.java
deleted file mode 100644 (file)
index 3a78f93..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.opendaylight.controller.config.yang.config.distributed_datastore_provider;
-
-import akka.actor.ActorSystem;
-import org.opendaylight.controller.cluster.datastore.DistributedDataStore;
-
-public class DistributedDataStoreProviderModule extends org.opendaylight.controller.config.yang.config.distributed_datastore_provider.AbstractDistributedDataStoreProviderModule {
-  public DistributedDataStoreProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
-    super(identifier, dependencyResolver);
-  }
-
-  public DistributedDataStoreProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.config.distributed_datastore_provider.DistributedDataStoreProviderModule oldModule, java.lang.AutoCloseable oldInstance) {
-    super(identifier, dependencyResolver, oldModule, oldInstance);
-  }
-
-  @Override
-  public void customValidation() {
-    // add custom validation form module attributes here.
-  }
-
-  @Override
-  public java.lang.AutoCloseable createInstance() {
-    ActorSystem actorSystem = ActorSystem.create("opendaylight-cluster");
-    final DistributedDataStore configurationStore = new DistributedDataStore(actorSystem, "config");
-    final DistributedDataStore operationalStore = new DistributedDataStore(actorSystem, "operational");
-
-    final class AutoCloseableDistributedDataStore implements AutoCloseable {
-
-      @Override
-      public void close() throws Exception {
-      }
-    }
-
-    return new AutoCloseableDistributedDataStore();
-  }
-
-}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java
new file mode 100644 (file)
index 0000000..1a06629
--- /dev/null
@@ -0,0 +1,32 @@
+package org.opendaylight.controller.config.yang.config.distributed_datastore_provider;
+
+import org.opendaylight.controller.cluster.datastore.DistributedDataStoreFactory;
+
+public class DistributedOperationalDataStoreProviderModule extends
+    org.opendaylight.controller.config.yang.config.distributed_datastore_provider.AbstractDistributedOperationalDataStoreProviderModule {
+    public DistributedOperationalDataStoreProviderModule(
+        org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+        org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public DistributedOperationalDataStoreProviderModule(
+        org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+        org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+        org.opendaylight.controller.config.yang.config.distributed_datastore_provider.DistributedOperationalDataStoreProviderModule oldModule,
+        java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        return DistributedDataStoreFactory
+            .createInstance("operational", getSchemaServiceDependency());
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModuleFactory.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModuleFactory.java
new file mode 100644 (file)
index 0000000..c9965fe
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: distributed-datastore-provider yang module local name: distributed-operational-datastore-provider
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Tue Jun 24 17:14:50 PDT 2014
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.config.distributed_datastore_provider;
+public class DistributedOperationalDataStoreProviderModuleFactory extends org.opendaylight.controller.config.yang.config.distributed_datastore_provider.AbstractDistributedOperationalDataStoreProviderModuleFactory {
+
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/application.conf b/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/application.conf
new file mode 100644 (file)
index 0000000..76914c2
--- /dev/null
@@ -0,0 +1,15 @@
+ODLCluster{
+
+actor {
+        serializers {
+          java = "akka.serialization.JavaSerializer"
+          proto = "akka.remote.serialization.ProtobufSerializer"
+        }
+
+        serialization-bindings {
+            "com.google.protobuf.Message" = proto
+
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/module-shards.conf b/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/module-shards.conf
new file mode 100644 (file)
index 0000000..60dd775
--- /dev/null
@@ -0,0 +1,25 @@
+module-shards = [
+    {
+        name = "default"
+        shards = [
+            {
+                name="default",
+                replicas = [
+                    "member-1",
+                ]
+            }
+        ]
+    },
+    {
+        name = "inventory"
+        shards = [
+            {
+                name="inventory"
+                replicas = [
+                    "member-1",
+                ]
+            }
+        ]
+    }
+
+]
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/modules.conf b/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/modules.conf
new file mode 100644 (file)
index 0000000..05ef33f
--- /dev/null
@@ -0,0 +1,7 @@
+modules = [
+    {
+        name = "inventory"
+        namespace = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:people"
+        shard-strategy = "module"
+    }
+]
index 0471bc806e00d65e973432b4faa7dea90e593516..5d3758986c40fc8858005aad29cf74f85c9af857 100644 (file)
@@ -7,6 +7,9 @@ module distributed-datastore-provider {
 
     import config { prefix config; revision-date 2013-04-05; }
     import rpc-context { prefix rpcx; revision-date 2013-06-17; }
+    import opendaylight-config-dom-datastore {prefix config-dom-store-spi;}
+    import opendaylight-operational-dom-datastore {prefix operational-dom-store-spi;}
+    import opendaylight-md-sal-dom {prefix sal;}
 
     description
         "This module contains the base YANG definitions for
@@ -18,17 +21,48 @@ module distributed-datastore-provider {
     }
 
     // This is the definition of the service implementation as a module identity.
-    identity distributed-datastore-provider {
+    identity distributed-config-datastore-provider {
             base config:module-type;
-
+            config:provided-service config-dom-store-spi:config-dom-datastore;
             // Specifies the prefix for generated java classes.
-            config:java-name-prefix DistributedDataStoreProvider;
+            config:java-name-prefix DistributedConfigDataStoreProvider;
     }
 
+     // This is the definition of the service implementation as a module identity.
+     identity distributed-operational-datastore-provider {
+                base config:module-type;
+                config:provided-service operational-dom-store-spi:operational-dom-datastore;
+                // Specifies the prefix for generated java classes.
+                config:java-name-prefix DistributedOperationalDataStoreProvider;
+     }
+
     // Augments the 'configuration' choice node under modules/module.
     augment "/config:modules/config:module/config:configuration" {
-        case distributed-datastore-provider {
-            when "/config:modules/config:module/config:type = 'distributed-datastore-provider'";
+        case distributed-config-datastore-provider {
+            when "/config:modules/config:module/config:type = 'distributed-config-datastore-provider'";
+            container schema-service {
+                          uses config:service-ref {
+                               refine type {
+                                      mandatory false;
+                                      config:required-identity sal:schema-service;
+                                }
+                          }
+                        }
         }
     }
+
+    // Augments the 'configuration' choice node under modules/module.
+        augment "/config:modules/config:module/config:configuration" {
+            case distributed-operational-datastore-provider {
+                when "/config:modules/config:module/config:type = 'distributed-operational-datastore-provider'";
+                container schema-service {
+                              uses config:service-ref {
+                                   refine type {
+                                          mandatory false;
+                                          config:required-identity sal:schema-service;
+                                    }
+                              }
+                            }
+            }
+        }
 }
index 45ef32f7ad798ad15a0840c1c7860bf61f34913d..e23a76b0b223ee2b8ee0d5398da878cd520caf65 100644 (file)
@@ -10,25 +10,42 @@ package org.opendaylight.controller.cluster.datastore;
 
 import akka.actor.ActorSystem;
 import akka.testkit.JavaTestKit;
+import org.apache.commons.io.FileUtils;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 
+import java.io.File;
+import java.io.IOException;
+
 public abstract class AbstractActorTest {
-  private static ActorSystem system;
-
-  @BeforeClass
-  public static void setUpClass(){
-    system = ActorSystem.create("test");
-  }
-
-  @AfterClass
-  public static void tearDownClass(){
-    JavaTestKit.shutdownActorSystem(system);
-    system = null;
-  }
-
-  protected ActorSystem getSystem(){
-    return system;
-  }
+    private static ActorSystem system;
+
+    @BeforeClass
+    public static void setUpClass() throws IOException {
+        File journal = new File("journal");
+
+        if(journal.exists()) {
+            FileUtils.deleteDirectory(journal);
+        }
+
+        System.setProperty("shard.persistent", "false");
+        system = ActorSystem.create("test");
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws IOException {
+        JavaTestKit.shutdownActorSystem(system);
+        system = null;
+
+        File journal = new File("journal");
+
+        if(journal.exists()) {
+            FileUtils.deleteDirectory(journal);
+        }
+    }
+
+    protected ActorSystem getSystem() {
+        return system;
+    }
 
 }
index 8c3ec82a54eb7c50d195675cffc122b6ed13d546..11ad559744a3923aebfbb07472771b98a4439ab0 100644 (file)
@@ -16,7 +16,6 @@ import akka.testkit.JavaTestKit;
 import junit.framework.Assert;
 import org.junit.Test;
 import org.opendaylight.controller.cluster.datastore.messages.CommitTransaction;
-import org.opendaylight.controller.cluster.datastore.messages.CommitTransactionReply;
 import org.opendaylight.controller.cluster.datastore.messages.CreateTransaction;
 import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionChain;
 import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionChainReply;
@@ -30,11 +29,17 @@ import org.opendaylight.controller.cluster.datastore.messages.WriteData;
 import org.opendaylight.controller.cluster.datastore.messages.WriteDataReply;
 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import scala.concurrent.Await;
+import scala.concurrent.Future;
+import scala.concurrent.duration.FiniteDuration;
+
+import java.util.Collections;
 
 public class BasicIntegrationTest extends AbstractActorTest {
 
     @Test
-    public void integrationTest() {
+    public void integrationTest() throws Exception{
+        // System.setProperty("shard.persistent", "true");
         // This test will
         // - create a Shard
         // - initiate a transaction
@@ -44,24 +49,33 @@ public class BasicIntegrationTest extends AbstractActorTest {
 
 
         new JavaTestKit(getSystem()) {{
-            final Props props = Shard.props("config");
+            final Props props = Shard.props("config", Collections.EMPTY_MAP);
             final ActorRef shard = getSystem().actorOf(props);
 
             new Within(duration("5 seconds")) {
                 protected void run() {
 
+
                     shard.tell(
                         new UpdateSchemaContext(TestModel.createTestContext()),
                         getRef());
 
-                    shard.tell(new CreateTransactionChain(), getRef());
+
+                    // Wait for Shard to become a Leader
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    // 1. Create a TransactionChain
+                    shard.tell(new CreateTransactionChain().toSerializable(), getRef());
 
                     final ActorSelection transactionChain =
-                        new ExpectMsg<ActorSelection>("match hint") {
+                        new ExpectMsg<ActorSelection>("CreateTransactionChainReply") {
                             protected ActorSelection match(Object in) {
-                                if (in instanceof CreateTransactionChainReply) {
+                                if (in.getClass().equals(CreateTransactionChainReply.SERIALIZABLE_CLASS)) {
                                     ActorPath transactionChainPath =
-                                        ((CreateTransactionChainReply) in)
+                                        CreateTransactionChainReply.fromSerializable(getSystem(),in)
                                             .getTransactionChainPath();
                                     return getSystem()
                                         .actorSelection(transactionChainPath);
@@ -73,17 +87,19 @@ public class BasicIntegrationTest extends AbstractActorTest {
 
                     Assert.assertNotNull(transactionChain);
 
-                    transactionChain.tell(new CreateTransaction(), getRef());
+                    System.out.println("Successfully created transaction chain");
+
+                    // 2. Create a Transaction on the TransactionChain
+                    transactionChain.tell(new CreateTransaction("txn-1").toSerializable(), getRef());
 
                     final ActorSelection transaction =
-                        new ExpectMsg<ActorSelection>("match hint") {
+                        new ExpectMsg<ActorSelection>("CreateTransactionReply") {
                             protected ActorSelection match(Object in) {
-                                if (in instanceof CreateTransactionReply) {
-                                    ActorPath transactionPath =
-                                        ((CreateTransactionReply) in)
-                                            .getTransactionPath();
+                                if (CreateTransactionReply.SERIALIZABLE_CLASS.equals(in.getClass())) {
+                                    CreateTransactionReply reply = CreateTransactionReply.fromSerializable(in);
                                     return getSystem()
-                                        .actorSelection(transactionPath);
+                                        .actorSelection(reply
+                                            .getTransactionPath());
                                 } else {
                                     throw noMatch();
                                 }
@@ -92,13 +108,16 @@ public class BasicIntegrationTest extends AbstractActorTest {
 
                     Assert.assertNotNull(transaction);
 
+                    System.out.println("Successfully created transaction");
+
+                    // 3. Write some data
                     transaction.tell(new WriteData(TestModel.TEST_PATH,
-                        ImmutableNodes.containerNode(TestModel.TEST_QNAME)),
+                        ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()).toSerializable(),
                         getRef());
 
-                    Boolean writeDone = new ExpectMsg<Boolean>("match hint") {
+                    Boolean writeDone = new ExpectMsg<Boolean>("WriteDataReply") {
                         protected Boolean match(Object in) {
-                            if (in instanceof WriteDataReply) {
+                            if (in.getClass().equals(WriteDataReply.SERIALIZABLE_CLASS)) {
                                 return true;
                             } else {
                                 throw noMatch();
@@ -108,14 +127,18 @@ public class BasicIntegrationTest extends AbstractActorTest {
 
                     Assert.assertTrue(writeDone);
 
-                    transaction.tell(new ReadyTransaction(), getRef());
+                    System.out.println("Successfully wrote data");
+
+                    // 4. Ready the transaction for commit
+
+                    transaction.tell(new ReadyTransaction().toSerializable(), getRef());
 
                     final ActorSelection cohort =
-                        new ExpectMsg<ActorSelection>("match hint") {
+                        new ExpectMsg<ActorSelection>("ReadyTransactionReply") {
                             protected ActorSelection match(Object in) {
-                                if (in instanceof ReadyTransactionReply) {
+                                if (in.getClass().equals(ReadyTransactionReply.SERIALIZABLE_CLASS)) {
                                     ActorPath cohortPath =
-                                        ((ReadyTransactionReply) in)
+                                        ReadyTransactionReply.fromSerializable(getSystem(),in)
                                             .getCohortPath();
                                     return getSystem()
                                         .actorSelection(cohortPath);
@@ -127,12 +150,16 @@ public class BasicIntegrationTest extends AbstractActorTest {
 
                     Assert.assertNotNull(cohort);
 
-                    cohort.tell(new PreCommitTransaction(), getRef());
+                    System.out.println("Successfully readied the transaction");
+
+                    // 5. PreCommit the transaction
+
+                    cohort.tell(new PreCommitTransaction().toSerializable(), getRef());
 
                     Boolean preCommitDone =
-                        new ExpectMsg<Boolean>("match hint") {
+                        new ExpectMsg<Boolean>("PreCommitTransactionReply") {
                             protected Boolean match(Object in) {
-                                if (in instanceof PreCommitTransactionReply) {
+                                if (in.getClass().equals(PreCommitTransactionReply.SERIALIZABLE_CLASS)) {
                                     return true;
                                 } else {
                                     throw noMatch();
@@ -142,26 +169,37 @@ public class BasicIntegrationTest extends AbstractActorTest {
 
                     Assert.assertTrue(preCommitDone);
 
-                    cohort.tell(new CommitTransaction(), getRef());
+                    System.out.println("Successfully pre-committed the transaction");
 
-                    final Boolean commitDone =
-                        new ExpectMsg<Boolean>("match hint") {
-                            protected Boolean match(Object in) {
-                                if (in instanceof CommitTransactionReply) {
-                                    return true;
-                                } else {
-                                    throw noMatch();
-                                }
-                            }
-                        }.get(); // this extracts the received message
+                    // 6. Commit the transaction
+                    cohort.tell(new CommitTransaction().toSerializable(), getRef());
 
-                    Assert.assertTrue(commitDone);
+                    // FIXME : Add assertions that the commit worked and that the cohort and transaction actors were terminated
 
+                    System.out.println("TODO : Check Successfully committed the transaction");
                 }
 
 
             };
-        }};
+        }
+
+            private ActorRef watchActor(ActorSelection actor) {
+                Future<ActorRef> future = actor
+                    .resolveOne(FiniteDuration.apply(100, "milliseconds"));
+
+                try {
+                    ActorRef actorRef = Await.result(future,
+                        FiniteDuration.apply(100, "milliseconds"));
+
+                    watch(actorRef);
+
+                    return actorRef;
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+
+            }
+        };
 
 
     }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ConfigurationImplTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ConfigurationImplTest.java
new file mode 100644 (file)
index 0000000..56fd3c5
--- /dev/null
@@ -0,0 +1,41 @@
+package org.opendaylight.controller.cluster.datastore;
+
+import com.typesafe.config.ConfigFactory;
+import junit.framework.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.List;
+
+import static org.junit.Assert.assertTrue;
+
+public class ConfigurationImplTest {
+
+    private static ConfigurationImpl configuration;
+
+    @BeforeClass
+    public static void staticSetup(){
+        configuration = new ConfigurationImpl("module-shards.conf", "modules.conf");
+    }
+
+    @Test
+    public void testConstructor(){
+        Assert.assertNotNull(configuration);
+    }
+
+    @Test
+    public void testGetMemberShardNames(){
+        List<String> memberShardNames =
+            configuration.getMemberShardNames("member-1");
+
+        assertTrue(memberShardNames.contains("people-1"));
+        assertTrue(memberShardNames.contains("cars-1"));
+    }
+
+    @Test
+    public void testReadConfigurationFromFile(){
+        File f = new File("./module-shards.conf");
+        ConfigFactory.parseFile(f);
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxyTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxyTest.java
new file mode 100644 (file)
index 0000000..8c1cbbb
--- /dev/null
@@ -0,0 +1,100 @@
+
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.ActorRef;
+import akka.actor.Props;
+import junit.framework.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.messages.DataChanged;
+import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
+import org.opendaylight.controller.cluster.datastore.utils.DoNothingActor;
+import org.opendaylight.controller.cluster.datastore.utils.MessageCollectorActor;
+import org.opendaylight.controller.cluster.datastore.utils.MockClusterWrapper;
+import org.opendaylight.controller.cluster.datastore.utils.MockConfiguration;
+import org.opendaylight.controller.md.cluster.datastore.model.CompositeModel;
+import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class DataChangeListenerProxyTest extends AbstractActorTest {
+
+  private static class MockDataChangedEvent implements AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> {
+    Map<YangInstanceIdentifier,NormalizedNode<?,?>> createdData = new HashMap();
+    Map<YangInstanceIdentifier,NormalizedNode<?,?>> updatedData = new HashMap();
+    Map<YangInstanceIdentifier,NormalizedNode<?,?>> originalData = new HashMap();
+
+
+
+    @Override
+    public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getCreatedData() {
+      createdData.put(YangInstanceIdentifier.builder().build(), CompositeModel.createDocumentOne(CompositeModel.createTestContext()));
+      return createdData;
+    }
+
+    @Override
+    public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getUpdatedData() {
+      updatedData.put(YangInstanceIdentifier.builder().build(), CompositeModel.createTestContainer());
+      return updatedData;
+
+    }
+
+    @Override
+    public Set<YangInstanceIdentifier> getRemovedPaths() {
+      Set<YangInstanceIdentifier>ids = new HashSet();
+      ids.add( CompositeModel.TEST_PATH);
+      return ids;
+    }
+
+    @Override
+    public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getOriginalData() {
+      originalData.put(YangInstanceIdentifier.builder().build(), CompositeModel.createFamily());
+      return originalData;
+    }
+
+    @Override public NormalizedNode<?, ?> getOriginalSubtree() {
+      return CompositeModel.createFamily() ;
+    }
+
+    @Override public NormalizedNode<?, ?> getUpdatedSubtree() {
+      return CompositeModel.createTestContainer();
+    }
+  }
+
+
+  @Test
+    public void testOnDataChanged() throws Exception {
+        final Props props = Props.create(MessageCollectorActor.class);
+        final ActorRef actorRef = getSystem().actorOf(props);
+
+        DataChangeListenerProxy dataChangeListenerProxy =
+            new DataChangeListenerProxy(TestModel.createTestContext(),
+                getSystem().actorSelection(actorRef.path()));
+
+        dataChangeListenerProxy.onDataChanged(new MockDataChangedEvent());
+
+        //Check if it was received by the remote actor
+        ActorContext
+            testContext = new ActorContext(getSystem(), getSystem().actorOf(Props.create(DoNothingActor.class)), new MockClusterWrapper(), new MockConfiguration());
+        Object messages = testContext
+            .executeLocalOperation(actorRef, "messages",
+                ActorContext.ASK_DURATION);
+
+        Assert.assertNotNull(messages);
+
+        Assert.assertTrue(messages instanceof List);
+
+        List<Object> listMessages = (List<Object>) messages;
+
+        Assert.assertEquals(1, listMessages.size());
+
+        Assert.assertTrue(listMessages.get(0).getClass().equals(DataChanged.SERIALIZABLE_CLASS));
+
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationProxyTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationProxyTest.java
new file mode 100644 (file)
index 0000000..c99a7e8
--- /dev/null
@@ -0,0 +1,78 @@
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.ActorRef;
+import akka.actor.Props;
+import junit.framework.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.messages.CloseDataChangeListenerRegistration;
+import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
+import org.opendaylight.controller.cluster.datastore.utils.DoNothingActor;
+import org.opendaylight.controller.cluster.datastore.utils.MessageCollectorActor;
+import org.opendaylight.controller.cluster.datastore.utils.MockClusterWrapper;
+import org.opendaylight.controller.cluster.datastore.utils.MockConfiguration;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+import java.util.List;
+
+public class DataChangeListenerRegistrationProxyTest extends AbstractActorTest{
+
+    private ActorRef dataChangeListenerActor = getSystem().actorOf(Props.create(DoNothingActor.class));
+
+    private static class MockDataChangeListener implements
+        AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> {
+
+        @Override public void onDataChanged(
+            AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
+            throw new UnsupportedOperationException("onDataChanged");
+        }
+    }
+
+    @Test
+    public void testGetInstance() throws Exception {
+        final Props props = Props.create(MessageCollectorActor.class);
+        final ActorRef actorRef = getSystem().actorOf(props);
+
+        MockDataChangeListener listener =
+            new MockDataChangeListener();
+        DataChangeListenerRegistrationProxy proxy =
+            new DataChangeListenerRegistrationProxy(
+                getSystem().actorSelection(actorRef.path()),
+                listener, dataChangeListenerActor);
+
+        Assert.assertEquals(listener, proxy.getInstance());
+
+    }
+
+    @Test
+    public void testClose() throws Exception {
+        final Props props = Props.create(MessageCollectorActor.class);
+        final ActorRef actorRef = getSystem().actorOf(props);
+
+        DataChangeListenerRegistrationProxy proxy =
+            new DataChangeListenerRegistrationProxy(
+                getSystem().actorSelection(actorRef.path()),
+                new MockDataChangeListener(), dataChangeListenerActor);
+
+        proxy.close();
+
+        //Check if it was received by the remote actor
+        ActorContext
+            testContext = new ActorContext(getSystem(), getSystem().actorOf(Props.create(DoNothingActor.class)),new MockClusterWrapper(), new MockConfiguration());
+        Object messages = testContext
+            .executeLocalOperation(actorRef, "messages",
+                ActorContext.ASK_DURATION);
+
+        Assert.assertNotNull(messages);
+
+        Assert.assertTrue(messages instanceof List);
+
+        List<Object> listMessages = (List<Object>) messages;
+
+        Assert.assertEquals(1, listMessages.size());
+
+        Assert.assertTrue(listMessages.get(0).getClass().equals(CloseDataChangeListenerRegistration.SERIALIZABLE_CLASS));
+    }
+}
@@ -6,19 +6,19 @@ import akka.testkit.JavaTestKit;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 import org.junit.Test;
-import org.opendaylight.controller.cluster.datastore.messages.CloseListenerRegistration;
-import org.opendaylight.controller.cluster.datastore.messages.CloseListenerRegistrationReply;
+import org.opendaylight.controller.cluster.datastore.messages.CloseDataChangeListenerRegistration;
+import org.opendaylight.controller.cluster.datastore.messages.CloseDataChangeListenerRegistrationReply;
 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import static org.junit.Assert.assertEquals;
 
-public class ListenerRegistrationTest extends AbstractActorTest {
+public class DataChangeListenerRegistrationTest extends AbstractActorTest {
   private static ListeningExecutorService storeExecutor = MoreExecutors.listeningDecorator(MoreExecutors.sameThreadExecutor());
 
   private static final InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER", storeExecutor);
@@ -31,18 +31,20 @@ public class ListenerRegistrationTest extends AbstractActorTest {
   @Test
   public void testOnReceiveCloseListenerRegistration() throws Exception {
     new JavaTestKit(getSystem()) {{
-      final Props props = ListenerRegistration.props(store.registerChangeListener(TestModel.TEST_PATH, noOpDataChangeListener(), AsyncDataBroker.DataChangeScope.BASE));
+      final Props props = DataChangeListenerRegistration.props(store
+          .registerChangeListener(TestModel.TEST_PATH, noOpDataChangeListener(),
+              AsyncDataBroker.DataChangeScope.BASE));
       final ActorRef subject = getSystem().actorOf(props, "testCloseListenerRegistration");
 
       new Within(duration("1 seconds")) {
         protected void run() {
 
-          subject.tell(new CloseListenerRegistration(), getRef());
+          subject.tell(new CloseDataChangeListenerRegistration().toSerializable(), getRef());
 
           final String out = new ExpectMsg<String>("match hint") {
             // do not put code outside this method, will run afterwards
             protected String match(Object in) {
-              if (in instanceof CloseListenerRegistrationReply) {
+              if (in.getClass().equals(CloseDataChangeListenerRegistrationReply.SERIALIZABLE_CLASS)) {
                 return "match";
               } else {
                 throw noMatch();
@@ -60,13 +62,13 @@ public class ListenerRegistrationTest extends AbstractActorTest {
     }};
   }
 
-  private  AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>> noOpDataChangeListener(){
-    return new AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>() {
+  private  AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> noOpDataChangeListener(){
+    return new AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>() {
       @Override
-      public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> change) {
+      public void onDataChanged(AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
 
       }
     };
   }
 
-}
\ No newline at end of file
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerTest.java
new file mode 100644 (file)
index 0000000..fd61032
--- /dev/null
@@ -0,0 +1,126 @@
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.ActorRef;
+import akka.actor.Props;
+import akka.testkit.JavaTestKit;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.messages.DataChanged;
+import org.opendaylight.controller.cluster.datastore.messages.DataChangedReply;
+import org.opendaylight.controller.md.cluster.datastore.model.CompositeModel;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class DataChangeListenerTest extends AbstractActorTest {
+
+    private static class MockDataChangedEvent implements AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> {
+       Map<YangInstanceIdentifier,NormalizedNode<?,?>> createdData = new HashMap();
+       Map<YangInstanceIdentifier,NormalizedNode<?,?>> updatedData = new HashMap();
+       Map<YangInstanceIdentifier,NormalizedNode<?,?>> originalData = new HashMap();
+
+
+
+        @Override
+        public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getCreatedData() {
+            createdData.put(CompositeModel.FAMILY_PATH, CompositeModel.createFamily());
+            return createdData;
+        }
+
+        @Override
+        public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getUpdatedData() {
+            updatedData.put(CompositeModel.FAMILY_PATH, CompositeModel.createFamily());
+            return updatedData;
+
+        }
+
+        @Override
+        public Set<YangInstanceIdentifier> getRemovedPaths() {
+               Set<YangInstanceIdentifier>ids = new HashSet();
+               ids.add( CompositeModel.TEST_PATH);
+              return ids;
+        }
+
+        @Override
+        public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getOriginalData() {
+          originalData.put(CompositeModel.FAMILY_PATH, CompositeModel.createFamily());
+          return originalData;
+        }
+
+        @Override public NormalizedNode<?, ?> getOriginalSubtree() {
+
+
+          return originalData.put(CompositeModel.FAMILY_PATH, CompositeModel.createFamily());
+        }
+
+        @Override public NormalizedNode<?, ?> getUpdatedSubtree() {
+
+          //fixme: need to have some valid data here
+          return originalData.put(CompositeModel.FAMILY_PATH, CompositeModel.createFamily());
+        }
+    }
+
+    private class MockDataChangeListener implements AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> {
+        private boolean gotIt = false;
+        private   AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change;
+
+        @Override public void onDataChanged(
+            AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
+            gotIt = true;this.change=change;
+        }
+
+        public boolean gotIt() {
+            return gotIt;
+        }
+        public  AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> getChange(){
+          return change;
+        }
+    }
+
+    @Test
+    public void testDataChanged(){
+        new JavaTestKit(getSystem()) {{
+            final MockDataChangeListener listener = new MockDataChangeListener();
+            final Props props = DataChangeListener.props(CompositeModel.createTestContext(),listener,CompositeModel.FAMILY_PATH );
+            final ActorRef subject =
+                getSystem().actorOf(props, "testDataChanged");
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    subject.tell(
+                        new DataChanged(CompositeModel.createTestContext(),new MockDataChangedEvent()).toSerializable(),
+                        getRef());
+
+                    final Boolean out = new ExpectMsg<Boolean>("dataChanged") {
+                        // do not put code outside this method, will run afterwards
+                        protected Boolean match(Object in) {
+                            if (in.getClass().equals(DataChangedReply.SERIALIZABLE_CLASS)) {
+
+                                return true;
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get(); // this extracts the received message
+
+                    assertTrue(out);
+                    assertTrue(listener.gotIt());
+                    assertNotNull(listener.getChange().getCreatedData());
+                    // Will wait for the rest of the 3 seconds
+                    expectNoMsg();
+                }
+
+
+            };
+        }};
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreIntegrationTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreIntegrationTest.java
new file mode 100644 (file)
index 0000000..b5e3d24
--- /dev/null
@@ -0,0 +1,124 @@
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.ActorSystem;
+import akka.testkit.JavaTestKit;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategyFactory;
+import org.opendaylight.controller.cluster.datastore.utils.MockClusterWrapper;
+import org.opendaylight.controller.md.cluster.datastore.model.CarsModel;
+import org.opendaylight.controller.md.cluster.datastore.model.PeopleModel;
+import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper;
+import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+
+import java.util.concurrent.ExecutionException;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+public class DistributedDataStoreIntegrationTest{
+
+    private static ActorSystem system;
+
+    @Before
+    public void setUp() {
+        System.setProperty("shard.persistent", "false");
+        system = ActorSystem.create("test");
+    }
+
+    @After
+    public void tearDown() {
+        JavaTestKit.shutdownActorSystem(system);
+        system = null;
+    }
+
+    protected ActorSystem getSystem() {
+        return system;
+    }
+
+    @Test
+    public void integrationTest() throws Exception {
+        Configuration configuration = new ConfigurationImpl("module-shards.conf", "modules.conf");
+        ShardStrategyFactory.setConfiguration(configuration);
+        DistributedDataStore distributedDataStore =
+            new DistributedDataStore(getSystem(), "config", new MockClusterWrapper(), configuration);
+
+        distributedDataStore.onGlobalContextUpdated(TestModel.createTestContext());
+
+        Thread.sleep(1000);
+
+        DOMStoreReadWriteTransaction transaction =
+            distributedDataStore.newReadWriteTransaction();
+
+        transaction.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+
+        ListenableFuture<Optional<NormalizedNode<?, ?>>> future =
+            transaction.read(TestModel.TEST_PATH);
+
+        Optional<NormalizedNode<?, ?>> optional = future.get();
+
+        NormalizedNode<?, ?> normalizedNode = optional.get();
+
+        assertEquals(TestModel.TEST_QNAME, normalizedNode.getNodeType());
+
+        DOMStoreThreePhaseCommitCohort ready = transaction.ready();
+
+        ListenableFuture<Boolean> canCommit = ready.canCommit();
+
+        assertTrue(canCommit.get());
+
+        ListenableFuture<Void> preCommit = ready.preCommit();
+
+        preCommit.get();
+
+        ListenableFuture<Void> commit = ready.commit();
+
+        commit.get();
+
+    }
+
+
+    @Test
+    public void integrationTestWithMultiShardConfiguration()
+        throws ExecutionException, InterruptedException {
+        Configuration configuration = new ConfigurationImpl("module-shards.conf", "modules.conf");
+
+        ShardStrategyFactory.setConfiguration(configuration);
+        DistributedDataStore distributedDataStore =
+            new DistributedDataStore(getSystem(), "config", new MockClusterWrapper(), configuration);
+
+
+        distributedDataStore.onGlobalContextUpdated(SchemaContextHelper.full());
+
+        Thread.sleep(1000);
+
+        DOMStoreReadWriteTransaction transaction =
+            distributedDataStore.newReadWriteTransaction();
+
+        transaction.write(CarsModel.BASE_PATH, CarsModel.emptyContainer());
+        transaction.write(PeopleModel.BASE_PATH, PeopleModel.emptyContainer());
+
+        DOMStoreThreePhaseCommitCohort ready = transaction.ready();
+
+        ListenableFuture<Boolean> canCommit = ready.canCommit();
+
+        assertTrue(canCommit.get());
+
+        ListenableFuture<Void> preCommit = ready.preCommit();
+
+        preCommit.get();
+
+        ListenableFuture<Void> commit = ready.commit();
+
+        commit.get();
+
+    }
+
+}
index 3a74a4ca7656dc01ae650d011595335474297de1..23a1ed49315ec827baa95c41b51dfe4d23159d4e 100644 (file)
@@ -3,20 +3,22 @@ package org.opendaylight.controller.cluster.datastore;
 import akka.actor.ActorRef;
 import akka.actor.Props;
 import junit.framework.Assert;
-import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionReply;
 import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListenerReply;
+import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategyFactory;
 import org.opendaylight.controller.cluster.datastore.utils.DoNothingActor;
 import org.opendaylight.controller.cluster.datastore.utils.MockActorContext;
+import org.opendaylight.controller.cluster.datastore.utils.MockConfiguration;
 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 public class DistributedDataStoreTest extends AbstractActorTest{
@@ -27,6 +29,7 @@ public class DistributedDataStoreTest extends AbstractActorTest{
 
     @org.junit.Before
     public void setUp() throws Exception {
+        ShardStrategyFactory.setConfiguration(new MockConfiguration());
         final Props props = Props.create(DoNothingActor.class);
 
         doNothingActorRef = getSystem().actorOf(props);
@@ -39,7 +42,10 @@ public class DistributedDataStoreTest extends AbstractActorTest{
         // Make CreateTransactionReply as the default response. Will need to be
         // tuned if a specific test requires some other response
         mockActorContext.setExecuteShardOperationResponse(
-            new CreateTransactionReply(doNothingActorRef.path()));
+            CreateTransactionReply.newBuilder()
+                .setTransactionActorPath(doNothingActorRef.path().toString())
+                .setTransactionId("txn-1 ")
+                .build());
     }
 
     @org.junit.After
@@ -49,11 +55,11 @@ public class DistributedDataStoreTest extends AbstractActorTest{
 
     @org.junit.Test
     public void testRegisterChangeListener() throws Exception {
-        mockActorContext.setExecuteShardOperationResponse(new RegisterChangeListenerReply(doNothingActorRef.path()));
+        mockActorContext.setExecuteShardOperationResponse(new RegisterChangeListenerReply(doNothingActorRef.path()).toSerializable());
         ListenerRegistration registration =
-                distributedDataStore.registerChangeListener(TestModel.TEST_PATH, new AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>() {
+                distributedDataStore.registerChangeListener(TestModel.TEST_PATH, new AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>() {
             @Override
-            public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> change) {
+            public void onDataChanged(AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
                 throw new UnsupportedOperationException("onDataChanged");
             }
         }, AsyncDataBroker.DataChangeScope.BASE);
index fa436c16053bc42ad9835e7ecbccd1cb202fc4b8..87d257a3f217bf0bfac0b3c8ade1cbe8d4555b04 100644 (file)
@@ -4,24 +4,27 @@ import akka.actor.ActorSystem;
 import akka.actor.Props;
 import akka.testkit.JavaTestKit;
 import akka.testkit.TestActorRef;
+import junit.framework.Assert;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.cluster.datastore.messages.FindPrimary;
 import org.opendaylight.controller.cluster.datastore.messages.PrimaryFound;
 import org.opendaylight.controller.cluster.datastore.messages.PrimaryNotFound;
+import org.opendaylight.controller.cluster.datastore.utils.MockClusterWrapper;
+import org.opendaylight.controller.cluster.datastore.utils.MockConfiguration;
 import scala.concurrent.duration.Duration;
 
 public class ShardManagerTest {
     private static ActorSystem system;
 
     @BeforeClass
-    public static void setUp(){
+    public static void setUp() {
         system = ActorSystem.create("test");
     }
 
     @AfterClass
-    public static void tearDown(){
+    public static void tearDown() {
         JavaTestKit.shutdownActorSystem(system);
         system = null;
     }
@@ -30,15 +33,19 @@ public class ShardManagerTest {
     public void testOnReceiveFindPrimaryForNonExistentShard() throws Exception {
 
         new JavaTestKit(system) {{
-            final Props props = ShardManager.props("config");
-            final TestActorRef<ShardManager> subject = TestActorRef.create(system, props);
+            final Props props = ShardManager
+                .props("config", new MockClusterWrapper(),
+                    new MockConfiguration());
+            final TestActorRef<ShardManager> subject =
+                TestActorRef.create(system, props);
 
             new Within(duration("1 seconds")) {
                 protected void run() {
 
-                    subject.tell(new FindPrimary("inventory"), getRef());
+                    subject.tell(new FindPrimary("inventory").toSerializable(), getRef());
 
-                    expectMsgEquals(Duration.Zero(), new PrimaryNotFound("inventory"));
+                    expectMsgEquals(Duration.Zero(),
+                        new PrimaryNotFound("inventory").toSerializable());
 
                     // Will wait for the rest of the 3 seconds
                     expectNoMsg();
@@ -47,24 +54,99 @@ public class ShardManagerTest {
         }};
     }
 
-  @Test
-  public void testOnReceiveFindPrimaryForExistentShard() throws Exception {
+    @Test
+    public void testOnReceiveFindPrimaryForExistentShard() throws Exception {
+
+        new JavaTestKit(system) {{
+            final Props props = ShardManager
+                .props("config", new MockClusterWrapper(),
+                    new MockConfiguration());
+            final TestActorRef<ShardManager> subject =
+                TestActorRef.create(system, props);
+
+            // the run() method needs to finish within 3 seconds
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    subject.tell(new FindPrimary(Shard.DEFAULT_NAME).toSerializable(), getRef());
+
+                    expectMsgClass(PrimaryFound.SERIALIZABLE_CLASS);
+
+                    expectNoMsg();
+                }
+            };
+        }};
+    }
+
+    @Test
+    public void testOnReceiveMemberUp() throws Exception {
+
+        new JavaTestKit(system) {{
+            final Props props = ShardManager
+                .props("config", new MockClusterWrapper(),
+                    new MockConfiguration());
+            final TestActorRef<ShardManager> subject =
+                TestActorRef.create(system, props);
 
-    new JavaTestKit(system) {{
-      final Props props = ShardManager.props("config");
-      final TestActorRef<ShardManager> subject = TestActorRef.create(system, props);
+            // the run() method needs to finish within 3 seconds
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    MockClusterWrapper.sendMemberUp(subject, "member-2", getRef().path().toString());
 
-      // the run() method needs to finish within 3 seconds
-      new Within(duration("1 seconds")) {
-        protected void run() {
+                    subject.tell(new FindPrimary("astronauts").toSerializable(), getRef());
 
-          subject.tell(new FindPrimary(Shard.DEFAULT_NAME), getRef());
+                    final String out = new ExpectMsg<String>("primary found") {
+                        // do not put code outside this method, will run afterwards
+                        protected String match(Object in) {
+                            if (in.getClass().equals(PrimaryFound.SERIALIZABLE_CLASS)) {
+                                PrimaryFound f = PrimaryFound.fromSerializable(in);
+                                return f.getPrimaryPath();
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get(); // this extracts the received message
+
+                    Assert.assertTrue(out, out.contains("member-2-shard-astronauts-config"));
+
+                    expectNoMsg();
+                }
+            };
+        }};
+    }
+
+    @Test
+    public void testOnReceiveMemberDown() throws Exception {
+
+        new JavaTestKit(system) {{
+            final Props props = ShardManager
+                .props("config", new MockClusterWrapper(),
+                    new MockConfiguration());
+            final TestActorRef<ShardManager> subject =
+                TestActorRef.create(system, props);
+
+            // the run() method needs to finish within 3 seconds
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    MockClusterWrapper.sendMemberUp(subject, "member-2", getRef().path().toString());
+
+                    subject.tell(new FindPrimary("astronauts").toSerializable(), getRef());
+
+                    expectMsgClass(PrimaryFound.SERIALIZABLE_CLASS);
+
+                    MockClusterWrapper.sendMemberRemoved(subject, "member-2", getRef().path().toString());
+
+                    subject.tell(new FindPrimary("astronauts").toSerializable(), getRef());
+
+                    expectMsgClass(PrimaryNotFound.SERIALIZABLE_CLASS);
+
+                    expectNoMsg();
+                }
+            };
+        }};
+    }
 
-          expectMsgClass(PrimaryFound.class);
 
-          expectNoMsg();
-        }
-      };
-    }};
-  }
-}
\ No newline at end of file
+}
index 48365fa1a06a90c87131ab6bda0e71db78595ee6..7d57ea8284e90dc3f941b7b82385e5db28ed75f4 100644 (file)
@@ -4,97 +4,200 @@ import akka.actor.ActorRef;
 import akka.actor.Props;
 import akka.testkit.JavaTestKit;
 import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.messages.CreateTransaction;
 import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionChain;
 import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionChainReply;
+import org.opendaylight.controller.cluster.datastore.messages.PeerAddressResolved;
 import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListener;
 import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListenerReply;
 import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
+import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper;
 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-public class ShardTest extends AbstractActorTest{
-  @Test
-  public void testOnReceiveCreateTransactionChain() throws Exception {
-    new JavaTestKit(getSystem()) {{
-      final Props props = Shard.props("config");
-      final ActorRef subject = getSystem().actorOf(props, "testCreateTransactionChain");
-
-      new Within(duration("1 seconds")) {
-        protected void run() {
-
-          subject.tell(new CreateTransactionChain(), getRef());
-
-          final String out = new ExpectMsg<String>("match hint") {
-            // do not put code outside this method, will run afterwards
-            protected String match(Object in) {
-              if (in instanceof CreateTransactionChainReply) {
-                CreateTransactionChainReply reply = (CreateTransactionChainReply) in;
-                return reply.getTransactionChainPath().toString();
-              } else {
-                throw noMatch();
-              }
+public class ShardTest extends AbstractActorTest {
+    @Test
+    public void testOnReceiveCreateTransactionChain() throws Exception {
+        new JavaTestKit(getSystem()) {{
+            final Props props = Shard.props("config", Collections.EMPTY_MAP);
+            final ActorRef subject =
+                getSystem().actorOf(props, "testCreateTransactionChain");
+
+
+            // Wait for Shard to become a Leader
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    subject.tell(new CreateTransactionChain().toSerializable(), getRef());
+
+                    final String out = new ExpectMsg<String>("match hint") {
+                        // do not put code outside this method, will run afterwards
+                        protected String match(Object in) {
+                            if (in.getClass().equals(CreateTransactionChainReply.SERIALIZABLE_CLASS)){
+                                CreateTransactionChainReply reply =
+                                    CreateTransactionChainReply.fromSerializable(getSystem(),in);
+                                return reply.getTransactionChainPath()
+                                    .toString();
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get(); // this extracts the received message
+
+                    assertEquals("Unexpected transaction path " + out,
+                        "akka://test/user/testCreateTransactionChain/$a",
+                        out);
+
+                    expectNoMsg();
+                }
+
+
+            };
+        }};
+    }
+
+    @Test
+    public void testOnReceiveRegisterListener() throws Exception {
+        new JavaTestKit(getSystem()) {{
+            final Props props = Shard.props("config", Collections.EMPTY_MAP);
+            final ActorRef subject =
+                getSystem().actorOf(props, "testRegisterChangeListener");
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    subject.tell(
+                        new UpdateSchemaContext(SchemaContextHelper.full()),
+                        getRef());
+
+                    subject.tell(new RegisterChangeListener(TestModel.TEST_PATH,
+                        getRef().path(), AsyncDataBroker.DataChangeScope.BASE).toSerializable(),
+                        getRef());
+
+                    final String out = new ExpectMsg<String>("match hint") {
+                        // do not put code outside this method, will run afterwards
+                        protected String match(Object in) {
+                            if (in.getClass().equals(RegisterChangeListenerReply.SERIALIZABLE_CLASS)) {
+                                RegisterChangeListenerReply reply =
+                                    RegisterChangeListenerReply.fromSerializable(getSystem(),in);
+                                return reply.getListenerRegistrationPath()
+                                    .toString();
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get(); // this extracts the received message
+
+                    assertTrue(out.matches(
+                        "akka:\\/\\/test\\/user\\/testRegisterChangeListener\\/\\$.*"));
+                    // Will wait for the rest of the 3 seconds
+                    expectNoMsg();
+                }
+
+
+            };
+        }};
+    }
+
+    @Test
+    public void testCreateTransaction(){
+        new JavaTestKit(getSystem()) {{
+            final Props props = Shard.props("config", Collections.EMPTY_MAP);
+            final ActorRef subject =
+                getSystem().actorOf(props, "testCreateTransaction");
+
+
+            // Wait for Shard to become a Leader
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
             }
-          }.get(); // this extracts the received message
 
-          assertTrue(out.matches("akka:\\/\\/test\\/user\\/testCreateTransactionChain\\/\\$.*"));
-          // Will wait for the rest of the 3 seconds
-          expectNoMsg();
-        }
 
+            new Within(duration("1 seconds")) {
+                protected void run() {
 
-      };
-    }};
-  }
+                    subject.tell(
+                        new UpdateSchemaContext(TestModel.createTestContext()),
+                        getRef());
 
-  @Test
-  public void testOnReceiveRegisterListener() throws Exception {
-    new JavaTestKit(getSystem()) {{
-      final Props props = Shard.props("config");
-      final ActorRef subject = getSystem().actorOf(props, "testRegisterChangeListener");
+                    subject.tell(new CreateTransaction("txn-1").toSerializable(),
+                        getRef());
 
-      new Within(duration("1 seconds")) {
-        protected void run() {
+                    final String out = new ExpectMsg<String>("match hint") {
+                        // do not put code outside this method, will run afterwards
+                        protected String match(Object in) {
+                            if (in instanceof CreateTransactionReply) {
+                                CreateTransactionReply reply =
+                                    (CreateTransactionReply) in;
+                                return reply.getTransactionActorPath()
+                                    .toString();
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get(); // this extracts the received message
 
-          subject.tell(new UpdateSchemaContext(TestModel.createTestContext()), getRef());
+                    assertTrue("Unexpected transaction path " + out,
+                        out.contains("akka://test/user/testCreateTransaction/shard-txn-1"));
+                    expectNoMsg();
+                }
 
-          subject.tell(new RegisterChangeListener(TestModel.TEST_PATH, getRef().path() , AsyncDataBroker.DataChangeScope.BASE), getRef());
 
-          final String out = new ExpectMsg<String>("match hint") {
-            // do not put code outside this method, will run afterwards
-            protected String match(Object in) {
-              if (in instanceof RegisterChangeListenerReply) {
-                RegisterChangeListenerReply reply = (RegisterChangeListenerReply) in;
-                return reply.getListenerRegistrationPath().toString();
-              } else {
-                throw noMatch();
-              }
-            }
-          }.get(); // this extracts the received message
+            };
+        }};
+    }
 
-          assertTrue(out.matches("akka:\\/\\/test\\/user\\/testRegisterChangeListener\\/\\$.*"));
-          // Will wait for the rest of the 3 seconds
-          expectNoMsg();
-        }
+    @Test
+    public void testPeerAddressResolved(){
+        new JavaTestKit(getSystem()) {{
+            Map<String, String> peerAddresses = new HashMap<>();
+            peerAddresses.put("member-2", null);
+            final Props props = Shard.props("config", peerAddresses);
+            final ActorRef subject =
+                getSystem().actorOf(props, "testPeerAddressResolved");
 
+            new Within(duration("1 seconds")) {
+                protected void run() {
 
-      };
-    }};
-  }
+                    subject.tell(
+                        new PeerAddressResolved("member-2", "akka://foobar"),
+                        getRef());
 
+                    expectNoMsg();
+                }
 
 
-  private  AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>> noOpDataChangeListener(){
-    return new AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>() {
-      @Override
-      public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> change) {
+            };
+        }};
+    }
 
-      }
-    };
-  }
+    private AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> noOpDataChangeListener() {
+        return new AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>() {
+            @Override
+            public void onDataChanged(
+                AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
+
+            }
+        };
+    }
 }
index bc3a1046566b2259012916c85e70ae933d921b3d..6330ad8acca33ab6c05f3263aa45ca459f0c283d 100644 (file)
@@ -14,7 +14,6 @@ import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 
 public class ShardTransactionChainTest extends AbstractActorTest {
 
@@ -28,26 +27,29 @@ public class ShardTransactionChainTest extends AbstractActorTest {
   @Test
   public void testOnReceiveCreateTransaction() throws Exception {
     new JavaTestKit(getSystem()) {{
-      final Props props = ShardTransactionChain.props(store.createTransactionChain());
+      final Props props = ShardTransactionChain.props(store.createTransactionChain(), TestModel.createTestContext());
       final ActorRef subject = getSystem().actorOf(props, "testCreateTransaction");
 
-      new Within(duration("1 seconds")) {
+     new Within(duration("1 seconds")) {
         protected void run() {
 
-          subject.tell(new CreateTransaction(), getRef());
+          subject.tell(new CreateTransaction("txn-1").toSerializable(), getRef());
 
           final String out = new ExpectMsg<String>("match hint") {
             // do not put code outside this method, will run afterwards
             protected String match(Object in) {
-              if (in instanceof CreateTransactionReply) {
-                return ((CreateTransactionReply) in).getTransactionPath().toString();
-              } else {
+              if (in.getClass().equals(CreateTransactionReply.SERIALIZABLE_CLASS)) {
+                return CreateTransactionReply.fromSerializable(in).getTransactionPath();
+              }else{
                 throw noMatch();
               }
             }
           }.get(); // this extracts the received message
 
-          assertTrue(out.matches("akka:\\/\\/test\\/user\\/testCreateTransaction\\/\\$.*"));
+          assertEquals("Unexpected transaction path " + out,
+              "akka://test/user/testCreateTransaction/shard-txn-1",
+              out);
+
           // Will wait for the rest of the 3 seconds
           expectNoMsg();
         }
@@ -60,18 +62,18 @@ public class ShardTransactionChainTest extends AbstractActorTest {
   @Test
   public void testOnReceiveCloseTransactionChain() throws Exception {
     new JavaTestKit(getSystem()) {{
-      final Props props = ShardTransactionChain.props(store.createTransactionChain());
+      final Props props = ShardTransactionChain.props(store.createTransactionChain(), TestModel.createTestContext());
       final ActorRef subject = getSystem().actorOf(props, "testCloseTransactionChain");
 
       new Within(duration("1 seconds")) {
         protected void run() {
 
-          subject.tell(new CloseTransactionChain(), getRef());
+          subject.tell(new CloseTransactionChain().toSerializable(), getRef());
 
           final String out = new ExpectMsg<String>("match hint") {
             // do not put code outside this method, will run afterwards
             protected String match(Object in) {
-              if (in instanceof CloseTransactionChainReply) {
+              if (in.getClass().equals(CloseTransactionChainReply.SERIALIZABLE_CLASS)) {
                 return "match";
               } else {
                 throw noMatch();
@@ -88,4 +90,4 @@ public class ShardTransactionChainTest extends AbstractActorTest {
       };
     }};
   }
-}
\ No newline at end of file
+}
index 9116f24c92971b3f0491b6de52d07eff01d84645..7884eeccdae7874f8d19c9090bf08d755cc991be 100644 (file)
@@ -2,6 +2,7 @@ package org.opendaylight.controller.cluster.datastore;
 
 import akka.actor.ActorRef;
 import akka.actor.Props;
+import akka.actor.Terminated;
 import akka.testkit.JavaTestKit;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
@@ -25,253 +26,339 @@ import org.opendaylight.controller.cluster.datastore.modification.Modification;
 import org.opendaylight.controller.cluster.datastore.modification.WriteModification;
 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import java.util.Collections;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 public class ShardTransactionTest extends AbstractActorTest {
-  private static ListeningExecutorService storeExecutor = MoreExecutors.listeningDecorator(MoreExecutors.sameThreadExecutor());
+    private static ListeningExecutorService storeExecutor =
+        MoreExecutors.listeningDecorator(MoreExecutors.sameThreadExecutor());
+
+    private static final InMemoryDOMDataStore store =
+        new InMemoryDOMDataStore("OPER", storeExecutor);
+
+    private static final SchemaContext testSchemaContext = TestModel.createTestContext();
+
+    static {
+        store.onGlobalContextUpdated(testSchemaContext);
+    }
+
+    @Test
+    public void testOnReceiveReadData() throws Exception {
+        new JavaTestKit(getSystem()) {{
+            final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
+            final Props props =
+                ShardTransaction.props(store.newReadWriteTransaction(), shard, testSchemaContext);
+            final ActorRef subject = getSystem().actorOf(props, "testReadData");
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    subject.tell(
+                        new ReadData(YangInstanceIdentifier.builder().build()).toSerializable(),
+                        getRef());
+
+                    final String out = new ExpectMsg<String>("match hint") {
+                        // do not put code outside this method, will run afterwards
+                        protected String match(Object in) {
+                            if (in.getClass().equals(ReadDataReply.SERIALIZABLE_CLASS)) {
+                              if (ReadDataReply.fromSerializable(testSchemaContext,YangInstanceIdentifier.builder().build(), in)
+                                  .getNormalizedNode()!= null) {
+                                    return "match";
+                                }
+                                return null;
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get(); // this extracts the received message
+
+                    assertEquals("match", out);
+
+                    expectNoMsg();
+                }
+
+
+            };
+        }};
+    }
+
+    @Test
+    public void testOnReceiveReadDataWhenDataNotFound() throws Exception {
+        new JavaTestKit(getSystem()) {{
+            final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
+            final Props props =
+                ShardTransaction.props(store.newReadWriteTransaction(), shard, testSchemaContext);
+            final ActorRef subject = getSystem().actorOf(props, "testReadDataWhenDataNotFound");
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    subject.tell(
+                        new ReadData(TestModel.TEST_PATH).toSerializable(),
+                        getRef());
+
+                    final String out = new ExpectMsg<String>("match hint") {
+                        // do not put code outside this method, will run afterwards
+                        protected String match(Object in) {
+                            if (in.getClass().equals(ReadDataReply.SERIALIZABLE_CLASS)) {
+                                if (ReadDataReply.fromSerializable(testSchemaContext,TestModel.TEST_PATH, in)
+                                    .getNormalizedNode()
+                                    == null) {
+                                    return "match";
+                                }
+                                return null;
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get(); // this extracts the received message
+
+                    assertEquals("match", out);
+
+                    expectNoMsg();
+                }
+
+
+            };
+        }};
+    }
+
+    private void assertModification(final ActorRef subject,
+        final Class<? extends Modification> modificationType) {
+        new JavaTestKit(getSystem()) {{
+            new Within(duration("1 seconds")) {
+                protected void run() {
+                    subject
+                        .tell(new ShardTransaction.GetCompositedModification(),
+                            getRef());
+
+                    final CompositeModification compositeModification =
+                        new ExpectMsg<CompositeModification>("match hint") {
+                            // do not put code outside this method, will run afterwards
+                            protected CompositeModification match(Object in) {
+                                if (in instanceof ShardTransaction.GetCompositeModificationReply) {
+                                    return ((ShardTransaction.GetCompositeModificationReply) in)
+                                        .getModification();
+                                } else {
+                                    throw noMatch();
+                                }
+                            }
+                        }.get(); // this extracts the received message
+
+                    assertTrue(
+                        compositeModification.getModifications().size() == 1);
+                    assertEquals(modificationType,
+                        compositeModification.getModifications().get(0)
+                            .getClass());
+
+                }
+            };
+        }};
+    }
+
+    @Test
+    public void testOnReceiveWriteData() throws Exception {
+        new JavaTestKit(getSystem()) {{
+            final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
+            final Props props =
+                ShardTransaction.props(store.newReadWriteTransaction(), shard, TestModel.createTestContext());
+            final ActorRef subject =
+                getSystem().actorOf(props, "testWriteData");
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
+
+                    subject.tell(new WriteData(TestModel.TEST_PATH,
+                        ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()).toSerializable(),
+                        getRef());
+
+                    final String out = new ExpectMsg<String>("match hint") {
+                        // do not put code outside this method, will run afterwards
+                        protected String match(Object in) {
+                            if (in.getClass().equals(WriteDataReply.SERIALIZABLE_CLASS)) {
+                                return "match";
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get(); // this extracts the received message
+
+                    assertEquals("match", out);
+
+                    assertModification(subject, WriteModification.class);
+                    expectNoMsg();
+                }
 
-  private static final InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER", storeExecutor);
 
-  static {
-    store.onGlobalContextUpdated(TestModel.createTestContext());
-  }
+            };
+        }};
+    }
 
-  @Test
-  public void testOnReceiveReadData() throws Exception {
-    new JavaTestKit(getSystem()) {{
-      final ActorRef shard = getSystem().actorOf(Shard.props("config"));
-      final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard);
-      final ActorRef subject = getSystem().actorOf(props, "testReadData");
+    @Test
+    public void testOnReceiveMergeData() throws Exception {
+        new JavaTestKit(getSystem()) {{
+            final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
+            final Props props =
+                ShardTransaction.props(store.newReadWriteTransaction(), shard, testSchemaContext);
+            final ActorRef subject =
+                getSystem().actorOf(props, "testMergeData");
 
-      new Within(duration("1 seconds")) {
-        protected void run() {
+            new Within(duration("1 seconds")) {
+                protected void run() {
 
-          subject.tell(new ReadData(InstanceIdentifier.builder().build()), getRef());
+                    subject.tell(new MergeData(TestModel.TEST_PATH,
+                        ImmutableNodes.containerNode(TestModel.TEST_QNAME), testSchemaContext).toSerializable(),
+                        getRef());
 
-          final String out = new ExpectMsg<String>("match hint") {
-            // do not put code outside this method, will run afterwards
-            protected String match(Object in) {
-              if (in instanceof ReadDataReply) {
-                if (((ReadDataReply) in).getNormalizedNode() != null) {
-                  return "match";
+                    final String out = new ExpectMsg<String>(duration("500 milliseconds"), "match hint") {
+                        // do not put code outside this method, will run afterwards
+                        protected String match(Object in) {
+                            if (in.getClass().equals(MergeDataReply.SERIALIZABLE_CLASS)) {
+                                return "match";
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get(); // this extracts the received message
+
+                    assertEquals("match", out);
+
+                    assertModification(subject, MergeModification.class);
+
+                    expectNoMsg();
                 }
-                return null;
-              } else {
-                throw noMatch();
-              }
-            }
-          }.get(); // this extracts the received message
-
-          assertEquals("match", out);
-
-          expectNoMsg();
-        }
-
-
-      };
-    }};
-  }
-
-  private void assertModification(final ActorRef subject, final Class<? extends Modification> modificationType){
-    new JavaTestKit(getSystem()) {{
-      new Within(duration("1 seconds")) {
-        protected void run() {
-          subject.tell(new ShardTransaction.GetCompositedModification(), getRef());
-
-          final CompositeModification compositeModification = new ExpectMsg<CompositeModification>("match hint") {
-            // do not put code outside this method, will run afterwards
-            protected CompositeModification match(Object in) {
-              if (in instanceof ShardTransaction.GetCompositeModificationReply) {
-                return ((ShardTransaction.GetCompositeModificationReply) in).getModification();
-              } else {
-                throw noMatch();
-              }
-            }
-          }.get(); // this extracts the received message
-
-          assertTrue(compositeModification.getModifications().size() == 1);
-          assertEquals(modificationType, compositeModification.getModifications().get(0).getClass());
-
-        }
-      };
-    }};
-  }
-
-  @Test
-  public void testOnReceiveWriteData() throws Exception {
-    new JavaTestKit(getSystem()) {{
-      final ActorRef shard = getSystem().actorOf(Shard.props("config"));
-      final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard);
-      final ActorRef subject = getSystem().actorOf(props, "testWriteData");
-
-      new Within(duration("1 seconds")) {
-        protected void run() {
-
-          subject.tell(new WriteData(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME)), getRef());
-
-          final String out = new ExpectMsg<String>("match hint") {
-            // do not put code outside this method, will run afterwards
-            protected String match(Object in) {
-              if (in instanceof WriteDataReply) {
-                return "match";
-              } else {
-                throw noMatch();
-              }
-            }
-          }.get(); // this extracts the received message
-
-          assertEquals("match", out);
-
-          assertModification(subject, WriteModification.class);
-          expectNoMsg();
-        }
-
-
-      };
-    }};
-  }
-
-  @Test
-  public void testOnReceiveMergeData() throws Exception {
-    new JavaTestKit(getSystem()) {{
-      final ActorRef shard = getSystem().actorOf(Shard.props("config"));
-      final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard);
-      final ActorRef subject = getSystem().actorOf(props, "testMergeData");
-
-      new Within(duration("1 seconds")) {
-        protected void run() {
-
-          subject.tell(new MergeData(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME)), getRef());
-
-          final String out = new ExpectMsg<String>("match hint") {
-            // do not put code outside this method, will run afterwards
-            protected String match(Object in) {
-              if (in instanceof MergeDataReply) {
-                return "match";
-              } else {
-                throw noMatch();
-              }
-            }
-          }.get(); // this extracts the received message
-
-          assertEquals("match", out);
-
-          assertModification(subject, MergeModification.class);
-
-          expectNoMsg();
-        }
-
-
-      };
-    }};
-  }
-
-  @Test
-  public void testOnReceiveDeleteData() throws Exception {
-    new JavaTestKit(getSystem()) {{
-      final ActorRef shard = getSystem().actorOf(Shard.props("config"));
-      final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard);
-      final ActorRef subject = getSystem().actorOf(props, "testDeleteData");
 
-      new Within(duration("1 seconds")) {
-        protected void run() {
 
-          subject.tell(new DeleteData(TestModel.TEST_PATH), getRef());
+            };
+        }};
+    }
+
+    @Test
+    public void testOnReceiveDeleteData() throws Exception {
+        new JavaTestKit(getSystem()) {{
+            final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
+            final Props props =
+                ShardTransaction.props(store.newReadWriteTransaction(), shard, TestModel.createTestContext());
+            final ActorRef subject =
+                getSystem().actorOf(props, "testDeleteData");
+
+            new Within(duration("1 seconds")) {
+                protected void run() {
 
-          final String out = new ExpectMsg<String>("match hint") {
-            // do not put code outside this method, will run afterwards
-            protected String match(Object in) {
-              if (in instanceof DeleteDataReply) {
-                return "match";
-              } else {
-                throw noMatch();
-              }
-            }
-          }.get(); // this extracts the received message
+                    subject.tell(new DeleteData(TestModel.TEST_PATH).toSerializable(), getRef());
 
-          assertEquals("match", out);
+                    final String out = new ExpectMsg<String>("match hint") {
+                        // do not put code outside this method, will run afterwards
+                        protected String match(Object in) {
+                            if (in.getClass().equals(DeleteDataReply.SERIALIZABLE_CLASS)) {
+                                return "match";
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get(); // this extracts the received message
 
-          assertModification(subject, DeleteModification.class);
-          expectNoMsg();
-        }
+                    assertEquals("match", out);
+
+                    assertModification(subject, DeleteModification.class);
+                    expectNoMsg();
+                }
 
 
-      };
-    }};
-  }
+            };
+        }};
+    }
 
 
-  @Test
-  public void testOnReceiveReadyTransaction() throws Exception {
-    new JavaTestKit(getSystem()) {{
-      final ActorRef shard = getSystem().actorOf(Shard.props("config"));
-      final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard);
-      final ActorRef subject = getSystem().actorOf(props, "testReadyTransaction");
+    @Test
+    public void testOnReceiveReadyTransaction() throws Exception {
+        new JavaTestKit(getSystem()) {{
+            final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
+            final Props props =
+                ShardTransaction.props(store.newReadWriteTransaction(), shard, TestModel.createTestContext());
+            final ActorRef subject =
+                getSystem().actorOf(props, "testReadyTransaction");
 
-      new Within(duration("1 seconds")) {
-        protected void run() {
+            new Within(duration("1 seconds")) {
+                protected void run() {
 
-          subject.tell(new ReadyTransaction(), getRef());
+                    subject.tell(new ReadyTransaction().toSerializable(), getRef());
 
-          final String out = new ExpectMsg<String>("match hint") {
-            // do not put code outside this method, will run afterwards
-            protected String match(Object in) {
-              if (in instanceof ReadyTransactionReply) {
-                return "match";
-              } else {
-                throw noMatch();
-              }
-            }
-          }.get(); // this extracts the received message
+                    final String out = new ExpectMsg<String>("match hint") {
+                        // do not put code outside this method, will run afterwards
+                        protected String match(Object in) {
+                            if (in.getClass().equals(ReadyTransactionReply.SERIALIZABLE_CLASS)) {
+                                return "match";
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get(); // this extracts the received message
 
-          assertEquals("match", out);
+                    assertEquals("match", out);
 
-          expectNoMsg();
-        }
+                    expectNoMsg();
+                }
 
 
-      };
-    }};
+            };
+        }};
 
-  }
+    }
 
-  @Test
-  public void testOnReceiveCloseTransaction() throws Exception {
-    new JavaTestKit(getSystem()) {{
-      final ActorRef shard = getSystem().actorOf(Shard.props("config"));
-      final Props props = ShardTransaction.props(store.newReadWriteTransaction(), shard);
-      final ActorRef subject = getSystem().actorOf(props, "testCloseTransaction");
+    @Test
+    public void testOnReceiveCloseTransaction() throws Exception {
+        new JavaTestKit(getSystem()) {{
+            final ActorRef shard = getSystem().actorOf(Shard.props("config", Collections.EMPTY_MAP));
+            final Props props =
+                ShardTransaction.props(store.newReadWriteTransaction(), shard, TestModel.createTestContext());
+            final ActorRef subject =
+                getSystem().actorOf(props, "testCloseTransaction");
 
-      new Within(duration("1 seconds")) {
-        protected void run() {
+            watch(subject);
 
-          subject.tell(new CloseTransaction(), getRef());
+            new Within(duration("2 seconds")) {
+                protected void run() {
 
-          final String out = new ExpectMsg<String>("match hint") {
-            // do not put code outside this method, will run afterwards
-            protected String match(Object in) {
-              if (in instanceof CloseTransactionReply) {
-                return "match";
-              } else {
-                throw noMatch();
-              }
-            }
-          }.get(); // this extracts the received message
+                    subject.tell(new CloseTransaction().toSerializable(), getRef());
 
-          assertEquals("match", out);
+                    final String out = new ExpectMsg<String>("match hint") {
+                        // do not put code outside this method, will run afterwards
+                        protected String match(Object in) {
+                            if (in.getClass().equals(CloseTransactionReply.SERIALIZABLE_CLASS)) {
+                                return "match";
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get(); // this extracts the received message
 
-          expectNoMsg();
-        }
+                    assertEquals("match", out);
 
+                    final String termination = new ExpectMsg<String>("match hint") {
+                        // do not put code outside this method, will run afterwards
+                        protected String match(Object in) {
+                            if (in instanceof Terminated) {
+                                return "match";
+                            } else {
+                                throw noMatch();
+                            }
+                        }
+                    }.get(); // this extracts the received message
 
-      };
-    }};
 
-  }
+                    expectNoMsg();
+                }
+
 
+            };
+        }};
 
-}
\ No newline at end of file
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ThreePhaseCommitCohortProxyTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ThreePhaseCommitCohortProxyTest.java
new file mode 100644 (file)
index 0000000..992518e
--- /dev/null
@@ -0,0 +1,85 @@
+package org.opendaylight.controller.cluster.datastore;
+
+import akka.actor.ActorRef;
+import akka.actor.Props;
+import com.google.common.util.concurrent.ListenableFuture;
+import junit.framework.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.messages.AbortTransactionReply;
+import org.opendaylight.controller.cluster.datastore.messages.CanCommitTransactionReply;
+import org.opendaylight.controller.cluster.datastore.messages.CommitTransactionReply;
+import org.opendaylight.controller.cluster.datastore.messages.PreCommitTransactionReply;
+import org.opendaylight.controller.cluster.datastore.utils.MessageCollectorActor;
+import org.opendaylight.controller.cluster.datastore.utils.MockActorContext;
+
+import java.util.Arrays;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static org.junit.Assert.assertNotNull;
+
+public class ThreePhaseCommitCohortProxyTest extends AbstractActorTest {
+
+    private ThreePhaseCommitCohortProxy proxy;
+    private Props props;
+    private ActorRef actorRef;
+    private MockActorContext actorContext;
+    private ExecutorService executor = Executors.newSingleThreadExecutor();
+
+    @Before
+    public void setUp(){
+        props = Props.create(MessageCollectorActor.class);
+        actorRef = getSystem().actorOf(props);
+        actorContext = new MockActorContext(this.getSystem());
+
+        proxy =
+            new ThreePhaseCommitCohortProxy(actorContext,
+                Arrays.asList(actorRef.path()), "txn-1", executor);
+
+    }
+
+    @Test
+    public void testCanCommit() throws Exception {
+        actorContext.setExecuteRemoteOperationResponse(new CanCommitTransactionReply(true).toSerializable());
+
+        ListenableFuture<Boolean> future = proxy.canCommit();
+
+        Assert.assertTrue(future.get().booleanValue());
+
+    }
+
+    @Test
+    public void testPreCommit() throws Exception {
+        actorContext.setExecuteRemoteOperationResponse(new PreCommitTransactionReply().toSerializable());
+
+        ListenableFuture<Void> future = proxy.preCommit();
+
+        future.get();
+
+    }
+
+    @Test
+    public void testAbort() throws Exception {
+        actorContext.setExecuteRemoteOperationResponse(new AbortTransactionReply().toSerializable());
+
+        ListenableFuture<Void> future = proxy.abort();
+
+        future.get();
+
+    }
+
+    @Test
+    public void testCommit() throws Exception {
+        actorContext.setExecuteRemoteOperationResponse(new CommitTransactionReply().toSerializable());
+
+        ListenableFuture<Void> future = proxy.commit();
+
+        future.get();
+    }
+
+    @Test
+    public void testGetCohortPaths() throws Exception {
+        assertNotNull(proxy.getCohortPaths());
+    }
+}
index 6d057a4dbeeffdfc7892a798f62fb539b7ffc4fc..f654e3aced738ef0c85a6400babe901d9c98d3ea 100644 (file)
@@ -5,39 +5,61 @@ import akka.actor.Props;
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
 import junit.framework.Assert;
+import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.cluster.datastore.messages.CloseTransaction;
-import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionReply;
 import org.opendaylight.controller.cluster.datastore.messages.DeleteData;
 import org.opendaylight.controller.cluster.datastore.messages.MergeData;
+import org.opendaylight.controller.cluster.datastore.messages.PrimaryFound;
 import org.opendaylight.controller.cluster.datastore.messages.ReadDataReply;
 import org.opendaylight.controller.cluster.datastore.messages.ReadyTransactionReply;
 import org.opendaylight.controller.cluster.datastore.messages.WriteData;
+import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategyFactory;
 import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
 import org.opendaylight.controller.cluster.datastore.utils.DoNothingActor;
 import org.opendaylight.controller.cluster.datastore.utils.MessageCollectorActor;
 import org.opendaylight.controller.cluster.datastore.utils.MockActorContext;
+import org.opendaylight.controller.cluster.datastore.utils.MockClusterWrapper;
+import org.opendaylight.controller.cluster.datastore.utils.MockConfiguration;
 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
+import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 
 import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 public class TransactionProxyTest extends AbstractActorTest {
 
+    private final Configuration configuration = new MockConfiguration();
+
+    private final ActorContext testContext =
+        new ActorContext(getSystem(), getSystem().actorOf(Props.create(DoNothingActor.class)), new MockClusterWrapper(), configuration );
+
+    private ExecutorService transactionExecutor =
+        Executors.newSingleThreadExecutor();
+
+    @Before
+    public void setUp(){
+        ShardStrategyFactory.setConfiguration(configuration);
+    }
+
     @Test
     public void testRead() throws Exception {
         final Props props = Props.create(DoNothingActor.class);
         final ActorRef actorRef = getSystem().actorOf(props);
 
         final MockActorContext actorContext = new MockActorContext(this.getSystem());
-        actorContext.setExecuteShardOperationResponse(new CreateTransactionReply(actorRef.path()));
+        actorContext.setExecuteLocalOperationResponse(createPrimaryFound(actorRef));
+        actorContext.setExecuteShardOperationResponse(createTransactionReply(actorRef));
         actorContext.setExecuteRemoteOperationResponse("message");
 
+
         TransactionProxy transactionProxy =
             new TransactionProxy(actorContext,
-                TransactionProxy.TransactionType.READ_ONLY);
+                TransactionProxy.TransactionType.READ_ONLY, transactionExecutor, TestModel.createTestContext());
 
 
         ListenableFuture<Optional<NormalizedNode<?, ?>>> read =
@@ -48,7 +70,7 @@ public class TransactionProxyTest extends AbstractActorTest {
         Assert.assertFalse(normalizedNodeOptional.isPresent());
 
         actorContext.setExecuteRemoteOperationResponse(new ReadDataReply(
-            ImmutableNodes.containerNode(TestModel.TEST_QNAME)));
+            TestModel.createTestContext(),ImmutableNodes.containerNode(TestModel.TEST_QNAME)).toSerializable());
 
         read = transactionProxy.read(TestModel.TEST_PATH);
 
@@ -57,23 +79,55 @@ public class TransactionProxyTest extends AbstractActorTest {
         Assert.assertTrue(normalizedNodeOptional.isPresent());
     }
 
+    @Test
+    public void testReadWhenANullIsReturned() throws Exception {
+        final Props props = Props.create(DoNothingActor.class);
+        final ActorRef actorRef = getSystem().actorOf(props);
+
+        final MockActorContext actorContext = new MockActorContext(this.getSystem());
+        actorContext.setExecuteLocalOperationResponse(createPrimaryFound(actorRef));
+        actorContext.setExecuteShardOperationResponse(createTransactionReply(actorRef));
+        actorContext.setExecuteRemoteOperationResponse("message");
+
+        TransactionProxy transactionProxy =
+            new TransactionProxy(actorContext,
+                TransactionProxy.TransactionType.READ_ONLY, transactionExecutor, TestModel.createTestContext());
+
+
+        ListenableFuture<Optional<NormalizedNode<?, ?>>> read =
+            transactionProxy.read(TestModel.TEST_PATH);
+
+        Optional<NormalizedNode<?, ?>> normalizedNodeOptional = read.get();
+
+        Assert.assertFalse(normalizedNodeOptional.isPresent());
+
+        actorContext.setExecuteRemoteOperationResponse(new ReadDataReply(
+           TestModel.createTestContext(), null).toSerializable());
+
+        read = transactionProxy.read(TestModel.TEST_PATH);
+
+        normalizedNodeOptional = read.get();
+
+        Assert.assertFalse(normalizedNodeOptional.isPresent());
+    }
+
     @Test
     public void testWrite() throws Exception {
         final Props props = Props.create(MessageCollectorActor.class);
         final ActorRef actorRef = getSystem().actorOf(props);
 
         final MockActorContext actorContext = new MockActorContext(this.getSystem());
-        actorContext.setExecuteShardOperationResponse(new CreateTransactionReply(actorRef.path()));
+        actorContext.setExecuteLocalOperationResponse(createPrimaryFound(actorRef));
+        actorContext.setExecuteShardOperationResponse(createTransactionReply(actorRef));
         actorContext.setExecuteRemoteOperationResponse("message");
 
         TransactionProxy transactionProxy =
             new TransactionProxy(actorContext,
-                TransactionProxy.TransactionType.READ_ONLY);
+                TransactionProxy.TransactionType.READ_ONLY, transactionExecutor, TestModel.createTestContext());
 
         transactionProxy.write(TestModel.TEST_PATH,
             ImmutableNodes.containerNode(TestModel.NAME_QNAME));
 
-        ActorContext testContext = new ActorContext(getSystem(), getSystem().actorOf(Props.create(DoNothingActor.class)));
         Object messages = testContext
             .executeLocalOperation(actorRef, "messages",
                 ActorContext.ASK_DURATION);
@@ -86,7 +140,11 @@ public class TransactionProxyTest extends AbstractActorTest {
 
         Assert.assertEquals(1, listMessages.size());
 
-        Assert.assertTrue(listMessages.get(0) instanceof WriteData);
+        Assert.assertEquals(WriteData.SERIALIZABLE_CLASS, listMessages.get(0).getClass());
+    }
+
+    private Object createPrimaryFound(ActorRef actorRef) {
+        return new PrimaryFound(actorRef.path().toString()).toSerializable();
     }
 
     @Test
@@ -95,17 +153,17 @@ public class TransactionProxyTest extends AbstractActorTest {
         final ActorRef actorRef = getSystem().actorOf(props);
 
         final MockActorContext actorContext = new MockActorContext(this.getSystem());
-        actorContext.setExecuteShardOperationResponse(new CreateTransactionReply(actorRef.path()));
+        actorContext.setExecuteLocalOperationResponse(createPrimaryFound(actorRef));
+        actorContext.setExecuteShardOperationResponse(createTransactionReply(actorRef));
         actorContext.setExecuteRemoteOperationResponse("message");
 
         TransactionProxy transactionProxy =
             new TransactionProxy(actorContext,
-                TransactionProxy.TransactionType.READ_ONLY);
+                TransactionProxy.TransactionType.READ_ONLY, transactionExecutor, TestModel.createTestContext());
 
         transactionProxy.merge(TestModel.TEST_PATH,
             ImmutableNodes.containerNode(TestModel.NAME_QNAME));
 
-        ActorContext testContext = new ActorContext(getSystem(), getSystem().actorOf(Props.create(DoNothingActor.class)));
         Object messages = testContext
             .executeLocalOperation(actorRef, "messages",
                 ActorContext.ASK_DURATION);
@@ -118,7 +176,7 @@ public class TransactionProxyTest extends AbstractActorTest {
 
         Assert.assertEquals(1, listMessages.size());
 
-        Assert.assertTrue(listMessages.get(0) instanceof MergeData);
+        Assert.assertEquals(MergeData.SERIALIZABLE_CLASS, listMessages.get(0).getClass());
     }
 
     @Test
@@ -127,16 +185,16 @@ public class TransactionProxyTest extends AbstractActorTest {
         final ActorRef actorRef = getSystem().actorOf(props);
 
         final MockActorContext actorContext = new MockActorContext(this.getSystem());
-        actorContext.setExecuteShardOperationResponse(new CreateTransactionReply(actorRef.path()));
+        actorContext.setExecuteLocalOperationResponse(createPrimaryFound(actorRef));
+        actorContext.setExecuteShardOperationResponse(createTransactionReply(actorRef));
         actorContext.setExecuteRemoteOperationResponse("message");
 
         TransactionProxy transactionProxy =
             new TransactionProxy(actorContext,
-                TransactionProxy.TransactionType.READ_ONLY);
+                TransactionProxy.TransactionType.READ_ONLY, transactionExecutor, TestModel.createTestContext());
 
         transactionProxy.delete(TestModel.TEST_PATH);
 
-        ActorContext testContext = new ActorContext(getSystem(), getSystem().actorOf(Props.create(DoNothingActor.class)));
         Object messages = testContext
             .executeLocalOperation(actorRef, "messages",
                 ActorContext.ASK_DURATION);
@@ -149,7 +207,7 @@ public class TransactionProxyTest extends AbstractActorTest {
 
         Assert.assertEquals(1, listMessages.size());
 
-        Assert.assertTrue(listMessages.get(0) instanceof DeleteData);
+        Assert.assertEquals(DeleteData.SERIALIZABLE_CLASS, listMessages.get(0).getClass());
     }
 
     @Test
@@ -158,14 +216,17 @@ public class TransactionProxyTest extends AbstractActorTest {
         final ActorRef doNothingActorRef = getSystem().actorOf(props);
 
         final MockActorContext actorContext = new MockActorContext(this.getSystem());
-        actorContext.setExecuteShardOperationResponse(new CreateTransactionReply(doNothingActorRef.path()));
-        actorContext.setExecuteRemoteOperationResponse(new ReadyTransactionReply(doNothingActorRef.path()));
+        actorContext.setExecuteLocalOperationResponse(createPrimaryFound(doNothingActorRef));
+        actorContext.setExecuteShardOperationResponse(createTransactionReply(doNothingActorRef));
+        actorContext.setExecuteRemoteOperationResponse(new ReadyTransactionReply(doNothingActorRef.path()).toSerializable());
 
         TransactionProxy transactionProxy =
             new TransactionProxy(actorContext,
-                TransactionProxy.TransactionType.READ_ONLY);
+                TransactionProxy.TransactionType.READ_ONLY, transactionExecutor, TestModel.createTestContext());
 
 
+        transactionProxy.read(TestModel.TEST_PATH);
+
         DOMStoreThreePhaseCommitCohort ready = transactionProxy.ready();
 
         Assert.assertTrue(ready instanceof ThreePhaseCommitCohortProxy);
@@ -182,12 +243,11 @@ public class TransactionProxyTest extends AbstractActorTest {
         final ActorRef doNothingActorRef = getSystem().actorOf(props);
 
         final MockActorContext actorContext = new MockActorContext(this.getSystem());
-        actorContext.setExecuteShardOperationResponse(
-            new CreateTransactionReply(doNothingActorRef.path()));
+        actorContext.setExecuteShardOperationResponse( createTransactionReply(doNothingActorRef) );
 
         TransactionProxy transactionProxy =
             new TransactionProxy(actorContext,
-                TransactionProxy.TransactionType.READ_ONLY);
+                TransactionProxy.TransactionType.READ_ONLY, transactionExecutor, TestModel.createTestContext());
 
         Assert.assertNotNull(transactionProxy.getIdentifier());
     }
@@ -198,16 +258,18 @@ public class TransactionProxyTest extends AbstractActorTest {
         final ActorRef actorRef = getSystem().actorOf(props);
 
         final MockActorContext actorContext = new MockActorContext(this.getSystem());
-        actorContext.setExecuteShardOperationResponse(new CreateTransactionReply(actorRef.path()));
+        actorContext.setExecuteLocalOperationResponse(createPrimaryFound(actorRef));
+        actorContext.setExecuteShardOperationResponse(createTransactionReply(actorRef));
         actorContext.setExecuteRemoteOperationResponse("message");
 
         TransactionProxy transactionProxy =
             new TransactionProxy(actorContext,
-                TransactionProxy.TransactionType.READ_ONLY);
+                TransactionProxy.TransactionType.READ_ONLY, transactionExecutor, TestModel.createTestContext());
+
+        transactionProxy.read(TestModel.TEST_PATH);
 
         transactionProxy.close();
 
-        ActorContext testContext = new ActorContext(getSystem(), getSystem().actorOf(Props.create(DoNothingActor.class)));
         Object messages = testContext
             .executeLocalOperation(actorRef, "messages",
                 ActorContext.ASK_DURATION);
@@ -220,6 +282,13 @@ public class TransactionProxyTest extends AbstractActorTest {
 
         Assert.assertEquals(1, listMessages.size());
 
-        Assert.assertTrue(listMessages.get(0) instanceof CloseTransaction);
+        Assert.assertTrue(listMessages.get(0).getClass().equals(CloseTransaction.SERIALIZABLE_CLASS));
+    }
+
+    private CreateTransactionReply createTransactionReply(ActorRef actorRef){
+        return CreateTransactionReply.newBuilder()
+            .setTransactionActorPath(actorRef.path().toString())
+            .setTransactionId("txn-1")
+            .build();
     }
 }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStatsTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStatsTest.java
new file mode 100644 (file)
index 0000000..f7c4676
--- /dev/null
@@ -0,0 +1,55 @@
+package org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.jmx.mbeans.AbstractBaseMBean;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+public class ShardStatsTest {
+  private MBeanServer mbeanServer;
+ private  ShardStats  shardStats;
+  private ObjectName testMBeanName;
+
+  @Before
+  public void setUp() throws Exception {
+
+    shardStats = new ShardStats("shard-1");
+    shardStats.registerMBean();
+    mbeanServer= shardStats.getMBeanServer();
+    String objectName = AbstractBaseMBean.BASE_JMX_PREFIX + "type="+shardStats.getMBeanType()+",Category="+
+        shardStats.getMBeanCategory() + ",name="+
+        shardStats.getMBeanName();
+    testMBeanName = new ObjectName(objectName);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    shardStats.unregisterMBean();
+  }
+
+  @Test
+  public void testGetShardName() throws Exception {
+
+    Object attribute = mbeanServer.getAttribute(testMBeanName,"ShardName");
+    Assert.assertEquals((String) attribute, "shard-1");
+
+  }
+
+  @Test
+  public void testGetCommittedTransactionsCount() throws Exception {
+    //let us increment some transactions count and then check
+    shardStats.incrementCommittedTransactionCount();
+    shardStats.incrementCommittedTransactionCount();
+    shardStats.incrementCommittedTransactionCount();
+
+    //now let us get from MBeanServer what is the transaction count.
+    Object attribute = mbeanServer.getAttribute(testMBeanName,"CommittedTransactionsCount");
+    Assert.assertEquals((Long) attribute, (Long)3L);
+
+
+  }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/messages/MergeDataTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/messages/MergeDataTest.java
new file mode 100644 (file)
index 0000000..75128e6
--- /dev/null
@@ -0,0 +1,47 @@
+package org.opendaylight.controller.cluster.datastore.messages;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.node.NormalizedNodeToNodeCodec;
+import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+
+public class MergeDataTest {
+
+    @Test
+    public void testBasic(){
+        MergeData mergeData = new MergeData(TestModel.TEST_PATH, ImmutableNodes
+            .containerNode(TestModel.TEST_QNAME),
+            TestModel.createTestContext());
+
+        MergeData output = MergeData
+            .fromSerializable(mergeData.toSerializable(),
+                TestModel.createTestContext());
+
+    }
+
+    @Test
+    public void testNormalizedNodeEncodeDecode(){
+        NormalizedNode<?, ?> expected =
+            ImmutableNodes.containerNode(TestModel.TEST_QNAME);
+
+
+        NormalizedNodeMessages.Container node =
+            new NormalizedNodeToNodeCodec(TestModel.createTestContext())
+                .encode(TestModel.TEST_PATH,
+                    expected);
+
+        String parentPath = node.getParentPath();
+
+        NormalizedNodeMessages.Node normalizedNode =
+            node.getNormalizedNode();
+
+        NormalizedNode<?,?> actual = new NormalizedNodeToNodeCodec(TestModel.createTestContext()).decode(TestModel.TEST_PATH,
+            normalizedNode);
+
+
+        Assert.assertEquals(expected, actual);
+    }
+}
index efaca5d4f6f3d583aec500b683909b8c28d245b8..d9c550a6db482d39855dc5a48ebb26b2fec8c6ad 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 public abstract class AbstractModificationTest {
@@ -36,7 +36,7 @@ public abstract class AbstractModificationTest {
     cohort.commit();
   }
 
-  protected Optional<NormalizedNode<?,?>> readData(InstanceIdentifier path) throws Exception{
+  protected Optional<NormalizedNode<?,?>> readData(YangInstanceIdentifier path) throws Exception{
     DOMStoreReadTransaction transaction = store.newReadOnlyTransaction();
     ListenableFuture<Optional<NormalizedNode<?, ?>>> future = transaction.read(path);
     return future.get();
index c1f9f3a631765f9437c8db4d15aaf6a85b9b038c..b33f902929a470eae42bb51f19718a5846d7c5e4 100644 (file)
@@ -15,7 +15,7 @@ public class DeleteModificationTest extends AbstractModificationTest{
   public void testApply() throws Exception {
     //Write something into the datastore
     DOMStoreReadWriteTransaction writeTransaction = store.newReadWriteTransaction();
-    WriteModification writeModification = new WriteModification(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+    WriteModification writeModification = new WriteModification(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext());
     writeModification.apply(writeTransaction);
     commitTransaction(writeTransaction);
 
@@ -32,4 +32,4 @@ public class DeleteModificationTest extends AbstractModificationTest{
     data = readData(TestModel.TEST_PATH);
     Assert.assertFalse(data.isPresent());
   }
-}
\ No newline at end of file
+}
index fd125fb79d8be2bc7fa85e31a914cf6d4c0a2dd3..9af3439ae196d95ca55148465d02b7beb8b9e5a6 100644 (file)
@@ -16,7 +16,7 @@ public class MergeModificationTest extends AbstractModificationTest{
 
     //Write something into the datastore
     DOMStoreReadWriteTransaction writeTransaction = store.newReadWriteTransaction();
-    MergeModification writeModification = new MergeModification(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+    MergeModification writeModification = new MergeModification(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext());
     writeModification.apply(writeTransaction);
     commitTransaction(writeTransaction);
 
@@ -25,4 +25,4 @@ public class MergeModificationTest extends AbstractModificationTest{
     Assert.assertTrue(data.isPresent());
 
   }
-}
\ No newline at end of file
+}
index e30936b3272da5e5cfb975dd803bf3ea241213db..7a21c8cdc5eea9ea208c651286423c63b107a13b 100644 (file)
@@ -14,7 +14,7 @@ public class MutableCompositeModificationTest extends AbstractModificationTest {
   public void testApply() throws Exception {
 
     MutableCompositeModification compositeModification = new MutableCompositeModification();
-    compositeModification.addModification(new WriteModification(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME)));
+    compositeModification.addModification(new WriteModification(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()));
 
     DOMStoreReadWriteTransaction transaction = store.newReadWriteTransaction();
     compositeModification.apply(transaction);
@@ -25,4 +25,4 @@ public class MutableCompositeModificationTest extends AbstractModificationTest {
     Assert.assertNotNull(data.get());
     Assert.assertEquals(TestModel.TEST_QNAME, data.get().getNodeType());
   }
-}
\ No newline at end of file
+}
index e206bf8196e034d0fdd4d3cb77207de41380e97e..75d8c00db8bb2c54bf7ab433c118d9a867914980 100644 (file)
@@ -14,7 +14,7 @@ public class WriteModificationTest extends AbstractModificationTest{
   public void testApply() throws Exception {
     //Write something into the datastore
     DOMStoreReadWriteTransaction writeTransaction = store.newReadWriteTransaction();
-    WriteModification writeModification = new WriteModification(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+    WriteModification writeModification = new WriteModification(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext());
     writeModification.apply(writeTransaction);
     commitTransaction(writeTransaction);
 
@@ -23,4 +23,4 @@ public class WriteModificationTest extends AbstractModificationTest{
     Assert.assertTrue(data.isPresent());
 
   }
-}
\ No newline at end of file
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ModuleShardStrategyTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ModuleShardStrategyTest.java
new file mode 100644 (file)
index 0000000..88753e4
--- /dev/null
@@ -0,0 +1,33 @@
+package org.opendaylight.controller.cluster.datastore.shardstrategy;
+
+import junit.framework.Assert;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.opendaylight.controller.cluster.datastore.Configuration;
+import org.opendaylight.controller.cluster.datastore.ConfigurationImpl;
+import org.opendaylight.controller.md.cluster.datastore.model.CarsModel;
+
+public class ModuleShardStrategyTest {
+    @Rule
+    public ExpectedException expectedEx = ExpectedException.none();
+
+    private static Configuration configuration;
+
+    @BeforeClass
+    public static void setUpClass(){
+        configuration = new ConfigurationImpl("module-shards.conf", "modules.conf");
+    }
+
+
+    @Test
+    public void testFindShard() throws Exception {
+        ModuleShardStrategy moduleShardStrategy =
+            new ModuleShardStrategy("cars", configuration);
+
+        String shard = moduleShardStrategy.findShard(CarsModel.BASE_PATH);
+
+        Assert.assertEquals("cars-1", shard);
+    }
+}
index 2cff981b680f99de9855db40ed68bd49ed23a2fb..ab74ba811a6348c4969a2408644b0e48502af076 100644 (file)
@@ -1,29 +1,49 @@
 package org.opendaylight.controller.cluster.datastore.shardstrategy;
 
+import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.opendaylight.controller.cluster.datastore.ConfigurationImpl;
+import org.opendaylight.controller.md.cluster.datastore.model.CarsModel;
 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
 
 public class ShardStrategyFactoryTest {
 
-  @Rule
-  public ExpectedException expectedEx = ExpectedException.none();
+    @Rule
+    public ExpectedException expectedEx = ExpectedException.none();
 
-  @Test
-  public void testGetStrategy(){
-    ShardStrategy strategy = ShardStrategyFactory.getStrategy(TestModel.TEST_PATH);
-    assertNotNull(strategy);
-  }
+    @BeforeClass
+    public static void setUpClass(){
+        ShardStrategyFactory.setConfiguration(new ConfigurationImpl("module-shards.conf", "modules.conf"));
+    }
 
-  @Test
-  public void testGetStrategyNullPointerExceptionWhenPathIsNull(){
-    expectedEx.expect(NullPointerException.class);
-    expectedEx.expectMessage("path should not be null");
+    @Test
+    public void testGetStrategy() {
+        ShardStrategy strategy =
+            ShardStrategyFactory.getStrategy(TestModel.TEST_PATH);
+        assertNotNull(strategy);
+    }
 
-    ShardStrategyFactory.getStrategy(null);
-  }
+    @Test
+    public void testGetStrategyForKnownModuleName() {
+        ShardStrategy strategy =
+            ShardStrategyFactory.getStrategy(
+                YangInstanceIdentifier.of(CarsModel.BASE_QNAME));
+        assertTrue(strategy instanceof ModuleShardStrategy);
+    }
 
-}
\ No newline at end of file
+
+    @Test
+    public void testGetStrategyNullPointerExceptionWhenPathIsNull() {
+        expectedEx.expect(NullPointerException.class);
+        expectedEx.expectMessage("path should not be null");
+
+        ShardStrategyFactory.getStrategy(null);
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/utils/ActorContextTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/utils/ActorContextTest.java
new file mode 100644 (file)
index 0000000..3dd0214
--- /dev/null
@@ -0,0 +1,47 @@
+package org.opendaylight.controller.cluster.datastore.utils;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.AbstractActorTest;
+import org.opendaylight.controller.cluster.datastore.ClusterWrapper;
+import org.opendaylight.controller.cluster.datastore.Configuration;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+public class ActorContextTest extends AbstractActorTest{
+    @Test
+    public void testResolvePathForRemoteActor(){
+        ActorContext actorContext =
+            new ActorContext(mock(ActorSystem.class), mock(ActorRef.class),mock(
+                ClusterWrapper.class),
+                mock(Configuration.class));
+
+        String actual = actorContext.resolvePath(
+            "akka.tcp://system@127.0.0.1:2550/user/shardmanager/shard",
+            "akka://system/user/shardmanager/shard/transaction");
+
+        String expected = "akka.tcp://system@127.0.0.1:2550/user/shardmanager/shard/transaction";
+
+        assertEquals(expected, actual);
+    }
+
+    @Test
+    public void testResolvePathForLocalActor(){
+        ActorContext actorContext =
+            new ActorContext(getSystem(), mock(ActorRef.class), mock(ClusterWrapper.class),
+                mock(Configuration.class));
+
+        String actual = actorContext.resolvePath(
+            "akka://system/user/shardmanager/shard",
+            "akka://system/user/shardmanager/shard/transaction");
+
+        String expected = "akka://system/user/shardmanager/shard/transaction";
+
+        assertEquals(expected, actual);
+
+        System.out.println(actorContext
+            .actorFor("akka://system/user/shardmanager/shard/transaction"));
+    }
+}
index fe62516098253c8dbe9f19424854578c1fe0120f..1d1e6614886e32d5593112375cbefaab0a9c1507 100644 (file)
@@ -21,11 +21,11 @@ public class MockActorContext extends ActorContext {
     private Object executeLocalOperationResponse;
 
     public MockActorContext(ActorSystem actorSystem) {
-        super(actorSystem, null);
+        super(actorSystem, null, new MockClusterWrapper(), new MockConfiguration());
     }
 
     public MockActorContext(ActorSystem actorSystem, ActorRef shardManager) {
-        super(actorSystem, shardManager);
+        super(actorSystem, shardManager, new MockClusterWrapper(), new MockConfiguration());
     }
 
 
@@ -56,5 +56,8 @@ public class MockActorContext extends ActorContext {
         this.executeLocalOperationResponse = executeLocalOperationResponse;
     }
 
-
+    @Override public Object executeLocalOperation(ActorRef actor,
+        Object message, FiniteDuration duration) {
+        return this.executeLocalOperationResponse;
+    }
 }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/utils/MockClusterWrapper.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/utils/MockClusterWrapper.java
new file mode 100644 (file)
index 0000000..803aa03
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.utils;
+
+import akka.actor.ActorRef;
+import akka.actor.AddressFromURIString;
+import akka.cluster.ClusterEvent;
+import akka.cluster.MemberStatus;
+import akka.cluster.UniqueAddress;
+import org.opendaylight.controller.cluster.datastore.ClusterWrapper;
+import scala.collection.JavaConversions;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class MockClusterWrapper implements ClusterWrapper{
+
+    @Override public void subscribeToMemberEvents(ActorRef actorRef) {
+    }
+
+    @Override public String getCurrentMemberName() {
+        return "member-1";
+    }
+
+    public static void sendMemberUp(ActorRef to, String memberName, String address){
+        to.tell(createMemberUp(memberName, address), null);
+    }
+
+    public static void sendMemberRemoved(ActorRef to, String memberName, String address){
+        to.tell(createMemberRemoved(memberName, address), null);
+    }
+
+    private static ClusterEvent.MemberRemoved createMemberRemoved(String memberName, String address) {
+        akka.cluster.UniqueAddress uniqueAddress = new UniqueAddress(
+            AddressFromURIString.parse(address), 55);
+
+        Set<String> roles = new HashSet<>();
+
+        roles.add(memberName);
+
+        akka.cluster.Member member = new akka.cluster.Member(uniqueAddress, 1, MemberStatus
+            .removed(),
+            JavaConversions.asScalaSet(roles).<String>toSet());
+
+        return new ClusterEvent.MemberRemoved(member, MemberStatus.up());
+
+    }
+
+
+    private static ClusterEvent.MemberUp createMemberUp(String memberName, String address) {
+        akka.cluster.UniqueAddress uniqueAddress = new UniqueAddress(
+            AddressFromURIString.parse(address), 55);
+
+        Set<String> roles = new HashSet<>();
+
+        roles.add(memberName);
+
+        akka.cluster.Member member = new akka.cluster.Member(uniqueAddress, 1, MemberStatus.up(),
+            JavaConversions.asScalaSet(roles).<String>toSet());
+
+        return new ClusterEvent.MemberUp(member);
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/utils/MockConfiguration.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/utils/MockConfiguration.java
new file mode 100644 (file)
index 0000000..8d49c6f
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.utils;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.cluster.datastore.Configuration;
+import org.opendaylight.controller.cluster.datastore.shardstrategy.ShardStrategy;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class MockConfiguration implements Configuration{
+    @Override public List<String> getMemberShardNames(String memberName) {
+        return Arrays.asList("default");
+    }
+
+    @Override public Optional<String> getModuleNameFromNameSpace(
+        String nameSpace) {
+        return Optional.absent();
+    }
+
+    @Override
+    public Map<String, ShardStrategy> getModuleNameToShardStrategyMap() {
+        return Collections.EMPTY_MAP;
+    }
+
+    @Override public List<String> getShardNamesFromModuleName(
+        String moduleName) {
+        return Collections.EMPTY_LIST;
+    }
+
+    @Override public List<String> getMembersFromShardName(String shardName) {
+        if("default".equals(shardName)) {
+            return Arrays.asList("member-1", "member-2");
+        } else if("astronauts".equals(shardName)){
+            return Arrays.asList("member-2", "member-3");
+        }
+
+        return Collections.EMPTY_LIST;
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/utils/TestUtils.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/utils/TestUtils.java
new file mode 100644 (file)
index 0000000..939096e
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.utils;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.actor.Props;
+import junit.framework.Assert;
+
+import java.util.List;
+
+public class TestUtils {
+
+    public static void assertFirstSentMessage(ActorSystem actorSystem, ActorRef actorRef, Class clazz){
+        ActorContext testContext = new ActorContext(actorSystem, actorSystem.actorOf(
+            Props.create(DoNothingActor.class)), new MockClusterWrapper(), new MockConfiguration());
+        Object messages = testContext
+            .executeLocalOperation(actorRef, "messages",
+                ActorContext.ASK_DURATION);
+
+        Assert.assertNotNull(messages);
+
+        Assert.assertTrue(messages instanceof List);
+
+        List<Object> listMessages = (List<Object>) messages;
+
+        Assert.assertEquals(1, listMessages.size());
+
+        Assert.assertTrue(listMessages.get(0).getClass().equals(clazz));
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/CarsModel.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/CarsModel.java
new file mode 100644 (file)
index 0000000..57df201
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.cluster.datastore.model;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
+
+public class CarsModel {
+    public static final QName BASE_QNAME = QName.create("urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars", "2014-03-13",
+        "cars");
+
+    public static final YangInstanceIdentifier BASE_PATH = YangInstanceIdentifier.of(BASE_QNAME);
+
+    public static final QName CARS_QNAME = QName.create(BASE_QNAME, "cars");
+    public static final QName CAR_QNAME = QName.create(CARS_QNAME, "car");
+    public static final QName CAR_NAME_QNAME = QName.create(CAR_QNAME, "name");
+    public static final QName CAR_PRICE_QNAME = QName.create(CAR_QNAME, "price");
+
+
+    public static NormalizedNode create(){
+
+        // Create a list builder
+        CollectionNodeBuilder<MapEntryNode, MapNode> cars =
+            ImmutableMapNodeBuilder.create().withNodeIdentifier(
+                new YangInstanceIdentifier.NodeIdentifier(
+                    CAR_QNAME));
+
+        // Create an entry for the car altima
+        MapEntryNode altima =
+            ImmutableNodes.mapEntryBuilder(CAR_QNAME, CAR_NAME_QNAME, "altima")
+                .withChild(ImmutableNodes.leafNode(CAR_NAME_QNAME, "altima"))
+                .withChild(ImmutableNodes.leafNode(CAR_PRICE_QNAME, 1000))
+                .build();
+
+        // Create an entry for the car accord
+        MapEntryNode honda =
+            ImmutableNodes.mapEntryBuilder(CAR_QNAME, CAR_NAME_QNAME, "accord")
+                .withChild(ImmutableNodes.leafNode(CAR_NAME_QNAME, "accord"))
+                .withChild(ImmutableNodes.leafNode(CAR_PRICE_QNAME, 2000))
+                .build();
+
+        cars.withChild(altima);
+        cars.withChild(honda);
+
+        return ImmutableContainerNodeBuilder.create()
+            .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(BASE_QNAME))
+            .withChild(cars.build())
+            .build();
+
+    }
+
+    public static NormalizedNode emptyContainer(){
+        return ImmutableContainerNodeBuilder.create()
+            .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(BASE_QNAME))
+            .build();
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/CompositeModel.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/CompositeModel.java
new file mode 100644 (file)
index 0000000..ece3127
--- /dev/null
@@ -0,0 +1,372 @@
+package org.opendaylight.controller.md.cluster.datastore.model;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
+
+public class CompositeModel {
+
+  public static final QName TEST_QNAME = QName.create(
+      "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test",
+      "2014-03-13", "test");
+
+  public static final QName AUG_QNAME = QName.create(
+      "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:aug",
+      "2014-03-13", "name");
+
+  public static final QName DESC_QNAME = QName.create(TEST_QNAME, "desc");
+  public static final QName OUTER_LIST_QNAME = QName.create(TEST_QNAME,
+      "outer-list");
+  public static final QName INNER_LIST_QNAME = QName.create(TEST_QNAME,
+      "inner-list");
+  public static final QName OUTER_CHOICE_QNAME = QName.create(TEST_QNAME,
+      "outer-choice");
+  public static final QName ID_QNAME = QName.create(TEST_QNAME, "id");
+  public static final QName NAME_QNAME = QName.create(TEST_QNAME, "name");
+  public static final QName VALUE_QNAME = QName.create(TEST_QNAME, "value");
+  private static final String DATASTORE_TEST_YANG = "/odl-datastore-test.yang";
+  private static final String DATASTORE_AUG_YANG =
+      "/odl-datastore-augmentation.yang";
+  private static final String DATASTORE_TEST_NOTIFICATION_YANG =
+      "/odl-datastore-test-notification.yang";
+
+
+  public static final YangInstanceIdentifier TEST_PATH = YangInstanceIdentifier
+      .of(TEST_QNAME);
+  public static final YangInstanceIdentifier DESC_PATH = YangInstanceIdentifier
+      .builder(TEST_PATH).node(DESC_QNAME).build();
+  public static final YangInstanceIdentifier OUTER_LIST_PATH = YangInstanceIdentifier
+      .builder(TEST_PATH).node(OUTER_LIST_QNAME).build();
+  public static final QName TWO_QNAME = QName.create(TEST_QNAME, "two");
+  public static final QName THREE_QNAME = QName.create(TEST_QNAME, "three");
+
+  private static final Integer ONE_ID = 1;
+  private static final Integer TWO_ID = 2;
+  private static final String TWO_ONE_NAME = "one";
+  private static final String TWO_TWO_NAME = "two";
+  private static final String DESC = "Hello there";
+
+  // Family specific constants
+  public static final QName FAMILY_QNAME =
+      QName
+          .create(
+              "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:notification-test",
+              "2014-04-17", "family");
+  public static final QName CHILDREN_QNAME = QName.create(FAMILY_QNAME,
+      "children");
+  public static final QName GRAND_CHILDREN_QNAME = QName.create(FAMILY_QNAME,
+      "grand-children");
+  public static final QName CHILD_NUMBER_QNAME = QName.create(FAMILY_QNAME,
+      "child-number");
+  public static final QName CHILD_NAME_QNAME = QName.create(FAMILY_QNAME,
+      "child-name");
+  public static final QName GRAND_CHILD_NUMBER_QNAME = QName.create(
+      FAMILY_QNAME, "grand-child-number");
+  public static final QName GRAND_CHILD_NAME_QNAME = QName.create(FAMILY_QNAME,
+      "grand-child-name");
+
+  public static final YangInstanceIdentifier FAMILY_PATH = YangInstanceIdentifier
+      .of(FAMILY_QNAME);
+  public static final YangInstanceIdentifier FAMILY_DESC_PATH = YangInstanceIdentifier
+      .builder(FAMILY_PATH).node(DESC_QNAME).build();
+  public static final YangInstanceIdentifier CHILDREN_PATH = YangInstanceIdentifier
+      .builder(FAMILY_PATH).node(CHILDREN_QNAME).build();
+
+  private static final Integer FIRST_CHILD_ID = 1;
+  private static final Integer SECOND_CHILD_ID = 2;
+
+  private static final String FIRST_CHILD_NAME = "first child";
+  private static final String SECOND_CHILD_NAME = "second child";
+
+  private static final Integer FIRST_GRAND_CHILD_ID = 1;
+  private static final Integer SECOND_GRAND_CHILD_ID = 2;
+
+  private static final String FIRST_GRAND_CHILD_NAME = "first grand child";
+  private static final String SECOND_GRAND_CHILD_NAME = "second grand child";
+
+  // first child
+  private static final YangInstanceIdentifier CHILDREN_1_PATH = YangInstanceIdentifier
+      .builder(CHILDREN_PATH)
+      .nodeWithKey(CHILDREN_QNAME, CHILD_NUMBER_QNAME, FIRST_CHILD_ID) //
+      .build();
+  private static final YangInstanceIdentifier CHILDREN_1_NAME_PATH =
+      YangInstanceIdentifier.builder(CHILDREN_PATH)
+          .nodeWithKey(CHILDREN_QNAME, CHILD_NAME_QNAME, FIRST_CHILD_NAME) //
+          .build();
+
+  private static final YangInstanceIdentifier CHILDREN_2_PATH = YangInstanceIdentifier
+      .builder(CHILDREN_PATH)
+      .nodeWithKey(CHILDREN_QNAME, CHILD_NUMBER_QNAME, SECOND_CHILD_ID) //
+      .build();
+  private static final YangInstanceIdentifier CHILDREN_2_NAME_PATH =
+      YangInstanceIdentifier.builder(CHILDREN_PATH)
+          .nodeWithKey(CHILDREN_QNAME, CHILD_NAME_QNAME, SECOND_CHILD_NAME) //
+          .build();
+
+
+  private static final YangInstanceIdentifier GRAND_CHILD_1_PATH =
+      YangInstanceIdentifier.builder(CHILDREN_1_PATH)
+          .node(GRAND_CHILDREN_QNAME)
+          //
+          .nodeWithKey(GRAND_CHILDREN_QNAME, GRAND_CHILD_NUMBER_QNAME,
+              FIRST_GRAND_CHILD_ID) //
+          .build();
+
+  private static final YangInstanceIdentifier GRAND_CHILD_1_NAME_PATH =
+      YangInstanceIdentifier.builder(CHILDREN_1_PATH)
+          .node(GRAND_CHILDREN_QNAME)
+          //
+          .nodeWithKey(GRAND_CHILDREN_QNAME, GRAND_CHILD_NAME_QNAME,
+              FIRST_GRAND_CHILD_NAME) //
+          .build();
+
+  private static final YangInstanceIdentifier GRAND_CHILD_2_PATH =
+      YangInstanceIdentifier.builder(CHILDREN_2_PATH)
+          .node(GRAND_CHILDREN_QNAME)
+          //
+          .nodeWithKey(GRAND_CHILDREN_QNAME, GRAND_CHILD_NUMBER_QNAME,
+              SECOND_GRAND_CHILD_ID) //
+          .build();
+
+  private static final YangInstanceIdentifier GRAND_CHILD_2_NAME_PATH =
+      YangInstanceIdentifier.builder(CHILDREN_2_PATH)
+          .node(GRAND_CHILDREN_QNAME)
+          //
+          .nodeWithKey(GRAND_CHILDREN_QNAME, GRAND_CHILD_NAME_QNAME,
+              SECOND_GRAND_CHILD_NAME) //
+          .build();
+
+  private static final YangInstanceIdentifier DESC_PATH_ID = YangInstanceIdentifier
+      .builder(DESC_PATH).build();
+  private static final YangInstanceIdentifier OUTER_LIST_1_PATH =
+      YangInstanceIdentifier.builder(OUTER_LIST_PATH)
+          .nodeWithKey(OUTER_LIST_QNAME, ID_QNAME, ONE_ID) //
+          .build();
+
+  private static final YangInstanceIdentifier OUTER_LIST_2_PATH =
+      YangInstanceIdentifier.builder(OUTER_LIST_PATH)
+          .nodeWithKey(OUTER_LIST_QNAME, ID_QNAME, TWO_ID) //
+          .build();
+
+  private static final YangInstanceIdentifier TWO_TWO_PATH = YangInstanceIdentifier
+      .builder(OUTER_LIST_2_PATH).node(INNER_LIST_QNAME) //
+      .nodeWithKey(INNER_LIST_QNAME, NAME_QNAME, TWO_TWO_NAME) //
+      .build();
+
+  private static final YangInstanceIdentifier TWO_TWO_VALUE_PATH =
+      YangInstanceIdentifier.builder(TWO_TWO_PATH).node(VALUE_QNAME) //
+          .build();
+
+  private static final MapEntryNode BAR_NODE = mapEntryBuilder(
+      OUTER_LIST_QNAME, ID_QNAME, TWO_ID) //
+      .withChild(mapNodeBuilder(INNER_LIST_QNAME) //
+          .withChild(mapEntry(INNER_LIST_QNAME, NAME_QNAME, TWO_ONE_NAME)) //
+          .withChild(mapEntry(INNER_LIST_QNAME, NAME_QNAME, TWO_TWO_NAME)) //
+          .build()) //
+      .build();
+
+  public static final InputStream getDatastoreTestInputStream() {
+    return getInputStream(DATASTORE_TEST_YANG);
+  }
+
+  public static final InputStream getDatastoreAugInputStream() {
+    return getInputStream(DATASTORE_AUG_YANG);
+  }
+
+  public static final InputStream getDatastoreTestNotificationInputStream() {
+    return getInputStream(DATASTORE_TEST_NOTIFICATION_YANG);
+  }
+
+  private static InputStream getInputStream(final String resourceName) {
+    return TestModel.class.getResourceAsStream(resourceName);
+  }
+
+  public static SchemaContext createTestContext() {
+    List<InputStream> inputStreams = new ArrayList<>();
+    inputStreams.add(getDatastoreTestInputStream());
+    inputStreams.add(getDatastoreAugInputStream());
+    inputStreams.add(getDatastoreTestNotificationInputStream());
+
+    YangParserImpl parser = new YangParserImpl();
+    Set<Module> modules = parser.parseYangModelsFromStreams(inputStreams);
+    return parser.resolveSchemaContext(modules);
+  }
+
+  /**
+   * Returns a test document
+   *
+   * <pre>
+   * test
+   *     outer-list
+   *          id 1
+   *     outer-list
+   *          id 2
+   *          inner-list
+   *                  name "one"
+   *          inner-list
+   *                  name "two"
+   *
+   * </pre>
+   *
+   * @return
+   */
+  public static NormalizedNode<?, ?> createDocumentOne(
+      SchemaContext schemaContext) {
+    return ImmutableContainerNodeBuilder
+        .create()
+        .withNodeIdentifier(
+            new YangInstanceIdentifier.NodeIdentifier(schemaContext.getQName()))
+        .withChild(createTestContainer()).build();
+
+  }
+
+  public static ContainerNode createTestContainer() {
+
+
+    final LeafSetEntryNode<Object> nike =
+        ImmutableLeafSetEntryNodeBuilder
+            .create()
+            .withNodeIdentifier(
+                new YangInstanceIdentifier.NodeWithValue(QName.create(TEST_QNAME,
+                    "shoe"), "nike")).withValue("nike").build();
+    final LeafSetEntryNode<Object> puma =
+        ImmutableLeafSetEntryNodeBuilder
+            .create()
+            .withNodeIdentifier(
+                new YangInstanceIdentifier.NodeWithValue(QName.create(TEST_QNAME,
+                    "shoe"), "puma")).withValue("puma").build();
+    final LeafSetNode<Object> shoes =
+        ImmutableLeafSetNodeBuilder
+            .create()
+            .withNodeIdentifier(
+                new YangInstanceIdentifier.NodeIdentifier(QName.create(TEST_QNAME,
+                    "shoe"))).withChild(nike).withChild(puma).build();
+
+
+    final LeafSetEntryNode<Object> five =
+        ImmutableLeafSetEntryNodeBuilder
+            .create()
+            .withNodeIdentifier(
+                (new YangInstanceIdentifier.NodeWithValue(QName.create(TEST_QNAME,
+                    "number"), 5))).withValue(5).build();
+    final LeafSetEntryNode<Object> fifteen =
+        ImmutableLeafSetEntryNodeBuilder
+            .create()
+            .withNodeIdentifier(
+                (new YangInstanceIdentifier.NodeWithValue(QName.create(TEST_QNAME,
+                    "number"), 15))).withValue(15).build();
+    final LeafSetNode<Object> numbers =
+        ImmutableLeafSetNodeBuilder
+            .create()
+            .withNodeIdentifier(
+                new YangInstanceIdentifier.NodeIdentifier(QName.create(TEST_QNAME,
+                    "number"))).withChild(five).withChild(fifteen).build();
+
+
+    Set<QName> childAugmentations = new HashSet<>();
+    childAugmentations.add(AUG_QNAME);
+    final YangInstanceIdentifier.AugmentationIdentifier augmentationIdentifier =
+        new YangInstanceIdentifier.AugmentationIdentifier(null, childAugmentations);
+    final AugmentationNode augmentationNode =
+        Builders.augmentationBuilder()
+            .withNodeIdentifier(augmentationIdentifier)
+            .withChild(ImmutableNodes.leafNode(AUG_QNAME, "First Test"))
+            .build();
+    return ImmutableContainerNodeBuilder
+        .create()
+        .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TEST_QNAME))
+        .withChild(ImmutableNodes.leafNode(DESC_QNAME, DESC))
+        .withChild(augmentationNode)
+        .withChild(shoes)
+        .withChild(numbers)
+        .withChild(
+            mapNodeBuilder(OUTER_LIST_QNAME)
+                .withChild(mapEntry(OUTER_LIST_QNAME, ID_QNAME, ONE_ID))
+                .withChild(BAR_NODE).build()).build();
+
+  }
+
+
+  public static ContainerNode createFamily() {
+    final DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode> familyContainerBuilder =
+        ImmutableContainerNodeBuilder.create().withNodeIdentifier(
+            new YangInstanceIdentifier.NodeIdentifier(FAMILY_QNAME));
+
+    final CollectionNodeBuilder<MapEntryNode, MapNode> childrenBuilder =
+        mapNodeBuilder(CHILDREN_QNAME);
+
+    final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> firstChildBuilder =
+        mapEntryBuilder(CHILDREN_QNAME, CHILD_NUMBER_QNAME, FIRST_CHILD_ID);
+    final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> secondChildBuilder =
+        mapEntryBuilder(CHILDREN_QNAME, CHILD_NUMBER_QNAME, SECOND_CHILD_ID);
+
+    final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> firstGrandChildBuilder =
+        mapEntryBuilder(GRAND_CHILDREN_QNAME, GRAND_CHILD_NUMBER_QNAME,
+            FIRST_GRAND_CHILD_ID);
+    final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> secondGrandChildBuilder =
+        mapEntryBuilder(GRAND_CHILDREN_QNAME, GRAND_CHILD_NUMBER_QNAME,
+            SECOND_GRAND_CHILD_ID);
+
+    firstGrandChildBuilder
+        .withChild(
+            ImmutableNodes.leafNode(GRAND_CHILD_NUMBER_QNAME,
+                FIRST_GRAND_CHILD_ID)).withChild(
+        ImmutableNodes.leafNode(GRAND_CHILD_NAME_QNAME,
+            FIRST_GRAND_CHILD_NAME));
+
+    secondGrandChildBuilder.withChild(
+        ImmutableNodes
+            .leafNode(GRAND_CHILD_NUMBER_QNAME, SECOND_GRAND_CHILD_ID))
+        .withChild(
+            ImmutableNodes.leafNode(GRAND_CHILD_NAME_QNAME,
+                SECOND_GRAND_CHILD_NAME));
+
+    firstChildBuilder
+        .withChild(ImmutableNodes.leafNode(CHILD_NUMBER_QNAME, FIRST_CHILD_ID))
+        .withChild(ImmutableNodes.leafNode(CHILD_NAME_QNAME, FIRST_CHILD_NAME))
+        .withChild(
+            mapNodeBuilder(GRAND_CHILDREN_QNAME).withChild(
+                firstGrandChildBuilder.build()).build());
+
+
+    secondChildBuilder
+        .withChild(ImmutableNodes.leafNode(CHILD_NUMBER_QNAME, SECOND_CHILD_ID))
+        .withChild(ImmutableNodes.leafNode(CHILD_NAME_QNAME, SECOND_CHILD_NAME))
+        .withChild(
+            mapNodeBuilder(GRAND_CHILDREN_QNAME).withChild(
+                firstGrandChildBuilder.build()).build());
+
+    childrenBuilder.withChild(firstChildBuilder.build());
+    childrenBuilder.withChild(secondChildBuilder.build());
+
+    return familyContainerBuilder.withChild(childrenBuilder.build()).build();
+  }
+
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/PeopleModel.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/PeopleModel.java
new file mode 100644 (file)
index 0000000..1b4020a
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.cluster.datastore.model;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
+
+public class PeopleModel {
+    public static final QName BASE_QNAME = QName.create("urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:people", "2014-03-13",
+        "people");
+
+    public static final YangInstanceIdentifier BASE_PATH = YangInstanceIdentifier.of(BASE_QNAME);
+    public static final QName PEOPLE_QNAME = QName.create(BASE_QNAME, "people");
+    public static final QName PERSON_QNAME = QName.create(PEOPLE_QNAME, "person");
+    public static final QName PERSON_NAME_QNAME = QName.create(PERSON_QNAME, "name");
+    public static final QName PERSON_AGE_QNAME = QName.create(PERSON_QNAME, "age");
+
+
+
+    public static NormalizedNode create(){
+
+        // Create a list builder
+        CollectionNodeBuilder<MapEntryNode, MapNode> cars =
+            ImmutableMapNodeBuilder.create().withNodeIdentifier(
+                new YangInstanceIdentifier.NodeIdentifier(
+                    PERSON_QNAME));
+
+        // Create an entry for the person jack
+        MapEntryNode jack =
+            ImmutableNodes.mapEntryBuilder(PERSON_QNAME, PERSON_NAME_QNAME, "jack")
+                .withChild(ImmutableNodes.leafNode(PERSON_NAME_QNAME, "jack"))
+                .withChild(ImmutableNodes.leafNode(PERSON_AGE_QNAME, 100))
+                .build();
+
+        // Create an entry for the person jill
+        MapEntryNode jill =
+            ImmutableNodes.mapEntryBuilder(PERSON_QNAME, PERSON_NAME_QNAME, "jill")
+                .withChild(ImmutableNodes.leafNode(PERSON_NAME_QNAME, "jill"))
+                .withChild(ImmutableNodes.leafNode(PERSON_AGE_QNAME, 200))
+                .build();
+
+        cars.withChild(jack);
+        cars.withChild(jill);
+
+        return ImmutableContainerNodeBuilder.create()
+            .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(BASE_QNAME))
+            .withChild(cars.build())
+            .build();
+
+    }
+
+    public static NormalizedNode emptyContainer(){
+        return ImmutableContainerNodeBuilder.create()
+            .withNodeIdentifier(
+                new YangInstanceIdentifier.NodeIdentifier(BASE_QNAME))
+            .build();
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/SampleModelsTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/SampleModelsTest.java
new file mode 100644 (file)
index 0000000..d8fefcd
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.cluster.datastore.model;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.node.NormalizedNodeToNodeCodec;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class SampleModelsTest {
+    @Test
+    public void testPeopleModel(){
+        NormalizedNode<?, ?> expected = PeopleModel.create();
+
+
+        NormalizedNodeMessages.Container node =
+            new NormalizedNodeToNodeCodec(SchemaContextHelper.full())
+                .encode(YangInstanceIdentifier.of(PeopleModel.BASE_QNAME),
+                    expected);
+
+        NormalizedNodeMessages.Node normalizedNode =
+            node.getNormalizedNode();
+
+        NormalizedNode<?,?> actual = new NormalizedNodeToNodeCodec(SchemaContextHelper.full()).decode(YangInstanceIdentifier.of(PeopleModel.BASE_QNAME),
+            normalizedNode);
+
+
+        Assert.assertEquals(expected.toString(), actual.toString());
+
+    }
+
+
+    @Test
+    public void testCarsModel(){
+        NormalizedNode<?, ?> expected = CarsModel.create();
+
+
+        NormalizedNodeMessages.Container node =
+            new NormalizedNodeToNodeCodec(SchemaContextHelper.full())
+                .encode(YangInstanceIdentifier.of(CarsModel.BASE_QNAME),
+                    expected);
+
+        NormalizedNodeMessages.Node normalizedNode =
+            node.getNormalizedNode();
+
+        NormalizedNode<?,?> actual = new NormalizedNodeToNodeCodec(SchemaContextHelper.full()).decode(
+            YangInstanceIdentifier.of(CarsModel.BASE_QNAME),
+            normalizedNode);
+
+
+        Assert.assertEquals(expected.toString(), actual.toString());
+
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/SchemaContextHelper.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/md/cluster/datastore/model/SchemaContextHelper.java
new file mode 100644 (file)
index 0000000..3395738
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.cluster.datastore.model;
+
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+public class SchemaContextHelper {
+
+    public static InputStream getInputStream(final String yangFileName) {
+        return TestModel.class.getResourceAsStream(yangFileName);
+    }
+
+    public static SchemaContext full(){
+        YangParserImpl parser = new YangParserImpl();
+        List<InputStream> streams = new ArrayList<>();
+        streams.add(getInputStream("/odl-datastore-test.yang"));
+        streams.add(getInputStream("/people.yang"));
+        streams.add(getInputStream("/cars.yang"));
+
+        Set<Module> modules = parser.parseYangModelsFromStreams(streams);
+        return parser.resolveSchemaContext(modules);
+
+    }
+}
index 7a1def9f89491ef5697f0b58f1ed4792883e20ec..85441eca0d290ca4968cea22e793b4897fc3ec36 100644 (file)
@@ -8,7 +8,7 @@
 package org.opendaylight.controller.md.cluster.datastore.model;
 
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
@@ -29,8 +29,8 @@ public class TestModel {
   public static final QName VALUE_QNAME = QName.create(TEST_QNAME, "value");
   private static final String DATASTORE_TEST_YANG = "/odl-datastore-test.yang";
 
-  public static final InstanceIdentifier TEST_PATH = InstanceIdentifier.of(TEST_QNAME);
-  public static final InstanceIdentifier OUTER_LIST_PATH = InstanceIdentifier.builder(TEST_PATH).node(OUTER_LIST_QNAME).build();
+  public static final YangInstanceIdentifier TEST_PATH = YangInstanceIdentifier.of(TEST_QNAME);
+  public static final YangInstanceIdentifier OUTER_LIST_PATH = YangInstanceIdentifier.builder(TEST_PATH).node(OUTER_LIST_QNAME).build();
   public static final QName TWO_QNAME = QName.create(TEST_QNAME,"two");
   public static final QName THREE_QNAME = QName.create(TEST_QNAME,"three");
 
index 2647850667e6f7f779d582b33267c1afcbc6d483..aebff27c7dc0345864bfb8ecff9f5b30789ecf24 100644 (file)
@@ -1,11 +1,14 @@
 akka {
     actor {
-        serializers {
-          java = "akka.serialization.JavaSerializer"
-        }
+         serializers {
+                  java = "akka.serialization.JavaSerializer"
+                  proto = "akka.remote.serialization.ProtobufSerializer"
+         }
 
         serialization-bindings {
             "org.opendaylight.controller.cluster.datastore.modification.MutableCompositeModification" = java
+            "com.google.protobuf.Message" = proto
+
         }
     }
-}
\ No newline at end of file
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/cars.yang b/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/cars.yang
new file mode 100644 (file)
index 0000000..d83135e
--- /dev/null
@@ -0,0 +1,22 @@
+module cars {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars";
+    prefix "cars";
+
+    revision "2014-03-13" {
+        description "Initial revision.";
+    }
+
+    container cars {
+        list car {
+            key name;
+            leaf name {
+                type string;
+            }
+
+            leaf price {
+                type uint64;
+            }
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/module-shards.conf b/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/module-shards.conf
new file mode 100644 (file)
index 0000000..b3de998
--- /dev/null
@@ -0,0 +1,49 @@
+module-shards = [
+    {
+        name = "default"
+        shards = [
+            {
+                name="default",
+                replicas = [
+                    "member-1",
+                    "member-2",
+                    "member-3"
+                ]
+            }
+        ]
+    },
+    {
+        name = "people"
+        shards = [
+            {
+                name="people-1"
+                replicas = [
+                    "member-1"
+                ]
+            }
+        ]
+    },
+    {
+        name = "cars"
+        shards = [
+            {
+                name="cars-1"
+                replicas = [
+                    "member-1"
+                ]
+            }
+        ]
+    },
+    {
+        name = "test"
+        shards = [
+            {
+                name="test-1"
+                replicas = [
+                    "member-1"
+                ]
+            }
+        ]
+    }
+
+]
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/modules.conf b/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/modules.conf
new file mode 100644 (file)
index 0000000..22854cb
--- /dev/null
@@ -0,0 +1,18 @@
+modules = [
+    {
+        name = "people"
+        namespace = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:people"
+        shard-strategy = "module"
+    },
+    {
+        name = "cars"
+        namespace = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars"
+        shard-strategy = "module"
+    },
+    {
+     name = "test"
+     namespace = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test"
+     shard-strategy = "module"
+    }
+
+]
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/odl-datastore-augmentation.yang b/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/odl-datastore-augmentation.yang
new file mode 100644 (file)
index 0000000..77d74c4
--- /dev/null
@@ -0,0 +1,19 @@
+module odl-datastore-augmentation {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:aug";
+    prefix "store-aug";
+
+    import odl-datastore-test {prefix test;revision-date "2014-03-13";}
+
+    revision "2014-03-13" {
+        description "Initial revision.";
+    }
+
+
+    augment "/test:test" {
+        leaf name {
+            type string;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/odl-datastore-test-notification.yang b/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/odl-datastore-test-notification.yang
new file mode 100644 (file)
index 0000000..25cc53a
--- /dev/null
@@ -0,0 +1,33 @@
+module odl-datastore-test-notification {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:notification-test";
+    prefix "notification-test-using-family-model";
+
+    revision "2014-04-17" {
+        description "Family structure created on ";
+    }
+
+    container family {
+        leaf desc {
+            type string;
+        }
+        list children {
+            key child-number;
+            leaf child-number {
+                type uint16;
+            }
+            leaf child-name {
+                type string;
+            }
+           list grand-children {
+                key grand-child-number;
+                leaf grand-child-number {
+                    type uint16;
+                }
+                leaf grand-child-name {
+                    type string;
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/people.yang b/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/people.yang
new file mode 100644 (file)
index 0000000..7ede0e6
--- /dev/null
@@ -0,0 +1,22 @@
+module people {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:people";
+    prefix "people";
+
+    revision "2014-03-13" {
+        description "Initial revision.";
+    }
+
+    container people {
+        list person {
+            key name;
+            leaf name {
+                type string;
+            }
+
+            leaf age {
+                type uint32;
+            }
+        }
+    }
+}
index 613cf1bfe24e1b31cf854d978c35c48ef11d96f3..fdb864059fbca351bba441045d4a7a89810bb558 100644 (file)
@@ -10,7 +10,7 @@ import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainFactory;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.sal.core.api.BrokerService;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 /**
@@ -22,8 +22,8 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
  *
  */
 public interface DOMDataBroker extends
-        AsyncDataBroker<InstanceIdentifier, NormalizedNode<?, ?>, DOMDataChangeListener>,
-        TransactionChainFactory<InstanceIdentifier, NormalizedNode<?, ?>>, BrokerService {
+        AsyncDataBroker<YangInstanceIdentifier, NormalizedNode<?, ?>, DOMDataChangeListener>,
+        TransactionChainFactory<YangInstanceIdentifier, NormalizedNode<?, ?>>, BrokerService, DOMService {
 
     /**
      * {@inheritDoc}
index d1f01760d2e3fef9b97c8d0c598cb6571eff5c75..393d1eaafeaaf85388af54fbd492316ebc013937 100644 (file)
@@ -8,9 +8,9 @@
 package org.opendaylight.controller.md.sal.dom.api;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
-public interface DOMDataChangeListener extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>> {
+public interface DOMDataChangeListener extends AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> {
 
 }
index 18fb9886611ab73098a0e34c41e08b6dd58a703e..856272f1f68d77b4f0e3e5978df6eda2fee54816 100644 (file)
@@ -1,9 +1,9 @@
 package org.opendaylight.controller.md.sal.dom.api;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncReadOnlyTransaction;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
-public interface DOMDataReadOnlyTransaction extends DOMDataReadTransaction, AsyncReadOnlyTransaction<InstanceIdentifier, NormalizedNode<?, ?>> {
+public interface DOMDataReadOnlyTransaction extends DOMDataReadTransaction, AsyncReadOnlyTransaction<YangInstanceIdentifier, NormalizedNode<?, ?>> {
 
 }
index 5baa5e72d31e8fe0bbd8444c9d86444ca79e594c..afa2286d53d94d4af669af7ba2c542221961372c 100644 (file)
@@ -8,9 +8,39 @@
 package org.opendaylight.controller.md.sal.dom.api;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncReadTransaction;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
-public interface DOMDataReadTransaction extends AsyncReadTransaction<InstanceIdentifier, NormalizedNode<?, ?>> {
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
 
+/**
+ * A transaction that provides read access to a logical data store.
+ * <p>
+ * For more information on usage and examples, please see the documentation in {@link AsyncReadTransaction}.
+ */
+public interface DOMDataReadTransaction extends AsyncReadTransaction<YangInstanceIdentifier, NormalizedNode<?, ?>> {
+
+    /**
+     * Reads data from provided logical data store located at the provided path.
+     *<p>
+     * If the target is a subtree, then the whole subtree is read (and will be
+     * accessible from the returned data object).
+     *
+     * @param store
+     *            Logical data store from which read should occur.
+     * @param path
+     *            Path which uniquely identifies subtree which client want to
+     *            read
+     * @return Listenable Future which contains read result
+     *         <ul>
+     *         <li>If data at supplied path exists the
+     *         {@link ListeblaFuture#get()} returns Optional object containing
+     *         data once read is done.
+     *         <li>If data at supplied path does not exists the
+     *         {@link ListenbleFuture#get()} returns {@link Optional#absent()}.
+     *         </ul>
+     */
+    ListenableFuture<Optional<NormalizedNode<?,?>>> read(LogicalDatastoreType store,YangInstanceIdentifier path);
 }
index 55600b07306d3f2a27681e9fbfaceccfe52c8404..d5fc5c957c852e563a82fb7871fcbee3f858d0f8 100644 (file)
@@ -8,9 +8,9 @@
 package org.opendaylight.controller.md.sal.dom.api;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncReadWriteTransaction;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
-public interface DOMDataReadWriteTransaction extends DOMDataReadTransaction, DOMDataWriteTransaction, AsyncReadWriteTransaction<InstanceIdentifier, NormalizedNode<?, ?>> {
+public interface DOMDataReadWriteTransaction extends DOMDataReadTransaction, DOMDataWriteTransaction, AsyncReadWriteTransaction<YangInstanceIdentifier, NormalizedNode<?, ?>> {
 
 }
index 9415973de5af3e0ec49d144ab3d5e541948580ac..b8fe26387bf59bcd8d7c06d797b53a8f01c72cb5 100644 (file)
@@ -8,9 +8,54 @@
 package org.opendaylight.controller.md.sal.dom.api;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncWriteTransaction;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
-public interface DOMDataWriteTransaction extends AsyncWriteTransaction<InstanceIdentifier, NormalizedNode<?, ?>> {
+/**
+ * A transaction that provides mutation capabilities on a data tree.
+ * <p>
+ * For more information on usage and examples, please see the documentation in {@link AsyncWriteTransaction}.
+ */
+public interface DOMDataWriteTransaction extends AsyncWriteTransaction<YangInstanceIdentifier, NormalizedNode<?, ?>> {
+
+    /**
+     * Stores a piece of data at the specified path. This acts as an add / replace
+     * operation, which is to say that whole subtree will be replaced by the specified data.
+     * <p>
+     * For more information on usage and examples, please see the documentation in {@link AsyncWriteTransaction}.
+     * <p>
+     * If you need to make sure that a parent object exists but you do not want modify
+     * its pre-existing state by using put, consider using {@link #merge} instead.
+     *
+     * @param store
+     *            the logical data store which should be modified
+     * @param path
+     *            the data object path
+     * @param data
+     *            the data object to be written to the specified path
+     * @throws IllegalStateException
+     *             if the transaction has already been submitted
+     */
+    void put(LogicalDatastoreType store, YangInstanceIdentifier path, NormalizedNode<?, ?> data);
 
+    /**
+     * Merges a piece of data with the existing data at a specified path. Any pre-existing data
+     * which is not explicitly overwritten will be preserved. This means that if you store a container,
+     * its child lists will be merged.
+     * <p>
+     * For more information on usage and examples, please see the documentation in {@link AsyncWriteTransaction}.
+     *<p>
+     * If you require an explicit replace operation, use {@link #put} instead.
+     *
+     * @param store
+     *            the logical data store which should be modified
+     * @param path
+     *            the data object path
+     * @param data
+     *            the data object to be merged to the specified path
+     * @throws IllegalStateException
+     *             if the transaction has already been submitted
+     */
+    void merge(LogicalDatastoreType store, YangInstanceIdentifier path, NormalizedNode<?, ?> data);
 }
diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMMountPoint.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMMountPoint.java
new file mode 100644 (file)
index 0000000..1431155
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+
+package org.opendaylight.controller.md.sal.dom.api;
+
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+import com.google.common.base.Optional;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public interface DOMMountPoint extends Identifiable<YangInstanceIdentifier> {
+
+    <T extends DOMService> Optional<T> getService(Class<T> cls);
+
+    SchemaContext getSchemaContext();
+}
diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMMountPointService.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMMountPointService.java
new file mode 100644 (file)
index 0000000..6023038
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+
+package org.opendaylight.controller.md.sal.dom.api;
+
+import org.opendaylight.controller.sal.core.api.BrokerService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import com.google.common.base.Optional;
+
+
+public interface DOMMountPointService extends BrokerService {
+
+    Optional<DOMMountPoint> getMountPoint(YangInstanceIdentifier path);
+
+    DOMMountPointBuilder createMountPoint(YangInstanceIdentifier path);
+
+    ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener);
+
+    public interface DOMMountPointBuilder {
+
+        <T extends DOMService> DOMMountPointBuilder addService(Class<T> type,T impl);
+
+        DOMMountPointBuilder addInitialSchemaContext(SchemaContext ctx);
+
+        ObjectRegistration<DOMMountPoint> register();
+    }
+}
@@ -3,10 +3,11 @@
  *
  * 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
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
  */
 
-package org.opendaylight.controller.cluster.datastore.messages;
+package org.opendaylight.controller.md.sal.dom.api;
+
+public interface DOMService {
 
-public class CloseListenerRegistration {
 }
index 73a0c28465108e951ddafdd6fa2639bd088f9ff1..2d2fa48c058a4513a49f5504a70781f35695cb8e 100644 (file)
@@ -8,7 +8,7 @@
 package org.opendaylight.controller.md.sal.dom.api;
 
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 /**
@@ -21,7 +21,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
  * <p>
  * This interface is type capture of {@link TransactionChain} for DOM Data Contracts.
  */
-public interface DOMTransactionChain extends TransactionChain<InstanceIdentifier, NormalizedNode<?, ?>> {
+public interface DOMTransactionChain extends TransactionChain<YangInstanceIdentifier, NormalizedNode<?, ?>> {
 
     @Override
     DOMDataReadOnlyTransaction newReadOnlyTransaction();
index 724cbe75f420e41ccfcfbe041f4b2854e2e1d616..203bd40329421ee08950eef0ef5023cf3c4edbe0 100644 (file)
@@ -16,7 +16,7 @@ import org.opendaylight.yangtools.concepts.ObjectRegistration;
 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.YangInstanceIdentifier;
 import org.osgi.framework.BundleContext;
 
 /**
@@ -78,13 +78,18 @@ public interface Broker {
      *
      * @param cons
      *            Consumer to be registered.
-     * @param context
      * @return a session specific to consumer registration
      * @throws IllegalArgumentException
      *             If the consumer is <code>null</code>.
      * @throws IllegalStateException
      *             If the consumer is already registered.
      */
+    ConsumerSession registerConsumer(Consumer cons);
+
+    /*
+     * @deprecated Use registerConsumer(Consumer cons) instead (BundleContext is no longer used)
+     */
+    @Deprecated
     ConsumerSession registerConsumer(Consumer cons, BundleContext context);
 
     /**
@@ -110,13 +115,18 @@ public interface Broker {
      *
      * @param prov
      *            Provider to be registered.
-     * @param context
      * @return a session unique to the provider registration.
      * @throws IllegalArgumentException
      *             If the provider is <code>null</code>.
      * @throws IllegalStateException
      *             If the consumer is already registered.
      */
+    ProviderSession registerProvider(Provider prov);
+
+    /*
+     * @deprecated Use registerProvider(Provider cons) instead (BundleContext is no longer used)
+     */
+    @Deprecated
     ProviderSession registerProvider(Provider prov, BundleContext context);
 
     /**
@@ -240,6 +250,6 @@ public interface Broker {
         void close();
     }
 
-    public interface RoutedRpcRegistration extends RpcRegistration, RoutedRegistration<QName, InstanceIdentifier, RpcImplementation> {
+    public interface RoutedRpcRegistration extends RpcRegistration, RoutedRegistration<QName, YangInstanceIdentifier, RpcImplementation> {
     }
 }
index a693cd6c49b475bc5f046cbb48c465f37858729f..a5ab8ac911b20fc703b96185af66e9bb60c170d7 100644 (file)
@@ -38,21 +38,22 @@ public interface Consumer {
     public void onSessionInitiated(ConsumerSession session);
 
     /**
-     * Get a set of implementations of consumer functionality to be registered
-     * into system during the consumer registration to the SAL.
-     *
-     * This method is invoked by {@link Broker#registerConsumer(Consumer)}.
-     *
-     * @return Set of consumer functionality.
+     * @deprecated - no longer used or needed
+     * *
+     * Suggested implementation until removed:
+     * @code {
+     * public Collection<ConsumerFunctionality> getConsumerFunctionality() {
+     *    return Collections.emptySet();
+     * }
+     * }
      */
+    @Deprecated
     public Collection<ConsumerFunctionality> getConsumerFunctionality();
 
     /**
-     * The marker interface for the interfaces describing the consumer
-     * functionality contracts.
-     *
-     *
+     * @deprecated - no longer used or needed
      */
+    @Deprecated
     public interface ConsumerFunctionality {
 
     }
index 0a57d12579239ae29e9fff251651db8483f1ee16..4f32983f84b7e7f5a0408e1b5dfcdf4f5a01b65c 100644 (file)
@@ -42,27 +42,22 @@ public interface Provider {
     public void onSessionInitiated(ProviderSession session);
 
     /**
-     * Gets a set of implementations of provider functionality to be registered
-     * into system during the provider registration to the SAL.
+     * @deprecated - No longer used or needed
      *
-     * <p>
-     * This method is invoked by {@link Broker#registerProvider(Provider)} to
-     * learn the initial provided functionality
-     *
-     * @return Set of provider's functionality.
+     * Suggested implementation until removed:
+     * @code {
+     * public Collection<ProviderFunctionality> getProviderFunctionality() {
+     *  return Collections.emptySet();
+     * }
+     * }
      */
+    @Deprecated
     public Collection<ProviderFunctionality> getProviderFunctionality();
 
     /**
-     * Functionality provided by the {@link Provider}
-     *
-     * <p>
-     * Marker interface used to mark the interfaces describing specific
-     * functionality which could be exposed by providers to other components.
-     *
-
-     *
+     * @deprecated - no longer used or needed
      */
+    @Deprecated
     public interface ProviderFunctionality {
 
     }
index 4f11ba066110be3f73d855a5c4871195fc47306c..7a7b144fed323d2a4d8e606cfeb1916a3245f464 100644 (file)
@@ -10,12 +10,12 @@ package org.opendaylight.controller.sal.core.api;
 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.YangInstanceIdentifier;
 
 import com.google.common.util.concurrent.ListenableFuture;
 
 public interface RoutedRpcDefaultImplementation {
 
-    ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input);
+    ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, YangInstanceIdentifier identifier, CompositeNode input);
 
 }
index a22a6ef75e6be7d25461071b1c8290d1a13c0be4..050225c5c20f42e4fea8eabf26577051a09aa8a7 100644 (file)
@@ -8,13 +8,14 @@
 package org.opendaylight.controller.sal.core.api;
 
 import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
+import org.opendaylight.controller.md.sal.dom.api.DOMService;
 import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
 import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
-public interface RpcProvisionRegistry extends RpcImplementation, BrokerService, RouteChangePublisher<RpcRoutingContext, InstanceIdentifier> {
+public interface RpcProvisionRegistry extends RpcImplementation, BrokerService, RouteChangePublisher<RpcRoutingContext, YangInstanceIdentifier>, DOMService {
 
     /**
      * Registers an implementation of the rpc.
index 266b6976afbde367ecca294a90023253d903b0ff..88289b310607e2c226a28e009a4197018e55ee97 100644 (file)
@@ -12,7 +12,7 @@ import org.opendaylight.controller.md.sal.common.api.data.DataModificationTransa
 import org.opendaylight.controller.md.sal.common.api.data.DataReader;
 import org.opendaylight.controller.sal.core.api.BrokerService;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 
 /**
@@ -21,20 +21,23 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
  *
  *
  * @see DataProviderService
+ * @deprecated Replaced by {@link org.opendaylight.controller.md.sal.dom.api.DOMDataBroker}
  *
  */
+@Deprecated
 public interface DataBrokerService extends
     BrokerService, //
-    DataReader<InstanceIdentifier, CompositeNode>, //
-    DataModificationTransactionFactory<InstanceIdentifier, CompositeNode>, //
-    DataChangePublisher<InstanceIdentifier, CompositeNode, DataChangeListener> {
+    DataReader<YangInstanceIdentifier, CompositeNode>, //
+    DataModificationTransactionFactory<YangInstanceIdentifier, CompositeNode>, //
+    DataChangePublisher<YangInstanceIdentifier, CompositeNode, DataChangeListener> {
 
 
     @Override
-    public CompositeNode readConfigurationData(InstanceIdentifier path);
+    public CompositeNode readConfigurationData(YangInstanceIdentifier path);
 
     @Override
-    public CompositeNode readOperationalData(InstanceIdentifier path);
+    public CompositeNode readOperationalData(YangInstanceIdentifier path);
 
+    @Override
     DataModificationTransaction beginTransaction();
 }
index 944ccc5b33a120f5ad3ef2eeb3e347dd5881621c..47ac2d78afcd39d49633166b1614178da4d7418a 100644 (file)
@@ -9,12 +9,17 @@ package org.opendaylight.controller.sal.core.api.data;
 
 import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
+/**
+ *
+ * @deprecated Replaced by {@link org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener}
+ */
+@Deprecated
 public interface DataChangeListener
         extends
-        org.opendaylight.controller.md.sal.common.api.data.DataChangeListener<InstanceIdentifier, CompositeNode> {
+        org.opendaylight.controller.md.sal.common.api.data.DataChangeListener<YangInstanceIdentifier, CompositeNode> {
 
     @Override
-    public void onDataChanged(DataChangeEvent<InstanceIdentifier, CompositeNode> change);
+    public void onDataChanged(DataChangeEvent<YangInstanceIdentifier, CompositeNode> change);
 }
index 9706bbacdbdbee3b22c3a8b163b069617b452347..dd5755e33ccd3ce8175427e5c454a69e467d27a3 100644 (file)
@@ -15,9 +15,19 @@ import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 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.YangInstanceIdentifier;
 
-public interface DataModificationTransaction extends DataModification<InstanceIdentifier, CompositeNode>{
+/**
+ *
+ * @deprecated Replaced by more specific
+ *             {@link org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction}
+ *             ,
+ *             {@link org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction}
+ *             or {@link org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction}
+ *
+ */
+@Deprecated
+public interface DataModificationTransaction extends DataModification<YangInstanceIdentifier, CompositeNode> {
 
     /**
      * Returns transaction identifier
@@ -34,8 +44,8 @@ public interface DataModificationTransaction extends DataModification<InstanceId
      * Commits transaction to be stored in global data repository.
      *
      *
-     * @return  Future object which returns RpcResult with TransactionStatus
-     *          when transaction is processed by store.
+     * @return Future object which returns RpcResult with TransactionStatus when
+     *         transaction is processed by store.
      */
     @Override
     Future<RpcResult<TransactionStatus>> commit();
@@ -43,6 +53,6 @@ public interface DataModificationTransaction extends DataModification<InstanceId
     ListenerRegistration<DataTransactionListener> registerListener(DataTransactionListener listener);
 
     public interface DataTransactionListener extends EventListener {
-        void onStatusUpdated(DataModificationTransaction transaction,TransactionStatus status);
+        void onStatusUpdated(DataModificationTransaction transaction, TransactionStatus status);
     }
 }
index 0538660fd79eea473d705ae588ce83035683941e..194da91695fbb32c94f4bcf3ef9c7ada91ebc64d 100644 (file)
@@ -8,16 +8,22 @@
 package org.opendaylight.controller.sal.core.api.data;
 
 import org.opendaylight.controller.md.sal.common.api.data.DataProvisionService;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
 import org.opendaylight.controller.sal.common.DataStoreIdentifier;
 import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-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.YangInstanceIdentifier;
 
+/**
+ *
+ * @deprecated Replaced by {@link org.opendaylight.controller.md.sal.dom.api.DOMDataBroker}
+ *
+ */
+@Deprecated
 public interface DataProviderService extends
     DataBrokerService, //
-    DataProvisionService<InstanceIdentifier, CompositeNode>
+    DataProvisionService<YangInstanceIdentifier, CompositeNode>
     {
 
     /**
@@ -57,9 +63,9 @@ public interface DataProviderService extends
     void removeRefresher(DataStoreIdentifier store, DataRefresher refresher);
 
 
-    Registration<DataReader<InstanceIdentifier, CompositeNode>> registerConfigurationReader(InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader);
+    Registration registerConfigurationReader(YangInstanceIdentifier path, DataReader<YangInstanceIdentifier, CompositeNode> reader);
 
-    Registration<DataReader<InstanceIdentifier, CompositeNode>> registerOperationalReader(InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader);
+    Registration registerOperationalReader(YangInstanceIdentifier path, DataReader<YangInstanceIdentifier, CompositeNode> reader);
 
     public interface DataRefresher extends Provider.ProviderFunctionality {
 
index 58ffb38365c0d6673fa10ef9f1ccd229cdb26bcd..d66d04816b300e7112f87da20924f272dc6b1ccf 100644 (file)
@@ -10,17 +10,23 @@ package org.opendaylight.controller.sal.core.api.data;
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
 import org.opendaylight.controller.md.sal.common.api.data.DataReader;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
+/**
+ *
+ * @deprecated Replaced by org.opendaylight.controller.sal.core.spi.data.DOMStore.
+ *
+ */
+@Deprecated
 public interface DataStore extends //
-    DataReader<InstanceIdentifier, CompositeNode>,
-    DataCommitHandler<InstanceIdentifier, CompositeNode> {
+    DataReader<YangInstanceIdentifier, CompositeNode>,
+    DataCommitHandler<YangInstanceIdentifier, CompositeNode> {
 
 
-    Iterable<InstanceIdentifier> getStoredConfigurationPaths();
-    Iterable<InstanceIdentifier> getStoredOperationalPaths();
+    Iterable<YangInstanceIdentifier> getStoredConfigurationPaths();
+    Iterable<YangInstanceIdentifier> getStoredOperationalPaths();
 
-    boolean containsConfigurationPath(InstanceIdentifier path);
-    boolean containsOperationalPath(InstanceIdentifier path);
+    boolean containsConfigurationPath(YangInstanceIdentifier path);
+    boolean containsOperationalPath(YangInstanceIdentifier path);
 
 }
index 286770b0482d36d600f9f2eeebe5ed24cf928a43..e4e6e2f26df00fb1baf8035649143e87afe95a96 100644 (file)
@@ -28,7 +28,10 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
  * {@link DataProviderService#addValidator(DataStoreIdentifier, DataValidator)}
  * </ul>
  *
+ * @deprecated Replaced by {@link org.opendaylight.controller.md.sal.common.api.data.AsyncConfigurationCommitHandler}
+ *
  **/
+@Deprecated
 public interface DataValidator extends Provider.ProviderFunctionality {
 
     /**
index 5698b969771bd4296cbcb8d85ebbd03fcbca59ae..a4343ba5cf7e2b8da6cd9034b2264f2fd698310a 100644 (file)
@@ -21,6 +21,7 @@ import com.google.common.util.concurrent.ListenableFuture;
  * Interface representing a single mount instance and represents a way for
  * clients to access underlying data, RPCs and notifications.
  */
+@Deprecated
 public interface MountInstance extends //
         NotificationService, //
         DataBrokerService {
index 29e3b911c1d1b1d8a5cdf64b30da0842bff7d11f..a5c3b5d0f6460a3ecc805994a6877883ebf09738 100644 (file)
@@ -12,6 +12,7 @@ import org.opendaylight.controller.sal.core.api.data.DataProviderService;
 import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
+@Deprecated
 public interface MountProvisionInstance extends //
         MountInstance,//
         NotificationPublishService, //
diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionListener.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionListener.java
new file mode 100644 (file)
index 0000000..1d724e4
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+
+package org.opendaylight.controller.sal.core.api.mount;
+
+import java.util.EventListener;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public interface MountProvisionListener extends EventListener {
+
+    void onMountPointCreated(YangInstanceIdentifier path);
+
+    void onMountPointRemoved(YangInstanceIdentifier path);
+
+}
index 1185c4528cee3e60bbc7bba70ab3beddc5eac021..37c30b6784c31b6d2131deed70f7e8eccf93202c 100644 (file)
@@ -7,27 +7,22 @@
  */
 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;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
+/**
+ * @deprecated Use org.opendaylight.controller.md.sal.dom.api.DOMMountPointService instead
+ */
+@Deprecated
 public interface MountProvisionService extends MountService {
 
     @Override
-    public MountProvisionInstance getMountPoint(InstanceIdentifier path);
+    public MountProvisionInstance getMountPoint(YangInstanceIdentifier path);
 
-    MountProvisionInstance createMountPoint(InstanceIdentifier path);
+    MountProvisionInstance createMountPoint(YangInstanceIdentifier path);
 
-    MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path);
+    MountProvisionInstance createOrGetMountPoint(YangInstanceIdentifier path);
 
     ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener);
 
-    public interface MountProvisionListener extends EventListener {
-
-        void onMountPointCreated(InstanceIdentifier path);
-
-        void onMountPointRemoved(InstanceIdentifier path);
-
-    }
 }
index 6d1f17255c7defd4a0e61a890d0b6246b4b466a1..55b74c63d324b171e1097a9c348df496500ccfed 100644 (file)
@@ -8,12 +8,15 @@
 package org.opendaylight.controller.sal.core.api.mount;
 
 import org.opendaylight.controller.sal.core.api.BrokerService;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 /**
  * Client-level interface for interacting with mount points. It provides access
  * to {@link MountInstance} instances based on their path.
+ *
+ *  @deprecated Use org.opendaylight.controller.md.sal.dom.api.DOMMountPointService instead
  */
+@Deprecated
 public interface MountService extends BrokerService {
     /**
      * Obtain access to a mount instance registered at the specified path.
@@ -21,5 +24,5 @@ public interface MountService extends BrokerService {
      * @param path Path at which the instance is registered
      * @return Reference to the instance, or null if no such instance exists.
      */
-    MountInstance getMountPoint(InstanceIdentifier path);
+    MountInstance getMountPoint(YangInstanceIdentifier path);
 }
index f1156c39642af935a0d0a88d5d4d55bc6f40077f..4f5c7abf5f1bb560ea2b1d5d1b57982cfc700f4a 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.sal.core.api.notify;
 
+import org.opendaylight.controller.md.sal.dom.api.DOMService;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 /**
@@ -23,7 +24,7 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
  * {@link NotificationListener#onNotification(CompositeNode)}
  * </ol>
  */
-public interface NotificationPublishService extends NotificationService {
+public interface NotificationPublishService extends NotificationService, DOMService {
     /**
      * Publishes a notification.
      *
index 1d67ca08241af4489c9582fdb5e39a576f67afca..9c0db42d6ceaf8007645b026057bc92558727d3b 100644 (file)
@@ -8,7 +8,7 @@
 package org.opendaylight.controller.sal.core.api.notify;
 
 import org.opendaylight.controller.sal.core.api.BrokerService;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.QName;
 
 
@@ -38,6 +38,6 @@ public interface NotificationService extends BrokerService {
      * @param notification
      * @param listener
      */
-    Registration<NotificationListener> addNotificationListener(QName notification,
+    ListenerRegistration<NotificationListener> addNotificationListener(QName notification,
             NotificationListener listener);
 }
index 022882fcebd042404689f64abf2ed614894c3262..96e353b80e23c284885a48cf2302e9759cb29386 100644 (file)
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
     </dependency>
+
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>mockito-configuration</artifactId>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-simple</artifactId>
           <instructions>
             <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
             <Bundle-Activator>org.opendaylight.controller.sal.dom.broker.osgi.SchemaServiceActivator</Bundle-Activator>
-            <Export-Package>org.opendaylight.controller.sal.dom.broker.spi</Export-Package>
-            <Private-Package>org.opendaylight.controller.sal.dom.broker,
+            <Export-Package>org.opendaylight.controller.sal.dom.broker.spi,
+                            <!--sal.broker.impl is exported for sal-netconf-connector to use SchemaAwareRpcRegistry.-->
+                            <!-- TODO Remove sal.broker.impl from export when SchemaAwareRpcRegistry is not used in connector anymore -->
                             org.opendaylight.controller.sal.dom.broker.impl,
                             org.opendaylight.controller.sal.dom.broker.impl.*,
+            </Export-Package>
+            <Private-Package>org.opendaylight.controller.sal.dom.broker,
                             org.opendaylight.controller.sal.dom.broker.osgi,
                             org.opendaylight.controller.sal.dom.broker.util,
                             org.opendaylight.controller.config.yang.md.sal.dom.impl,
-                            org.opendaylight.controller.config.yang.md.sal.dom.statistics,
+                            org.opendaylight.controller.config.yang.md.sal.dom.statistics,\
                             org.opendaylight.controller.md.sal.dom.broker.impl,
                             org.opendaylight.controller.md.sal.dom.broker.impl.*,
                             org.opendaylight.yangtools.yang.util,
index 767785dbf13c1dac1231b46e2339f044ebe0cb97..17b78f4ebd0e6602532f4fd7f5869d184d8125ba 100644 (file)
@@ -7,11 +7,28 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.dom.impl;
 
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.MutableClassToInstanceMap;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.broker.impl.compat.BackwardsCompatibleDataBroker;
+import org.opendaylight.controller.md.sal.dom.broker.impl.mount.DOMMountPointServiceImpl;
+import org.opendaylight.controller.sal.core.api.BrokerService;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
 import org.opendaylight.controller.sal.core.api.data.DataStore;
-import org.opendaylight.controller.sal.dom.broker.BrokerConfigActivator;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.sal.dom.broker.BackwardsCompatibleMountPointManager;
 import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
-import org.osgi.framework.BundleContext;
+import org.opendaylight.controller.sal.dom.broker.DataBrokerImpl;
+import org.opendaylight.controller.sal.dom.broker.GlobalBundleScanningSchemaServiceImpl;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProviders;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 /**
 *
@@ -19,8 +36,6 @@ import org.osgi.framework.BundleContext;
 public final class DomBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractDomBrokerImplModule
 {
 
-    private BundleContext bundleContext;
-
     public DomBrokerImplModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
     }
@@ -36,23 +51,61 @@ public final class DomBrokerImplModule extends org.opendaylight.controller.confi
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final BrokerImpl broker = new BrokerImpl();
-        final BrokerConfigActivator activator = new BrokerConfigActivator();
-        final DataStore store = getDataStoreDependency();
+        final DataStore legacyStore = getDataStoreDependency();
         final DOMDataBroker asyncBroker= getAsyncDataBrokerDependency();
 
-        activator.start(broker, store, asyncBroker,getBundleContext());
+        ClassToInstanceMap<BrokerService> services = MutableClassToInstanceMap.create();
+
+
+        SchemaService schemaService = getSchemaServiceImpl();
+        services.putInstance(SchemaService.class, schemaService);
+        SchemaAwareRpcBroker router = new SchemaAwareRpcBroker("/", SchemaContextProviders
+                .fromSchemaService(schemaService));
+        services.putInstance(RpcProvisionRegistry.class, router);
+
+        final DataProviderService legacyData;
+        if(asyncBroker != null) {
+            services.putInstance(DOMDataBroker.class, asyncBroker);
+            legacyData = new BackwardsCompatibleDataBroker(asyncBroker,schemaService);
+        } else {
+            legacyData = createLegacyDataService(legacyStore,schemaService);
+        }
+        services.putInstance(DataProviderService.class,legacyData);
+        services.putInstance(DataBrokerService.class, legacyData);
 
-//        final DomBrokerImplRuntimeMXBean domBrokerRuntimeMXBean = new DomBrokerRuntimeMXBeanImpl(activator.getDataService());
-//        getRootRuntimeBeanRegistratorWrapper().register(domBrokerRuntimeMXBean);
-        return broker;
+        final DOMMountPointService mountService = new DOMMountPointServiceImpl();
+        services.putInstance(DOMMountPointService.class, mountService);
+
+        // TODO remove backwards service, use only new DOMMountPointService
+        final MountProvisionService backwardsMountService = new BackwardsCompatibleMountPointManager(mountService);
+        services.putInstance(MountService.class, backwardsMountService);
+        services.putInstance(MountProvisionService.class, backwardsMountService);
+
+        return new BrokerImpl(router, services);
     }
 
-    private BundleContext getBundleContext() {
-        return this.bundleContext;
+    private DataProviderService createLegacyDataService(final DataStore legacyStore, final SchemaService schemaService) {
+        YangInstanceIdentifier rootPath = YangInstanceIdentifier.builder().toInstance();
+        DataBrokerImpl dataService = new DataBrokerImpl();
+        SchemaAwareDataStoreAdapter wrappedStore = new SchemaAwareDataStoreAdapter();
+        wrappedStore.changeDelegate(legacyStore);
+        wrappedStore.setValidationEnabled(false);
+
+        schemaService.registerSchemaServiceListener(wrappedStore);
+
+        dataService.registerConfigurationReader(rootPath, wrappedStore);
+        dataService.registerCommitHandler(rootPath, wrappedStore);
+        dataService.registerOperationalReader(rootPath, wrappedStore);
+        return dataService;
     }
 
-    public void setBundleContext(final BundleContext bundleContext) {
-        this.bundleContext = bundleContext;
+    private SchemaService getSchemaServiceImpl() {
+        final SchemaService schemaService;
+        if(getRootSchemaService() != null) {
+            schemaService = getRootSchemaServiceDependency();
+        } else {
+            schemaService = GlobalBundleScanningSchemaServiceImpl.getInstance();
+        }
+        return schemaService;
     }
 }
index 38f5009feb85e14376755f71008425d137c8cd00..f1fcb495aace6a38ade530efa34b32eba817772f 100644 (file)
@@ -7,10 +7,6 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.dom.impl;
 
-import org.opendaylight.controller.config.api.DependencyResolver;
-import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
-import org.opendaylight.controller.config.spi.Module;
-import org.osgi.framework.BundleContext;
 
 /**
 *
@@ -18,19 +14,4 @@ import org.osgi.framework.BundleContext;
 public class DomBrokerImplModuleFactory extends
         org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractDomBrokerImplModuleFactory {
 
-    @Override
-    public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
-        DomBrokerImplModule module = (DomBrokerImplModule) super.createModule(instanceName, dependencyResolver, bundleContext);
-        module.setBundleContext(bundleContext);
-        return module;
-    }
-
-    @Override
-    public Module createModule(String instanceName, DependencyResolver dependencyResolver,
-            DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
-        DomBrokerImplModule module = (DomBrokerImplModule) super.createModule(instanceName, dependencyResolver, old, bundleContext);
-        module.setBundleContext(bundleContext);
-        return module;
-    }
-
 }
index d3852d28c5ba1ff9d6191f135cbcaba0c88ad2b4..69b17ee3c48aeb5aae64dc8c4b02e36abdfce7a7 100644 (file)
@@ -7,18 +7,16 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.dom.impl;
 
-import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
+import java.util.concurrent.Executors;
+
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.broker.impl.DOMDataBrokerImpl;
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
-import org.osgi.framework.BundleContext;
 
-import java.util.Hashtable;
-import java.util.concurrent.Executors;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
 
 /**
 *
@@ -26,8 +24,6 @@ import java.util.concurrent.Executors;
 public final class DomInmemoryDataBrokerModule extends
         org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractDomInmemoryDataBrokerModule {
 
-    private BundleContext bundleContext;
-
     public DomInmemoryDataBrokerModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
             final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
@@ -70,17 +66,6 @@ public final class DomInmemoryDataBrokerModule extends
 
         DOMDataBrokerImpl newDataBroker = new DOMDataBrokerImpl(datastores, MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()));
 
-        getBundleContext().registerService(DOMDataBroker.class, newDataBroker, new Hashtable<String, String>());
-
-
         return newDataBroker;
     }
-
-    private BundleContext getBundleContext() {
-        return bundleContext;
-    }
-
-    void setBundleContext(final BundleContext ctx) {
-        bundleContext = ctx;
-    }
 }
index 91d42c48c13577853ecbc7d3a618bf0b2de93f4e..56a51ed45e75588d40adca6b9613348e3e1c8d9a 100644 (file)
@@ -7,10 +7,6 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.dom.impl;
 
-import org.opendaylight.controller.config.api.DependencyResolver;
-import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
-import org.opendaylight.controller.config.spi.Module;
-import org.osgi.framework.BundleContext;
 
 /**
 *
@@ -19,19 +15,4 @@ public class DomInmemoryDataBrokerModuleFactory extends org.opendaylight.control
 {
 
 
-
-    @Override
-    public Module createModule(final String instanceName, final DependencyResolver dependencyResolver, final BundleContext bundleContext) {
-        DomInmemoryDataBrokerModule module = (DomInmemoryDataBrokerModule) super.createModule(instanceName, dependencyResolver, bundleContext);
-        module.setBundleContext(bundleContext);
-        return module;
-    }
-
-    @Override
-    public Module createModule(final String instanceName, final DependencyResolver dependencyResolver,
-            final DynamicMBeanWithInstance old, final BundleContext bundleContext) throws Exception {
-        DomInmemoryDataBrokerModule module = (DomInmemoryDataBrokerModule)  super.createModule(instanceName, dependencyResolver, old, bundleContext);
-        module.setBundleContext(bundleContext);
-        return module;
-    }
 }
index fd24944018c69b3b9480a7018e0fea1c23986719..fbc418dc2aec0203d4f52ad6b7ace8cc083ca019 100644 (file)
@@ -15,7 +15,6 @@ import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -57,43 +56,21 @@ org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractSchemaServiceImp
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        ServiceReference<SchemaService> ref = getBundleContext().getServiceReference(SchemaService.class);
-        if (ref != null) {
-            return new GlobalSchemaServiceProxy(getBundleContext(), ref);
-        }
-
-        GlobalBundleScanningSchemaServiceImpl newInstance = new GlobalBundleScanningSchemaServiceImpl(getBundleContext());
-        newInstance.start();
-        return newInstance;
+        return GlobalBundleScanningSchemaServiceImpl.getInstance();
     }
 
     public class GlobalSchemaServiceProxy implements AutoCloseable, SchemaService, Delegator<SchemaService> {
 
-        private BundleContext bundleContext;
-        private ServiceReference<SchemaService> reference;
         private SchemaService delegate;
 
-        public GlobalSchemaServiceProxy(final BundleContext bundleContext, final ServiceReference<SchemaService> ref) {
-            this.bundleContext = bundleContext;
-            this.reference = ref;
-            this.delegate = bundleContext.getService(reference);
+        public GlobalSchemaServiceProxy() {
+            this.delegate = GlobalBundleScanningSchemaServiceImpl.getInstance();
         }
 
         @Override
         public void close() throws Exception {
             if (delegate != null) {
                 delegate = null;
-
-                try {
-                    bundleContext.ungetService(reference);
-                } catch (IllegalStateException e) {
-                    // Indicates the service was already unregistered which can happen normally
-                    // on shutdown.
-                    LOG.debug( "Error unregistering service", e );
-                }
-
-                reference = null;
-                bundleContext = null;
             }
         }
 
index 0be4327f7ae06231cd86814c62c724ddb16fd937..d3791a08782b6cbdf0217b85834af12bbf1b9fab 100644 (file)
@@ -8,7 +8,7 @@ package org.opendaylight.controller.md.sal.dom.broker.impl;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransaction;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.base.Preconditions;
@@ -27,7 +27,7 @@ import com.google.common.collect.ImmutableMap;
  *            Subtransaction type
  */
 abstract class AbstractDOMForwardedCompositeTransaction<K, T extends DOMStoreTransaction> implements
-        AsyncTransaction<InstanceIdentifier, NormalizedNode<?, ?>> {
+        AsyncTransaction<YangInstanceIdentifier, NormalizedNode<?, ?>> {
 
     private final ImmutableMap<K, T> backingTxs;
     private final Object identifier;
index 5694d0bca9a68fccd5f31557418a8824b35d7a5a..d354cca005974c332c2814c76e696f774b772bc4 100644 (file)
@@ -114,7 +114,7 @@ public abstract class AbstractDOMForwardedTransactionFactory<T extends DOMStoreT
      * <li> {@link DOMDataWriteTransaction#commit()} - results in invoking
      * {@link DOMStoreWriteTransaction#ready()}, gathering all resulting cohorts
      * and then invoking finalized implementation callback
-     * {@link #commit(DOMDataWriteTransaction, Iterable)} with transaction which
+     * {@link #submit(DOMDataWriteTransaction, Iterable)} with transaction which
      * was commited and gathered results.
      * </ul>
      *
@@ -167,7 +167,7 @@ public abstract class AbstractDOMForwardedTransactionFactory<T extends DOMStoreT
      * <li> {@link DOMDataWriteTransaction#commit()} - results in invoking
      * {@link DOMStoreWriteTransaction#ready()}, gathering all resulting cohorts
      * and then invoking finalized implementation callback
-     * {@link #commit(DOMDataWriteTransaction, Iterable)} with transaction which
+     * {@link #submit(DOMDataWriteTransaction, Iterable)} with transaction which
      * was commited and gathered results.
      * <li>
      * </ul>
index 7e37a1e3a3467837b16963a8026236738535f599..d1b9a8f6005097ccc463d87efe2a52d0e3911b4c 100644 (file)
@@ -12,9 +12,9 @@ import static com.google.common.base.Preconditions.checkState;
 import java.util.Map.Entry;
 import java.util.concurrent.atomic.AtomicLong;
 
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
@@ -23,14 +23,13 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStore;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 
 public class DOMDataBrokerImpl extends AbstractDOMForwardedTransactionFactory<DOMStore> implements DOMDataBroker,
@@ -55,7 +54,7 @@ public class DOMDataBrokerImpl extends AbstractDOMForwardedTransactionFactory<DO
 
     @Override
     public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(final LogicalDatastoreType store,
-            final InstanceIdentifier path, final DOMDataChangeListener listener, final DataChangeScope triggeringScope) {
+            final YangInstanceIdentifier path, final DOMDataChangeListener listener, final DataChangeScope triggeringScope) {
 
         DOMStore potentialStore = getTxFactories().get(store);
         checkState(potentialStore != null, "Requested logical data store is not available.");
@@ -78,7 +77,7 @@ public class DOMDataBrokerImpl extends AbstractDOMForwardedTransactionFactory<DO
     }
 
     @Override
-    public ListenableFuture<RpcResult<TransactionStatus>> commit(final DOMDataWriteTransaction transaction,
+    public CheckedFuture<Void,TransactionCommitFailedException> submit(final DOMDataWriteTransaction transaction,
             final Iterable<DOMStoreThreePhaseCommitCohort> cohorts) {
         LOG.debug("Transaction: {} submitted with cohorts {}.", transaction.getIdentifier(), cohorts);
         return coordinator.submit(transaction, cohorts, Optional.<DOMDataCommitErrorListener> absent());
index b9f096aafc251400b01ee6b7319395cc8ec739fd..227693ca4df5015f79d8f88cf02e666be7f25e39 100644 (file)
@@ -10,21 +10,20 @@ import java.util.concurrent.atomic.AtomicLong;
 
 import javax.annotation.concurrent.GuardedBy;
 
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
-import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.CheckedFuture;
 
 /**
  * NormalizedNode implementation of {@link org.opendaylight.controller.md.sal.common.api.data.TransactionChain} which is backed
@@ -73,7 +72,7 @@ public class DOMDataBrokerTransactionChainImpl extends AbstractDOMForwardedTrans
     }
 
     @Override
-    public synchronized ListenableFuture<RpcResult<TransactionStatus>> commit(
+    public synchronized CheckedFuture<Void,TransactionCommitFailedException> submit(
             final DOMDataWriteTransaction transaction, final Iterable<DOMStoreThreePhaseCommitCohort> cohorts) {
         return coordinator.submit(transaction, cohorts, Optional.<DOMDataCommitErrorListener> of(this));
     }
index 540e2fe20ce52208ffd4a659b5e21c70eafe4b10..8b9eb445fd45b4d19f5a3f6523a7ce2a711ef310 100644 (file)
@@ -6,20 +6,15 @@
  */
 package org.opendaylight.controller.md.sal.dom.broker.impl;
 
-import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 
 import javax.annotation.concurrent.GuardedBy;
 
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -84,18 +79,19 @@ public class DOMDataCommitCoordinatorImpl implements DOMDataCommitExecutor {
     }
 
     @Override
-    public ListenableFuture<RpcResult<TransactionStatus>> submit(final DOMDataWriteTransaction transaction,
+    public CheckedFuture<Void,TransactionCommitFailedException> submit(final DOMDataWriteTransaction transaction,
             final Iterable<DOMStoreThreePhaseCommitCohort> cohorts, final Optional<DOMDataCommitErrorListener> listener) {
         Preconditions.checkArgument(transaction != null, "Transaction must not be null.");
         Preconditions.checkArgument(cohorts != null, "Cohorts must not be null.");
         Preconditions.checkArgument(listener != null, "Listener must not be null");
         LOG.debug("Tx: {} is submitted for execution.", transaction.getIdentifier());
-        ListenableFuture<RpcResult<TransactionStatus>> commitFuture = executor.submit(new CommitCoordinationTask(
+        ListenableFuture<Void> commitFuture = executor.submit(new CommitCoordinationTask(
                 transaction, cohorts, listener));
         if (listener.isPresent()) {
             Futures.addCallback(commitFuture, new DOMDataCommitErrorInvoker(transaction, listener.get()));
         }
-        return commitFuture;
+
+        return Futures.makeChecked(commitFuture, TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER);
     }
 
     /**
@@ -141,7 +137,7 @@ public class DOMDataCommitCoordinatorImpl implements DOMDataCommitExecutor {
      * support of cancelation.
      *
      */
-    private static class CommitCoordinationTask implements Callable<RpcResult<TransactionStatus>> {
+    private static class CommitCoordinationTask implements Callable<Void> {
 
         private final DOMDataWriteTransaction tx;
         private final Iterable<DOMStoreThreePhaseCommitCohort> cohorts;
@@ -158,12 +154,13 @@ public class DOMDataCommitCoordinatorImpl implements DOMDataCommitExecutor {
         }
 
         @Override
-        public RpcResult<TransactionStatus> call() throws TransactionCommitFailedException {
+        public Void call() throws TransactionCommitFailedException {
 
             try {
                 canCommitBlocking();
                 preCommitBlocking();
-                return commitBlocking();
+                commitBlocking();
+                return null;
             } catch (TransactionCommitFailedException e) {
                 LOG.warn("Tx: {} Error during phase {}, starting Abort", tx.getIdentifier(), currentPhase, e);
                 abortBlocking(e);
@@ -219,9 +216,8 @@ public class DOMDataCommitCoordinatorImpl implements DOMDataCommitExecutor {
          *             If one of cohorts failed preCommit
          *
          */
-        private RpcResult<TransactionStatus> commitBlocking() throws TransactionCommitFailedException {
+        private void commitBlocking() throws TransactionCommitFailedException {
             commitAll().checkedGet();
-            return Rpcs.getRpcResult(true, TransactionStatus.COMMITED, Collections.<RpcError> emptySet());
         }
 
         /**
index 811d4d88394fa3a51da6facbd1fc00dff6e61cfe..5ce9241dd2943399ddac9a9d3d9cb7d9bb2c6c1d 100644 (file)
@@ -6,10 +6,7 @@
  */
 package org.opendaylight.controller.md.sal.dom.broker.impl;
 
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.FutureCallback;
 
@@ -22,7 +19,7 @@ import com.google.common.util.concurrent.FutureCallback;
  * callback is invoked with associated transaction and throwable is invoked on listener.
  *
  */
-class DOMDataCommitErrorInvoker implements FutureCallback<RpcResult<TransactionStatus>> {
+class DOMDataCommitErrorInvoker implements FutureCallback<Void> {
 
     private final DOMDataWriteTransaction tx;
     private final DOMDataCommitErrorListener listener;
@@ -46,7 +43,7 @@ class DOMDataCommitErrorInvoker implements FutureCallback<RpcResult<TransactionS
     }
 
     @Override
-    public void onSuccess(RpcResult<TransactionStatus> result) {
+    public void onSuccess(Void result) {
         // NOOP
     }
 }
\ No newline at end of file
index 2050d148a8a9638bd562b81d1b2f2a5374f8f4c9..234758ca75413e3381cf5b71fd67c2e2f41e815a 100644 (file)
@@ -7,13 +7,11 @@
  */
 package org.opendaylight.controller.md.sal.dom.broker.impl;
 
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
 import com.google.common.base.Optional;
-import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.CheckedFuture;
 
 /**
  * Executor of Three Phase Commit coordination for
@@ -40,12 +38,12 @@ interface DOMDataCommitExecutor {
      *            subtransactoins.
      * @param listener
      *            Error listener which should be notified if transaction failed.
-     * @return ListenableFuture which contains RpcResult with
-     *         {@link TransactionStatus#COMMITED} if commit coordination on
-     *         cohorts finished successfully.
+     * @return a CheckedFuture. if commit coordination on cohorts finished successfully,
+     *         nothing is returned from the Future, On failure,
+     *         the Future fails with a {@link TransactionCommitFailedException}.
      *
      */
-    ListenableFuture<RpcResult<TransactionStatus>> submit(DOMDataWriteTransaction tx,
+    CheckedFuture<Void,TransactionCommitFailedException> submit(DOMDataWriteTransaction tx,
             Iterable<DOMStoreThreePhaseCommitCohort> cohort, Optional<DOMDataCommitErrorListener> listener);
 
 }
index 4906b6e84df9c9b84516c9e958d146f15d9766af..2f2b6e508a198f013f94892ce2c446cc1bb27955 100644 (file)
@@ -7,12 +7,10 @@
  */
 package org.opendaylight.controller.md.sal.dom.broker.impl;
 
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
-import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.CheckedFuture;
 
 /**
  *
@@ -23,10 +21,10 @@ import com.google.common.util.concurrent.ListenableFuture;
 public interface DOMDataCommitImplementation {
 
     /**
-     * User-supplied implementation of {@link DOMDataWriteTransaction#commit()}
+     * User-supplied implementation of {@link DOMDataWriteTransaction#submit()}
      * for transaction.
      *
-     * Callback invoked when {@link DOMDataWriteTransaction#commit()} is invoked
+     * Callback invoked when {@link DOMDataWriteTransaction#submit()} is invoked
      * on transaction created by this factory.
      *
      * @param transaction
@@ -37,7 +35,7 @@ public interface DOMDataCommitImplementation {
      *            commited transaction.
      *
      */
-    ListenableFuture<RpcResult<TransactionStatus>> commit(final DOMDataWriteTransaction transaction,
+    CheckedFuture<Void,TransactionCommitFailedException> submit(final DOMDataWriteTransaction transaction,
             final Iterable<DOMStoreThreePhaseCommitCohort> cohorts);
 }
 
index f207783c29f7820e5e472b13359d90f8b92f39db..c8edcbc6e2ef1dcf50e6b644da69c0224a62c140 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.md.sal.dom.broker.impl;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.base.Optional;
@@ -22,7 +22,7 @@ import com.google.common.util.concurrent.ListenableFuture;
  * Read Only Transaction, which is composed of several
  * {@link DOMStoreReadTransaction} transactions. Subtransaction is selected by
  * {@link LogicalDatastoreType} type parameter in
- * {@link #read(LogicalDatastoreType, InstanceIdentifier)}.
+ * {@link #read(LogicalDatastoreType, YangInstanceIdentifier)}.
  */
 class DOMForwardedReadOnlyTransaction extends
         AbstractDOMForwardedCompositeTransaction<LogicalDatastoreType, DOMStoreReadTransaction> implements
@@ -35,7 +35,7 @@ class DOMForwardedReadOnlyTransaction extends
 
     @Override
     public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final LogicalDatastoreType store,
-            final InstanceIdentifier path) {
+            final YangInstanceIdentifier path) {
         return getSubtransaction(store).read(path);
     }
 
index f5b96e27f5724be29a7bf844b508cbe6d51117cb..e6521b237727f10a8a1ccef376da0f13c0d61af9 100644 (file)
@@ -9,7 +9,7 @@
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.base.Optional;
@@ -23,13 +23,13 @@ import com.google.common.util.concurrent.ListenableFuture;
  * {@link LogicalDatastoreType} type parameter in:
  *
  * <ul>
- * <li>{@link #read(LogicalDatastoreType, InstanceIdentifier)}
- * <li>{@link #put(LogicalDatastoreType, InstanceIdentifier, NormalizedNode)}
- * <li>{@link #delete(LogicalDatastoreType, InstanceIdentifier)}
- * <li>{@link #merge(LogicalDatastoreType, InstanceIdentifier, NormalizedNode)}
+ * <li>{@link #read(LogicalDatastoreType, YangInstanceIdentifier)}
+ * <li>{@link #put(LogicalDatastoreType, YangInstanceIdentifier, NormalizedNode)}
+ * <li>{@link #delete(LogicalDatastoreType, YangInstanceIdentifier)}
+ * <li>{@link #merge(LogicalDatastoreType, YangInstanceIdentifier, NormalizedNode)}
  * </ul>
  * {@link #commit()} will result in invocation of
- * {@link DOMDataCommitImplementation#commit(org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction, Iterable)}
+ * {@link DOMDataCommitImplementation#submit(org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction, Iterable)}
  * invocation with all {@link org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort} for underlying
  * transactions.
  *
@@ -46,7 +46,7 @@ class DOMForwardedReadWriteTransaction extends DOMForwardedWriteTransaction<DOMS
 
     @Override
     public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final LogicalDatastoreType store,
-            final InstanceIdentifier path) {
+            final YangInstanceIdentifier path) {
         return getSubtransaction(store).read(path);
     }
 }
\ No newline at end of file
index f791522a2a77214e9a233f966801fac096948618..5d4ad4d803ac90d75c3769b76ef5133e6283cf17 100644 (file)
@@ -13,16 +13,19 @@ import javax.annotation.concurrent.GuardedBy;
 
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
 import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.ListenableFuture;
 
 /**
@@ -33,13 +36,13 @@ import com.google.common.util.concurrent.ListenableFuture;
  * {@link LogicalDatastoreType} type parameter in:
  *
  * <ul>
- * <li>{@link #put(LogicalDatastoreType, InstanceIdentifier, NormalizedNode)}
- * <li>{@link #delete(LogicalDatastoreType, InstanceIdentifier)}
- * <li>{@link #merge(LogicalDatastoreType, InstanceIdentifier, NormalizedNode)}
+ * <li>{@link #put(LogicalDatastoreType, YangInstanceIdentifier, NormalizedNode)}
+ * <li>{@link #delete(LogicalDatastoreType, YangInstanceIdentifier)}
+ * <li>{@link #merge(LogicalDatastoreType, YangInstanceIdentifier, NormalizedNode)}
  * </ul>
  * <p>
  * {@link #commit()} will result in invocation of
- * {@link DOMDataCommitImplementation#commit(org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction, Iterable)}
+ * {@link DOMDataCommitImplementation#submit(org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction, Iterable)}
  * invocation with all {@link org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort} for underlying
  * transactions.
  *
@@ -74,7 +77,7 @@ class DOMForwardedWriteTransaction<T extends DOMStoreWriteTransaction> extends
      *
      */
     @GuardedBy("this")
-    private volatile ListenableFuture<RpcResult<TransactionStatus>> commitFuture;
+    private volatile CheckedFuture<Void, TransactionCommitFailedException> commitFuture;
 
     protected DOMForwardedWriteTransaction(final Object identifier,
             final ImmutableMap<LogicalDatastoreType, T> backingTxs, final DOMDataCommitImplementation commitImpl) {
@@ -83,19 +86,19 @@ class DOMForwardedWriteTransaction<T extends DOMStoreWriteTransaction> extends
     }
 
     @Override
-    public void put(final LogicalDatastoreType store, final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
+    public void put(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
         checkNotReady();
         getSubtransaction(store).write(path, data);
     }
 
     @Override
-    public void delete(final LogicalDatastoreType store, final InstanceIdentifier path) {
+    public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
         checkNotReady();
         getSubtransaction(store).delete(path);
     }
 
     @Override
-    public void merge(final LogicalDatastoreType store, final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
+    public void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
         checkNotReady();
         getSubtransaction(store).merge(path, data);
     }
@@ -119,6 +122,11 @@ class DOMForwardedWriteTransaction<T extends DOMStoreWriteTransaction> extends
 
     @Override
     public synchronized ListenableFuture<RpcResult<TransactionStatus>> commit() {
+        return AbstractDataTransaction.convertToLegacyCommitFuture(submit());
+    }
+
+    @Override
+    public CheckedFuture<Void,TransactionCommitFailedException> submit() {
         checkNotReady();
 
         ImmutableList.Builder<DOMStoreThreePhaseCommitCohort> cohortsBuilder = ImmutableList.builder();
@@ -126,7 +134,7 @@ class DOMForwardedWriteTransaction<T extends DOMStoreWriteTransaction> extends
             cohortsBuilder.add(subTx.ready());
         }
         ImmutableList<DOMStoreThreePhaseCommitCohort> cohorts = cohortsBuilder.build();
-        commitFuture = commitImpl.commit(this, cohorts);
+        commitFuture = commitImpl.submit(this, cohorts);
 
         /*
          *We remove reference to Commit Implementation in order
@@ -148,5 +156,4 @@ class DOMForwardedWriteTransaction<T extends DOMStoreWriteTransaction> extends
     private void checkNotCommited() {
         checkState(commitFuture == null, "Transaction was already submited.");
     }
-
 }
\ No newline at end of file
index 5b34fba69ac1b0eaebabaf8a82c801082eacc864..e8f8da53c90dd7ff1cafd2f96f50cc2072a5c432 100644 (file)
@@ -1,5 +1,7 @@
 package org.opendaylight.controller.md.sal.dom.broker.impl.compat;
 
+import javax.annotation.concurrent.ThreadSafe;
+
 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;
@@ -11,30 +13,30 @@ import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
 import org.opendaylight.controller.sal.core.api.data.DataProviderService;
 import org.opendaylight.controller.sal.core.api.data.DataValidator;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener;
 
-public class BackwardsCompatibleDataBroker implements DataProviderService, SchemaContextListener {
+@ThreadSafe
+public class BackwardsCompatibleDataBroker implements DataProviderService {
 
     private final DOMDataBroker backingBroker;
-    private DataNormalizer normalizer;
+    private volatile DataNormalizer normalizer;
+    private final ListenerRegistration<SchemaServiceListener> schemaReg;
 
-    public BackwardsCompatibleDataBroker(final DOMDataBroker newBiDataImpl) {
+    public BackwardsCompatibleDataBroker(final DOMDataBroker newBiDataImpl, final SchemaService schemaService) {
         backingBroker = newBiDataImpl;
+        schemaReg = schemaService.registerSchemaServiceListener(new SchemaListener());
     }
 
     @Override
-    public void onGlobalContextUpdated(final SchemaContext ctx) {
-        normalizer = new DataNormalizer(ctx);
-    }
-
-    @Override
-    public CompositeNode readConfigurationData(final InstanceIdentifier legacyPath) {
+    public CompositeNode readConfigurationData(final YangInstanceIdentifier legacyPath) {
         final BackwardsCompatibleTransaction<?> tx = BackwardsCompatibleTransaction.readOnlyTransaction(backingBroker.newReadOnlyTransaction(),normalizer);
         try {
             return tx.readConfigurationData(legacyPath);
@@ -44,7 +46,7 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem
     }
 
     @Override
-    public CompositeNode readOperationalData(final InstanceIdentifier legacyPath) {
+    public CompositeNode readOperationalData(final YangInstanceIdentifier legacyPath) {
         final BackwardsCompatibleTransaction<?> tx = BackwardsCompatibleTransaction.readOnlyTransaction(backingBroker.newReadOnlyTransaction(),normalizer);
         try {
             return tx.readOperationalData(legacyPath);
@@ -59,9 +61,9 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem
     }
 
     @Override
-    public ListenerRegistration<DataChangeListener> registerDataChangeListener(final InstanceIdentifier legacyPath,
+    public ListenerRegistration<DataChangeListener> registerDataChangeListener(final YangInstanceIdentifier legacyPath,
             final DataChangeListener listener) {
-        final InstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
+        final YangInstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
 
         final TranslatingListenerInvoker translatingCfgListener =
                 TranslatingListenerInvoker.createConfig(listener, normalizer);
@@ -75,10 +77,10 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem
     }
 
     @Override
-    public Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> registerCommitHandler(
-            final InstanceIdentifier path, final DataCommitHandler<InstanceIdentifier, CompositeNode> commitHandler) {
+    public Registration registerCommitHandler(
+            final YangInstanceIdentifier path, final DataCommitHandler<YangInstanceIdentifier, CompositeNode> commitHandler) {
         // FIXME Do real forwarding
-        return new AbstractObjectRegistration<DataCommitHandler<InstanceIdentifier,CompositeNode>>(commitHandler) {
+        return new AbstractObjectRegistration<DataCommitHandler<YangInstanceIdentifier,CompositeNode>>(commitHandler) {
             @Override
             protected void removeRegistration() {
                 // NOOP
@@ -87,8 +89,8 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem
     }
 
     @Override
-    public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>>> registerCommitHandlerListener(
-            final RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>> commitHandlerListener) {
+    public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<YangInstanceIdentifier, CompositeNode>>> registerCommitHandlerListener(
+            final RegistrationListener<DataCommitHandlerRegistration<YangInstanceIdentifier, CompositeNode>> commitHandlerListener) {
         return null;
     }
 
@@ -115,14 +117,14 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem
     }
 
     @Override
-    public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerConfigurationReader(
-            final InstanceIdentifier path, final DataReader<InstanceIdentifier, CompositeNode> reader) {
+    public Registration registerConfigurationReader(
+            final YangInstanceIdentifier path, final DataReader<YangInstanceIdentifier, CompositeNode> reader) {
         throw new UnsupportedOperationException("Data Reader contract is not supported.");
     }
 
     @Override
-    public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerOperationalReader(
-            final InstanceIdentifier path, final DataReader<InstanceIdentifier, CompositeNode> reader) {
+    public Registration registerOperationalReader(
+            final YangInstanceIdentifier path, final DataReader<YangInstanceIdentifier, CompositeNode> reader) {
         throw new UnsupportedOperationException("Data Reader contract is not supported.");
     }
 
@@ -148,4 +150,13 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem
             return listener;
         }
     }
+
+    private class SchemaListener implements SchemaContextListener {
+
+        @Override
+        public void onGlobalContextUpdated(final SchemaContext ctx) {
+            normalizer = new DataNormalizer(ctx);
+        }
+
+    }
 }
index b3fb7b6da8be09d67c0b7244f50f99c093a8173b..70baaae33939c59d4f1cf4336aed30c29b48826a 100644 (file)
@@ -21,6 +21,7 @@ import java.util.concurrent.Future;
 
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
@@ -32,8 +33,8 @@ import org.opendaylight.yangtools.concepts.Delegator;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 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.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -43,7 +44,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.ListenableFuture;
 
 public abstract class BackwardsCompatibleTransaction<T extends DOMDataReadTransaction> implements
-        DataModificationTransaction, Delegator<T> {
+DataModificationTransaction, Delegator<T> {
 
     private static final Logger LOG = LoggerFactory.getLogger(BackwardsCompatibleTransaction.class);
 
@@ -89,9 +90,9 @@ public abstract class BackwardsCompatibleTransaction<T extends DOMDataReadTransa
     };
 
     @Override
-    public CompositeNode readConfigurationData(final InstanceIdentifier legacyPath) {
+    public CompositeNode readConfigurationData(final YangInstanceIdentifier legacyPath) {
 
-        InstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
+        YangInstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
 
         ListenableFuture<Optional<NormalizedNode<?, ?>>> normalizedData = asyncTx.read(
                 LogicalDatastoreType.CONFIGURATION, normalizedPath);
@@ -104,8 +105,8 @@ public abstract class BackwardsCompatibleTransaction<T extends DOMDataReadTransa
     }
 
     @Override
-    public CompositeNode readOperationalData(final InstanceIdentifier legacyPath) {
-        InstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
+    public CompositeNode readOperationalData(final YangInstanceIdentifier legacyPath) {
+        YangInstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
 
         ListenableFuture<Optional<NormalizedNode<?, ?>>> normalizedData = asyncTx.read(
                 LogicalDatastoreType.OPERATIONAL, normalizedPath);
@@ -123,62 +124,62 @@ public abstract class BackwardsCompatibleTransaction<T extends DOMDataReadTransa
     }
 
     @Override
-    public Map<InstanceIdentifier, CompositeNode> getCreatedConfigurationData() {
+    public Map<YangInstanceIdentifier, CompositeNode> getCreatedConfigurationData() {
         return Collections.emptyMap();
     }
 
     @Override
-    public Map<InstanceIdentifier, CompositeNode> getCreatedOperationalData() {
+    public Map<YangInstanceIdentifier, CompositeNode> getCreatedOperationalData() {
         return Collections.emptyMap();
     }
 
     @Override
-    public Map<InstanceIdentifier, CompositeNode> getOriginalConfigurationData() {
+    public Map<YangInstanceIdentifier, CompositeNode> getOriginalConfigurationData() {
         return Collections.emptyMap();
     }
 
     @Override
-    public Map<InstanceIdentifier, CompositeNode> getOriginalOperationalData() {
+    public Map<YangInstanceIdentifier, CompositeNode> getOriginalOperationalData() {
         return Collections.emptyMap();
     }
 
     @Override
-    public Set<InstanceIdentifier> getRemovedConfigurationData() {
+    public Set<YangInstanceIdentifier> getRemovedConfigurationData() {
         return Collections.emptySet();
     }
 
     @Override
-    public Set<InstanceIdentifier> getRemovedOperationalData() {
+    public Set<YangInstanceIdentifier> getRemovedOperationalData() {
         return Collections.emptySet();
     }
 
     @Override
-    public Map<InstanceIdentifier, CompositeNode> getUpdatedConfigurationData() {
+    public Map<YangInstanceIdentifier, CompositeNode> getUpdatedConfigurationData() {
         return Collections.emptyMap();
     }
 
     @Override
-    public Map<InstanceIdentifier, CompositeNode> getUpdatedOperationalData() {
+    public Map<YangInstanceIdentifier, CompositeNode> getUpdatedOperationalData() {
         return Collections.emptyMap();
     }
 
     @Override
-    public void putConfigurationData(final InstanceIdentifier path, final CompositeNode data) {
+    public void putConfigurationData(final YangInstanceIdentifier path, final CompositeNode data) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public void putOperationalData(final InstanceIdentifier path, final CompositeNode data) {
+    public void putOperationalData(final YangInstanceIdentifier path, final CompositeNode data) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public void removeConfigurationData(final InstanceIdentifier path) {
+    public void removeConfigurationData(final YangInstanceIdentifier path) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public void removeOperationalData(final InstanceIdentifier path) {
+    public void removeOperationalData(final YangInstanceIdentifier path) {
         throw new UnsupportedOperationException();
     }
 
@@ -204,47 +205,47 @@ public abstract class BackwardsCompatibleTransaction<T extends DOMDataReadTransa
         public Future<RpcResult<TransactionStatus>> commit() {
             Preconditions.checkState(status == TransactionStatus.NEW);
             status = TransactionStatus.SUBMITED;
-            return getDelegate().commit();
+            return AbstractDataTransaction.convertToLegacyCommitFuture(getDelegate().submit());
         }
 
         @Override
-        public void putConfigurationData(final InstanceIdentifier legacyPath, final CompositeNode legacyData) {
+        public void putConfigurationData(final YangInstanceIdentifier legacyPath, final CompositeNode legacyData) {
             checkNotNull(legacyPath, "Path MUST NOT be null.");
             checkNotNull(legacyData, "Data for path %s MUST NOT be null",legacyData);
-            Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedData = getNormalizer().toNormalized(legacyPath, legacyData);
+            Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedData = getNormalizer().toNormalized(legacyPath, legacyData);
             putWithEnsuredParents(LogicalDatastoreType.CONFIGURATION, normalizedData.getKey(), normalizedData.getValue());
         }
 
         @Override
-        public void putOperationalData(final InstanceIdentifier legacyPath, final CompositeNode legacyData) {
+        public void putOperationalData(final YangInstanceIdentifier legacyPath, final CompositeNode legacyData) {
             checkNotNull(legacyPath, "Path MUST NOT be null.");
             checkNotNull(legacyData, "Data for path %s MUST NOT be null",legacyData);
-            Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedData = getNormalizer().toNormalized(legacyPath, legacyData);
+            Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedData = getNormalizer().toNormalized(legacyPath, legacyData);
             putWithEnsuredParents(LogicalDatastoreType.OPERATIONAL, normalizedData.getKey(), normalizedData.getValue());
         }
 
-        private void putWithEnsuredParents(final LogicalDatastoreType store, final InstanceIdentifier normalizedPath,
+        private void putWithEnsuredParents(final LogicalDatastoreType store, final YangInstanceIdentifier normalizedPath,
                 final NormalizedNode<?, ?> normalizedData) {
 
             LOG.trace("write {}:{} ",store,normalizedPath);
             try {
-            List<PathArgument> currentArguments = new ArrayList<>();
-            DataNormalizationOperation<?> currentOp = getNormalizer().getRootOperation();
-            Iterator<PathArgument> iterator = normalizedPath.getPath().iterator();
-            while(iterator.hasNext()) {
-                PathArgument currentArg = iterator.next();
-                try {
-                    currentOp = currentOp.getChild(currentArg);
-                } catch (DataNormalizationException e) {
-                    throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", normalizedPath), e);
+                List<PathArgument> currentArguments = new ArrayList<>();
+                DataNormalizationOperation<?> currentOp = getNormalizer().getRootOperation();
+                Iterator<PathArgument> iterator = normalizedPath.getPathArguments().iterator();
+                while(iterator.hasNext()) {
+                    PathArgument currentArg = iterator.next();
+                    try {
+                        currentOp = currentOp.getChild(currentArg);
+                    } catch (DataNormalizationException e) {
+                        throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", normalizedPath), e);
+                    }
+                    currentArguments.add(currentArg);
+                    YangInstanceIdentifier currentPath = YangInstanceIdentifier.create(currentArguments);
+                    boolean isPresent = getDelegate().read(store, currentPath).get().isPresent();
+                    if(isPresent == false && iterator.hasNext()) {
+                        getDelegate().merge(store, currentPath, currentOp.createDefault(currentArg));
+                    }
                 }
-                currentArguments.add(currentArg);
-                InstanceIdentifier currentPath = new InstanceIdentifier(currentArguments);
-                boolean isPresent = getDelegate().read(store, currentPath).get().isPresent();
-                if(isPresent == false && iterator.hasNext()) {
-                    getDelegate().merge(store, currentPath, currentOp.createDefault(currentArg));
-                }
-            }
             } catch (InterruptedException | ExecutionException e) {
                 LOG.error("Exception durring read.",e);
             }
@@ -253,13 +254,13 @@ public abstract class BackwardsCompatibleTransaction<T extends DOMDataReadTransa
         }
 
         @Override
-        public void removeConfigurationData(final InstanceIdentifier legacyPath) {
+        public void removeConfigurationData(final YangInstanceIdentifier legacyPath) {
             checkNotNull(legacyPath, "Path MUST NOT be null.");
             getDelegate().delete(LogicalDatastoreType.CONFIGURATION, getNormalizer().toNormalized(legacyPath));
         }
 
         @Override
-        public void removeOperationalData(final InstanceIdentifier legacyPath) {
+        public void removeOperationalData(final YangInstanceIdentifier legacyPath) {
             checkNotNull(legacyPath, "Path MUST NOT be null.");
             getDelegate().delete(LogicalDatastoreType.OPERATIONAL, getNormalizer().toNormalized(legacyPath));
         }
index 3de07fc2abee209f0bbab84e822614604aea4bc9..d6d79cd624ae05ae178eaf67228525cfe4c80f43 100644 (file)
@@ -17,64 +17,64 @@ import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.collect.Maps;
 
 public abstract class TranslatingDataChangeEvent implements
-DataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
+DataChangeEvent<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> {
 
     private TranslatingDataChangeEvent() {
     }
 
-    public static DataChangeEvent<InstanceIdentifier, CompositeNode> createOperational(
-            final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> change, final DataNormalizer normalizer) {
+    public static DataChangeEvent<YangInstanceIdentifier, CompositeNode> createOperational(
+            final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change, final DataNormalizer normalizer) {
         return new OperationalChangeEvent(change, normalizer);
     }
 
-    public static DataChangeEvent<InstanceIdentifier, CompositeNode> createConfiguration(
-            final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> change, final DataNormalizer normalizer) {
+    public static DataChangeEvent<YangInstanceIdentifier, CompositeNode> createConfiguration(
+            final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change, final DataNormalizer normalizer) {
         return new ConfigurationChangeEvent(change, normalizer);
     }
 
     @Override
-    public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getCreatedOperationalData() {
+    public Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> getCreatedOperationalData() {
         return Collections.emptyMap();
     }
 
     @Override
-    public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getCreatedConfigurationData() {
+    public Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> getCreatedConfigurationData() {
         return Collections.emptyMap();
     }
 
     @Override
-    public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getUpdatedOperationalData() {
+    public Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> getUpdatedOperationalData() {
         return Collections.emptyMap();
     }
 
     @Override
-    public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getUpdatedConfigurationData() {
+    public Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> getUpdatedConfigurationData() {
         return Collections.emptyMap();
     }
 
     @Override
-    public Set<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> getRemovedConfigurationData() {
+    public Set<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier> getRemovedConfigurationData() {
         return Collections.emptySet();
     }
 
     @Override
-    public Set<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> getRemovedOperationalData() {
+    public Set<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier> getRemovedOperationalData() {
         return Collections.emptySet();
     }
 
     @Override
-    public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getOriginalConfigurationData() {
+    public Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> getOriginalConfigurationData() {
         return Collections.emptyMap();
     }
 
     @Override
-    public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getOriginalOperationalData() {
+    public Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> getOriginalOperationalData() {
         return Collections.emptyMap();
     }
 
@@ -100,24 +100,24 @@ DataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, Com
 
     private final static class OperationalChangeEvent extends TranslatingDataChangeEvent {
 
-        private final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> delegate;
+        private final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> delegate;
         private final DataNormalizer normalizer;
-        private Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> updatedCache;
+        private Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> updatedCache;
 
-        public OperationalChangeEvent(final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> change,
+        public OperationalChangeEvent(final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change,
                 final DataNormalizer normalizer) {
             this.delegate = change;
             this.normalizer = normalizer;
         }
 
         @Override
-        public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getCreatedOperationalData() {
+        public Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> getCreatedOperationalData() {
             return transformToLegacy(normalizer, delegate.getCreatedData());
         }
 
 
         @Override
-        public Set<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> getRemovedOperationalData() {
+        public Set<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier> getRemovedOperationalData() {
             return delegate.getRemovedPaths();
         }
 
@@ -134,16 +134,16 @@ DataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, Com
         }
 
         @Override
-        public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getOriginalOperationalData() {
+        public Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> getOriginalOperationalData() {
             return transformToLegacy(normalizer, delegate.getOriginalData());
         }
 
         @Override
-        public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getUpdatedOperationalData() {
+        public Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> getUpdatedOperationalData() {
             if(updatedCache == null) {
-                final Map<InstanceIdentifier, CompositeNode> updated = transformToLegacy(normalizer, delegate.getUpdatedData());
-                final Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> created = getCreatedConfigurationData();
-                final HashMap<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> updatedComposite = new HashMap<>(created.size() + updated.size());
+                final Map<YangInstanceIdentifier, CompositeNode> updated = transformToLegacy(normalizer, delegate.getUpdatedData());
+                final Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> created = getCreatedConfigurationData();
+                final HashMap<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> updatedComposite = new HashMap<>(created.size() + updated.size());
                 updatedComposite.putAll(created);
                 updatedComposite.putAll(updated);
                 updatedCache = Collections.unmodifiableMap(updatedComposite);
@@ -158,10 +158,10 @@ DataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, Com
 
     }
 
-    private static Map<InstanceIdentifier, CompositeNode> transformToLegacy(final DataNormalizer normalizer, final Map<InstanceIdentifier, ? extends NormalizedNode<?, ?>> nodes) {
-        final Map<InstanceIdentifier, CompositeNode> legacy = Maps.newHashMap();
+    private static Map<YangInstanceIdentifier, CompositeNode> transformToLegacy(final DataNormalizer normalizer, final Map<YangInstanceIdentifier, ? extends NormalizedNode<?, ?>> nodes) {
+        final Map<YangInstanceIdentifier, CompositeNode> legacy = Maps.newHashMap();
 
-        for (final Map.Entry<InstanceIdentifier, ? extends NormalizedNode<?, ?>> entry : nodes.entrySet()) {
+        for (final Map.Entry<YangInstanceIdentifier, ? extends NormalizedNode<?, ?>> entry : nodes.entrySet()) {
             try {
                 legacy.put(normalizer.toLegacy(entry.getKey()), normalizer.toLegacy(entry.getKey(), entry.getValue()));
             } catch (final DataNormalizationException e) {
@@ -173,24 +173,24 @@ DataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, Com
 
     private final static class ConfigurationChangeEvent extends TranslatingDataChangeEvent {
 
-        private final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> delegate;
+        private final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> delegate;
         private final DataNormalizer normalizer;
-        private Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> updatedCache;
+        private Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> updatedCache;
 
-        public ConfigurationChangeEvent(final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> change,
+        public ConfigurationChangeEvent(final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change,
                 final DataNormalizer normalizer) {
             this.delegate = change;
             this.normalizer = normalizer;
         }
 
         @Override
-        public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getCreatedConfigurationData() {
+        public Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> getCreatedConfigurationData() {
             return transformToLegacy(normalizer, delegate.getCreatedData());
         }
 
 
         @Override
-        public Set<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> getRemovedConfigurationData() {
+        public Set<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier> getRemovedConfigurationData() {
             return delegate.getRemovedPaths();
         }
 
@@ -207,16 +207,16 @@ DataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, Com
         }
 
         @Override
-        public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getOriginalConfigurationData() {
+        public Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> getOriginalConfigurationData() {
             return transformToLegacy(normalizer, delegate.getOriginalData());
         }
 
         @Override
-        public Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getUpdatedConfigurationData() {
+        public Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> getUpdatedConfigurationData() {
             if(updatedCache == null) {
-                final Map<InstanceIdentifier, CompositeNode> updated = transformToLegacy(normalizer, delegate.getUpdatedData());
-                final Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> created = getCreatedConfigurationData();
-                final HashMap<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> updatedComposite = new HashMap<>(created.size() + updated.size());
+                final Map<YangInstanceIdentifier, CompositeNode> updated = transformToLegacy(normalizer, delegate.getUpdatedData());
+                final Map<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> created = getCreatedConfigurationData();
+                final HashMap<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> updatedComposite = new HashMap<>(created.size() + updated.size());
                 updatedComposite.putAll(created);
                 updatedComposite.putAll(updated);
                 updatedCache = Collections.unmodifiableMap(updatedComposite);
index 1ce252df98ca4e030ec4fdfc43dd5004a432d54a..b9504e72685f92f401173030af658d34b1982dcf 100644 (file)
@@ -18,7 +18,7 @@ import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
 import org.opendaylight.yangtools.concepts.Delegator;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 abstract class TranslatingListenerInvoker implements AutoCloseable, DOMDataChangeListener, Delegator<DataChangeListener> {
@@ -41,19 +41,19 @@ abstract class TranslatingListenerInvoker implements AutoCloseable, DOMDataChang
     }
 
     @Override
-    public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> normalizedChange) {
+    public void onDataChanged(final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedChange) {
         delegate.onDataChanged(getLegacyEvent(normalizer, normalizedChange));
     }
 
-    abstract DataChangeEvent<InstanceIdentifier, CompositeNode> getLegacyEvent(final DataNormalizer normalizer,
-                                                                               final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> normalizedChange);
+    abstract DataChangeEvent<YangInstanceIdentifier, CompositeNode> getLegacyEvent(final DataNormalizer normalizer,
+                                                                               final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedChange);
 
     @Override
     public DataChangeListener getDelegate() {
         return delegate;
     }
 
-    abstract void register(final DOMDataBroker backingBroker, final InstanceIdentifier normalizedPath);
+    abstract void register(final DOMDataBroker backingBroker, final YangInstanceIdentifier normalizedPath);
 
     @Override
     public void close() {
@@ -68,12 +68,12 @@ abstract class TranslatingListenerInvoker implements AutoCloseable, DOMDataChang
             super(listener, normalizer);
         }
 
-        DataChangeEvent<InstanceIdentifier, CompositeNode> getLegacyEvent(final DataNormalizer normalizer, final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> normalizedChange) {
+        DataChangeEvent<YangInstanceIdentifier, CompositeNode> getLegacyEvent(final DataNormalizer normalizer, final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedChange) {
             return TranslatingDataChangeEvent.createConfiguration(normalizedChange, normalizer);
         }
 
         @Override
-        void register(final DOMDataBroker backingBroker, final InstanceIdentifier normalizedPath) {
+        void register(final DOMDataBroker backingBroker, final YangInstanceIdentifier normalizedPath) {
             reg = backingBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, normalizedPath, this,
                     AsyncDataBroker.DataChangeScope.SUBTREE);
         }
@@ -85,12 +85,12 @@ abstract class TranslatingListenerInvoker implements AutoCloseable, DOMDataChang
             super(listener, normalizer);
         }
 
-        DataChangeEvent<InstanceIdentifier, CompositeNode> getLegacyEvent(final DataNormalizer normalizer, final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> normalizedChange) {
+        DataChangeEvent<YangInstanceIdentifier, CompositeNode> getLegacyEvent(final DataNormalizer normalizer, final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedChange) {
             return TranslatingDataChangeEvent.createOperational(normalizedChange, normalizer);
         }
 
         @Override
-        void register(final DOMDataBroker backingBroker, final InstanceIdentifier normalizedPath) {
+        void register(final DOMDataBroker backingBroker, final YangInstanceIdentifier normalizedPath) {
             reg = backingBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, normalizedPath, this,
                     AsyncDataBroker.DataChangeScope.SUBTREE);
         }
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/mount/DOMMountPointServiceImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/mount/DOMMountPointServiceImpl.java
new file mode 100644 (file)
index 0000000..4165066
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+
+package org.opendaylight.controller.md.sal.dom.broker.impl.mount;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.MutableClassToInstanceMap;
+import java.util.HashMap;
+import java.util.Map;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMService;
+import org.opendaylight.controller.md.sal.dom.broker.spi.mount.SimpleDOMMountPoint;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class DOMMountPointServiceImpl implements DOMMountPointService {
+
+    private final Map<YangInstanceIdentifier, DOMMountPoint> mountPoints = new HashMap<>();
+
+    private final ListenerRegistry<MountProvisionListener> listeners = ListenerRegistry.create();
+
+    @Override
+    public Optional<DOMMountPoint> getMountPoint(final YangInstanceIdentifier path) {
+        return Optional.fromNullable(mountPoints.get(path));
+    }
+
+    @Override
+    public DOMMountPointBuilder createMountPoint(final YangInstanceIdentifier path) {
+        Preconditions.checkState(!mountPoints.containsKey(path), "Mount point already exists");
+        return new DOMMountPointBuilderImpl(path);
+    }
+
+    public void notifyMountCreated(final YangInstanceIdentifier identifier) {
+        for (final ListenerRegistration<MountProvisionListener> listener : listeners
+                .getListeners()) {
+            listener.getInstance().onMountPointCreated(identifier);
+        }
+    }
+
+    public void notifyMountRemoved(final YangInstanceIdentifier identifier) {
+        for (final ListenerRegistration<MountProvisionListener> listener : listeners
+                .getListeners()) {
+            listener.getInstance().onMountPointRemoved(identifier);
+        }
+    }
+
+    @Override
+    public ListenerRegistration<MountProvisionListener> registerProvisionListener(
+            final MountProvisionListener listener) {
+        return listeners.register(listener);
+    }
+
+    public ObjectRegistration<DOMMountPoint> registerMountPoint(final DOMMountPoint mountPoint) {
+        synchronized (mountPoints) {
+            Preconditions.checkState(!mountPoints.containsKey(mountPoint.getIdentifier()), "Mount point already exists");
+            mountPoints.put(mountPoint.getIdentifier(), mountPoint);
+        }
+        notifyMountCreated(mountPoint.getIdentifier());
+
+        return new MountRegistration(mountPoint);
+    }
+
+    public void unregisterMountPoint(final YangInstanceIdentifier mountPointId) {
+        synchronized (mountPoints) {
+            Preconditions.checkState(mountPoints.containsKey(mountPointId), "Mount point does not exist");
+            mountPoints.remove(mountPointId);
+        }
+        notifyMountRemoved(mountPointId);
+    }
+
+    public class DOMMountPointBuilderImpl implements DOMMountPointBuilder {
+
+        ClassToInstanceMap<DOMService> services = MutableClassToInstanceMap.create();
+        private SimpleDOMMountPoint mountPoint;
+        private final YangInstanceIdentifier path;
+        private SchemaContext schemaContext;
+
+        public DOMMountPointBuilderImpl(final YangInstanceIdentifier path) {
+            this.path = path;
+        }
+
+        @Override
+        public <T extends DOMService> DOMMountPointBuilder addService(final Class<T> type, final T impl) {
+            services.putInstance(type, impl);
+            return this;
+        }
+
+        @Override
+        public DOMMountPointBuilder addInitialSchemaContext(final SchemaContext ctx) {
+            schemaContext = ctx;
+            return this;
+        }
+
+        @Override
+        public ObjectRegistration<DOMMountPoint> register() {
+            Preconditions.checkState(mountPoint == null, "Mount point is already built.");
+            mountPoint = SimpleDOMMountPoint.create(path, services,schemaContext);
+            return registerMountPoint(mountPoint);
+        }
+    }
+
+    private final class MountRegistration implements ObjectRegistration<DOMMountPoint> {
+        private final DOMMountPoint mountPoint;
+
+        public MountRegistration(final DOMMountPoint mountPoint) {
+            this.mountPoint = mountPoint;
+        }
+
+        @Override
+        public DOMMountPoint getInstance() {
+            return mountPoint;
+        }
+
+        @Override
+        public void close() throws Exception {
+            unregisterMountPoint(mountPoint.getIdentifier());
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPoint.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPoint.java
new file mode 100644 (file)
index 0000000..d837d75
--- /dev/null
@@ -0,0 +1,568 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+package org.opendaylight.controller.sal.dom.broker;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.JdkFutureAdapters;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nullable;
+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.DataCommitHandlerRegistration;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.md.sal.common.impl.ListenerRegistry;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMService;
+import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.controller.md.sal.dom.broker.impl.compat.BackwardsCompatibleDataBroker;
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;
+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.RoutedRpcDefaultImplementation;
+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.RpcRoutingContext;
+import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
+import org.opendaylight.controller.sal.core.api.data.DataValidator;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+import org.opendaylight.controller.sal.dom.broker.impl.NotificationRouterImpl;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider;
+import org.opendaylight.controller.sal.dom.broker.spi.NotificationRouter;
+import org.opendaylight.controller.sal.dom.broker.util.ProxySchemaContext;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Registration;
+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.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener;
+
+public class BackwardsCompatibleMountPoint implements MountProvisionInstance, SchemaContextProvider, SchemaService {
+
+    private final DataProviderService dataReader;
+    private final DataReader<YangInstanceIdentifier,CompositeNode> readWrapper;
+
+    private final YangInstanceIdentifier mountPath;
+    private final NotificationPublishService notificationPublishService;
+    private final RpcProvisionRegistry rpcs;
+
+    private final ListenerRegistry<SchemaServiceListener> schemaListenerRegistry = new ListenerRegistry<>();
+
+    private SchemaContext schemaContext;
+
+    public BackwardsCompatibleMountPoint(final YangInstanceIdentifier path, final DOMMountPointService.DOMMountPointBuilder mountPointBuilder) {
+        this.mountPath = Preconditions.checkNotNull(path);
+        Preconditions.checkNotNull(mountPointBuilder);
+
+        dataReader = new DataBrokerImpl();
+        readWrapper = new ReadWrapper();
+        notificationPublishService = new DelgatingNotificationPublishService();
+        rpcs = new SchemaAwareRpcBroker(path.toString(), this);
+
+        mountPointBuilder.addService(DOMDataBroker.class, new BackwardsCompatibleDomStore(dataReader, this));
+        mountPointBuilder.addService(NotificationPublishService.class, notificationPublishService);
+        mountPointBuilder.addService(RpcProvisionRegistry.class, rpcs);
+
+        mountPointBuilder.addInitialSchemaContext(new ProxySchemaContext(this));
+
+        mountPointBuilder.register();
+    }
+
+    public BackwardsCompatibleMountPoint(final YangInstanceIdentifier path, final DOMMountPoint mount) {
+        this.mountPath = Preconditions.checkNotNull(path);
+        Preconditions.checkNotNull(mount);
+
+        final DOMDataBroker domBroker = getServiceWithCheck(mount, DOMDataBroker.class);
+
+        this.schemaContext = mount.getSchemaContext();
+
+        dataReader = new BackwardsCompatibleDataBroker(domBroker, this);
+
+        // Set schema context to provide it for BackwardsCompatibleDataBroker
+        if(schemaContext != null) {
+            setSchemaContext(schemaContext);
+        }
+
+        readWrapper = new ReadWrapper();
+
+        notificationPublishService = getServiceWithCheck(mount, NotificationPublishService.class);
+        rpcs = getServiceWithCheck(mount, RpcProvisionRegistry.class);
+    }
+
+    private <T extends DOMService> T getServiceWithCheck(final DOMMountPoint mount, final Class<T> type) {
+        final Optional<T> serviceOptional = mount.getService(type);
+        Preconditions.checkArgument(serviceOptional.isPresent(), "Service {} has to be set in {}. " +
+                "Cannot construct backwards compatible mount wrapper without it", type, mount);
+        return serviceOptional.get();
+    }
+
+    @Override
+    public void addModule(final Module module) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void removeModule(final Module module) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public SchemaContext getSessionContext() {
+        return getSchemaContext();
+    }
+
+    @Override
+    public SchemaContext getGlobalContext() {
+        return getSchemaContext();
+    }
+
+    @Override
+    public ListenerRegistration<SchemaServiceListener> registerSchemaServiceListener(final SchemaServiceListener listener) {
+        return schemaListenerRegistry.register(listener);
+    }
+
+    @Override
+    public void publish(final CompositeNode notification) {
+        notificationPublishService.publish(notification);
+    }
+
+    @Override
+    public ListenerRegistration<NotificationListener> addNotificationListener(final QName notification, final NotificationListener listener) {
+        return notificationPublishService.addNotificationListener(notification, listener);
+    }
+
+    // TODO Read wrapper is never used ... same in org.opendaylight.controller.sal.dom.broker.MountPointImpl
+    public DataReader<YangInstanceIdentifier, CompositeNode> getReadWrapper() {
+        return readWrapper;
+    }
+
+    @Override
+    public CompositeNode readConfigurationData(final YangInstanceIdentifier path) {
+        return dataReader.readConfigurationData(path);
+    }
+
+    @Override
+    public CompositeNode readOperationalData(final YangInstanceIdentifier path) {
+        return dataReader.readOperationalData(path);
+    }
+
+    @Override
+    public Registration registerOperationalReader(
+            final YangInstanceIdentifier path, final DataReader<YangInstanceIdentifier, CompositeNode> reader) {
+        return dataReader.registerOperationalReader(path, reader);
+    }
+
+    @Override
+    public Registration registerConfigurationReader(
+            final YangInstanceIdentifier path, final DataReader<YangInstanceIdentifier, CompositeNode> reader) {
+        return dataReader.registerConfigurationReader(path, reader);
+    }
+
+    @Override
+    public RoutedRpcRegistration addRoutedRpcImplementation(final QName rpcType, final RpcImplementation implementation) {
+        return rpcs.addRoutedRpcImplementation(rpcType, implementation);
+    }
+
+    @Override
+    public void setRoutedRpcDefaultDelegate(final RoutedRpcDefaultImplementation defaultImplementation) {
+        rpcs.setRoutedRpcDefaultDelegate(defaultImplementation);
+    }
+
+    @Override
+    public RpcRegistration addRpcImplementation(final QName rpcType, final RpcImplementation implementation)
+            throws IllegalArgumentException {
+        return rpcs.addRpcImplementation(rpcType, implementation);
+    }
+
+    @Override
+    public Set<QName> getSupportedRpcs() {
+        return rpcs.getSupportedRpcs();
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(final QName rpc, final CompositeNode input) {
+        return rpcs.invokeRpc(rpc, input);
+    }
+
+    @Override
+    public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(final RpcRegistrationListener listener) {
+        return rpcs.addRpcRegistrationListener(listener);
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<CompositeNode>> rpc(final QName type, final CompositeNode input) {
+        return rpcs.invokeRpc(type, input);
+    }
+
+    @Override
+    public DataModificationTransaction beginTransaction() {
+        return dataReader.beginTransaction();
+    }
+
+    @Override
+    public ListenerRegistration<DataChangeListener> registerDataChangeListener(final YangInstanceIdentifier path,
+            final DataChangeListener listener) {
+        return dataReader.registerDataChangeListener(path, listener);
+    }
+
+    @Override
+    public Registration registerCommitHandler(
+            final YangInstanceIdentifier path, final DataCommitHandler<YangInstanceIdentifier, CompositeNode> commitHandler) {
+        return dataReader.registerCommitHandler(path, commitHandler);
+    }
+
+    @Override
+    public void removeRefresher(final DataStoreIdentifier store, final DataRefresher refresher) {
+        // NOOP
+    }
+
+    @Override
+    public void addRefresher(final DataStoreIdentifier store, final DataRefresher refresher) {
+        // NOOP
+    }
+
+    @Override
+    public void addValidator(final DataStoreIdentifier store, final DataValidator validator) {
+        // NOOP
+    }
+    @Override
+    public void removeValidator(final DataStoreIdentifier store, final DataValidator validator) {
+        // NOOP
+    }
+
+    @Override
+    public SchemaContext getSchemaContext() {
+        return schemaContext;
+    }
+
+    @Override
+    public void setSchemaContext(final SchemaContext schemaContext) {
+        this.schemaContext = schemaContext;
+        for (ListenerRegistration<SchemaServiceListener> schemaServiceListenerListenerRegistration : schemaListenerRegistry.getListeners()) {
+            schemaServiceListenerListenerRegistration.getInstance().onGlobalContextUpdated(schemaContext);
+        }
+    }
+
+    class ReadWrapper implements DataReader<YangInstanceIdentifier, CompositeNode> {
+        private YangInstanceIdentifier shortenPath(final YangInstanceIdentifier path) {
+            YangInstanceIdentifier ret = null;
+            if(mountPath.contains(path)) {
+                final List<PathArgument> newArgs = path.getPath().subList(mountPath.getPath().size(), path.getPath().size());
+                ret = YangInstanceIdentifier.create(newArgs);
+            }
+            return ret;
+        }
+
+        @Override
+        public CompositeNode readConfigurationData(final YangInstanceIdentifier path) {
+            final YangInstanceIdentifier newPath = shortenPath(path);
+            if(newPath == null) {
+                return null;
+            }
+            return BackwardsCompatibleMountPoint.this.readConfigurationData(newPath);
+        }
+
+        @Override
+        public CompositeNode readOperationalData(final YangInstanceIdentifier path) {
+            final YangInstanceIdentifier newPath = shortenPath(path);
+            if(newPath == null) {
+                return null;
+            }
+            return BackwardsCompatibleMountPoint.this.readOperationalData(newPath);
+        }
+    }
+
+    @Override
+    public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<YangInstanceIdentifier, CompositeNode>>> registerCommitHandlerListener(
+            final RegistrationListener<DataCommitHandlerRegistration<YangInstanceIdentifier, CompositeNode>> commitHandlerListener) {
+        return dataReader.registerCommitHandlerListener(commitHandlerListener);
+    }
+
+    @Override
+    public <L extends RouteChangeListener<RpcRoutingContext, YangInstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(
+            final L listener) {
+        return rpcs.registerRouteChangeListener(listener);
+    }
+
+    @VisibleForTesting
+    static final class BackwardsCompatibleDomStore implements DOMDataBroker {
+        private final DataProviderService dataReader;
+        private final SchemaContextProvider schemaContextProvider;
+
+        public BackwardsCompatibleDomStore(final DataProviderService dataReader, final SchemaContextProvider schemaContextProvider) {
+            this.dataReader = dataReader;
+            this.schemaContextProvider = schemaContextProvider;
+        }
+
+        @Override
+        public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
+            final DataNormalizer dataNormalizer = new DataNormalizer(schemaContextProvider.getSchemaContext());
+            return new BackwardsCompatibleReadTransaction(dataReader, dataNormalizer);
+        }
+
+        @Override
+        public DOMDataWriteTransaction newWriteOnlyTransaction() {
+            final DataNormalizer dataNormalizer = new DataNormalizer(schemaContextProvider.getSchemaContext());
+            return new BackwardsCompatibleWriteTransaction(dataReader, dataNormalizer);
+        }
+
+        @Override
+        public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(final LogicalDatastoreType store, final YangInstanceIdentifier path, final DOMDataChangeListener listener, final DataChangeScope triggeringScope) {
+            throw new UnsupportedOperationException("Register data listener not supported for mount point");
+        }
+
+        @Override
+        public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
+            throw new UnsupportedOperationException("Transaction chain not supported for mount point");
+        }
+
+        @Override
+        public DOMDataReadWriteTransaction newReadWriteTransaction() {
+            final DataNormalizer dataNormalizer = new DataNormalizer(schemaContextProvider.getSchemaContext());
+            return new BackwardsCompatibleReadWriteTransaction(dataReader, dataNormalizer);
+        }
+
+        @VisibleForTesting
+        static final class BackwardsCompatibleReadTransaction implements DOMDataReadOnlyTransaction {
+            private final DataProviderService dataReader;
+            private final DataNormalizer normalizer;
+
+            public BackwardsCompatibleReadTransaction(final DataProviderService dataReader, final DataNormalizer normalizer) {
+                this.dataReader = dataReader;
+                this.normalizer = normalizer;
+            }
+
+            @Override
+            public Object getIdentifier() {
+                return this;
+            }
+
+            @Override
+            public void close() {
+                // NOOP
+            }
+
+            @Override
+            public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+
+                CompositeNode rawData = null;
+
+                switch (store) {
+                    case CONFIGURATION: {
+                        rawData = dataReader.readConfigurationData(path);
+                        break;
+                    }
+                    case OPERATIONAL: {
+                        rawData = dataReader.readOperationalData(path);
+                        break;
+                    }
+                }
+                Preconditions.checkNotNull(rawData, "Unable to read %s data on path %s", store, path);
+
+                final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalized = normalizer.toNormalized(path, rawData);
+                final Optional<NormalizedNode<?, ?>> normalizedNodeOptional = Optional.<NormalizedNode<?, ?>>fromNullable(normalized.getValue());
+                return com.google.common.util.concurrent.Futures.immediateFuture(normalizedNodeOptional);
+            }
+        }
+
+        @VisibleForTesting
+        static final class BackwardsCompatibleWriteTransaction implements DOMDataWriteTransaction {
+            private DataModificationTransaction oldTx;
+            private final DataNormalizer dataNormalizer;
+
+            public BackwardsCompatibleWriteTransaction(final DataProviderService dataReader, final DataNormalizer dataNormalizer) {
+                this.oldTx = dataReader.beginTransaction();
+                this.dataNormalizer = dataNormalizer;
+            }
+
+            @Override
+            public Object getIdentifier() {
+                return this;
+            }
+
+            @Override
+            public boolean cancel() {
+                oldTx = null;
+                return true;
+            }
+
+            @Override
+            public void put(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+                final CompositeNode legacyData = dataNormalizer.toLegacy(path, data);
+                try {
+                    final YangInstanceIdentifier legacyPath = dataNormalizer.toLegacy(path);
+
+                    switch (store) {
+                        case CONFIGURATION: {
+                            oldTx.putConfigurationData(legacyPath, legacyData);
+                            return;
+                        }
+                    }
+
+                    throw new IllegalArgumentException("Cannot put data " + path + " to datastore " + store);
+                } catch (final DataNormalizationException e) {
+                    throw new IllegalArgumentException(String.format("Cannot transform path %s to legacy format", path), e);
+                }
+            }
+
+            @Override
+            public void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+                // TODO not supported
+                throw new UnsupportedOperationException("Merge not supported for mount point");
+            }
+
+            @Override
+            public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+                try {
+                    final YangInstanceIdentifier legacyPath = dataNormalizer.toLegacy(path);
+
+                    switch (store) {
+                        case CONFIGURATION: {
+                            oldTx.removeConfigurationData(legacyPath);
+                            return;
+                        }
+                    }
+                    throw new IllegalArgumentException("Cannot delete data " + path + " from datastore " + store);
+                } catch (final DataNormalizationException e) {
+                    throw new IllegalArgumentException(String.format("Cannot transform path %s to legacy format", path), e);
+                }
+            }
+
+            @Override
+            public CheckedFuture<Void, TransactionCommitFailedException> submit() {
+                final ListenableFuture<Void> commitAsVoid = Futures.transform(commit(), new Function<RpcResult<TransactionStatus>, Void>() {
+                    @Override
+                    public Void apply(@Nullable final RpcResult<TransactionStatus> input) {
+                        return null;
+                    }
+                });
+
+                return Futures.makeChecked(commitAsVoid, new Function<Exception, TransactionCommitFailedException>() {
+                    @Override
+                    public TransactionCommitFailedException apply(@Nullable final Exception input) {
+                        return new TransactionCommitFailedException("Commit failed", input);
+                    }
+                });
+            }
+
+            @Override
+            public ListenableFuture<RpcResult<TransactionStatus>> commit() {
+                return JdkFutureAdapters.listenInPoolThread(oldTx.commit());
+            }
+        }
+
+
+        @VisibleForTesting
+        static class BackwardsCompatibleReadWriteTransaction implements DOMDataReadWriteTransaction {
+
+            private final DataProviderService dataReader;
+            private final DataNormalizer dataNormalizer;
+            private final BackwardsCompatibleWriteTransaction delegateWriteTx;
+
+            public BackwardsCompatibleReadWriteTransaction(final DataProviderService dataReader, final DataNormalizer dataNormalizer) {
+                this.dataReader = dataReader;
+                this.dataNormalizer = dataNormalizer;
+                this.delegateWriteTx = new BackwardsCompatibleWriteTransaction(dataReader, dataNormalizer);
+            }
+
+            @Override
+            public Object getIdentifier() {
+                return this;
+            }
+
+            @Override
+            public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+                return new BackwardsCompatibleReadTransaction(dataReader, dataNormalizer).read(store, path);
+            }
+
+            @Override
+            public boolean cancel() {
+                return delegateWriteTx.cancel();
+            }
+
+            @Override
+            public void put(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+                delegateWriteTx.put(store, path, data);
+            }
+
+            @Override
+            public void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+                delegateWriteTx.merge(store, path, data);
+            }
+
+            @Override
+            public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+                delegateWriteTx.delete(store, path);
+            }
+
+            @Override
+            public CheckedFuture<Void, TransactionCommitFailedException> submit() {
+                return delegateWriteTx.submit();
+            }
+
+            @Override
+            public ListenableFuture<RpcResult<TransactionStatus>> commit() {
+                return delegateWriteTx.commit();
+            }
+        }
+    }
+
+    private class DelgatingNotificationPublishService implements NotificationPublishService {
+        private final NotificationRouter notificationRouter;
+
+        public DelgatingNotificationPublishService(final NotificationRouter notificationRouter) {
+            this.notificationRouter = notificationRouter;
+        }
+
+        private DelgatingNotificationPublishService() {
+            this(new NotificationRouterImpl());
+        }
+
+        @Override
+        public void publish(final CompositeNode notification) {
+            notificationRouter.publish(notification);
+        }
+
+        @Override
+        public ListenerRegistration<NotificationListener> addNotificationListener(final QName notification, final NotificationListener listener) {
+            return notificationRouter.addNotificationListener(notification, listener);
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPointManager.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPointManager.java
new file mode 100644 (file)
index 0000000..b01db3d
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+package org.opendaylight.controller.sal.dom.broker;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.base.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionListener;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public class BackwardsCompatibleMountPointManager implements MountProvisionService, MountProvisionListener {
+
+    private final ListenerRegistry<MountProvisionListener> listeners = ListenerRegistry.create();
+    private final ConcurrentMap<YangInstanceIdentifier, MountProvisionInstance> mounts = new ConcurrentHashMap<>();
+
+    private final DOMMountPointService domMountPointService;
+
+    public BackwardsCompatibleMountPointManager(final DOMMountPointService domMountPointService) {
+        this.domMountPointService = domMountPointService;
+    }
+
+    @Override
+    public MountProvisionInstance createMountPoint(final YangInstanceIdentifier path) {
+        checkState(!mounts.containsKey(path), "Mount already created");
+        // Create mount point instance, wrap instance of new API with BackwardsCompatibleMountPoint to preserve backwards comatibility
+        final BackwardsCompatibleMountPoint mount = new BackwardsCompatibleMountPoint(path, domMountPointService.createMountPoint(path));
+        mounts.put(path, mount);
+        return mount;
+    }
+
+    public void notifyMountCreated(final YangInstanceIdentifier identifier) {
+        for (final ListenerRegistration<MountProvisionListener> listener : listeners.getListeners()) {
+            listener.getInstance().onMountPointCreated(identifier);
+        }
+    }
+
+    public void notifyMountRemoved(final YangInstanceIdentifier identifier) {
+        for (final ListenerRegistration<MountProvisionListener> listener : listeners.getListeners()) {
+            listener.getInstance().onMountPointRemoved(identifier);
+        }
+    }
+
+    @Override
+    public MountProvisionInstance createOrGetMountPoint(
+            final YangInstanceIdentifier path) {
+        final MountProvisionInstance mount = getMountPoint(path);
+        if (mount == null) {
+            return createMountPoint(path);
+        }
+        return mount;
+    }
+
+    @Override
+    public MountProvisionInstance getMountPoint(final YangInstanceIdentifier path) {
+        // If the mount point was created here, return directly
+        if(mounts.containsKey(path)) {
+            return mounts.get(path);
+        }
+
+        // If mount was created in underlying DOMMountService, wrap as MountProvisionInstance
+        final Optional<DOMMountPoint> mount = domMountPointService.getMountPoint(path);
+        if(mount.isPresent()) {
+            return new BackwardsCompatibleMountPoint(path, mount.get());
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public ListenerRegistration<MountProvisionListener> registerProvisionListener(
+            final MountProvisionListener listener) {
+        return domMountPointService.registerProvisionListener(listener);
+    }
+
+    @Override
+    public void onMountPointCreated(final YangInstanceIdentifier path) {
+        notifyMountCreated(path);
+    }
+
+    @Override
+    public void onMountPointRemoved(final YangInstanceIdentifier path) {
+            notifyMountRemoved(path);
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.java
deleted file mode 100644 (file)
index 3291afa..0000000
+++ /dev/null
@@ -1,134 +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.dom.broker;
-
-import java.util.Hashtable;
-
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.broker.impl.compat.BackwardsCompatibleDataBroker;
-import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
-import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.core.api.data.DataProviderService;
-import org.opendaylight.controller.sal.core.api.data.DataStore;
-import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
-import org.opendaylight.controller.sal.core.api.mount.MountService;
-import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter;
-import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
-import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProviders;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-public class BrokerConfigActivator implements AutoCloseable {
-
-    private static InstanceIdentifier ROOT = InstanceIdentifier.builder()
-            .toInstance();
-
-    private DataProviderService dataService;
-
-    private ServiceRegistration<DataBrokerService> dataReg = null;
-    private ServiceRegistration<DataProviderService> dataProviderReg = null;
-    private ServiceRegistration<MountService> mountReg = null;
-    private ServiceRegistration<MountProvisionService> mountProviderReg = null;
-    private SchemaService schemaService = null;
-    private ServiceRegistration<RpcProvisionRegistry> rpcProvisionRegistryReg = null;
-    private MountPointManagerImpl mountService = null;
-
-    private SchemaAwareDataStoreAdapter wrappedStore = null;
-
-    public void start(final BrokerImpl broker, final DataStore store,
-            final DOMDataBroker asyncBroker, final BundleContext context) {
-
-        final Hashtable<String, String> emptyProperties = new Hashtable<String, String>();
-        broker.setBundleContext(context);
-
-        final ServiceReference<SchemaService> serviceRef = context
-                .getServiceReference(SchemaService.class);
-        schemaService = context.<SchemaService> getService(serviceRef);
-
-        broker.setRouter(new SchemaAwareRpcBroker("/", SchemaContextProviders
-                .fromSchemaService(schemaService)));
-
-        if (asyncBroker == null) {
-            dataService = new DataBrokerImpl();
-            dataProviderReg = context.registerService(
-                    DataProviderService.class, dataService, emptyProperties);
-
-            wrappedStore = new SchemaAwareDataStoreAdapter();
-            wrappedStore.changeDelegate(store);
-            wrappedStore.setValidationEnabled(false);
-            context.registerService(SchemaServiceListener.class, wrappedStore,
-                    emptyProperties);
-
-            dataService.registerConfigurationReader(ROOT, wrappedStore);
-            dataService.registerCommitHandler(ROOT, wrappedStore);
-            dataService.registerOperationalReader(ROOT, wrappedStore);
-        } else {
-            BackwardsCompatibleDataBroker compatibleDataBroker = new BackwardsCompatibleDataBroker(
-                    asyncBroker);
-            context.registerService(SchemaServiceListener.class,
-                    compatibleDataBroker, emptyProperties);
-            dataService = compatibleDataBroker;
-        }
-
-        mountService = new MountPointManagerImpl();
-        dataReg = context.registerService(DataBrokerService.class, dataService,
-                emptyProperties);
-        mountReg = context.registerService(MountService.class, mountService,
-                emptyProperties);
-        mountProviderReg = context.registerService(MountProvisionService.class,
-                mountService, emptyProperties);
-
-        rpcProvisionRegistryReg = context
-                .registerService(RpcProvisionRegistry.class,
-                        broker.getRouter(), emptyProperties);
-    }
-
-    @Override
-    public void close() {
-
-        if (dataReg != null) {
-            dataReg.unregister();
-            dataReg = null;
-        }
-        if (dataProviderReg != null) {
-            dataProviderReg.unregister();
-            dataProviderReg = null;
-        }
-        if (mountReg != null) {
-            mountReg.unregister();
-            mountReg = null;
-        }
-        if (mountProviderReg != null) {
-            mountProviderReg.unregister();
-            mountProviderReg = null;
-        }
-        if (rpcProvisionRegistryReg != null) {
-            rpcProvisionRegistryReg.unregister();
-            rpcProvisionRegistryReg = null;
-        }
-    }
-
-    /**
-     * @return the dataService
-     */
-    public DataProviderService getDataService() {
-        return dataService;
-    }
-
-    /**
-     * @param dataService
-     *            the dataService to set
-     */
-    public void setDataService(final DataProviderService dataService) {
-        this.dataService = dataService;
-    }
-}
index e4bd0343cfcf62999d3becca52177eaf8d366bcd..a200793fea651ebb09b32bc53708d4cbbf3d67b3 100644 (file)
@@ -7,9 +7,6 @@
  */
 package org.opendaylight.controller.sal.dom.broker;
 
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.ListenableFuture;
-
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
@@ -17,22 +14,29 @@ import java.util.concurrent.Future;
 
 import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
 import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.BrokerService;
 import org.opendaylight.controller.sal.core.api.Consumer;
 import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.controller.sal.core.api.RoutedRpcDefaultImplementation;
+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.RpcRoutingContext;
+import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter;
 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.data.api.YangInstanceIdentifier;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter;
-import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
-import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.controller.sal.core.api.RpcRoutingContext;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.controller.sal.core.api.RoutedRpcDefaultImplementation;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.ImmutableClassToInstanceMap;
+import com.google.common.util.concurrent.ListenableFuture;
 
 public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable {
     private final static Logger log = LoggerFactory.getLogger(BrokerImpl.class);
@@ -43,31 +47,28 @@ public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable {
     private final Set<ProviderContextImpl> providerSessions = Collections
             .synchronizedSet(new HashSet<ProviderContextImpl>());
 
-    private BundleContext bundleContext = null;
-
     private AutoCloseable deactivator = null;
 
     private RpcRouter router = null;
 
+    private final ClassToInstanceMap<BrokerService> services;
+
+    public  BrokerImpl(final RpcRouter router,final ClassToInstanceMap<BrokerService> services) {
+        this.router = Preconditions.checkNotNull(router, "RPC Router must not be null");
+        this.services = ImmutableClassToInstanceMap.copyOf(services);
+    }
+
+
     @Override
     public ConsumerSession registerConsumer(final Consumer consumer,
             final BundleContext ctx) {
-        checkPredicates(consumer);
-        log.trace("Registering consumer {}", consumer);
-        final ConsumerContextImpl session = newSessionFor(consumer, ctx);
-        consumer.onSessionInitiated(session);
-        sessions.add(session);
-        return session;
+        return registerConsumer(consumer);
     }
 
     @Override
     public ProviderSession registerProvider(final Provider provider,
             final BundleContext ctx) {
-        checkPredicates(provider);
-        final ProviderContextImpl session = newSessionFor(provider, ctx);
-        provider.onSessionInitiated(session);
-        providerSessions.add(session);
-        return session;
+        return registerProvider(provider);
     }
 
     protected Future<RpcResult<CompositeNode>> invokeRpcAsync(final QName rpc,
@@ -79,8 +80,9 @@ public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable {
     private void checkPredicates(final Provider prov) {
         Preconditions.checkNotNull(prov, "Provider should not be null.");
         for (ProviderContextImpl session : providerSessions) {
-            if (prov.equals(session.getProvider()))
+            if (prov.equals(session.getProvider())) {
                 throw new IllegalStateException("Provider already registered");
+            }
         }
 
     }
@@ -88,23 +90,20 @@ public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable {
     private void checkPredicates(final Consumer cons) {
         Preconditions.checkNotNull(cons, "Consumer should not be null.");
         for (ConsumerContextImpl session : sessions) {
-            if (cons.equals(session.getConsumer()))
+            if (cons.equals(session.getConsumer())) {
                 throw new IllegalStateException("Consumer already registered");
+            }
         }
     }
 
     // Private Factory methods
-    private ConsumerContextImpl newSessionFor(final Consumer provider,
-            final BundleContext ctx) {
-        ConsumerContextImpl ret = new ConsumerContextImpl(provider, ctx);
-        ret.setBroker(this);
+    private ConsumerContextImpl newSessionFor(final Consumer provider) {
+        ConsumerContextImpl ret = new ConsumerContextImpl(provider, this);
         return ret;
     }
 
-    private ProviderContextImpl newSessionFor(final Provider provider,
-            final BundleContext ctx) {
-        ProviderContextImpl ret = new ProviderContextImpl(provider, ctx);
-        ret.setBroker(this);
+    private ProviderContextImpl newSessionFor(final Provider provider) {
+        ProviderContextImpl ret = new ProviderContextImpl(provider, this);
         return ret;
     }
 
@@ -148,7 +147,7 @@ public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable {
     }
 
     @Override
-    public <L extends RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(
+    public <L extends RouteChangeListener<RpcRoutingContext, YangInstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(
             final L listener) {
         return router.registerRouteChangeListener(listener);
     }
@@ -164,21 +163,6 @@ public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable {
         return router.invokeRpc(rpc, input);
     }
 
-    /**
-     * @return the bundleContext
-     */
-    public BundleContext getBundleContext() {
-        return bundleContext;
-    }
-
-    /**
-     * @param bundleContext
-     *            the bundleContext to set
-     */
-    public void setBundleContext(final BundleContext bundleContext) {
-        this.bundleContext = bundleContext;
-    }
-
     /**
      * @return the deactivator
      */
@@ -208,4 +192,30 @@ public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable {
     public void setRouter(final RpcRouter router) {
         this.router = router;
     }
+
+    protected <T extends BrokerService> Optional<T> getGlobalService(final Class<T> service) {
+        return Optional.fromNullable(services.getInstance(service));
+    }
+
+
+    @Override
+    public ConsumerSession registerConsumer(Consumer consumer) {
+        checkPredicates(consumer);
+        log.trace("Registering consumer {}", consumer);
+        final ConsumerContextImpl session = newSessionFor(consumer);
+        consumer.onSessionInitiated(session);
+        sessions.add(session);
+        return session;
+    }
+
+
+    @Override
+    public ProviderSession registerProvider(Provider provider) {
+        checkPredicates(provider);
+        final ProviderContextImpl session = newSessionFor(provider);
+        provider.onSessionInitiated(session);
+        providerSessions.add(session);
+        return session;
+    }
+
 }
index fa81bc9040849c6b198187c4d846de308bfbe685..e96b242720e88bbabe918cbde127af6eb0b3d5e8 100644 (file)
@@ -20,9 +20,9 @@ import org.opendaylight.controller.sal.dom.broker.osgi.ProxyFactory;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ClassToInstanceMap;
 import com.google.common.collect.MutableClassToInstanceMap;
 
@@ -30,41 +30,39 @@ class ConsumerContextImpl implements ConsumerSession {
 
     private final ClassToInstanceMap<BrokerService> instantiatedServices = MutableClassToInstanceMap
             .create();
-    private final BundleContext context;
     private final Consumer consumer;
 
     private BrokerImpl broker = null;
     @GuardedBy("this")
     private boolean closed = false;
 
-    public ConsumerContextImpl(final Consumer consumer, final BundleContext ctx) {
-        this.consumer = consumer;
-        this.context = ctx;
+    public ConsumerContextImpl(final Consumer provider, final BrokerImpl brokerImpl) {
+        broker = brokerImpl;
+        consumer = provider;
     }
 
     @Override
     public Future<RpcResult<CompositeNode>> rpc(final QName rpc,
             final CompositeNode input) {
+        checkNotClosed();
         return broker.invokeRpcAsync(rpc, input);
     }
 
     @Override
     public <T extends BrokerService> T getService(final Class<T> service) {
+        checkNotClosed();
         final T localProxy = instantiatedServices.getInstance(service);
         if (localProxy != null) {
             return localProxy;
         }
-        final ServiceReference<T> serviceRef = context
-                .getServiceReference(service);
-        if (serviceRef == null) {
-            return null;
-        }
-        final T serviceImpl = context.getService(serviceRef);
-        final T ret = ProxyFactory.createProxy(serviceRef, serviceImpl);
-        if (ret != null) {
+        final Optional<T> serviceImpl = broker.getGlobalService(service);
+        if(serviceImpl.isPresent()) {
+            final T ret = ProxyFactory.createProxy(null,serviceImpl.get());
             instantiatedServices.putInstance(service, ret);
+            return ret;
+        } else {
+            return null;
         }
-        return ret;
     }
 
     @Override
@@ -83,6 +81,7 @@ class ConsumerContextImpl implements ConsumerSession {
             }
         }
         broker.consumerSessionClosed(this);
+        broker = null;
     }
 
     @Override
@@ -93,22 +92,19 @@ class ConsumerContextImpl implements ConsumerSession {
     /**
      * @return the broker
      */
-    public BrokerImpl getBroker() {
+    protected final  BrokerImpl getBrokerChecked() {
+        checkNotClosed();
         return broker;
     }
 
-    /**
-     * @param broker
-     *            the broker to set
-     */
-    public void setBroker(final BrokerImpl broker) {
-        this.broker = broker;
-    }
-
     /**
      * @return the _consumer
      */
     public Consumer getConsumer() {
         return consumer;
     }
+
+    protected final void checkNotClosed()  {
+        Preconditions.checkState(!closed, "Session is closed.");
+    }
 }
index 69f518bb32f5c57f467285f0a32056240893043b..27e351c28a05707a782be3b3e708b01d5cde60e6 100644 (file)
@@ -18,11 +18,11 @@ import org.opendaylight.controller.sal.core.api.data.DataValidator;
 import org.opendaylight.controller.sal.dom.broker.impl.DataReaderRouter;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 import com.google.common.util.concurrent.MoreExecutors;
 
-public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier, CompositeNode, DataChangeListener> implements
+public class DataBrokerImpl extends AbstractDataBroker<YangInstanceIdentifier, CompositeNode, DataChangeListener> implements
         DataProviderService, AutoCloseable {
 
     private AtomicLong nextTransaction = new AtomicLong();
@@ -45,14 +45,14 @@ public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier, Compo
     }
 
     @Override
-    public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerConfigurationReader(
-            InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+    public Registration registerConfigurationReader(
+            YangInstanceIdentifier path, DataReader<YangInstanceIdentifier, CompositeNode> reader) {
         return getDataReadRouter().registerConfigurationReader(path, reader);
     }
 
     @Override
-    public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerOperationalReader(
-            InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+    public Registration registerOperationalReader(
+            YangInstanceIdentifier path, DataReader<YangInstanceIdentifier, CompositeNode> reader) {
         return getDataReadRouter().registerOperationalReader(path, reader);
     }
 
index 65aa99deea9e70b62a0a86d6b108a10048ea1a30..f0dd5b921c7624ae985adc5cdf15bcc9546813fa 100644 (file)
@@ -13,9 +13,9 @@ import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
-public class DataTransactionImpl extends AbstractDataTransaction<InstanceIdentifier, CompositeNode>
+public class DataTransactionImpl extends AbstractDataTransaction<YangInstanceIdentifier, CompositeNode>
     implements DataModificationTransaction {
     private final ListenerRegistry<DataTransactionListener> listeners = new ListenerRegistry<DataTransactionListener>();
 
index 430963a884b4fbaa71a7c3c12d5df9356058be0c..d8174c312ab0e9622a23f17549dd841130a633ff 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.sal.dom.broker;
 
 import static com.google.common.base.Preconditions.checkState;
 
+import com.google.common.annotations.VisibleForTesting;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -48,13 +49,31 @@ public class GlobalBundleScanningSchemaServiceImpl implements SchemaContextProvi
     private final BundleContext context;
 
     private ServiceTracker<SchemaServiceListener, SchemaServiceListener> listenerTracker;
-    private BundleTracker<Iterable<Registration<URL>>> bundleTracker;
+    private BundleTracker<Iterable<Registration>> bundleTracker;
     private boolean starting = true;
+    private static GlobalBundleScanningSchemaServiceImpl instance;
 
-    public GlobalBundleScanningSchemaServiceImpl(final BundleContext context) {
+    private GlobalBundleScanningSchemaServiceImpl(final BundleContext context) {
         this.context = Preconditions.checkNotNull(context);
     }
 
+    public synchronized static GlobalBundleScanningSchemaServiceImpl createInstance(final BundleContext ctx) {
+        Preconditions.checkState(instance == null);
+        instance = new GlobalBundleScanningSchemaServiceImpl(ctx);
+        instance.start();
+        return instance;
+    }
+
+    public synchronized static GlobalBundleScanningSchemaServiceImpl getInstance() {
+        Preconditions.checkState(instance != null, "Global Instance was not instantiated");
+        return instance;
+    }
+
+    @VisibleForTesting
+    public static synchronized void destroyInstance() {
+        instance = null;
+    }
+
     public BundleContext getContext() {
         return context;
     }
@@ -96,7 +115,7 @@ public class GlobalBundleScanningSchemaServiceImpl implements SchemaContextProvi
     }
 
     @Override
-    public ListenerRegistration<SchemaServiceListener> registerSchemaServiceListener(final SchemaServiceListener listener) {
+    public synchronized ListenerRegistration<SchemaServiceListener> registerSchemaServiceListener(final SchemaServiceListener listener) {
         Optional<SchemaContext> potentialCtx = contextResolver.getSchemaContext();
         if(potentialCtx.isPresent()) {
             listener.onGlobalContextUpdated(potentialCtx.get());
@@ -116,7 +135,7 @@ public class GlobalBundleScanningSchemaServiceImpl implements SchemaContextProvi
     }
 
 
-    private void updateContext(final SchemaContext snapshot) {
+    private synchronized void updateContext(final SchemaContext snapshot) {
         Object[] services = listenerTracker.getServices();
         for (ListenerRegistration<SchemaServiceListener> listener : listeners) {
             try {
@@ -137,9 +156,9 @@ public class GlobalBundleScanningSchemaServiceImpl implements SchemaContextProvi
         }
     }
 
-    private class BundleScanner implements BundleTrackerCustomizer<Iterable<Registration<URL>>> {
+    private class BundleScanner implements BundleTrackerCustomizer<Iterable<Registration>> {
         @Override
-        public Iterable<Registration<URL>> addingBundle(final Bundle bundle, final BundleEvent event) {
+        public Iterable<Registration> addingBundle(final Bundle bundle, final BundleEvent event) {
 
             if (bundle.getBundleId() == 0) {
                 return Collections.emptyList();
@@ -150,7 +169,7 @@ public class GlobalBundleScanningSchemaServiceImpl implements SchemaContextProvi
                 return Collections.emptyList();
             }
 
-            final List<Registration<URL>> urls = new ArrayList<>();
+            final List<Registration> urls = new ArrayList<>();
             while (enumeration.hasMoreElements()) {
                 final URL u = enumeration.nextElement();
                 try {
@@ -170,7 +189,7 @@ public class GlobalBundleScanningSchemaServiceImpl implements SchemaContextProvi
         }
 
         @Override
-        public void modifiedBundle(final Bundle bundle, final BundleEvent event, final Iterable<Registration<URL>> object) {
+        public void modifiedBundle(final Bundle bundle, final BundleEvent event, final Iterable<Registration> object) {
             LOG.debug("Modified bundle {} {} {}", bundle, event, object);
         }
 
@@ -181,8 +200,8 @@ public class GlobalBundleScanningSchemaServiceImpl implements SchemaContextProvi
          */
 
         @Override
-        public synchronized void removedBundle(final Bundle bundle, final BundleEvent event, final Iterable<Registration<URL>> urls) {
-            for (Registration<URL> url : urls) {
+        public synchronized void removedBundle(final Bundle bundle, final BundleEvent event, final Iterable<Registration> urls) {
+            for (Registration url : urls) {
                 try {
                     url.close();
                 } catch (Exception e) {
@@ -194,7 +213,7 @@ public class GlobalBundleScanningSchemaServiceImpl implements SchemaContextProvi
     }
 
     @Override
-    public SchemaServiceListener addingService(final ServiceReference<SchemaServiceListener> reference) {
+    public synchronized SchemaServiceListener addingService(final ServiceReference<SchemaServiceListener> reference) {
 
         SchemaServiceListener listener = context.getService(reference);
         SchemaContext _ctxContext = getGlobalContext();
index 623bbdb19514ce15ffa0b9102959fbac77cb51d2..054c8ea851cf2e8f56e6891a40c0dd790b72e34e 100644 (file)
@@ -36,25 +36,26 @@ import org.opendaylight.yangtools.concepts.Registration;
 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.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 import com.google.common.util.concurrent.ListenableFuture;
 
+@Deprecated
 public class MountPointImpl implements MountProvisionInstance, SchemaContextProvider {
 
     private final SchemaAwareRpcBroker rpcs;
     private final DataBrokerImpl dataReader;
     private final NotificationRouter notificationRouter;
-    private final DataReader<InstanceIdentifier,CompositeNode> readWrapper;
+    private final DataReader<YangInstanceIdentifier,CompositeNode> readWrapper;
 
 
-    private final InstanceIdentifier mountPath;
+    private final YangInstanceIdentifier mountPath;
 
     private SchemaContext schemaContext;
 
-    public MountPointImpl(InstanceIdentifier path) {
+    public MountPointImpl(final YangInstanceIdentifier path) {
         this.mountPath = path;
         rpcs = new SchemaAwareRpcBroker(path.toString(),this);
         dataReader = new DataBrokerImpl();
@@ -62,58 +63,58 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
         readWrapper = new ReadWrapper();
     }
 
-    public InstanceIdentifier getMountPath() {
+    public YangInstanceIdentifier getMountPath() {
         return mountPath;
     }
 
-    public DataReader<InstanceIdentifier, CompositeNode> getReadWrapper() {
+    public DataReader<YangInstanceIdentifier, CompositeNode> getReadWrapper() {
         return readWrapper;
     }
 
     @Override
-    public void publish(CompositeNode notification) {
+    public void publish(final CompositeNode notification) {
         notificationRouter.publish(notification);
     }
 
     @Override
-    public Registration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
+    public ListenerRegistration<NotificationListener> addNotificationListener(final QName notification, final NotificationListener listener) {
         return notificationRouter.addNotificationListener(notification, listener);
     }
 
     @Override
-    public CompositeNode readConfigurationData(InstanceIdentifier path) {
+    public CompositeNode readConfigurationData(final YangInstanceIdentifier path) {
         return dataReader.readConfigurationData(path);
     }
 
     @Override
-    public CompositeNode readOperationalData(InstanceIdentifier path) {
+    public CompositeNode readOperationalData(final YangInstanceIdentifier path) {
         return dataReader.readOperationalData(path);
     }
 
     @Override
-    public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerOperationalReader(
-            InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+    public Registration registerOperationalReader(
+            final YangInstanceIdentifier path, final DataReader<YangInstanceIdentifier, CompositeNode> reader) {
         return dataReader.registerOperationalReader(path, reader);
     }
 
     @Override
-    public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerConfigurationReader(
-            InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+    public Registration registerConfigurationReader(
+            final YangInstanceIdentifier path, final DataReader<YangInstanceIdentifier, CompositeNode> reader) {
         return dataReader.registerConfigurationReader(path, reader);
     }
 
     @Override
-    public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+    public RoutedRpcRegistration addRoutedRpcImplementation(final QName rpcType, final RpcImplementation implementation) {
         return rpcs.addRoutedRpcImplementation(rpcType, implementation);
     }
 
     @Override
-    public void setRoutedRpcDefaultDelegate(RoutedRpcDefaultImplementation defaultImplementation) {
-      rpcs.setRoutedRpcDefaultDelegate(defaultImplementation);
+    public void setRoutedRpcDefaultDelegate(final RoutedRpcDefaultImplementation defaultImplementation) {
+        rpcs.setRoutedRpcDefaultDelegate(defaultImplementation);
     }
 
-  @Override
-    public RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
+    @Override
+    public RpcRegistration addRpcImplementation(final QName rpcType, final RpcImplementation implementation)
             throws IllegalArgumentException {
         return rpcs.addRpcImplementation(rpcType, implementation);
     }
@@ -124,17 +125,17 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
     }
 
     @Override
-    public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
+    public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(final QName rpc, final CompositeNode input) {
         return rpcs.invokeRpc(rpc, input);
     }
 
     @Override
-    public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener) {
+    public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(final RpcRegistrationListener listener) {
         return rpcs.addRpcRegistrationListener(listener);
     }
 
     @Override
-    public ListenableFuture<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input) {
+    public ListenableFuture<RpcResult<CompositeNode>> rpc(final QName type, final CompositeNode input) {
         return rpcs.invokeRpc( type, input );
     }
 
@@ -144,33 +145,33 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
     }
 
     @Override
-    public ListenerRegistration<DataChangeListener> registerDataChangeListener(InstanceIdentifier path,
-            DataChangeListener listener) {
+    public ListenerRegistration<DataChangeListener> registerDataChangeListener(final YangInstanceIdentifier path,
+            final DataChangeListener listener) {
         return dataReader.registerDataChangeListener(path, listener);
     }
 
     @Override
-    public Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> registerCommitHandler(
-            InstanceIdentifier path, DataCommitHandler<InstanceIdentifier, CompositeNode> commitHandler) {
+    public Registration registerCommitHandler(
+            final YangInstanceIdentifier path, final DataCommitHandler<YangInstanceIdentifier, CompositeNode> commitHandler) {
         return dataReader.registerCommitHandler(path, commitHandler);
     }
 
     @Override
-    public void removeRefresher(DataStoreIdentifier store, DataRefresher refresher) {
-     // NOOP
+    public void removeRefresher(final DataStoreIdentifier store, final DataRefresher refresher) {
+        // NOOP
     }
 
     @Override
-    public void addRefresher(DataStoreIdentifier store, DataRefresher refresher) {
-     // NOOP
+    public void addRefresher(final DataStoreIdentifier store, final DataRefresher refresher) {
+        // NOOP
     }
 
     @Override
-    public void addValidator(DataStoreIdentifier store, DataValidator validator) {
-     // NOOP
+    public void addValidator(final DataStoreIdentifier store, final DataValidator validator) {
+        // NOOP
     }
     @Override
-    public void removeValidator(DataStoreIdentifier store, DataValidator validator) {
+    public void removeValidator(final DataStoreIdentifier store, final DataValidator validator) {
         // NOOP
     }
 
@@ -180,25 +181,23 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
     }
 
     @Override
-    public void setSchemaContext(SchemaContext schemaContext) {
+    public void setSchemaContext(final SchemaContext schemaContext) {
         this.schemaContext = schemaContext;
     }
 
-    class ReadWrapper implements DataReader<InstanceIdentifier, CompositeNode> {
-
-
-        private InstanceIdentifier shortenPath(InstanceIdentifier path) {
-            InstanceIdentifier ret = null;
+    class ReadWrapper implements DataReader<YangInstanceIdentifier, CompositeNode> {
+        private YangInstanceIdentifier shortenPath(final YangInstanceIdentifier path) {
+            YangInstanceIdentifier ret = null;
             if(mountPath.contains(path)) {
                 List<PathArgument> newArgs = path.getPath().subList(mountPath.getPath().size(), path.getPath().size());
-                ret = new InstanceIdentifier(newArgs);
+                ret = YangInstanceIdentifier.create(newArgs);
             }
             return ret;
         }
 
         @Override
-        public CompositeNode readConfigurationData(InstanceIdentifier path) {
-            InstanceIdentifier newPath = shortenPath(path);
+        public CompositeNode readConfigurationData(final YangInstanceIdentifier path) {
+            YangInstanceIdentifier newPath = shortenPath(path);
             if(newPath == null) {
                 return null;
             }
@@ -206,8 +205,8 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
         }
 
         @Override
-        public CompositeNode readOperationalData(InstanceIdentifier path) {
-            InstanceIdentifier newPath = shortenPath(path);
+        public CompositeNode readOperationalData(final YangInstanceIdentifier path) {
+            YangInstanceIdentifier newPath = shortenPath(path);
             if(newPath == null) {
                 return null;
             }
@@ -216,14 +215,14 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
     }
 
     @Override
-    public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>>> registerCommitHandlerListener(
-            RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>> commitHandlerListener) {
+    public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<YangInstanceIdentifier, CompositeNode>>> registerCommitHandlerListener(
+            final RegistrationListener<DataCommitHandlerRegistration<YangInstanceIdentifier, CompositeNode>> commitHandlerListener) {
         return dataReader.registerCommitHandlerListener(commitHandlerListener);
     }
 
     @Override
-    public <L extends RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(
-            L listener) {
+    public <L extends RouteChangeListener<RpcRoutingContext, YangInstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(
+            final L listener) {
         return rpcs.registerRouteChangeListener(listener);
     }
 }
index 55a6ee77b470c2c2a98f5f2fbd30e47d1ba8f17d..d84f1dc03105389b81f9a8c239c5b33d7fcf3c6c 100644 (file)
@@ -14,21 +14,23 @@ import java.util.concurrent.ConcurrentMap;
 
 import org.opendaylight.controller.sal.core.api.data.DataProviderService;
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionListener;
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
+@Deprecated
 public class MountPointManagerImpl implements MountProvisionService {
 
     private final ListenerRegistry<MountProvisionListener> listeners =
             ListenerRegistry.create();
-    private final ConcurrentMap<InstanceIdentifier, MountPointImpl> mounts =
+    private final ConcurrentMap<YangInstanceIdentifier, MountPointImpl> mounts =
             new ConcurrentHashMap<>();
     private DataProviderService dataBroker = null;
 
     @Override
-    public MountProvisionInstance createMountPoint(final InstanceIdentifier path) {
+    public MountProvisionInstance createMountPoint(final YangInstanceIdentifier path) {
         checkState(!mounts.containsKey(path), "Mount already created");
         final MountPointImpl mount = new MountPointImpl(path);
         registerMountPoint(mount);
@@ -37,7 +39,7 @@ public class MountPointManagerImpl implements MountProvisionService {
         return mount;
     }
 
-    public void notifyMountCreated(final InstanceIdentifier identifier) {
+    public void notifyMountCreated(final YangInstanceIdentifier identifier) {
         for (final ListenerRegistration<MountProvisionListener> listener : listeners
                 .getListeners()) {
             listener.getInstance().onMountPointCreated(identifier);
@@ -53,7 +55,7 @@ public class MountPointManagerImpl implements MountProvisionService {
 
     @Override
     public MountProvisionInstance createOrGetMountPoint(
-            final InstanceIdentifier path) {
+            final YangInstanceIdentifier path) {
         final MountPointImpl mount = mounts.get(path);
         if (mount == null) {
             return createMountPoint(path);
@@ -62,7 +64,7 @@ public class MountPointManagerImpl implements MountProvisionService {
     }
 
     @Override
-    public MountProvisionInstance getMountPoint(final InstanceIdentifier path) {
+    public MountProvisionInstance getMountPoint(final YangInstanceIdentifier path) {
         return mounts.get(path);
     }
 
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/NotificationModule.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/NotificationModule.java
deleted file mode 100644 (file)
index b298a02..0000000
+++ /dev/null
@@ -1,187 +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.dom.broker;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.controller.sal.core.api.BrokerService;
-import org.opendaylight.controller.sal.core.api.Consumer.ConsumerFunctionality;
-import org.opendaylight.controller.sal.core.api.Provider.ProviderFunctionality;
-import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
-import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
-import org.opendaylight.controller.sal.core.api.notify.NotificationService;
-import org.opendaylight.controller.sal.core.spi.BrokerModule;
-import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Multimap;
-
-public class NotificationModule implements BrokerModule {
-    private static Logger log = LoggerFactory
-            .getLogger(NotificationModule.class);
-
-    private final Multimap<QName, NotificationListener> listeners = HashMultimap
-            .create();
-
-    private static final Set<Class<? extends BrokerService>> PROVIDED_SERVICE_TYPE = ImmutableSet
-            .<Class<? extends BrokerService>>of(NotificationService.class,
-                    NotificationPublishService.class);
-
-    private static final Set<Class<? extends ConsumerFunctionality>> SUPPORTED_CONSUMER_FUNCTIONALITY = ImmutableSet
-            .of((Class<? extends ConsumerFunctionality>) NotificationListener.class,
-                    NotificationListener.class); // Workaround: if we use the
-                                                 // version of method with only
-                                                 // one argument, the generics
-                                                 // inference will not work
-
-    @Override
-    public Set<Class<? extends BrokerService>> getProvidedServices() {
-        return PROVIDED_SERVICE_TYPE;
-    }
-
-    @Override
-    public Set<Class<? extends ConsumerFunctionality>> getSupportedConsumerFunctionality() {
-        return SUPPORTED_CONSUMER_FUNCTIONALITY;
-    }
-
-    @Override
-    public <T extends BrokerService> T getServiceForSession(Class<T> service,
-            ConsumerSession session) {
-        if (NotificationPublishService.class.equals(service)
-                && session instanceof ProviderSession) {
-            @SuppressWarnings("unchecked")
-            T ret = (T) newNotificationPublishService(session);
-            return ret;
-        } else if (NotificationService.class.equals(service)) {
-
-            @SuppressWarnings("unchecked")
-            T ret = (T) newNotificationConsumerService(session);
-            return ret;
-        }
-
-        throw new IllegalArgumentException(
-                "The requested session-specific service is not provided by this module.");
-    }
-
-    private void sendNotification(CompositeNode notification) {
-        QName type = notification.getNodeType();
-        Collection<NotificationListener> toNotify = listeners.get(type);
-        log.trace("Publishing notification " + type);
-
-        if (toNotify == null) {
-            // No listeners were registered - returns.
-            return;
-        }
-
-        for (NotificationListener listener : toNotify) {
-            try {
-                // FIXME: ensure that notification is immutable
-                listener.onNotification(notification);
-            } catch (Exception e) {
-                log.error("Uncaught exception in NotificationListener", e);
-            }
-        }
-
-    }
-
-    private NotificationService newNotificationConsumerService(
-            ConsumerSession session) {
-        return new NotificationConsumerSessionImpl();
-    }
-
-    private NotificationPublishService newNotificationPublishService(
-            ConsumerSession session) {
-        return new NotificationProviderSessionImpl();
-    }
-
-    private class NotificationConsumerSessionImpl implements
-            NotificationService {
-
-        private final Multimap<QName, NotificationListener> consumerListeners = HashMultimap
-                .create();
-        private boolean closed = false;
-
-
-        @Override
-        public Registration<NotificationListener> addNotificationListener(QName notification,
-                NotificationListener listener) {
-            checkSessionState();
-            if (notification == null) {
-                throw new IllegalArgumentException(
-                        "Notification type must not be null.");
-            }
-            if (listener == null) {
-                throw new IllegalArgumentException("Listener must not be null.");
-            }
-
-            consumerListeners.put(notification, listener);
-            listeners.put(notification, listener);
-            log.trace("Registered listener for notification: " + notification);
-            return null; // Return registration Object.
-        }
-
-        public void removeNotificationListener(QName notification,
-                NotificationListener listener) {
-            checkSessionState();
-            if (notification == null) {
-                throw new IllegalArgumentException(
-                        "Notification type must not be null.");
-            }
-            if (listener == null) {
-                throw new IllegalArgumentException("Listener must not be null.");
-            }
-            consumerListeners.remove(notification, listener);
-            listeners.remove(notification, listener);
-        }
-
-        public void closeSession() {
-            closed = true;
-            Map<QName, Collection<NotificationListener>> toRemove = consumerListeners
-                    .asMap();
-            for (Entry<QName, Collection<NotificationListener>> entry : toRemove
-                    .entrySet()) {
-                listeners.remove(entry.getKey(), entry.getValue());
-            }
-        }
-
-        protected void checkSessionState() {
-            if (closed)
-                throw new IllegalStateException("Session is closed");
-        }
-    }
-
-    private class NotificationProviderSessionImpl extends
-            NotificationConsumerSessionImpl implements
-            NotificationPublishService {
-
-        @Override
-        public void publish(CompositeNode notification) {
-            checkSessionState();
-            if (notification == null)
-                throw new IllegalArgumentException(
-                        "Notification must not be null.");
-            NotificationModule.this.sendNotification(notification);
-        }
-    }
-
-    @Override
-    public Set<Class<? extends ProviderFunctionality>> getSupportedProviderFunctionality() {
-        return Collections.emptySet();
-    }
-}
index 5e8c0e82538b4d2beacddd3366571ac2a734f7c5..b8bb279297cf835cb185d909d6eaf280dccc59d7 100644 (file)
@@ -18,21 +18,20 @@ import org.opendaylight.controller.sal.core.api.RpcImplementation;
 import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.osgi.framework.BundleContext;
 
 class ProviderContextImpl extends ConsumerContextImpl implements ProviderSession {
     private final Set<RpcRegistrationWrapper> registrations = new HashSet<>();
     private final Provider provider;
 
-    public ProviderContextImpl(final Provider provider, final BundleContext ctx) {
-        super(null, ctx);
+    public ProviderContextImpl(final Provider provider, final BrokerImpl broker) {
+        super(null, broker);
         this.provider = provider;
     }
 
     @Override
     public RpcRegistrationWrapper addRpcImplementation(final QName rpcType,
             final RpcImplementation implementation) throws IllegalArgumentException {
-        final RpcRegistration origReg = getBroker().getRouter()
+        final RpcRegistration origReg = getBrokerChecked().getRouter()
                 .addRpcImplementation(rpcType, implementation);
         final RpcRegistrationWrapper newReg = new RpcRegistrationWrapper(
                 origReg);
@@ -56,24 +55,24 @@ class ProviderContextImpl extends ConsumerContextImpl implements ProviderSession
             final QName rpcType, final RpcImplementation implementation) {
         throw new UnsupportedOperationException(
                 "TODO: auto-generated method stub");
+
     }
 
     @Override
     public RoutedRpcRegistration addRoutedRpcImplementation(
             final QName rpcType, final RpcImplementation implementation) {
-        throw new UnsupportedOperationException(
-                "TODO: auto-generated method stub");
+        return getBrokerChecked().getRouter().addRoutedRpcImplementation(rpcType, implementation);
     }
 
     @Override
     public Set<QName> getSupportedRpcs() {
-        return getBroker().getRouter().getSupportedRpcs();
+        return getBrokerChecked().getRouter().getSupportedRpcs();
     }
 
     @Override
     public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(
             final RpcRegistrationListener listener) {
-        return getBroker().getRouter().addRpcRegistrationListener(listener);
+        return getBrokerChecked().getRouter().addRpcRegistrationListener(listener);
     }
 
     /**
index ba9b2b7f55964d90023532082bc41767f037daa4..4f029bc919b1f58a1542a501e63987ea9334433f 100644 (file)
@@ -9,6 +9,8 @@ package org.opendaylight.controller.sal.dom.broker.impl;
 
 import static com.google.common.base.Preconditions.checkState;
 
+import com.google.common.collect.Iterables;
+
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -23,19 +25,17 @@ import java.util.Set;
 import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter;
 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.InstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 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.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Iterables;
-
 public class DataReaderRouter extends
-AbstractDataReadRouter<InstanceIdentifier, CompositeNode> {
+AbstractDataReadRouter<YangInstanceIdentifier, CompositeNode> {
     private final static Logger LOG = LoggerFactory
             .getLogger(DataReaderRouter.class);
     private final static URI NETCONF_NAMESPACE = URI
@@ -44,9 +44,9 @@ AbstractDataReadRouter<InstanceIdentifier, CompositeNode> {
             "data");
 
     @Override
-    protected CompositeNodeTOImpl merge(final InstanceIdentifier path,
+    protected CompositeNodeTOImpl merge(final YangInstanceIdentifier path,
             final Iterable<CompositeNode> data) {
-        PathArgument pathArgument = Iterables.getLast(path.getPath(), null);
+        PathArgument pathArgument = Iterables.getLast(path.getPathArguments(), null);
         boolean empty = true;
         QName name = (pathArgument == null ? null : pathArgument.getNodeType());
         final ArrayList<Node<?>> nodes = new ArrayList<Node<?>>();
@@ -117,11 +117,11 @@ AbstractDataReadRouter<InstanceIdentifier, CompositeNode> {
     }
 
     public Map<QName, SimpleNode<?>> getKeyNodes(
-            final InstanceIdentifier.PathArgument argument,
+            final YangInstanceIdentifier.PathArgument argument,
             final CompositeNode node) {
-        if (argument instanceof InstanceIdentifier.NodeIdentifierWithPredicates) {
+        if (argument instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) {
             return _getKeyNodes(
-                    (InstanceIdentifier.NodeIdentifierWithPredicates) argument,
+                    (YangInstanceIdentifier.NodeIdentifierWithPredicates) argument,
                     node);
         } else if (argument != null) {
             return _getKeyNodes(argument, node);
index aa4297613e183a335aea53eef47e9f39b3788cc9..82c913327962132068aa663d941848402f8031bc 100644 (file)
@@ -13,7 +13,7 @@ import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.sal.core.api.data.DataStore;
 import org.opendaylight.yangtools.concepts.Delegator;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 public class DataStoreStatsWrapper implements Delegator<DataStore>, DataStore {
 
@@ -38,7 +38,7 @@ public class DataStoreStatsWrapper implements Delegator<DataStore>, DataStore {
     }
 
     @Override
-    public CompositeNode readConfigurationData(InstanceIdentifier path) {
+    public CompositeNode readConfigurationData(YangInstanceIdentifier path) {
         cfgReadCount.incrementAndGet();
         final long startTime = System.nanoTime();
         try {
@@ -51,7 +51,7 @@ public class DataStoreStatsWrapper implements Delegator<DataStore>, DataStore {
     }
 
     @Override
-    public CompositeNode readOperationalData(InstanceIdentifier path) {
+    public CompositeNode readOperationalData(YangInstanceIdentifier path) {
         operReadCount.incrementAndGet();
         final long startTime = System.nanoTime();
         try {
@@ -63,8 +63,8 @@ public class DataStoreStatsWrapper implements Delegator<DataStore>, DataStore {
         }
     }
 
-    public DataCommitTransaction<InstanceIdentifier, CompositeNode> requestCommit(
-            DataModification<InstanceIdentifier, CompositeNode> modification) {
+    public DataCommitTransaction<YangInstanceIdentifier, CompositeNode> requestCommit(
+            DataModification<YangInstanceIdentifier, CompositeNode> modification) {
         requestCommitCount.incrementAndGet();
         final long startTime = System.nanoTime();
         try {
@@ -77,19 +77,19 @@ public class DataStoreStatsWrapper implements Delegator<DataStore>, DataStore {
     };
 
     @Override
-    public boolean containsConfigurationPath(InstanceIdentifier path) {
+    public boolean containsConfigurationPath(YangInstanceIdentifier path) {
         return delegate.containsConfigurationPath(path);
     }
 
-    public Iterable<InstanceIdentifier> getStoredConfigurationPaths() {
+    public Iterable<YangInstanceIdentifier> getStoredConfigurationPaths() {
         return delegate.getStoredConfigurationPaths();
     }
 
-    public Iterable<InstanceIdentifier> getStoredOperationalPaths() {
+    public Iterable<YangInstanceIdentifier> getStoredOperationalPaths() {
         return delegate.getStoredOperationalPaths();
     }
 
-    public boolean containsOperationalPath(InstanceIdentifier path) {
+    public boolean containsOperationalPath(YangInstanceIdentifier path) {
         return delegate.containsOperationalPath(path);
     }
 
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/GlobalRpcRegistration.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/GlobalRpcRegistration.java
new file mode 100644 (file)
index 0000000..f63e5ea
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.dom.broker.impl;
+
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
+
+class GlobalRpcRegistration extends AbstractObjectRegistration<RpcImplementation> implements
+        RpcRegistration {
+    private final QName type;
+    private SchemaAwareRpcBroker router;
+
+    public GlobalRpcRegistration(final QName type, final RpcImplementation instance, final SchemaAwareRpcBroker router) {
+        super(instance);
+        this.type = type;
+        this.router = router;
+    }
+
+    @Override
+    public QName getType() {
+        return type;
+    }
+
+    @Override
+    protected void removeRegistration() {
+        if (router != null) {
+            router.remove(this);
+            router = null;
+        }
+    }
+}
\ No newline at end of file
index 50dfbe852b4d7241e08fba0686c6253068a59492..1f82bd71b4a4cdf07ce8bfbd0c8d0e3829659aa2 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.controller.sal.dom.broker.impl;
 
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
@@ -15,12 +14,11 @@ import java.util.concurrent.ConcurrentHashMap;
 
 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.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.api.data.DataStore;
-import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -28,71 +26,70 @@ public final class HashMapDataStore implements DataStore, AutoCloseable {
     private static final Logger LOG = LoggerFactory
             .getLogger(HashMapDataStore.class);
 
-    private final Map<InstanceIdentifier, CompositeNode> configuration = new ConcurrentHashMap<InstanceIdentifier, CompositeNode>();
-    private final Map<InstanceIdentifier, CompositeNode> operational = new ConcurrentHashMap<InstanceIdentifier, CompositeNode>();
+    private final Map<YangInstanceIdentifier, CompositeNode> configuration = new ConcurrentHashMap<YangInstanceIdentifier, CompositeNode>();
+    private final Map<YangInstanceIdentifier, CompositeNode> operational = new ConcurrentHashMap<YangInstanceIdentifier, CompositeNode>();
 
     @Override
-    public boolean containsConfigurationPath(final InstanceIdentifier path) {
+    public boolean containsConfigurationPath(final YangInstanceIdentifier path) {
         return configuration.containsKey(path);
     }
 
     @Override
-    public boolean containsOperationalPath(final InstanceIdentifier path) {
+    public boolean containsOperationalPath(final YangInstanceIdentifier path) {
         return operational.containsKey(path);
     }
 
     @Override
-    public Iterable<InstanceIdentifier> getStoredConfigurationPaths() {
+    public Iterable<YangInstanceIdentifier> getStoredConfigurationPaths() {
         return configuration.keySet();
     }
 
     @Override
-    public Iterable<InstanceIdentifier> getStoredOperationalPaths() {
+    public Iterable<YangInstanceIdentifier> getStoredOperationalPaths() {
         return operational.keySet();
     }
 
     @Override
-    public CompositeNode readConfigurationData(final InstanceIdentifier path) {
+    public CompositeNode readConfigurationData(final YangInstanceIdentifier path) {
         LOG.trace("Reading configuration path {}", path);
         return configuration.get(path);
     }
 
     @Override
-    public CompositeNode readOperationalData(InstanceIdentifier path) {
+    public CompositeNode readOperationalData(YangInstanceIdentifier path) {
         LOG.trace("Reading operational path {}", path);
         return operational.get(path);
     }
 
     @Override
-    public DataCommitHandler.DataCommitTransaction<InstanceIdentifier, CompositeNode> requestCommit(
-            final DataModification<InstanceIdentifier, CompositeNode> modification) {
+    public DataCommitHandler.DataCommitTransaction<YangInstanceIdentifier, CompositeNode> requestCommit(
+            final DataModification<YangInstanceIdentifier, CompositeNode> modification) {
         return new HashMapDataStoreTransaction(modification, this);
     }
 
     public RpcResult<Void> rollback(HashMapDataStoreTransaction transaction) {
-        return Rpcs.<Void> getRpcResult(true, null,
-                Collections.<RpcError> emptySet());
+        return RpcResultBuilder.<Void> success().build();
     }
 
     public RpcResult<Void> finish(HashMapDataStoreTransaction transaction) {
-        final DataModification<InstanceIdentifier, CompositeNode> modification = transaction
+        final DataModification<YangInstanceIdentifier, CompositeNode> modification = transaction
                 .getModification();
-        for (final InstanceIdentifier removal : modification
+        for (final YangInstanceIdentifier removal : modification
                 .getRemovedConfigurationData()) {
             LOG.trace("Removing configuration path {}", removal);
             remove(configuration, removal);
         }
-        for (final InstanceIdentifier removal : modification
+        for (final YangInstanceIdentifier removal : modification
                 .getRemovedOperationalData()) {
             LOG.trace("Removing operational path {}", removal);
             remove(operational, removal);
         }
         if (LOG.isTraceEnabled()) {
-            for (final InstanceIdentifier a : modification
+            for (final YangInstanceIdentifier a : modification
                     .getUpdatedConfigurationData().keySet()) {
                 LOG.trace("Adding configuration path {}", a);
             }
-            for (final InstanceIdentifier a : modification
+            for (final YangInstanceIdentifier a : modification
                     .getUpdatedOperationalData().keySet()) {
                 LOG.trace("Adding operational path {}", a);
             }
@@ -100,19 +97,18 @@ public final class HashMapDataStore implements DataStore, AutoCloseable {
         configuration.putAll(modification.getUpdatedConfigurationData());
         operational.putAll(modification.getUpdatedOperationalData());
 
-        return Rpcs.<Void> getRpcResult(true, null,
-                Collections.<RpcError> emptySet());
+        return RpcResultBuilder.<Void> success().build();
     }
 
-    public void remove(final Map<InstanceIdentifier, CompositeNode> map,
-            final InstanceIdentifier identifier) {
-        Set<InstanceIdentifier> affected = new HashSet<InstanceIdentifier>();
-        for (final InstanceIdentifier path : map.keySet()) {
+    public void remove(final Map<YangInstanceIdentifier, CompositeNode> map,
+            final YangInstanceIdentifier identifier) {
+        Set<YangInstanceIdentifier> affected = new HashSet<YangInstanceIdentifier>();
+        for (final YangInstanceIdentifier path : map.keySet()) {
             if (identifier.contains(path)) {
                 affected.add(path);
             }
         }
-        for (final InstanceIdentifier pathToRemove : affected) {
+        for (final YangInstanceIdentifier pathToRemove : affected) {
             LOG.trace("Removed path {}", pathToRemove);
             map.remove(pathToRemove);
         }
index bb66594ac942ec4700c4f30a3c3b6e2a69fd44a1..ee026b60063d5a8737f63b1417a8cb81d81f29c3 100644 (file)
@@ -11,15 +11,15 @@ import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 public class HashMapDataStoreTransaction implements
-        DataCommitTransaction<InstanceIdentifier, CompositeNode> {
-    private final DataModification<InstanceIdentifier, CompositeNode> modification;
+        DataCommitTransaction<YangInstanceIdentifier, CompositeNode> {
+    private final DataModification<YangInstanceIdentifier, CompositeNode> modification;
     private final HashMapDataStore datastore;
 
     HashMapDataStoreTransaction(
-            final DataModification<InstanceIdentifier, CompositeNode> modify,
+            final DataModification<YangInstanceIdentifier, CompositeNode> modify,
             final HashMapDataStore store) {
         modification = modify;
         datastore = store;
@@ -31,7 +31,7 @@ public class HashMapDataStoreTransaction implements
     }
 
     @Override
-    public DataModification<InstanceIdentifier, CompositeNode> getModification() {
+    public DataModification<YangInstanceIdentifier, CompositeNode> getModification() {
         return this.modification;
     }
 
index 7fba31114f6d53a2c491f91511109a32b6c8efec..1e93202007cbd9a800e485a9ba0343298160c035 100644 (file)
@@ -12,7 +12,7 @@ import java.util.Collection;
 import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
 import org.opendaylight.controller.sal.dom.broker.spi.NotificationRouter;
 import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.slf4j.Logger;
@@ -25,12 +25,12 @@ import com.google.common.collect.Multimaps;
 public class NotificationRouterImpl implements NotificationRouter {
     private static Logger log = LoggerFactory.getLogger(NotificationRouterImpl.class);
 
-    private final Multimap<QName, ListenerRegistration> listeners = Multimaps.synchronizedSetMultimap(HashMultimap.<QName, ListenerRegistration>create());
+    private final Multimap<QName, MyListenerRegistration> listeners = Multimaps.synchronizedSetMultimap(HashMultimap.<QName, MyListenerRegistration>create());
 //    private Registration<NotificationListener> defaultListener;
 
     private void sendNotification(CompositeNode notification) {
         final QName type = notification.getNodeType();
-        final Collection<ListenerRegistration> toNotify = listeners.get(type);
+        final Collection<MyListenerRegistration> toNotify = listeners.get(type);
         log.trace("Publishing notification " + type);
 
         if ((toNotify == null) || toNotify.isEmpty()) {
@@ -38,7 +38,7 @@ public class NotificationRouterImpl implements NotificationRouter {
             return;
         }
 
-        for (ListenerRegistration listener : toNotify) {
+        for (MyListenerRegistration listener : toNotify) {
             try {
                 // FIXME: ensure that notification is immutable
                 listener.getInstance().onNotification(notification);
@@ -54,17 +54,17 @@ public class NotificationRouterImpl implements NotificationRouter {
     }
 
     @Override
-    public Registration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
-        ListenerRegistration ret = new ListenerRegistration(notification, listener);
+    public ListenerRegistration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
+        MyListenerRegistration ret = new MyListenerRegistration(notification, listener);
         listeners.put(notification, ret);
         return ret;
     }
 
-    private class ListenerRegistration extends AbstractListenerRegistration<NotificationListener> {
+    private class MyListenerRegistration extends AbstractListenerRegistration<NotificationListener> {
 
         final QName type;
 
-        public ListenerRegistration(QName type, NotificationListener instance) {
+        public MyListenerRegistration(QName type, NotificationListener instance) {
             super(instance);
             this.type = type;
         }
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/RoutedRpcRegImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/RoutedRpcRegImpl.java
new file mode 100644 (file)
index 0000000..c2fa82b
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.dom.broker.impl;
+
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+class RoutedRpcRegImpl extends AbstractObjectRegistration<RpcImplementation> implements
+        RoutedRpcRegistration {
+
+    private final QName type;
+    private final RoutedRpcSelector router;
+
+    public RoutedRpcRegImpl(final QName rpcType, final RpcImplementation implementation, final RoutedRpcSelector routedRpcSelector) {
+        super(implementation);
+        this.type = rpcType;
+        router = routedRpcSelector;
+    }
+
+    @Override
+    public void registerPath(final QName context, final YangInstanceIdentifier path) {
+        router.addPath(context, path, this);
+    }
+
+    @Override
+    public void unregisterPath(final QName context, final YangInstanceIdentifier path) {
+        router.removePath(context, path, this);
+    }
+
+    @Override
+    protected void removeRegistration() {
+
+    }
+
+    @Override
+    public QName getType() {
+        return type;
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/RoutedRpcSelector.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/RoutedRpcSelector.java
new file mode 100644 (file)
index 0000000..19ff03b
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.dom.broker.impl;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.md.sal.dom.broker.spi.rpc.RpcRoutingStrategy;
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.controller.sal.core.api.RpcRoutingContext;
+import org.opendaylight.yangtools.concepts.Identifiable;
+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.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.ListenableFuture;
+
+class RoutedRpcSelector implements RpcImplementation, AutoCloseable, Identifiable<RpcRoutingContext> {
+
+    private final RpcRoutingStrategy strategy;
+    private final Set<QName> supportedRpcs;
+    private final RpcRoutingContext identifier;
+    final ConcurrentMap<YangInstanceIdentifier, RoutedRpcRegImpl> implementations = new ConcurrentHashMap<>();
+    private final SchemaAwareRpcBroker router;
+
+    public RoutedRpcSelector(final RpcRoutingStrategy strategy, final SchemaAwareRpcBroker router) {
+        super();
+        this.strategy = strategy;
+        supportedRpcs = ImmutableSet.of(strategy.getIdentifier());
+        identifier = RpcRoutingContext.create(strategy.getContext(), strategy.getIdentifier());
+        this.router = router;
+    }
+
+    @Override
+    public RpcRoutingContext getIdentifier() {
+        return identifier;
+    }
+
+    @Override
+    public void close() throws Exception {
+
+    }
+
+    @Override
+    public Set<QName> getSupportedRpcs() {
+        return supportedRpcs;
+    }
+
+    public RoutedRpcRegistration addRoutedRpcImplementation(final QName rpcType, final RpcImplementation implementation) {
+        return new RoutedRpcRegImpl(rpcType, implementation, this);
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(final QName rpc, final CompositeNode input) {
+        CompositeNode inputContainer = input.getFirstCompositeByName(QName.create(rpc,"input"));
+        checkArgument(inputContainer != null, "Rpc payload must contain input element");
+        SimpleNode<?> routeContainer = inputContainer.getFirstSimpleByName(strategy.getLeaf());
+        checkArgument(routeContainer != null, "Leaf %s must be set with value", strategy.getLeaf());
+        Object route = routeContainer.getValue();
+        checkArgument(route instanceof YangInstanceIdentifier,
+                      "The routed node %s is not an instance identifier", route);
+        RpcImplementation potential = null;
+        if (route != null) {
+            RoutedRpcRegImpl potentialReg = implementations.get(route);
+            if (potentialReg != null) {
+                potential = potentialReg.getInstance();
+            }
+        }
+        if (potential == null) {
+            return router.invokeRpc(rpc, (YangInstanceIdentifier) route, input);
+        }
+        checkState(potential != null, "No implementation is available for rpc:%s path:%s", rpc, route);
+        return potential.invokeRpc(rpc, input);
+    }
+
+    public void addPath(final QName context, final YangInstanceIdentifier path, final RoutedRpcRegImpl routedRpcRegImpl) {
+        //checkArgument(strategy.getContext().equals(context),"Supplied context is not supported.");
+        RoutedRpcRegImpl previous = implementations.put(path, routedRpcRegImpl);
+        if (previous == null) {
+            router.notifyPathAnnouncement(context,strategy.getIdentifier(), path);
+        }
+
+    }
+
+    public void removePath(final QName context, final YangInstanceIdentifier path, final RoutedRpcRegImpl routedRpcRegImpl) {
+        boolean removed = implementations.remove(path, routedRpcRegImpl);
+        if (removed) {
+            router.notifyPathWithdrawal(context, strategy.getIdentifier(), path);
+        }
+    }
+}
\ No newline at end of file
index 1a572d157dba9f8272140495b8eabf9669df11bc..94553f52757dbc24a811ab2a840c797d29608f3a 100644 (file)
@@ -9,6 +9,11 @@ package org.opendaylight.controller.sal.dom.broker.impl;
 
 import static com.google.common.base.Preconditions.checkState;
 
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.HashMap;
@@ -28,7 +33,7 @@ import org.opendaylight.controller.sal.dom.broker.util.YangSchemaUtils;
 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.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
@@ -40,10 +45,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableSet;
-
 public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataStore> implements //
 DataStore, //
 SchemaContextListener, //
@@ -53,10 +54,10 @@ AutoCloseable {
 
     private SchemaContext schema = null;
     private boolean validationEnabled = false;
-    private final DataReader<InstanceIdentifier, CompositeNode> reader = new MergeFirstLevelReader();
+    private final DataReader<YangInstanceIdentifier, CompositeNode> reader = new MergeFirstLevelReader();
 
     @Override
-    public boolean containsConfigurationPath(final InstanceIdentifier path) {
+    public boolean containsConfigurationPath(final YangInstanceIdentifier path) {
         try {
             getDelegateReadLock().lock();
             return getDelegate().containsConfigurationPath(path);
@@ -67,7 +68,7 @@ AutoCloseable {
     }
 
     @Override
-    public boolean containsOperationalPath(final InstanceIdentifier path) {
+    public boolean containsOperationalPath(final YangInstanceIdentifier path) {
         try {
             getDelegateReadLock().lock();
             return getDelegate().containsOperationalPath(path);
@@ -78,7 +79,7 @@ AutoCloseable {
     }
 
     @Override
-    public Iterable<InstanceIdentifier> getStoredConfigurationPaths() {
+    public Iterable<YangInstanceIdentifier> getStoredConfigurationPaths() {
         try {
             getDelegateReadLock().lock();
             return getDelegate().getStoredConfigurationPaths();
@@ -89,7 +90,7 @@ AutoCloseable {
     }
 
     @Override
-    public Iterable<InstanceIdentifier> getStoredOperationalPaths() {
+    public Iterable<YangInstanceIdentifier> getStoredOperationalPaths() {
         try {
             getDelegateReadLock().lock();
             return getDelegate().getStoredOperationalPaths();
@@ -100,18 +101,18 @@ AutoCloseable {
     }
 
     @Override
-    public CompositeNode readConfigurationData(final InstanceIdentifier path) {
+    public CompositeNode readConfigurationData(final YangInstanceIdentifier path) {
         return reader.readConfigurationData(path);
     }
 
     @Override
-    public CompositeNode readOperationalData(final InstanceIdentifier path) {
+    public CompositeNode readOperationalData(final YangInstanceIdentifier path) {
         return reader.readOperationalData(path);
     }
 
     @Override
-    public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier, CompositeNode> requestCommit(
-            final DataModification<InstanceIdentifier, CompositeNode> modification) {
+    public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<YangInstanceIdentifier, CompositeNode> requestCommit(
+            final DataModification<YangInstanceIdentifier, CompositeNode> modification) {
         validateAgainstSchema(modification);
         NormalizedDataModification cleanedUp = prepareMergedTransaction(modification);
         cleanedUp.status = TransactionStatus.SUBMITED;
@@ -126,7 +127,7 @@ AutoCloseable {
         this.validationEnabled = validationEnabled;
     }
 
-    private void validateAgainstSchema(final DataModification<InstanceIdentifier, CompositeNode> modification) {
+    private void validateAgainstSchema(final DataModification<YangInstanceIdentifier, CompositeNode> modification) {
         if (!validationEnabled) {
             return;
         }
@@ -152,7 +153,7 @@ AutoCloseable {
         this.schema = null;
     }
 
-    protected CompositeNode mergeData(final InstanceIdentifier path, final CompositeNode stored, final CompositeNode modified,
+    protected CompositeNode mergeData(final YangInstanceIdentifier path, final CompositeNode stored, final CompositeNode modified,
             final boolean config) {
         // long startTime = System.nanoTime();
         try {
@@ -164,13 +165,13 @@ AutoCloseable {
         }
     }
 
-    private DataSchemaNode schemaNodeFor(final InstanceIdentifier path) {
+    private DataSchemaNode schemaNodeFor(final YangInstanceIdentifier path) {
         checkState(schema != null, "YANG Schema is not available");
         return YangSchemaUtils.getSchemaNode(schema, path);
     }
 
     private NormalizedDataModification prepareMergedTransaction(
-            final DataModification<InstanceIdentifier, CompositeNode> original) {
+            final DataModification<YangInstanceIdentifier, CompositeNode> original) {
         NormalizedDataModification normalized = new NormalizedDataModification(original);
         LOG.trace("Transaction: {} Removed Configuration {}, Removed Operational {}", original.getIdentifier(),
                 original.getRemovedConfigurationData(), original.getRemovedConfigurationData());
@@ -179,40 +180,40 @@ AutoCloseable {
         LOG.trace("Transaction: {} Updated Configuration {}, Updated Operational {}", original.getIdentifier(),
                 original.getUpdatedConfigurationData().entrySet(), original.getUpdatedOperationalData().entrySet());
 
-        for (InstanceIdentifier entry : original.getRemovedConfigurationData()) {
+        for (YangInstanceIdentifier entry : original.getRemovedConfigurationData()) {
             normalized.deepRemoveConfigurationData(entry);
         }
-        for (InstanceIdentifier entry : original.getRemovedOperationalData()) {
+        for (YangInstanceIdentifier entry : original.getRemovedOperationalData()) {
             normalized.deepRemoveOperationalData(entry);
         }
-        for (Entry<InstanceIdentifier, CompositeNode> entry : original.getUpdatedConfigurationData().entrySet()) {
+        for (Entry<YangInstanceIdentifier, CompositeNode> entry : original.getUpdatedConfigurationData().entrySet()) {
             normalized.putDeepConfigurationData(entry.getKey(), entry.getValue());
         }
-        for (Entry<InstanceIdentifier, CompositeNode> entry : original.getUpdatedOperationalData().entrySet()) {
+        for (Entry<YangInstanceIdentifier, CompositeNode> entry : original.getUpdatedOperationalData().entrySet()) {
             normalized.putDeepOperationalData(entry.getKey(), entry.getValue());
         }
         return normalized;
     }
 
-    private Iterable<InstanceIdentifier> getConfigurationSubpaths(final InstanceIdentifier entry) {
+    private Iterable<YangInstanceIdentifier> getConfigurationSubpaths(final YangInstanceIdentifier entry) {
         // FIXME: This should be replaced by index
-        Iterable<InstanceIdentifier> paths = getStoredConfigurationPaths();
+        Iterable<YangInstanceIdentifier> paths = getStoredConfigurationPaths();
 
         return getChildrenPaths(entry, paths);
 
     }
 
-    public Iterable<InstanceIdentifier> getOperationalSubpaths(final InstanceIdentifier entry) {
+    public Iterable<YangInstanceIdentifier> getOperationalSubpaths(final YangInstanceIdentifier entry) {
         // FIXME: This should be indexed
-        Iterable<InstanceIdentifier> paths = getStoredOperationalPaths();
+        Iterable<YangInstanceIdentifier> paths = getStoredOperationalPaths();
 
         return getChildrenPaths(entry, paths);
     }
 
-    private static final Iterable<InstanceIdentifier> getChildrenPaths(final InstanceIdentifier entry,
-            final Iterable<InstanceIdentifier> paths) {
-        ImmutableSet.Builder<InstanceIdentifier> children = ImmutableSet.builder();
-        for (InstanceIdentifier potential : paths) {
+    private static final Iterable<YangInstanceIdentifier> getChildrenPaths(final YangInstanceIdentifier entry,
+            final Iterable<YangInstanceIdentifier> paths) {
+        ImmutableSet.Builder<YangInstanceIdentifier> children = ImmutableSet.builder();
+        for (YangInstanceIdentifier potential : paths) {
             if (entry.contains(potential)) {
                 children.add(entry);
             }
@@ -220,22 +221,22 @@ AutoCloseable {
         return children.build();
     }
 
-    private final Comparator<Entry<InstanceIdentifier, CompositeNode>> preparationComparator = new Comparator<Entry<InstanceIdentifier, CompositeNode>>() {
+    private final Comparator<Entry<YangInstanceIdentifier, CompositeNode>> preparationComparator = new Comparator<Entry<YangInstanceIdentifier, CompositeNode>>() {
         @Override
-        public int compare(final Entry<InstanceIdentifier, CompositeNode> o1, final Entry<InstanceIdentifier, CompositeNode> o2) {
-            InstanceIdentifier o1Key = o1.getKey();
-            InstanceIdentifier o2Key = o2.getKey();
+        public int compare(final Entry<YangInstanceIdentifier, CompositeNode> o1, final Entry<YangInstanceIdentifier, CompositeNode> o2) {
+            YangInstanceIdentifier o1Key = o1.getKey();
+            YangInstanceIdentifier o2Key = o2.getKey();
             return Integer.compare(o1Key.getPath().size(), o2Key.getPath().size());
         }
     };
 
-    private class MergeFirstLevelReader implements DataReader<InstanceIdentifier, CompositeNode> {
+    private class MergeFirstLevelReader implements DataReader<YangInstanceIdentifier, CompositeNode> {
 
         @Override
-        public CompositeNode readConfigurationData(final InstanceIdentifier path) {
+        public CompositeNode readConfigurationData(final YangInstanceIdentifier path) {
             getDelegateReadLock().lock();
             try {
-                if (path.getPath().isEmpty()) {
+                if (Iterables.isEmpty(path.getPathArguments())) {
                     return null;
                 }
                 QName qname = null;
@@ -248,10 +249,10 @@ AutoCloseable {
                     qname = path.getPath().get(path.getPath().size() - 1).getNodeType();
                 }
 
-                FluentIterable<InstanceIdentifier> directChildren = FluentIterable.from(getStoredConfigurationPaths())
-                        .filter(new Predicate<InstanceIdentifier>() {
+                FluentIterable<YangInstanceIdentifier> directChildren = FluentIterable.from(getStoredConfigurationPaths())
+                        .filter(new Predicate<YangInstanceIdentifier>() {
                             @Override
-                            public boolean apply(final InstanceIdentifier input) {
+                            public boolean apply(final YangInstanceIdentifier input) {
                                 if (path.contains(input)) {
                                     int nesting = input.getPath().size() - path.getPath().size();
                                     if (nesting == 1) {
@@ -261,7 +262,7 @@ AutoCloseable {
                                 return false;
                             }
                         });
-                for (InstanceIdentifier instanceIdentifier : directChildren) {
+                for (YangInstanceIdentifier instanceIdentifier : directChildren) {
                     childNodes.add(getDelegate().readConfigurationData(instanceIdentifier));
                 }
                 if (original == null && childNodes.isEmpty()) {
@@ -275,10 +276,10 @@ AutoCloseable {
         }
 
         @Override
-        public CompositeNode readOperationalData(final InstanceIdentifier path) {
+        public CompositeNode readOperationalData(final YangInstanceIdentifier path) {
             getDelegateReadLock().lock();
             try {
-                if (path.getPath().isEmpty()) {
+                if (Iterables.isEmpty(path.getPathArguments())) {
                     return null;
                 }
                 QName qname = null;
@@ -291,10 +292,10 @@ AutoCloseable {
                     qname = path.getPath().get(path.getPath().size() - 1).getNodeType();
                 }
 
-                FluentIterable<InstanceIdentifier> directChildren = FluentIterable.from(getStoredOperationalPaths())
-                        .filter(new Predicate<InstanceIdentifier>() {
+                FluentIterable<YangInstanceIdentifier> directChildren = FluentIterable.from(getStoredOperationalPaths())
+                        .filter(new Predicate<YangInstanceIdentifier>() {
                             @Override
-                            public boolean apply(final InstanceIdentifier input) {
+                            public boolean apply(final YangInstanceIdentifier input) {
                                 if (path.contains(input)) {
                                     int nesting = input.getPath().size() - path.getPath().size();
                                     if (nesting == 1) {
@@ -305,7 +306,7 @@ AutoCloseable {
                             }
                         });
 
-                for (InstanceIdentifier instanceIdentifier : directChildren) {
+                for (YangInstanceIdentifier instanceIdentifier : directChildren) {
                     childNodes.add(getDelegate().readOperationalData(instanceIdentifier));
                 }
                 if (original == null && childNodes.isEmpty()) {
@@ -319,14 +320,14 @@ AutoCloseable {
         }
     }
 
-    private class NormalizedDataModification extends AbstractDataModification<InstanceIdentifier, CompositeNode> {
+    private class NormalizedDataModification extends AbstractDataModification<YangInstanceIdentifier, CompositeNode> {
 
         private final String CONFIGURATIONAL_DATA_STORE_MARKER = "configurational";
         private final String OPERATIONAL_DATA_STORE_MARKER = "operational";
         private final Object identifier;
         private TransactionStatus status;
 
-        public NormalizedDataModification(final DataModification<InstanceIdentifier, CompositeNode> original) {
+        public NormalizedDataModification(final DataModification<YangInstanceIdentifier, CompositeNode> original) {
             super(getDelegate());
             identifier = original;
             status = TransactionStatus.NEW;
@@ -339,27 +340,27 @@ AutoCloseable {
          *
          * @param entry
          */
-        public void deepRemoveOperationalData(final InstanceIdentifier entry) {
-            Iterable<InstanceIdentifier> paths = getOperationalSubpaths(entry);
+        public void deepRemoveOperationalData(final YangInstanceIdentifier entry) {
+            Iterable<YangInstanceIdentifier> paths = getOperationalSubpaths(entry);
             removeOperationalData(entry);
-            for (InstanceIdentifier potential : paths) {
+            for (YangInstanceIdentifier potential : paths) {
                 removeOperationalData(potential);
             }
         }
 
-        public void deepRemoveConfigurationData(final InstanceIdentifier entry) {
-            Iterable<InstanceIdentifier> paths = getConfigurationSubpaths(entry);
+        public void deepRemoveConfigurationData(final YangInstanceIdentifier entry) {
+            Iterable<YangInstanceIdentifier> paths = getConfigurationSubpaths(entry);
             removeConfigurationData(entry);
-            for (InstanceIdentifier potential : paths) {
+            for (YangInstanceIdentifier potential : paths) {
                 removeConfigurationData(potential);
             }
         }
 
-        public void putDeepConfigurationData(final InstanceIdentifier entryKey, final CompositeNode entryData) {
+        public void putDeepConfigurationData(final YangInstanceIdentifier entryKey, final CompositeNode entryData) {
             this.putCompositeNodeData(entryKey, entryData, CONFIGURATIONAL_DATA_STORE_MARKER);
         }
 
-        public void putDeepOperationalData(final InstanceIdentifier entryKey, final CompositeNode entryData) {
+        public void putDeepOperationalData(final YangInstanceIdentifier entryKey, final CompositeNode entryData) {
             this.putCompositeNodeData(entryKey, entryData, OPERATIONAL_DATA_STORE_MARKER);
         }
 
@@ -379,18 +380,18 @@ AutoCloseable {
         }
 
         @Override
-        protected CompositeNode mergeConfigurationData(final InstanceIdentifier path, final CompositeNode stored,
+        protected CompositeNode mergeConfigurationData(final YangInstanceIdentifier path, final CompositeNode stored,
                 final CompositeNode modified) {
             return mergeData(path, stored, modified, true);
         }
 
         @Override
-        protected CompositeNode mergeOperationalData(final InstanceIdentifier path, final CompositeNode stored,
+        protected CompositeNode mergeOperationalData(final YangInstanceIdentifier path, final CompositeNode stored,
                 final CompositeNode modified) {
             return mergeData(path, stored, modified, false);
         }
 
-        private void putData(final InstanceIdentifier entryKey, final CompositeNode entryData, final String dataStoreIdentifier) {
+        private void putData(final YangInstanceIdentifier entryKey, final CompositeNode entryData, final String dataStoreIdentifier) {
             if (dataStoreIdentifier != null && entryKey != null && entryData != null) {
                 switch (dataStoreIdentifier) {
                 case (CONFIGURATIONAL_DATA_STORE_MARKER):
@@ -407,29 +408,29 @@ AutoCloseable {
             }
         }
 
-        private void putCompositeNodeData(final InstanceIdentifier entryKey, final CompositeNode entryData,
+        private void putCompositeNodeData(final YangInstanceIdentifier entryKey, final CompositeNode entryData,
                 final String dataStoreIdentifier) {
             this.putData(entryKey, entryData, dataStoreIdentifier);
 
             for (Node<?> child : entryData.getValue()) {
-                InstanceIdentifier subEntryId = InstanceIdentifier.builder(entryKey).node(child.getNodeType())
+                YangInstanceIdentifier subEntryId = YangInstanceIdentifier.builder(entryKey).node(child.getNodeType())
                         .toInstance();
                 if (child instanceof CompositeNode) {
                     DataSchemaNode subSchema = schemaNodeFor(subEntryId);
                     CompositeNode compNode = (CompositeNode) child;
-                    InstanceIdentifier instanceId = null;
+                    YangInstanceIdentifier instanceId = null;
 
                     if (subSchema instanceof ListSchemaNode) {
                         ListSchemaNode listSubSchema = (ListSchemaNode) subSchema;
                         Map<QName, Object> mapOfSubValues = this.getValuesFromListSchema(listSubSchema,
                                 (CompositeNode) child);
                         if (mapOfSubValues != null) {
-                            instanceId = InstanceIdentifier.builder(entryKey)
+                            instanceId = YangInstanceIdentifier.builder(entryKey)
                                     .nodeWithKey(listSubSchema.getQName(), mapOfSubValues).toInstance();
                         }
                     } else if (subSchema instanceof ContainerSchemaNode) {
                         ContainerSchemaNode containerSchema = (ContainerSchemaNode) subSchema;
-                        instanceId = InstanceIdentifier.builder(entryKey).node(subSchema.getQName()).toInstance();
+                        instanceId = YangInstanceIdentifier.builder(entryKey).node(subSchema.getQName()).toInstance();
                     }
                     if (instanceId != null) {
                         this.putCompositeNodeData(instanceId, compNode, dataStoreIdentifier);
index 8fc6fe229500ecc39506fcc5b215b82cfdd9cb5e..44e7abc3aa117fcb778d56f7b1423f5bd07c2649 100644 (file)
@@ -17,6 +17,7 @@ import java.util.concurrent.ConcurrentMap;
 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.impl.routing.RoutingUtils;
+import org.opendaylight.controller.md.sal.dom.broker.spi.rpc.RpcRoutingStrategy;
 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.RoutedRpcDefaultImplementation;
@@ -24,25 +25,20 @@ import org.opendaylight.controller.sal.core.api.RpcImplementation;
 import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
 import org.opendaylight.controller.sal.core.api.RpcRoutingContext;
 import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter;
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
 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.SimpleNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 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.UnknownSchemaNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
@@ -52,10 +48,9 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String>, Ro
 
     private static final Logger LOG = LoggerFactory.getLogger(SchemaAwareRpcBroker.class);
 
-    private static final QName CONTEXT_REFERENCE = QName.create("urn:opendaylight:yang:extension:yang-ext",
-            "2013-07-09", "context-reference");
+
     private final ListenerRegistry<RpcRegistrationListener> rpcRegistrationListeners = new ListenerRegistry<>();
-    private final ListenerRegistry<RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> routeChangeListeners = new ListenerRegistry<>();
+    private final ListenerRegistry<RouteChangeListener<RpcRoutingContext, YangInstanceIdentifier>> routeChangeListeners = new ListenerRegistry<>();
 
 
     private final String identifier;
@@ -64,7 +59,7 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String>, Ro
     private SchemaContextProvider schemaProvider;
     private RoutedRpcDefaultImplementation defaultDelegate;
 
-    public SchemaAwareRpcBroker(String identifier, SchemaContextProvider schemaProvider) {
+    public SchemaAwareRpcBroker(final String identifier, final SchemaContextProvider schemaProvider) {
         super();
         this.identifier = identifier;
         this.schemaProvider = schemaProvider;
@@ -74,7 +69,7 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String>, Ro
         return defaultImplementation;
     }
 
-    public void setDefaultImplementation(RpcImplementation defaultImplementation) {
+    public void setDefaultImplementation(final RpcImplementation defaultImplementation) {
         this.defaultImplementation = defaultImplementation;
     }
 
@@ -82,7 +77,7 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String>, Ro
         return schemaProvider;
     }
 
-    public void setSchemaProvider(SchemaContextProvider schemaProvider) {
+    public void setSchemaProvider(final SchemaContextProvider schemaProvider) {
         this.schemaProvider = schemaProvider;
     }
 
@@ -91,18 +86,18 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String>, Ro
     }
 
     @Override
-    public void setRoutedRpcDefaultDelegate(RoutedRpcDefaultImplementation defaultDelegate) {
+    public void setRoutedRpcDefaultDelegate(final RoutedRpcDefaultImplementation defaultDelegate) {
         this.defaultDelegate = defaultDelegate;
     }
 
     @Override
-    public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+    public RoutedRpcRegistration addRoutedRpcImplementation(final QName rpcType, final RpcImplementation implementation) {
         checkArgument(rpcType != null, "RPC Type should not be null");
         checkArgument(implementation != null, "RPC Implementatoin should not be null");
         return getOrCreateRoutedRpcRouter(rpcType).addRoutedRpcImplementation(rpcType, implementation);
     }
 
-    private RoutedRpcSelector getOrCreateRoutedRpcRouter(QName rpcType) {
+    private RoutedRpcSelector getOrCreateRoutedRpcRouter(final QName rpcType) {
         RoutedRpcSelector potential = getRoutedRpcRouter(rpcType);
         if (potential != null) {
             return potential;
@@ -113,15 +108,15 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String>, Ro
                 return potential;
             }
             RpcDefinition definition = findRpcDefinition(rpcType);
-            RoutingStrategy strategy = getRoutingStrategy(definition);
-            checkState(strategy instanceof RoutedRpcStrategy, "Rpc %s is not routed.", rpcType);
-            potential = new RoutedRpcSelector((RoutedRpcStrategy) strategy, this);
+            RpcRoutingStrategy strategy = RpcRoutingStrategy.from(definition);
+            checkState(strategy.isContextBasedRouted(), "Rpc %s is not routed.", rpcType);
+            potential = new RoutedRpcSelector( strategy, this);
             implementations.put(rpcType, potential);
             return potential;
         }
     }
 
-    private RoutedRpcSelector getRoutedRpcRouter(QName rpcType) {
+    private RoutedRpcSelector getRoutedRpcRouter(final QName rpcType) {
         RpcImplementation potential = implementations.get(rpcType);
         if (potential != null) {
             checkState(potential instanceof RoutedRpcSelector, "Rpc %s is not routed.", rpcType);
@@ -132,25 +127,38 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String>, Ro
     }
 
     @Override
-    public RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
+    public RpcRegistration addRpcImplementation(final QName rpcType, final RpcImplementation implementation)
             throws IllegalArgumentException {
         checkArgument(rpcType != null, "RPC Type should not be null");
         checkArgument(implementation != null, "RPC Implementatoin should not be null");
         checkState(!hasRpcImplementation(rpcType), "Implementation already registered");
         RpcDefinition definition = findRpcDefinition(rpcType);
-        checkArgument(!isRoutedRpc(definition), "RPC Type must not be routed.");
+        checkArgument(!RpcRoutingStrategy.from(definition).isContextBasedRouted(), "RPC Type must not be content routed.");
         GlobalRpcRegistration reg = new GlobalRpcRegistration(rpcType, implementation, this);
-        implementations.putIfAbsent(rpcType, implementation);
+        final RpcImplementation previous = implementations.putIfAbsent(rpcType, implementation);
+        Preconditions.checkState(previous == null, "Rpc %s is already registered.",rpcType);
+        notifyRpcAdded(rpcType);
         return reg;
     }
 
-    private boolean isRoutedRpc(RpcDefinition definition) {
-        return getRoutingStrategy(definition) instanceof RoutedRpcStrategy;
+    private void notifyRpcAdded(final QName rpcType) {
+        for (ListenerRegistration<RpcRegistrationListener> listener : rpcRegistrationListeners) {
+            try {
+                listener.getInstance().onRpcImplementationAdded(rpcType);
+            } catch (Exception ex) {
+                LOG.error("Unhandled exception during invoking listener {}", listener.getInstance(), ex);
+            }
+
+        }
     }
 
     @Override
-    public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener) {
-        return rpcRegistrationListeners.register(listener);
+    public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(final RpcRegistrationListener listener) {
+        ListenerRegistration<RpcRegistrationListener> reg = rpcRegistrationListeners.register(listener);
+        for (QName impl : implementations.keySet()) {
+            listener.onRpcImplementationAdded(impl);
+        }
+        return reg;
     }
 
     @Override
@@ -164,11 +172,11 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String>, Ro
     }
 
     @Override
-    public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
+    public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(final QName rpc, final CompositeNode input) {
         return findRpcImplemention(rpc).invokeRpc(rpc, input);
     }
 
-    private RpcImplementation findRpcImplemention(QName rpc) {
+    private RpcImplementation findRpcImplemention(final QName rpc) {
         checkArgument(rpc != null, "Rpc name should not be null");
         RpcImplementation potentialImpl = implementations.get(rpc);
         if (potentialImpl != null) {
@@ -183,11 +191,11 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String>, Ro
         return potentialImpl;
     }
 
-    private boolean hasRpcImplementation(QName rpc) {
+    private boolean hasRpcImplementation(final QName rpc) {
         return implementations.containsKey(rpc);
     }
 
-    private RpcDefinition findRpcDefinition(QName rpcType) {
+    private RpcDefinition findRpcDefinition(final QName rpcType) {
         checkArgument(rpcType != null, "Rpc name must be supplied.");
         checkState(schemaProvider != null, "Schema Provider is not available.");
         SchemaContext ctx = schemaProvider.getSchemaContext();
@@ -197,7 +205,7 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String>, Ro
         return findRpcDefinition(rpcType, module.getRpcs());
     }
 
-    static private RpcDefinition findRpcDefinition(QName rpcType, Set<RpcDefinition> rpcs) {
+    static private RpcDefinition findRpcDefinition(final QName rpcType, final Set<RpcDefinition> rpcs) {
         checkState(rpcs != null, "Rpc schema is not available.");
         for (RpcDefinition rpc : rpcs) {
             if (rpcType.equals(rpc.getQName())) {
@@ -207,244 +215,33 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String>, Ro
         throw new IllegalArgumentException("Supplied Rpc Type is not defined.");
     }
 
-    private RoutingStrategy getRoutingStrategy(RpcDefinition rpc) {
-        ContainerSchemaNode input = rpc.getInput();
-        if (input != null) {
-            for (DataSchemaNode schemaNode : input.getChildNodes()) {
-                Optional<QName> context = getRoutingContext(schemaNode);
-                if (context.isPresent()) {
-                    return createRoutedStrategy(rpc, context.get(), schemaNode.getQName());
-                }
-            }
-        }
-        return createGlobalStrategy(rpc);
-    }
-
-    private static RoutingStrategy createRoutedStrategy(RpcDefinition rpc, QName context, QName leafNode) {
-        return new RoutedRpcStrategy(rpc.getQName(), context, leafNode);
-    }
-
-    private Optional<QName> getRoutingContext(DataSchemaNode schemaNode) {
-        for (UnknownSchemaNode extension : schemaNode.getUnknownSchemaNodes()) {
-            if (CONTEXT_REFERENCE.equals(extension.getNodeType())) {
-                return Optional.fromNullable(extension.getQName());
-            }
-        }
-        return Optional.absent();
-    }
-
-    private static RoutingStrategy createGlobalStrategy(RpcDefinition rpc) {
-        GlobalRpcStrategy ret = new GlobalRpcStrategy(rpc.getQName());
-        return ret;
-    }
-
     @Override
-    public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) {
-      checkState(defaultDelegate != null);
-      return defaultDelegate.invokeRpc(rpc, identifier, input);
+    public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(final QName rpc, final YangInstanceIdentifier route, final CompositeNode input) {
+      checkState(defaultDelegate != null, "No implementation is available for rpc:%s path:%s", rpc, route);
+      return defaultDelegate.invokeRpc(rpc, route, input);
     }
 
-    private static abstract class RoutingStrategy implements Identifiable<QName> {
-
-        private final QName identifier;
-
-        public RoutingStrategy(QName identifier) {
-            super();
-            this.identifier = identifier;
-        }
-
-        @Override
-        public QName getIdentifier() {
-            return identifier;
-        }
-    }
-
-    private static class GlobalRpcStrategy extends RoutingStrategy {
-
-        public GlobalRpcStrategy(QName identifier) {
-            super(identifier);
-        }
-    }
-
-    private static class RoutedRpcStrategy extends RoutingStrategy {
-
-        private final QName context;
-        private final QName leaf;
-
-        public RoutedRpcStrategy(QName identifier, QName ctx, QName leaf) {
-            super(identifier);
-            this.context = ctx;
-            this.leaf = leaf;
-        }
-
-        public QName getContext() {
-            return context;
-        }
-
-        public QName getLeaf() {
-            return leaf;
-        }
-    }
-
-    private static class RoutedRpcSelector implements RpcImplementation, AutoCloseable, Identifiable<RpcRoutingContext> {
-
-        private final RoutedRpcStrategy strategy;
-        private final Set<QName> supportedRpcs;
-        private final RpcRoutingContext identifier;
-        private RpcImplementation defaultDelegate;
-        private final ConcurrentMap<InstanceIdentifier, RoutedRpcRegImpl> implementations = new ConcurrentHashMap<>();
-        private final SchemaAwareRpcBroker router;
-
-        public RoutedRpcSelector(RoutedRpcStrategy strategy, SchemaAwareRpcBroker router) {
-            super();
-            this.strategy = strategy;
-            supportedRpcs = ImmutableSet.of(strategy.getIdentifier());
-            identifier = RpcRoutingContext.create(strategy.context, strategy.getIdentifier());
-            this.router = router;
-        }
-
-        @Override
-        public RpcRoutingContext getIdentifier() {
-            return identifier;
-        }
-
-        @Override
-        public void close() throws Exception {
-
-        }
-
-        @Override
-        public Set<QName> getSupportedRpcs() {
-            return supportedRpcs;
-        }
-
-        public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
-            return new RoutedRpcRegImpl(rpcType, implementation, this);
-        }
-
-        @Override
-        public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
-            CompositeNode inputContainer = input.getFirstCompositeByName(QName.create(rpc,"input"));
-            checkArgument(inputContainer != null, "Rpc payload must contain input element");
-            SimpleNode<?> routeContainer = inputContainer.getFirstSimpleByName(strategy.getLeaf());
-            checkArgument(routeContainer != null, "Leaf %s must be set with value", strategy.getLeaf());
-            Object route = routeContainer.getValue();
-            checkArgument(route instanceof InstanceIdentifier,
-                          "The routed node %s is not an instance identifier", route);
-            RpcImplementation potential = null;
-            if (route != null) {
-                RoutedRpcRegImpl potentialReg = implementations.get(route);
-                if (potentialReg != null) {
-                    potential = potentialReg.getInstance();
-                }
-            }
-            if (potential == null) {
-                return router.invokeRpc(rpc, (InstanceIdentifier) route, input);
-            }
-            checkState(potential != null, "No implementation is available for rpc:%s path:%s", rpc, route);
-            return potential.invokeRpc(rpc, input);
-        }
-
-        public void addPath(QName context, InstanceIdentifier path, RoutedRpcRegImpl routedRpcRegImpl) {
-            //checkArgument(strategy.getContext().equals(context),"Supplied context is not supported.");
-            RoutedRpcRegImpl previous = implementations.put(path, routedRpcRegImpl);
-            if (previous == null) {
-                router.notifyPathAnnouncement(context,strategy.getIdentifier(), path);
-            }
-
-        }
-
-        public void removePath(QName context, InstanceIdentifier path, RoutedRpcRegImpl routedRpcRegImpl) {
-            boolean removed = implementations.remove(path, routedRpcRegImpl);
-            if (removed) {
-                router.notifyPathWithdrawal(context, strategy.getIdentifier(), path);
-            }
-        }
-    }
-
-    private static class GlobalRpcRegistration extends AbstractObjectRegistration<RpcImplementation> implements
-            RpcRegistration {
-        private final QName type;
-        private SchemaAwareRpcBroker router;
-
-        public GlobalRpcRegistration(QName type, RpcImplementation instance, SchemaAwareRpcBroker router) {
-            super(instance);
-            this.type = type;
-            this.router = router;
-        }
-
-        @Override
-        public QName getType() {
-            return type;
-        }
-
-        @Override
-        protected void removeRegistration() {
-            if (router != null) {
-                router.remove(this);
-                router = null;
-            }
-        }
-    }
-
-    private static class RoutedRpcRegImpl extends AbstractObjectRegistration<RpcImplementation> implements
-            RoutedRpcRegistration {
-
-        private final QName type;
-        private final RoutedRpcSelector router;
-
-        public RoutedRpcRegImpl(QName rpcType, RpcImplementation implementation, RoutedRpcSelector routedRpcSelector) {
-            super(implementation);
-            this.type = rpcType;
-            router = routedRpcSelector;
-        }
-
-        @Override
-        public void registerPath(QName context, InstanceIdentifier path) {
-            router.addPath(context, path, this);
-        }
-
-        @Override
-        public void unregisterPath(QName context, InstanceIdentifier path) {
-            router.removePath(context, path, this);
-        }
-
-        @Override
-        protected void removeRegistration() {
-
-        }
-
-        @Override
-        public QName getType() {
-            return type;
-        }
-
-    }
-
-    private void remove(GlobalRpcRegistration registration) {
+    void remove(final GlobalRpcRegistration registration) {
         implementations.remove(registration.getType(), registration);
     }
 
-    private void notifyPathAnnouncement(QName context, QName identifier, InstanceIdentifier path) {
+    void notifyPathAnnouncement(final QName context, final QName identifier, final YangInstanceIdentifier path) {
         RpcRoutingContext contextWrapped = RpcRoutingContext.create(context, identifier);
-        RouteChange<RpcRoutingContext, InstanceIdentifier> change = RoutingUtils.announcementChange(contextWrapped , path);
-        for(ListenerRegistration<RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> routeListener : routeChangeListeners) {
+        RouteChange<RpcRoutingContext, YangInstanceIdentifier> change = RoutingUtils.announcementChange(contextWrapped , path);
+        for(ListenerRegistration<RouteChangeListener<RpcRoutingContext, YangInstanceIdentifier>> routeListener : routeChangeListeners) {
             try {
                 routeListener.getInstance().onRouteChange(change);
             } catch (Exception e) {
                 LOG.error("Unhandled exception during invoking onRouteChange for {}",routeListener.getInstance(),e);
-
             }
         }
 
     }
 
-
-
-    private void notifyPathWithdrawal(QName context,QName identifier, InstanceIdentifier path) {
+    void notifyPathWithdrawal(final QName context,final QName identifier, final YangInstanceIdentifier path) {
         RpcRoutingContext contextWrapped = RpcRoutingContext.create(context, identifier);
-        RouteChange<RpcRoutingContext, InstanceIdentifier> change = RoutingUtils.removalChange(contextWrapped , path);
-        for(ListenerRegistration<RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> routeListener : routeChangeListeners) {
+        RouteChange<RpcRoutingContext, YangInstanceIdentifier> change = RoutingUtils.removalChange(contextWrapped , path);
+        for(ListenerRegistration<RouteChangeListener<RpcRoutingContext, YangInstanceIdentifier>> routeListener : routeChangeListeners) {
             try {
                 routeListener.getInstance().onRouteChange(change);
             } catch (Exception e) {
@@ -454,10 +251,10 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String>, Ro
     }
 
     @Override
-    public <L extends RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(
-            L listener) {
+    public <L extends RouteChangeListener<RpcRoutingContext, YangInstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(
+            final L listener) {
         ListenerRegistration<L> reg = routeChangeListeners.registerWithType(listener);
-        RouteChange<RpcRoutingContext, InstanceIdentifier> initial = createInitialRouteChange();
+        RouteChange<RpcRoutingContext, YangInstanceIdentifier> initial = createInitialRouteChange();
         try {
         listener.onRouteChange(initial);
         } catch (Exception e) {
@@ -466,15 +263,15 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String>, Ro
         return reg;
     }
 
-    private RouteChange<RpcRoutingContext, InstanceIdentifier> createInitialRouteChange() {
+    private RouteChange<RpcRoutingContext, YangInstanceIdentifier> createInitialRouteChange() {
         FluentIterable<RoutedRpcSelector> rpcSelectors = FluentIterable.from(implementations.values()).filter(RoutedRpcSelector.class);
 
 
-        ImmutableMap.Builder<RpcRoutingContext, Set<InstanceIdentifier>> announcements = ImmutableMap.builder();
-        ImmutableMap.Builder<RpcRoutingContext, Set<InstanceIdentifier>> removals = ImmutableMap.builder();
+        ImmutableMap.Builder<RpcRoutingContext, Set<YangInstanceIdentifier>> announcements = ImmutableMap.builder();
+        ImmutableMap.Builder<RpcRoutingContext, Set<YangInstanceIdentifier>> removals = ImmutableMap.builder();
         for (RoutedRpcSelector routedRpcSelector : rpcSelectors) {
             final RpcRoutingContext context = routedRpcSelector.getIdentifier();
-            final Set<InstanceIdentifier> paths = ImmutableSet.copyOf(routedRpcSelector.implementations.keySet());
+            final Set<YangInstanceIdentifier> paths = ImmutableSet.copyOf(routedRpcSelector.implementations.keySet());
             announcements.put(context, paths);
         }
         return RoutingUtils.change(announcements.build(), removals.build());
index 853e3e391f591a8b3d6c5aad72d5d62da0093471..275107ed8fb062bcfaf7c766cd0701ab3f0625af 100644 (file)
@@ -14,6 +14,8 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
+import javax.annotation.Nullable;
+
 import org.opendaylight.controller.sal.core.api.BrokerService;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.osgi.framework.ServiceReference;
@@ -23,9 +25,9 @@ public abstract class AbstractBrokerServiceProxy<T extends BrokerService> implem
     private T delegate;
     private final ServiceReference<T> reference;
 
-    public AbstractBrokerServiceProxy(final ServiceReference<T> ref, final T delegate) {
+    public AbstractBrokerServiceProxy(final @Nullable ServiceReference<T> ref, final T delegate) {
         this.delegate = checkNotNull(delegate, "Delegate should not be null.");
-        this.reference = checkNotNull(ref, "Reference should not be null.");
+        this.reference = ref;
     }
 
     protected final T getDelegate() {
@@ -37,9 +39,9 @@ public abstract class AbstractBrokerServiceProxy<T extends BrokerService> implem
         return reference;
     }
 
-    private final Set<Registration<?>> registrations = Collections.synchronizedSet(new HashSet<Registration<?>>());
+    private final Set<Registration> registrations = Collections.synchronizedSet(new HashSet<Registration>());
 
-    protected <R extends Registration<?>> R addRegistration(final R registration) {
+    protected <R extends Registration> R addRegistration(final R registration) {
         if (registration != null) {
             registrations.add(registration);
         }
@@ -61,7 +63,7 @@ public abstract class AbstractBrokerServiceProxy<T extends BrokerService> implem
             RuntimeException potentialException = new RuntimeException(
                     "Uncaught exceptions occured during unregistration");
             boolean hasSuppressed = false;
-            for (Registration<?> registration : registrations) {
+            for (Registration registration : registrations) {
                 try {
                     registration.close();
                 } catch (Exception e) {
index 4f44f361d5d352e51378a681ef57dc48ebddd78c..b539cb948daadda555060379581788c1712bc1bf 100644 (file)
@@ -9,7 +9,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.osgi.framework.ServiceReference;
 
 public class DOMDataBrokerProxy extends AbstractBrokerServiceProxy<DOMDataBroker> implements DOMDataBroker {
@@ -35,7 +35,7 @@ public class DOMDataBrokerProxy extends AbstractBrokerServiceProxy<DOMDataBroker
 
     @Override
     public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(final LogicalDatastoreType store,
-            final InstanceIdentifier path, final DOMDataChangeListener listener,
+            final YangInstanceIdentifier path, final DOMDataChangeListener listener,
             final org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope triggeringScope) {
         return getDelegate().registerDataChangeListener(store, path, listener, triggeringScope);
     }
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/DOMMountPointServiceProxy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/DOMMountPointServiceProxy.java
new file mode 100644 (file)
index 0000000..7a67755
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+package org.opendaylight.controller.sal.dom.broker.osgi;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.osgi.framework.ServiceReference;
+
+public class DOMMountPointServiceProxy extends AbstractBrokerServiceProxy<DOMMountPointService> implements DOMMountPointService{
+
+
+    public DOMMountPointServiceProxy(final ServiceReference<DOMMountPointService> ref, final DOMMountPointService delegate) {
+        super(ref, delegate);
+    }
+
+    @Override
+    public Optional<DOMMountPoint> getMountPoint(final YangInstanceIdentifier path) {
+        return getDelegate().getMountPoint(path);
+    }
+
+    @Override
+    public DOMMountPointBuilder createMountPoint(final YangInstanceIdentifier path) {
+        return getDelegate().createMountPoint(path);
+    }
+
+    public ListenerRegistration<MountProvisionListener> registerProvisionListener(final MountProvisionListener listener) {
+        return getDelegate().registerProvisionListener(listener);
+    }
+}
index 30027ec929b2529d366de9c7fd5c6d0fe25f5d7d..94d423e0126931559e08ca40fd7c56b5e98f1843 100644 (file)
@@ -12,7 +12,7 @@ import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.osgi.framework.ServiceReference;
 
 public class DataBrokerServiceProxy extends AbstractBrokerServiceProxy<DataBrokerService> implements DataBrokerService {
@@ -21,16 +21,16 @@ public class DataBrokerServiceProxy extends AbstractBrokerServiceProxy<DataBroke
         super(ref, delegate);
     }
 
-    public ListenerRegistration<DataChangeListener> registerDataChangeListener(InstanceIdentifier path,
+    public ListenerRegistration<DataChangeListener> registerDataChangeListener(YangInstanceIdentifier path,
             DataChangeListener listener) {
         return addRegistration(getDelegate().registerDataChangeListener(path, listener));
     }
 
-    public CompositeNode readConfigurationData(InstanceIdentifier path) {
+    public CompositeNode readConfigurationData(YangInstanceIdentifier path) {
         return getDelegate().readConfigurationData(path);
     }
 
-    public CompositeNode readOperationalData(InstanceIdentifier path) {
+    public CompositeNode readOperationalData(YangInstanceIdentifier path) {
         return getDelegate().readOperationalData(path);
     }
 
index caae2971f8bf8eaba5cc392f7252aa123c086fa4..86bfa23ed22c38b2135f3fcf80dc70b2701a104f 100644 (file)
@@ -19,7 +19,7 @@ import org.opendaylight.controller.sal.core.api.data.DataValidator;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.osgi.framework.ServiceReference;
 
 public class DataProviderServiceProxy extends AbstractBrokerServiceProxy<DataProviderService> implements
@@ -29,16 +29,16 @@ public class DataProviderServiceProxy extends AbstractBrokerServiceProxy<DataPro
         super(ref, delegate);
     }
 
-    public ListenerRegistration<DataChangeListener> registerDataChangeListener(InstanceIdentifier path,
+    public ListenerRegistration<DataChangeListener> registerDataChangeListener(YangInstanceIdentifier path,
             DataChangeListener listener) {
         return addRegistration(getDelegate().registerDataChangeListener(path, listener));
     }
 
-    public CompositeNode readConfigurationData(InstanceIdentifier path) {
+    public CompositeNode readConfigurationData(YangInstanceIdentifier path) {
         return getDelegate().readConfigurationData(path);
     }
 
-    public CompositeNode readOperationalData(InstanceIdentifier path) {
+    public CompositeNode readOperationalData(YangInstanceIdentifier path) {
         return getDelegate().readOperationalData(path);
     }
 
@@ -57,20 +57,20 @@ public class DataProviderServiceProxy extends AbstractBrokerServiceProxy<DataPro
     }
 
     @Override
-    public Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> registerCommitHandler(
-            InstanceIdentifier path, DataCommitHandler<InstanceIdentifier, CompositeNode> commitHandler) {
+    public Registration registerCommitHandler(
+            YangInstanceIdentifier path, DataCommitHandler<YangInstanceIdentifier, CompositeNode> commitHandler) {
         return addRegistration(getDelegate().registerCommitHandler(path, commitHandler));
     }
 
     @Override
-    public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerConfigurationReader(
-            InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+    public Registration registerConfigurationReader(
+            YangInstanceIdentifier path, DataReader<YangInstanceIdentifier, CompositeNode> reader) {
         return addRegistration(getDelegate().registerConfigurationReader(path, reader));
     }
 
     @Override
-    public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerOperationalReader(
-            InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+    public Registration registerOperationalReader(
+            YangInstanceIdentifier path, DataReader<YangInstanceIdentifier, CompositeNode> reader) {
         return addRegistration(getDelegate().registerOperationalReader(path, reader));
     }
 
@@ -85,8 +85,8 @@ public class DataProviderServiceProxy extends AbstractBrokerServiceProxy<DataPro
     }
 
     @Override
-    public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>>> registerCommitHandlerListener(
-            RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>> commitHandlerListener) {
+    public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<YangInstanceIdentifier, CompositeNode>>> registerCommitHandlerListener(
+            RegistrationListener<DataCommitHandlerRegistration<YangInstanceIdentifier, CompositeNode>> commitHandlerListener) {
         return addRegistration(getDelegate().registerCommitHandlerListener(commitHandlerListener));
     }
 }
index 24d5430d6d3713a0c6b3e5a5252eb710e9550e7d..c807aa0b84e8e6e9d745cd285b33692fdc785871 100644 (file)
@@ -8,9 +8,10 @@
 package org.opendaylight.controller.sal.dom.broker.osgi;
 
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionListener;
 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.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.osgi.framework.ServiceReference;
 
 public class MountProviderServiceProxy extends AbstractBrokerServiceProxy<MountProvisionService> implements MountProvisionService{
@@ -21,17 +22,17 @@ public class MountProviderServiceProxy extends AbstractBrokerServiceProxy<MountP
     }
 
     @Override
-    public MountProvisionInstance getMountPoint(InstanceIdentifier path) {
+    public MountProvisionInstance getMountPoint(YangInstanceIdentifier path) {
         return getDelegate().getMountPoint(path);
     }
 
     @Override
-    public MountProvisionInstance createMountPoint(InstanceIdentifier path) {
+    public MountProvisionInstance createMountPoint(YangInstanceIdentifier path) {
         return getDelegate().createMountPoint(path);
     }
 
     @Override
-    public MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path) {
+    public MountProvisionInstance createOrGetMountPoint(YangInstanceIdentifier path) {
         return getDelegate().createOrGetMountPoint(path);
     }
 
index cd26c4ea5c51f1f8d0283d8fb40803954528e48b..72cd41b9336d5233ad2129f7d81644b38065730b 100644 (file)
@@ -9,7 +9,7 @@ package org.opendaylight.controller.sal.dom.broker.osgi;
 
 import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
 import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.osgi.framework.ServiceReference;
@@ -22,7 +22,7 @@ public class NotificationPublishServiceProxy extends AbstractBrokerServiceProxy<
     }
 
     @Override
-    public Registration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
+    public ListenerRegistration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
         return addRegistration(getDelegate().addNotificationListener(notification, listener));
 
     }
index a0051dc38e5efa2f3156bc3fc6a2e9b8fb4d5420..4da7f025b34bec4ba57cf483e3595e6d0bbf545f 100644 (file)
@@ -9,7 +9,7 @@ package org.opendaylight.controller.sal.dom.broker.osgi;
 
 import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
 import org.opendaylight.controller.sal.core.api.notify.NotificationService;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.osgi.framework.ServiceReference;
 
@@ -21,7 +21,7 @@ public class NotificationServiceProxy extends AbstractBrokerServiceProxy<Notific
     }
 
     @Override
-    public Registration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
+    public ListenerRegistration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
         return addRegistration(getDelegate().addNotificationListener(notification, listener));
     }
 }
index c2d6add17a07c8ffefa711618034b690d35040ae..2ce2bac86227f2e9b0decf770a68dea7f5bcd1bb 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.sal.dom.broker.osgi;
 
 import java.util.Arrays;
 
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.sal.core.api.BrokerService;
 import org.osgi.framework.ServiceReference;
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
@@ -66,6 +67,13 @@ public class ProxyFactory {
                 ((ServiceReference<MountProvisionService>) ref), service);
     }
 
+    private static Object _createProxyImpl(final ServiceReference<?> ref,
+            final DOMMountPointService service) {
+
+        return new DOMMountPointServiceProxy(
+                ((ServiceReference<DOMMountPointService>) ref), service);
+    }
+
     private static Object _createProxyImpl(final ServiceReference<?> ref,
             final SchemaService service) {
 
@@ -113,6 +121,8 @@ public class ProxyFactory {
             return _createProxyImpl(ref, (SchemaService) service);
         } else if (service instanceof NotificationService) {
             return _createProxyImpl(ref, (NotificationService) service);
+        } else if (service instanceof DOMMountPointService) {
+            return _createProxyImpl(ref, (DOMMountPointService) service);
         } else if (service != null) {
             return _createProxyImpl(ref, service);
         } else {
index 7193a5317709e1b3494eef90bd563b628b6dadec..3c1901a53096c42ac7dc2a821a35887bb8dd77a2 100644 (file)
@@ -21,7 +21,7 @@ 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.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.osgi.framework.ServiceReference;
 
 import com.google.common.util.concurrent.ListenableFuture;
@@ -53,7 +53,7 @@ public class RpcProvisionRegistryProxy extends AbstractBrokerServiceProxy<RpcPro
     }
 
     @Override
-    public <L extends RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(final L listener) {
+    public <L extends RouteChangeListener<RpcRoutingContext, YangInstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(final L listener) {
         return getDelegate().registerRouteChangeListener(listener);
     }
 
index f893f96d18c59e94df9fe7961b8856b214a6f196..113a9c08dbe064f2d8d2066ee94dd8a1e0952505 100644 (file)
@@ -23,7 +23,7 @@ public class SchemaServiceActivator implements BundleActivator {
 
     @Override
     public void start(final BundleContext context) {
-        schemaService = new GlobalBundleScanningSchemaServiceImpl(context);
+        schemaService = GlobalBundleScanningSchemaServiceImpl.createInstance(context);
         schemaService.start();
         schemaServiceReg = context.registerService(SchemaService.class, schemaService, new Hashtable<String,String>());
     }
index ebe95d6eb5589624536c887f7b8802898b0e7384..2d8bd186c5fb3e5eb297722b10724fb44cee022d 100644 (file)
@@ -8,7 +8,7 @@
 package org.opendaylight.controller.sal.dom.broker.spi;
 
 import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
@@ -22,7 +22,7 @@ public interface NotificationRouter {
      * @param notification
      * @param listener
      */
-    Registration<NotificationListener> addNotificationListener(QName notification,
+    ListenerRegistration<NotificationListener> addNotificationListener(QName notification,
             NotificationListener listener);
 
 }
index 2976c76ffa0a8ea91679baa975ecf2e77efc14cf..f5e7dc99bda604493b6b8bc8cd1b396a7efe438b 100644 (file)
@@ -12,7 +12,7 @@ import java.util.Map;
 import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
 import org.opendaylight.controller.sal.core.api.RpcImplementation;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 public interface RoutedRpcProcessor extends RpcImplementation {
 
@@ -20,7 +20,7 @@ public interface RoutedRpcProcessor extends RpcImplementation {
 
     QName getRpcType();
 
-    Map<InstanceIdentifier,RpcImplementation> getRoutes();
+    Map<YangInstanceIdentifier,RpcImplementation> getRoutes();
 
     RpcImplementation getDefaultRoute();
 
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/ProxySchemaContext.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/ProxySchemaContext.java
new file mode 100644 (file)
index 0000000..311055f
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+
+package org.opendaylight.controller.sal.dom.broker.util;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+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 com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+/**
+ * ProxySchema Context for SchemaContextProviders
+ */
+public class ProxySchemaContext implements SchemaContext {
+
+    private final SchemaContextProvider schemaProvider;
+
+    public ProxySchemaContext(final SchemaContextProvider schemaProvider) {
+        this.schemaProvider = schemaProvider;
+    }
+
+    private SchemaContext getCurrentSchema() {
+        Preconditions.checkState(schemaProvider.getSchemaContext() != null, "Schema context unavailable from %s", schemaProvider);
+        return schemaProvider.getSchemaContext();
+    }
+
+    @Override
+    public Set<DataSchemaNode> getDataDefinitions() {
+        return getCurrentSchema().getDataDefinitions();
+    }
+
+    @Override
+    public Set<Module> getModules() {
+        return getCurrentSchema().getModules();
+    }
+
+    @Override
+    public Set<NotificationDefinition> getNotifications() {
+        return getCurrentSchema().getNotifications();
+    }
+
+    @Override
+    public Set<RpcDefinition> getOperations() {
+        return getCurrentSchema().getOperations();
+    }
+
+    @Override
+    public Set<ExtensionDefinition> getExtensions() {
+        return getCurrentSchema().getExtensions();
+    }
+
+    @Override
+    public Module findModuleByName(final String s, final Date date) {
+        return getCurrentSchema().findModuleByName(s, date);
+    }
+
+    @Override
+    public Set<Module> findModuleByNamespace(final URI uri) {
+        return getCurrentSchema().findModuleByNamespace(uri);
+    }
+
+    @Override
+    public Module findModuleByNamespaceAndRevision(final URI uri, final Date date) {
+        return getCurrentSchema().findModuleByNamespaceAndRevision(uri, date);
+    }
+
+    @Override
+    public Optional<String> getModuleSource(final ModuleIdentifier moduleIdentifier) {
+        return getCurrentSchema().getModuleSource(moduleIdentifier);
+    }
+
+    @Override
+    public Set<ModuleIdentifier> getAllModuleIdentifiers() {
+        return getCurrentSchema().getAllModuleIdentifiers();
+    }
+
+    @Override
+    public boolean isPresenceContainer() {
+        return getCurrentSchema().isPresenceContainer();
+    }
+
+    @Override
+    public Set<TypeDefinition<?>> getTypeDefinitions() {
+        return getCurrentSchema().getTypeDefinitions();
+    }
+
+    @Override
+    public Collection<DataSchemaNode> getChildNodes() {
+        return getCurrentSchema().getChildNodes();
+    }
+
+    @Override
+    public Set<GroupingDefinition> getGroupings() {
+        return getCurrentSchema().getGroupings();
+    }
+
+    @Override
+    public DataSchemaNode getDataChildByName(final QName qName) {
+        return getCurrentSchema().getDataChildByName(qName);
+    }
+
+    @Override
+    public DataSchemaNode getDataChildByName(final String s) {
+        return getCurrentSchema().getDataChildByName(s);
+    }
+
+    @Override
+    public Set<UsesNode> getUses() {
+        return getCurrentSchema().getUses();
+    }
+
+    @Override
+    public Set<AugmentationSchema> getAvailableAugmentations() {
+        return getCurrentSchema().getAvailableAugmentations();
+    }
+
+    @Override
+    public boolean isAugmenting() {
+        return getCurrentSchema().isAugmenting();
+    }
+
+    @Override
+    public boolean isAddedByUses() {
+        return getCurrentSchema().isAddedByUses();
+    }
+
+    @Override
+    public boolean isConfiguration() {
+        return getCurrentSchema().isConfiguration();
+    }
+
+    @Override
+    public ConstraintDefinition getConstraints() {
+        return getCurrentSchema().getConstraints();
+    }
+
+    @Override
+    public QName getQName() {
+        return getCurrentSchema().getQName();
+    }
+
+    @Override
+    public SchemaPath getPath() {
+        return getCurrentSchema().getPath();
+    }
+
+    @Override
+    public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+        return getCurrentSchema().getUnknownSchemaNodes();
+    }
+
+    @Override
+    public String getDescription() {
+        return getCurrentSchema().getDescription();
+    }
+
+    @Override
+    public String getReference() {
+        return getCurrentSchema().getReference();
+    }
+
+    @Override
+    public Status getStatus() {
+        return getCurrentSchema().getStatus();
+    }
+}
index 0f8ce1d95d31f727c018a9f801dca421c73f8a32..5adf39142ec5ee2af194b921a76b2ce01031ffd5 100644 (file)
@@ -9,6 +9,9 @@ package org.opendaylight.controller.sal.dom.broker.util;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -29,9 +32,6 @@ 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 com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
-
 public class YangDataOperations {
 
     public static CompositeNode merge(final DataSchemaNode schema,
@@ -84,10 +84,10 @@ public class YangDataOperations {
         }
         @SuppressWarnings({ "unchecked", "rawtypes" })
         final Map<Map<QName, Object>, CompositeNode> originalMap = YangDataUtils
-                .toIndexMap((List) original, node.getKeyDefinition());
+        .toIndexMap((List) original, node.getKeyDefinition());
         @SuppressWarnings({ "unchecked", "rawtypes" })
         final Map<Map<QName, Object>, CompositeNode> modifiedMap = YangDataUtils
-                .toIndexMap((List) modified, node.getKeyDefinition());
+        .toIndexMap((List) modified, node.getKeyDefinition());
 
         final List<Node<?>> mergedNodes = new ArrayList<Node<?>>(
                 original.size() + modified.size());
@@ -140,7 +140,7 @@ public class YangDataOperations {
                 modified.getNodeType()));
 
         final List<Node<?>> mergedChildNodes = new ArrayList<Node<?>>(stored
-                .getChildren().size() + modified.getChildren().size());
+                .getValue().size() + modified.getValue().size());
         final Set<QName> toProcess = new HashSet<QName>(stored.keySet());
         toProcess.addAll(modified.keySet());
 
index 306cd34a69502187084bec2a33643cac5231e979..970bb0289910d2f2cd5dc3c473acec9af661a2d0 100644 (file)
@@ -10,13 +10,16 @@ package org.opendaylight.controller.sal.dom.broker.util;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
 
+import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
+
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
@@ -34,9 +37,6 @@ 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 com.google.common.base.Function;
-import com.google.common.collect.FluentIterable;
-
 public final class YangSchemaUtils {
 
     private static final Function<PathArgument, QName> QNAME_FROM_PATH_ARGUMENT = new Function<PathArgument, QName>(){
@@ -54,10 +54,10 @@ public final class YangSchemaUtils {
         throw new UnsupportedOperationException("Utility class.");
     }
 
-    public static DataSchemaNode getSchemaNode(final SchemaContext schema,final InstanceIdentifier path) {
+    public static DataSchemaNode getSchemaNode(final SchemaContext schema,final YangInstanceIdentifier path) {
         checkArgument(schema != null,"YANG Schema must not be null.");
         checkArgument(path != null,"Path must not be null.");
-        return getSchemaNode(schema, FluentIterable.from(path.getPath()).transform(QNAME_FROM_PATH_ARGUMENT));
+        return getSchemaNode(schema, FluentIterable.from(path.getPathArguments()).transform(QNAME_FROM_PATH_ARGUMENT));
     }
 
     public static DataSchemaNode getSchemaNode(final SchemaContext schema,final Iterable<QName> path) {
@@ -92,8 +92,7 @@ public final class YangSchemaUtils {
     }
 
     private static DataSchemaNode searchInChoices(final DataNodeContainer node, final QName arg) {
-        Set<DataSchemaNode> children = node.getChildNodes();
-        for (DataSchemaNode child : children) {
+        for (DataSchemaNode child : node.getChildNodes()) {
             if (child instanceof ChoiceNode) {
                 ChoiceNode choiceNode = (ChoiceNode) child;
                 DataSchemaNode potential = searchInCases(choiceNode, arg);
index 82897b0198cbf183953f2051f87c8fcfe9f030a8..a0ee5c50c93bc8a576c2d71b2dd7b37b86cda896 100644 (file)
@@ -55,7 +55,7 @@ module opendaylight-sal-dom-broker-impl {
                     }
                 }
             }
-            
+
             container async-data-broker {
                 uses config:service-ref {
                     refine type {
@@ -63,7 +63,15 @@ module opendaylight-sal-dom-broker-impl {
                         config:required-identity sal:dom-async-data-broker;
                     }
                 }
-            
+            }
+
+            container root-schema-service {
+                uses config:service-ref {
+                    refine type {
+                        mandatory false;
+                        config:required-identity sal:schema-service;
+                    }
+                }
             }
         }
     }
index 29e078918e65eeae080f62c61d6ce5bae4fc3a9f..181396fc884699e07eef9e0778e1ce3655d5e721 100644 (file)
@@ -18,7 +18,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
 import org.opendaylight.controller.md.sal.dom.store.impl.TestModel;
 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -40,8 +40,8 @@ public class DOMBrokerPerformanceTest {
         return ImmutableNodes.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, i);
     }
 
-    private static InstanceIdentifier outerListPath(final int i) {
-        return InstanceIdentifier.builder(TestModel.OUTER_LIST_PATH)//
+    private static YangInstanceIdentifier outerListPath(final int i) {
+        return YangInstanceIdentifier.builder(TestModel.OUTER_LIST_PATH)//
                 .nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, i) //
                 .build();
     }
@@ -141,11 +141,11 @@ public class DOMBrokerPerformanceTest {
                 int i = 0;
                 for (DOMDataReadWriteTransaction writeTx :transactions) {
                     // Writes /test/outer-list/i in writeTx
-                    InstanceIdentifier path = InstanceIdentifier.builder(outerListPath(i))
+                    YangInstanceIdentifier path = YangInstanceIdentifier.builder(outerListPath(i))
                             .node(TestModel.INNER_LIST_QNAME).build();
                     writeTx.put(OPERATIONAL, path, ImmutableNodes.mapNodeBuilder(TestModel.INNER_LIST_QNAME).build());
                     for (int j = 0; j < innerNum; j++) {
-                        InstanceIdentifier innerPath = InstanceIdentifier.builder(path)
+                        YangInstanceIdentifier innerPath = YangInstanceIdentifier.builder(path)
                                 .nodeWithKey(TestModel.INNER_LIST_QNAME, TestModel.NAME_QNAME, String.valueOf(j))
                                 .build();
                         writeTx.put(
@@ -169,7 +169,7 @@ public class DOMBrokerPerformanceTest {
                             public List<ListenableFuture<?>> call() throws Exception {
                                 List<ListenableFuture<?>> builder = new ArrayList<>(txNum);
                                 for (DOMDataReadWriteTransaction tx :transactions) {
-                                    builder.add(tx.commit());
+                                    builder.add(tx.submit());
                                 }
                                 return builder;
                             }
@@ -205,7 +205,7 @@ public class DOMBrokerPerformanceTest {
             public Void call() throws Exception {
                 for (int i = 0; i < txNum; i++) {
                     for (int j = 0; j < innerNum; j++) {
-                        InstanceIdentifier path = InstanceIdentifier
+                        YangInstanceIdentifier path = YangInstanceIdentifier
                                 .builder(outerListPath(i))
                                 //
                                 .node(TestModel.INNER_LIST_QNAME)
@@ -267,7 +267,7 @@ public class DOMBrokerPerformanceTest {
                 measure("Txs:1 Submit", new Callable<ListenableFuture<?>>() {
                     @Override
                     public ListenableFuture<?> call() throws Exception {
-                        return writeTx.commit();
+                        return writeTx.submit();
                     }
                 }).get();
                 return null;
index fec73d665b90763a30ac7cc400d2bf364ffdd358..b006ca94e5d1387bfd84e7a76eccba3700756905 100644 (file)
@@ -107,7 +107,7 @@ public class DOMBrokerTest {
                 TestModel.TEST_PATH);
         assertTrue(writeTxContainer.get().isPresent());
 
-        writeTx.commit().get();
+        writeTx.submit().get();
 
         Optional<NormalizedNode<?, ?>> afterCommitRead = domBroker.newReadOnlyTransaction()
                 .read(OPERATIONAL, TestModel.TEST_PATH).get();
index 38f08b30f94ea37d4e73e3537c5c7bd798eb12ed..3ea0bcefa5bab97ea12a9ead64e40cce49b78277 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.controller.md.sal.dom.broker.impl;
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -21,7 +20,6 @@ import java.util.concurrent.TimeoutException;
 
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
@@ -29,7 +27,6 @@ import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
 import org.opendaylight.controller.md.sal.dom.store.impl.TestModel;
 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
-import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -80,7 +77,7 @@ public class DOMTransactionChainTest {
          * First transaction is marked as ready, we are able to allocate chained
          * transactions
          */
-        ListenableFuture<RpcResult<TransactionStatus>> firstWriteTxFuture = firstTx.commit();
+        ListenableFuture<Void> firstWriteTxFuture = firstTx.submit();
 
         /**
          * We alocate chained transaction - read transaction.
@@ -126,7 +123,7 @@ public class DOMTransactionChainTest {
         /**
          * third transaction is sealed and commited
          */
-        ListenableFuture<RpcResult<TransactionStatus>> thirdDeleteTxFuture = thirdDeleteTx.commit();
+        ListenableFuture<Void> thirdDeleteTxFuture = thirdDeleteTx.submit();
         assertCommitSuccessful(thirdDeleteTxFuture);
 
         /**
@@ -188,11 +185,9 @@ public class DOMTransactionChainTest {
         return tx;
     }
 
-    private static void assertCommitSuccessful(final ListenableFuture<RpcResult<TransactionStatus>> future)
+    private static void assertCommitSuccessful(final ListenableFuture<Void> future)
             throws InterruptedException, ExecutionException {
-        RpcResult<TransactionStatus> rpcResult = future.get();
-        assertTrue(rpcResult.isSuccessful());
-        assertEquals(TransactionStatus.COMMITED, rpcResult.getResult());
+        future.get();
     }
 
     private static void assertTestContainerExists(final DOMDataReadTransaction readTx) throws InterruptedException,
diff --git a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/broker/impl/MountPointServiceTest.java b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/broker/impl/MountPointServiceTest.java
new file mode 100644 (file)
index 0000000..4d686a9
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+
+package org.opendaylight.controller.md.sal.dom.broker.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.base.Optional;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService.DOMMountPointBuilder;
+import org.opendaylight.controller.md.sal.dom.broker.impl.mount.DOMMountPointServiceImpl;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public class MountPointServiceTest {
+
+    private DOMMountPointService mountService;
+    private static final YangInstanceIdentifier PATH = YangInstanceIdentifier.of(QName.create("namespace", "12-12-2012", "top"));
+
+    @Before
+    public void setup() {
+        mountService = new DOMMountPointServiceImpl();
+    }
+
+    @Test
+    public void createSimpleMountPoint() {
+        Optional<DOMMountPoint> mountNotPresent = mountService.getMountPoint(PATH);
+        assertFalse(mountNotPresent.isPresent());
+        DOMMountPointBuilder mountBuilder = mountService.createMountPoint(PATH);
+        mountBuilder.register();
+
+        Optional<DOMMountPoint> mountPresent = mountService.getMountPoint(PATH);
+        assertTrue(mountPresent.isPresent());
+    }
+}
index 91aa57c25957a392bffb82f092c4b19f0a5ba4ed..d5ba2a2b9a50212e0b75c4036f1afc5fc890b065 100644 (file)
@@ -8,7 +8,7 @@
 package org.opendaylight.controller.md.sal.dom.store.impl;
 
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
@@ -29,8 +29,8 @@ public class TestModel {
     public static final QName VALUE_QNAME = QName.create(TEST_QNAME, "value");
     private static final String DATASTORE_TEST_YANG = "/odl-datastore-test.yang";
 
-    public static final InstanceIdentifier TEST_PATH = InstanceIdentifier.of(TEST_QNAME);
-    public static final InstanceIdentifier OUTER_LIST_PATH = InstanceIdentifier.builder(TEST_PATH).node(OUTER_LIST_QNAME).build();
+    public static final YangInstanceIdentifier TEST_PATH = YangInstanceIdentifier.of(TEST_QNAME);
+    public static final YangInstanceIdentifier OUTER_LIST_PATH = YangInstanceIdentifier.builder(TEST_PATH).node(OUTER_LIST_QNAME).build();
     public static final QName TWO_QNAME = QName.create(TEST_QNAME,"two");
     public static final QName THREE_QNAME = QName.create(TEST_QNAME,"three");
 
diff --git a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPointManagerTest.java b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPointManagerTest.java
new file mode 100644 (file)
index 0000000..4d239a9
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+
+package org.opendaylight.controller.sal.dom.broker;
+
+import static junit.framework.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMService;
+import org.opendaylight.controller.md.sal.dom.broker.impl.mount.DOMMountPointServiceImpl;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionListener;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+public class BackwardsCompatibleMountPointManagerTest {
+    private static final Logger log = LoggerFactory.getLogger(BackwardsCompatibleMountPointManagerTest.class);
+
+    @Mock
+    private DOMMountPointServiceImpl domMountPointService;
+    @Mock
+    private DOMMountPointService.DOMMountPointBuilder mountBuilder;
+
+    private BackwardsCompatibleMountPointManager compatibleMountPointManager;
+    static final QName qName = QName.create("namespace", "12-12-1212", "mount");
+    static final YangInstanceIdentifier id = YangInstanceIdentifier.builder(qName).build();
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        stubMountService();
+        compatibleMountPointManager = new BackwardsCompatibleMountPointManager(domMountPointService);
+    }
+
+    @Test
+    public void testCreateMountpointAlreadyCreated() throws Exception {
+        compatibleMountPointManager.createMountPoint(id);
+        verify(domMountPointService).createMountPoint(id);
+        verify(mountBuilder, times(3)).addService(any(Class.class), any(DOMService.class));
+        verify(mountBuilder).addInitialSchemaContext(any(SchemaContext.class));
+
+        try {
+            compatibleMountPointManager.createMountPoint(id);
+        } catch (final IllegalStateException e) {
+            log.debug("", e);
+            return;
+        }
+        fail("Should fail to create duplicate mount");
+    }
+
+    @Test
+    public void testCreateMountpointGetOrCreate() throws Exception {
+        compatibleMountPointManager = new BackwardsCompatibleMountPointManager(new DOMMountPointServiceImpl());
+
+        final MountProvisionListener listener = new MountProvisionListener() {
+            public int createdMounts = 0;
+
+            @Override
+            public void onMountPointCreated(final YangInstanceIdentifier path) {
+                if(createdMounts++ > 1 ) {
+                    fail("Only one mount point should have been created");
+                }
+            }
+
+            @Override
+            public void onMountPointRemoved(final YangInstanceIdentifier path) {}
+        };
+
+        compatibleMountPointManager.registerProvisionListener(listener);
+
+        final MountProvisionInstance m1 = compatibleMountPointManager.createOrGetMountPoint(id);
+        m1.setSchemaContext(mockSchemaContext());
+        compatibleMountPointManager.createOrGetMountPoint(id);
+        compatibleMountPointManager.createOrGetMountPoint(id);
+    }
+
+    private void stubMountService() {
+        doReturn(mockMountPointBuilder()).when(domMountPointService).createMountPoint(any(YangInstanceIdentifier.class));
+        doReturn(Optional.of(mockMountPoint())).when(domMountPointService).getMountPoint(any(YangInstanceIdentifier.class));
+    }
+
+    private DOMMountPoint mockMountPoint() {
+        final DOMMountPoint mock = mock(DOMMountPoint.class);
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(final InvocationOnMock invocation) throws Throwable {
+                return Optional.of(mock(((Class<?>) invocation.getArguments()[0])));
+            }
+        }).when(mock).getService(any(Class.class));
+        doReturn(mockSchemaContext()).when(mock).getSchemaContext();
+        return mock;
+    }
+
+    static SchemaContext mockSchemaContext() {
+        final SchemaContext mock = mock(SchemaContext.class);
+        doReturn(qName).when(mock).getQName();
+        doReturn("schema").when(mock).toString();
+        doReturn(mock(DataSchemaNode.class)).when(mock).getDataChildByName(any(QName.class));
+        return mock;
+    }
+
+    private DOMMountPointService.DOMMountPointBuilder mockMountPointBuilder() {
+        doReturn(mountBuilder).when(mountBuilder).addService(any(Class.class), any(DOMService.class));
+        doReturn(mockObjectRegistration()).when(mountBuilder).register();
+        doReturn(mountBuilder).when(mountBuilder).addInitialSchemaContext(any(SchemaContext.class));
+        return mountBuilder;
+    }
+
+    private ObjectRegistration<?> mockObjectRegistration() {
+        return mock(ObjectRegistration.class);
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPointTest.java b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPointTest.java
new file mode 100644 (file)
index 0000000..91ae0c2
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+
+package org.opendaylight.controller.sal.dom.broker;
+
+import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.AbstractMap;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
+import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BackwardsCompatibleMountPointTest {
+    private static final Logger log = LoggerFactory.getLogger(BackwardsCompatibleMountPointManagerTest.class);
+
+    private static final YangInstanceIdentifier id = BackwardsCompatibleMountPointManagerTest.id;
+    private final NormalizedNode<?, ?> normalizedNode = mockNormalizedNode();
+    private final CompositeNode compositeNode = mockCompositeNode();
+
+    @Mock
+    private DataProviderService oldBroker;
+    @Mock
+    private SchemaContextProvider schemaContextProvider;
+    @Mock
+    private DataModificationTransaction mockTx;
+
+    private BackwardsCompatibleMountPoint.BackwardsCompatibleDomStore backwardsCompatibleDomStore;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        stubSchemaProvider();
+        stubOldBroker();
+        backwardsCompatibleDomStore = new BackwardsCompatibleMountPoint.BackwardsCompatibleDomStore(oldBroker, schemaContextProvider);
+    }
+
+    private void stubOldBroker() {
+        doReturn(compositeNode).when(oldBroker).readConfigurationData(id);
+        doReturn(compositeNode).when(oldBroker).readOperationalData(id);
+        doReturn(mockTx).when(oldBroker).beginTransaction();
+        doNothing().when(mockTx).putConfigurationData(id, compositeNode);
+        doNothing().when(mockTx).putOperationalData(id, compositeNode);
+        doReturn(com.google.common.util.concurrent.Futures.immediateFuture(RpcResultBuilder.success(TransactionStatus.COMMITED))).when(mockTx).commit();
+    }
+
+    private CompositeNode mockCompositeNode() {
+        final CompositeNode mock = mock(CompositeNode.class);
+        doReturn("node").when(mock).toString();
+        return mock;
+    }
+
+    private void stubSchemaProvider() {
+        doReturn(BackwardsCompatibleMountPointManagerTest.mockSchemaContext()).when(schemaContextProvider).getSchemaContext();
+    }
+
+    @Test
+    public void testBackwardsCompatibleBroker() throws Exception {
+        backwardsCompatibleDomStore.newReadOnlyTransaction();
+        backwardsCompatibleDomStore.newWriteOnlyTransaction();
+        backwardsCompatibleDomStore.newReadWriteTransaction();
+    }
+
+    @Test
+    public void testReadTransaction() throws Exception {
+        final BackwardsCompatibleMountPoint.BackwardsCompatibleDomStore.BackwardsCompatibleReadTransaction tx =
+                new BackwardsCompatibleMountPoint.BackwardsCompatibleDomStore.BackwardsCompatibleReadTransaction(oldBroker, mockNormalizer());
+
+        ListenableFuture<Optional<NormalizedNode<?, ?>>> read = tx.read(LogicalDatastoreType.CONFIGURATION, id);
+        assertEquals(normalizedNode, read.get().get());
+        verify(oldBroker).readConfigurationData(id);
+
+        read = tx.read(LogicalDatastoreType.OPERATIONAL, id);
+        assertEquals(normalizedNode, read.get().get());
+
+        verify(oldBroker).readOperationalData(id);
+    }
+
+    @Test
+    public void testReadWriteTransactionOperational() throws Exception {
+        final BackwardsCompatibleMountPoint.BackwardsCompatibleDomStore.BackwardsCompatibleWriteTransaction tx =
+                new BackwardsCompatibleMountPoint.BackwardsCompatibleDomStore.BackwardsCompatibleWriteTransaction(oldBroker, mockNormalizer());
+
+        verify(oldBroker).beginTransaction();
+
+        tx.put(LogicalDatastoreType.CONFIGURATION, id, normalizedNode);
+        verify(mockTx).putConfigurationData(id, compositeNode);
+
+        tx.put(LogicalDatastoreType.CONFIGURATION, id, normalizedNode);
+        verify(mockTx, times(2)).putConfigurationData(id, compositeNode);
+
+        tx.commit();
+        verify(mockTx).commit();
+    }
+
+
+    @Test
+    public void testCannotPutOperational() throws Exception {
+        final BackwardsCompatibleMountPoint.BackwardsCompatibleDomStore.BackwardsCompatibleWriteTransaction tx =
+                new BackwardsCompatibleMountPoint.BackwardsCompatibleDomStore.BackwardsCompatibleWriteTransaction(oldBroker, mockNormalizer());
+
+        try {
+            tx.put(LogicalDatastoreType.OPERATIONAL, id, normalizedNode);
+        } catch (IllegalArgumentException e) {
+            // Cannot put operational data
+            log.debug("", e);
+            return;
+        }
+
+        fail("Should fail when putting operational data");
+    }
+
+    private DataNormalizer mockNormalizer() throws DataNormalizationException {
+        final DataNormalizer mock = mock(DataNormalizer.class);
+        doReturn(new AbstractMap.SimpleEntry<YangInstanceIdentifier, NormalizedNode<?, ?>>(id, normalizedNode) {})
+                .when(mock).toNormalized(any(YangInstanceIdentifier.class), any(CompositeNode.class));
+        doReturn(compositeNode).when(mock).toLegacy(any(YangInstanceIdentifier.class), any(NormalizedNode.class));
+        doReturn(id).when(mock).toLegacy(any(YangInstanceIdentifier.class));
+        return mock;
+    }
+
+    private NormalizedNode<?, ?> mockNormalizedNode() {
+        final NormalizedNode mock = mock(NormalizedNode.class);
+        doReturn("mockNormalizedNode").when(mock).toString();
+        return mock;
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/md/sal/dom/broker/spi/mount/SimpleDOMMountPoint.java b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/md/sal/dom/broker/spi/mount/SimpleDOMMountPoint.java
new file mode 100644 (file)
index 0000000..003da3e
--- /dev/null
@@ -0,0 +1,41 @@
+package org.opendaylight.controller.md.sal.dom.broker.spi.mount;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMService;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.ImmutableClassToInstanceMap;
+
+public class SimpleDOMMountPoint implements DOMMountPoint {
+
+    private final YangInstanceIdentifier identifier;
+    private final ClassToInstanceMap<DOMService> services;
+    private final SchemaContext schemaContext;
+
+    public static final SimpleDOMMountPoint create(final YangInstanceIdentifier identifier, final ClassToInstanceMap<DOMService> services, final SchemaContext ctx) {
+        return new SimpleDOMMountPoint(identifier, services, ctx);
+    }
+    private SimpleDOMMountPoint(final YangInstanceIdentifier identifier, final ClassToInstanceMap<DOMService> services, final SchemaContext ctx) {
+        this.identifier = identifier;
+        this.services = ImmutableClassToInstanceMap.copyOf(services);
+        this.schemaContext = ctx;
+    }
+
+    @Override
+    public YangInstanceIdentifier getIdentifier() {
+        return identifier;
+    }
+
+    @Override
+    public SchemaContext getSchemaContext() {
+        return schemaContext;
+    }
+
+    @Override
+    public <T extends DOMService> Optional<T> getService(final Class<T> cls) {
+        return Optional.fromNullable(services.getInstance(cls));
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/md/sal/dom/broker/spi/rpc/RpcRoutingStrategy.java b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/md/sal/dom/broker/spi/rpc/RpcRoutingStrategy.java
new file mode 100644 (file)
index 0000000..81203c5
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.broker.spi.rpc;
+
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+
+import com.google.common.base.Optional;
+
+public abstract class RpcRoutingStrategy implements Identifiable<QName> {
+
+    private final QName identifier;
+    private static final QName CONTEXT_REFERENCE = QName.create("urn:opendaylight:yang:extension:yang-ext",
+            "2013-07-09", "context-reference");
+
+    private RpcRoutingStrategy(final QName identifier) {
+        super();
+        this.identifier = identifier;
+    }
+
+    /**
+     * Returns leaf QName in which RPC Route is stored
+     *
+     *
+     * @return leaf QName in which RPC Route is stored
+     * @throws UnsupportedOperationException If RPC is not content routed.
+     *  ({@link #isContextBasedRouted()} returned <code>false</code>)
+     */
+    public abstract QName getLeaf();
+
+    /**
+     * Returns identity QName which represents RPC Routing context
+     *
+     * @return identity QName which represents RPC Routing context
+     * @throws UnsupportedOperationException If RPC is not content routed.
+     *  ({@link #isContextBasedRouted()} returned <code>false</code>)
+     */
+    public abstract QName getContext();
+
+    @Override
+    public QName getIdentifier() {
+        return identifier;
+    }
+
+    /**
+     * Returns true if RPC is routed by context.
+     *
+     * @return true if RPC is routed by content.
+     */
+    public abstract boolean isContextBasedRouted();
+
+    public static RpcRoutingStrategy from(final RpcDefinition rpc) {
+        ContainerSchemaNode input = rpc.getInput();
+        if (input != null) {
+            for (DataSchemaNode schemaNode : input.getChildNodes()) {
+                Optional<QName> context = getRoutingContext(schemaNode);
+                if (context.isPresent()) {
+                    return createRoutedStrategy(rpc, context.get(), schemaNode.getQName());
+                }
+            }
+        }
+        return createGlobalStrategy(rpc);
+    }
+
+    public static  Optional<QName> getRoutingContext(final DataSchemaNode schemaNode) {
+        for (UnknownSchemaNode extension : schemaNode.getUnknownSchemaNodes()) {
+            if (CONTEXT_REFERENCE.equals(extension.getNodeType())) {
+                return Optional.fromNullable(extension.getQName());
+            }
+        }
+        return Optional.absent();
+    }
+
+    private static RpcRoutingStrategy createRoutedStrategy(final RpcDefinition rpc, final QName context, final QName leafNode) {
+        return new RoutedRpcStrategy(rpc.getQName(), context, leafNode);
+    }
+
+
+
+    private static RpcRoutingStrategy createGlobalStrategy(final RpcDefinition rpc) {
+        GlobalRpcStrategy ret = new GlobalRpcStrategy(rpc.getQName());
+        return ret;
+    }
+
+    private static class RoutedRpcStrategy extends RpcRoutingStrategy {
+
+        final QName context;
+        private final QName leaf;
+
+        private RoutedRpcStrategy(final QName identifier, final QName ctx, final QName leaf) {
+            super(identifier);
+            this.context = ctx;
+            this.leaf = leaf;
+        }
+
+        @Override
+        public QName getContext() {
+            return context;
+        }
+
+        @Override
+        public QName getLeaf() {
+            return leaf;
+        }
+
+        @Override
+        public boolean isContextBasedRouted() {
+            return true;
+        }
+    }
+
+    private static class GlobalRpcStrategy extends RpcRoutingStrategy {
+
+        public GlobalRpcStrategy(final QName identifier) {
+            super(identifier);
+        }
+
+        @Override
+        public boolean isContextBasedRouted() {
+            return false;
+        }
+
+        @Override
+        public QName getContext() {
+            throw new UnsupportedOperationException("Not routed strategy does not have context.");
+        }
+
+        @Override
+        public QName getLeaf() {
+            throw new UnsupportedOperationException("Not routed strategy does not have context.");
+        }
+    }
+}
\ No newline at end of file
index ab47d1034f884307a58a9453db55420ad9fd1947..0bab570bd130b4378c7e78510908eea5fa53a393 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.sal.core.spi.data;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 /**
@@ -48,8 +48,8 @@ public interface DOMStore extends DOMStoreTransactionFactory {
      *         registration / interest on receiving data changes.
      *
      */
-    <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> ListenerRegistration<L> registerChangeListener(
-            InstanceIdentifier path, L listener, DataChangeScope scope);
+    <L extends AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>> ListenerRegistration<L> registerChangeListener(
+            YangInstanceIdentifier path, L listener, DataChangeScope scope);
 
     /**
      *
index b546f2e77d20c93b215ea5305c1f0bd56ffa3fc0..ae1b3ee2aa32db9eb0836a6403fcadc5d0615a87 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.controller.sal.core.spi.data;
 
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.base.Optional;
@@ -31,5 +31,5 @@ public interface DOMStoreReadTransaction extends DOMStoreTransaction {
      *         {@link java.util.concurrent.Future#get()} returns {@link Optional#absent()}.
      *         </ul>
      */
-    ListenableFuture<Optional<NormalizedNode<?,?>>> read(InstanceIdentifier path);
+    ListenableFuture<Optional<NormalizedNode<?,?>>> read(YangInstanceIdentifier path);
 }
index 19bb0538c26023c2819f4cff2fa52964ed7056cb..0a090520f24dfd8ca94eac21a978c36bdac6eacc 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.controller.sal.core.spi.data;
 
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 public interface DOMStoreWriteTransaction extends DOMStoreTransaction {
@@ -29,7 +29,7 @@ public interface DOMStoreWriteTransaction extends DOMStoreTransaction {
      *             if the client code already sealed transaction and invoked
      *             {@link #ready()}
      */
-    void write(InstanceIdentifier path, NormalizedNode<?, ?> data);
+    void write(YangInstanceIdentifier path, NormalizedNode<?, ?> data);
 
     /**
      * Store a provided data at specified path. This acts as a add / replace
@@ -48,7 +48,7 @@ public interface DOMStoreWriteTransaction extends DOMStoreTransaction {
      *             if the client code already sealed transaction and invoked
      *             {@link #ready()}
      */
-    void merge(InstanceIdentifier path, NormalizedNode<?, ?> data);
+    void merge(YangInstanceIdentifier path, NormalizedNode<?, ?> data);
 
     /**
      *
@@ -60,7 +60,7 @@ public interface DOMStoreWriteTransaction extends DOMStoreTransaction {
      *             if the client code already sealed transaction and invoked
      *             {@link #ready()}
      */
-    void delete(InstanceIdentifier path);
+    void delete(YangInstanceIdentifier path);
 
     /**
      *
diff --git a/opendaylight/md-sal/sal-dom-xsql/.checkstyle b/opendaylight/md-sal/sal-dom-xsql/.checkstyle
new file mode 100644 (file)
index 0000000..48e02b8
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
+  <fileset name="all" enabled="true" check-config-name="Sun Checks" local="false">
+    <file-match-pattern match-pattern=".*" include-pattern="true"/>
+  </fileset>
+</fileset-config>
diff --git a/opendaylight/md-sal/sal-dom-xsql/.gitignore b/opendaylight/md-sal/sal-dom-xsql/.gitignore
new file mode 100644 (file)
index 0000000..a48e45b
--- /dev/null
@@ -0,0 +1 @@
+/target-ide
diff --git a/opendaylight/md-sal/sal-dom-xsql/pom.xml b/opendaylight/md-sal/sal-dom-xsql/pom.xml
new file mode 100644 (file)
index 0000000..2ab80da
--- /dev/null
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>sal-parent</artifactId>
+    <version>1.1-SNAPSHOT</version>
+  </parent>
+  <artifactId>sal-dom-xsql</artifactId>
+  <packaging>bundle</packaging>
+  <name>sal-dom-xsql</name>
+  <description>XSQL language</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>config-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-config</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-common-util</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-core-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>yang-jmx-generator-plugin</artifactId>
+      <version>${config.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-binding</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+    </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>
+        <dependencies>
+          <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>maven-sal-api-gen-plugin</artifactId>
+            <version>${yangtools.version}</version>
+            <type>jar</type>
+          </dependency>
+        </dependencies>
+        <executions>
+          <execution>
+            <goals>
+              <goal>generate-sources</goal>
+            </goals>
+            <configuration>
+              <yangFilesRootDir>src/main/yang</yangFilesRootDir>
+              <codeGenerators>
+                <generator>
+                  <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
+                  <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
+                  <additionalConfiguration>
+                    <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
+                  </additionalConfiguration>
+                </generator>
+                <generator>
+                  <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+                  <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+                </generator>
+              </codeGenerators>
+              <inspectDependencies>true</inspectDependencies>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:XSQL</url>
+  <scm>
+    <developerConnection>Sharon Aicler</developerConnection>
+    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:XSQL</url>
+  </scm>
+</project>
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/TablesResultSet.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/TablesResultSet.java
new file mode 100644 (file)
index 0000000..2f28052
--- /dev/null
@@ -0,0 +1,1241 @@
+package org.opendaylight.controller.md.sal.dom.xsql;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Map;
+
+public class TablesResultSet implements ResultSet {
+
+    private String tables[] = null;
+    private int pos = -1;
+
+    public TablesResultSet(XSQLBluePrint cache) {
+        //tables = cache.getInterfaceNames();
+    }
+
+    @Override
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean next() throws SQLException {
+        if (tables == null) {
+            return false;
+        }
+        pos++;
+        if (pos >= tables.length) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public void close() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean wasNull() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public String getString(int columnIndex) throws SQLException {
+        return tables[pos];
+    }
+
+    @Override
+    public boolean getBoolean(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public byte getByte(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public short getShort(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getInt(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public long getLong(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public float getFloat(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public double getDouble(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public BigDecimal getBigDecimal(int columnIndex, int scale)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public byte[] getBytes(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Date getDate(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Time getTime(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Timestamp getTimestamp(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public InputStream getAsciiStream(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public InputStream getUnicodeStream(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public InputStream getBinaryStream(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getString(String columnLabel) throws SQLException {
+        return tables[pos];
+    }
+
+    @Override
+    public boolean getBoolean(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public byte getByte(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public short getShort(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getInt(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public long getLong(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public float getFloat(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public double getDouble(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public BigDecimal getBigDecimal(String columnLabel, int scale)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public byte[] getBytes(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Date getDate(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Time getTime(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Timestamp getTimestamp(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public InputStream getAsciiStream(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public InputStream getUnicodeStream(String columnLabel)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public InputStream getBinaryStream(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public SQLWarning getWarnings() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void clearWarnings() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public String getCursorName() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSetMetaData getMetaData() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Object getObject(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Object getObject(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int findColumn(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public Reader getCharacterStream(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Reader getCharacterStream(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isBeforeFirst() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isAfterLast() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isFirst() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isLast() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void beforeFirst() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void afterLast() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean first() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean last() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public int getRow() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public boolean absolute(int row) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean relative(int rows) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean previous() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void setFetchDirection(int direction) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public int getFetchDirection() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public void setFetchSize(int rows) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public int getFetchSize() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getType() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getConcurrency() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public boolean rowUpdated() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean rowInserted() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean rowDeleted() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void updateNull(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBoolean(int columnIndex, boolean x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateByte(int columnIndex, byte x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateShort(int columnIndex, short x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateInt(int columnIndex, int x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateLong(int columnIndex, long x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateFloat(int columnIndex, float x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateDouble(int columnIndex, double x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBigDecimal(int columnIndex, BigDecimal x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateString(int columnIndex, String x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBytes(int columnIndex, byte[] x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateDate(int columnIndex, Date x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateTime(int columnIndex, Time x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateTimestamp(int columnIndex, Timestamp x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateAsciiStream(int columnIndex, InputStream x, int length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBinaryStream(int columnIndex, InputStream x, int length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateCharacterStream(int columnIndex, Reader x, int length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateObject(int columnIndex, Object x, int scaleOrLength)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateObject(int columnIndex, Object x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNull(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBoolean(String columnLabel, boolean x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateByte(String columnLabel, byte x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateShort(String columnLabel, short x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateInt(String columnLabel, int x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateLong(String columnLabel, long x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateFloat(String columnLabel, float x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateDouble(String columnLabel, double x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBigDecimal(String columnLabel, BigDecimal x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateString(String columnLabel, String x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBytes(String columnLabel, byte[] x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateDate(String columnLabel, Date x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateTime(String columnLabel, Time x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateTimestamp(String columnLabel, Timestamp x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateAsciiStream(String columnLabel, InputStream x, int length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBinaryStream(String columnLabel, InputStream x,
+        int length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateCharacterStream(String columnLabel, Reader reader,
+        int length) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateObject(String columnLabel, Object x, int scaleOrLength)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateObject(String columnLabel, Object x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void insertRow() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateRow() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void deleteRow() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void refreshRow() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void cancelRowUpdates() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void moveToInsertRow() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void moveToCurrentRow() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public Statement getStatement() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Object getObject(int columnIndex, Map<String, Class<?>> map)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Ref getRef(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Blob getBlob(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Clob getClob(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Array getArray(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Object getObject(String columnLabel, Map<String, Class<?>> map)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Ref getRef(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Blob getBlob(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Clob getClob(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Array getArray(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Date getDate(int columnIndex, Calendar cal) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Date getDate(String columnLabel, Calendar cal) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Time getTime(int columnIndex, Calendar cal) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Time getTime(String columnLabel, Calendar cal) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Timestamp getTimestamp(int columnIndex, Calendar cal)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Timestamp getTimestamp(String columnLabel, Calendar cal)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public URL getURL(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public URL getURL(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void updateRef(int columnIndex, Ref x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateRef(String columnLabel, Ref x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBlob(int columnIndex, Blob x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBlob(String columnLabel, Blob x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateClob(int columnIndex, Clob x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateClob(String columnLabel, Clob x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateArray(int columnIndex, Array x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateArray(String columnLabel, Array x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public RowId getRowId(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public RowId getRowId(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void updateRowId(int columnIndex, RowId x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateRowId(String columnLabel, RowId x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public int getHoldability() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public boolean isClosed() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void updateNString(int columnIndex, String nString)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNString(String columnLabel, String nString)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNClob(String columnLabel, NClob nClob)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public NClob getNClob(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NClob getNClob(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public SQLXML getSQLXML(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public SQLXML getSQLXML(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void updateSQLXML(int columnIndex, SQLXML xmlObject)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateSQLXML(String columnLabel, SQLXML xmlObject)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public String getNString(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getNString(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Reader getNCharacterStream(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Reader getNCharacterStream(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void updateNCharacterStream(int columnIndex, Reader x, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNCharacterStream(String columnLabel, Reader reader,
+        long length) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateAsciiStream(int columnIndex, InputStream x, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBinaryStream(int columnIndex, InputStream x, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateCharacterStream(int columnIndex, Reader x, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateAsciiStream(String columnLabel, InputStream x,
+        long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBinaryStream(String columnLabel, InputStream x,
+        long length) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateCharacterStream(String columnLabel, Reader reader,
+        long length) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBlob(int columnIndex, InputStream inputStream,
+        long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBlob(String columnLabel, InputStream inputStream,
+        long length) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateClob(int columnIndex, Reader reader, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateClob(String columnLabel, Reader reader, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNClob(int columnIndex, Reader reader, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNClob(String columnLabel, Reader reader, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNCharacterStream(int columnIndex, Reader x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNCharacterStream(String columnLabel, Reader reader)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateAsciiStream(int columnIndex, InputStream x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBinaryStream(int columnIndex, InputStream x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateCharacterStream(int columnIndex, Reader x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateAsciiStream(String columnLabel, InputStream x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBinaryStream(String columnLabel, InputStream x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateCharacterStream(String columnLabel, Reader reader)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBlob(int columnIndex, InputStream inputStream)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBlob(String columnLabel, InputStream inputStream)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateClob(int columnIndex, Reader reader) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateClob(String columnLabel, Reader reader)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNClob(int columnIndex, Reader reader)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNClob(String columnLabel, Reader reader)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <T> T getObject(String columnLabel, Class<T> type)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}
+
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLAdapter.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLAdapter.java
new file mode 100644 (file)
index 0000000..6d4400f
--- /dev/null
@@ -0,0 +1,531 @@
+package org.opendaylight.controller.md.sal.dom.xsql;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+import org.opendaylight.controller.md.sal.dom.xsql.jdbc.JDBCResultSet;
+import org.opendaylight.controller.md.sal.dom.xsql.jdbc.JDBCServer;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+
+public class XSQLAdapter extends Thread implements SchemaContextListener {
+
+    private static final int SLEEP = 10000;
+    private static XSQLAdapter a = new XSQLAdapter();
+    private static PrintStream l = null;
+    public boolean stopped = false;
+    private List<String> elementHosts = new ArrayList<String>();
+    private String username;
+    private String password;
+    private String transport = "tcp";
+    private int reconnectTimeout;
+    private int nThreads;
+    private int qsize;
+    private String applicationName = "NQL Adapter";
+    private Map<String, NEEntry> elements = new ConcurrentHashMap<String, XSQLAdapter.NEEntry>();
+    private StringBuffer lastInputString = new StringBuffer();
+    private XSQLBluePrint bluePrint = new XSQLBluePrint();
+    private boolean toCsv = false;
+    private String exportToFileName = null;
+    private XSQLThreadPool threadPool = new XSQLThreadPool(1, "Tasks", 2000);
+    private JDBCServer jdbcServer = new JDBCServer(this);
+    private String pinningFile;
+    private ServerSocket serverSocket = null;
+    private DOMDataBroker domDataBroker = null;
+
+    private XSQLAdapter() {
+        XSQLAdapter.log("Starting Adapter");
+        this.setDaemon(true);
+        try {
+            serverSocket = new ServerSocket(34343);
+        } catch (Exception err) {
+            XSQLAdapter.log(err);
+        }
+        this.start();
+        XSQLAdapter.log("Adapter Started!");
+
+    }
+
+    public static XSQLAdapter getInstance() {
+        return a;
+    }
+
+    public static void main(String args[]) {
+        XSQLAdapter adapter = new XSQLAdapter();
+        adapter.start();
+    }
+
+    public static void log(String str) {
+        try {
+            if (l == null) {
+                synchronized (XSQLAdapter.class) {
+                    if (l == null) {
+                        l = new PrintStream(
+                                new FileOutputStream("/tmp/xql.log"));
+                    }
+                }
+            }
+            l.print(Calendar.getInstance().getTime());
+            l.print(" - ");
+            l.println(str);
+        } catch (Exception err) {
+            err.printStackTrace();
+        }
+    }
+
+    public static void log(Exception e) {
+        try {
+            if (l == null) {
+                synchronized (XSQLAdapter.class) {
+                    if (l == null) {
+                        l = new PrintStream(
+                                new FileOutputStream("/tmp/xql.log"));
+                    }
+                }
+            }
+            l.print(Calendar.getInstance().getTime());
+            l.print(" - ");
+            e.printStackTrace(l);
+        } catch (Exception err) {
+            err.printStackTrace();
+        }
+    }
+
+    @Override
+    public void onGlobalContextUpdated(SchemaContext context) {
+        Set<Module> modules = context.getModules();
+        for (Module m : modules) {
+            if (XSQLODLUtils.createOpenDaylightCache(this.bluePrint, m)) {
+                this.addRootElement(m);
+            }
+        }
+    }
+
+    public void setDataBroker(DOMDataBroker ddb) {
+        this.domDataBroker = ddb;
+    }
+
+    public XSQLBluePrint getBluePrint() {
+        return this.bluePrint;
+    }
+
+    public List<Object> collectModuleRoots(XSQLBluePrintNode table) {
+        if (table.getParent().isModule()) {
+            try {
+                List<Object> result = new LinkedList<Object>();
+                YangInstanceIdentifier instanceIdentifier = YangInstanceIdentifier
+                        .builder()
+                        .node(XSQLODLUtils.getPath(table.getODLNode()).get(0))
+                        .toInstance();
+                DOMDataReadTransaction t = this.domDataBroker
+                        .newReadOnlyTransaction();
+                Object node = t.read(LogicalDatastoreType.OPERATIONAL,
+                        instanceIdentifier).get();
+                node = XSQLODLUtils.get(node, "reference");
+                if (node == null) {
+                    return result;
+                }
+
+                // XSQLAdapter.log(""+node);
+                Map<?, ?> children = XSQLODLUtils.getChildren(node);
+                for (Object c : children.values()) {
+                    Map<?, ?> sons = XSQLODLUtils.getChildren(c);
+                    for (Object child : sons.values()) {
+                        result.add(child);
+                    }
+                }
+
+                return result;
+            } catch (Exception err) {
+                XSQLAdapter.log(err);
+            }
+        } else {
+            return collectModuleRoots(table.getParent());
+        }
+        return null;
+    }
+
+    public void execute(JDBCResultSet rs) {
+        List<XSQLBluePrintNode> tables = rs.getTables();
+        List<Object> roots = collectModuleRoots(tables.get(0));
+        XSQLBluePrintNode main = rs.getMainTable();
+        List<NETask> tasks = new LinkedList<XSQLAdapter.NETask>();
+
+        for (Object entry : roots) {
+            NETask task = new NETask(rs, entry, main, bluePrint);
+            rs.numberOfTasks++;
+            tasks.add(task);
+        }
+        for (NETask task : tasks) {
+            threadPool.addTask(task);
+        }
+    }
+
+    public void run() {
+        while (!stopped) {
+            try {
+                Socket s = serverSocket.accept();
+                new TelnetConnection(s);
+            } catch (Exception err) {
+                err.printStackTrace();
+                try {
+                    Thread.sleep(20000);
+                } catch (Exception err2) {
+                }
+                stopped = true;
+            }
+        }
+    }
+
+    public void addRootElement(Object o) {
+        NEEntry entry = new NEEntry(o);
+        elements.put(o.toString(), entry);
+
+    }
+
+    protected void processCommand(StringBuffer inputString, PrintStream sout,
+            TelnetConnection tc) {
+        if (inputString.toString().trim().equals("r")) {
+            sout.println(lastInputString);
+            inputString = lastInputString;
+        }
+        lastInputString = inputString;
+        String input = inputString.toString().trim();
+        if (input.startsWith("setExcel")) {
+            String substr = input.substring("setExcel".length()).trim();
+            if (!substr.equals("")) {
+                // excelPath01 = substr;
+            }
+            // sout.println("Excel Path="+excelPath01);
+        } else if (input.startsWith("list vrel")) {
+            String substr = input.substring("list vrel".length()).trim();
+            XSQLBluePrintNode node = bluePrint
+                    .getBluePrintNodeByTableName(substr);
+            if (node == null) {
+                sout.println("Unknown Interface " + substr);
+                return;
+            }
+            List<String> fld = new ArrayList<String>();
+            for (XSQLBluePrintRelation r : node.getRelations()) {
+                fld.add(r.toString());
+            }
+            String p[] = (String[]) fld.toArray(new String[fld.size()]);
+            Arrays.sort(p);
+            for (int i = 0; i < p.length; i++) {
+                sout.println(p[i]);
+            }
+        } else if (input.startsWith("list vfields")) {
+            String substr = input.substring("list vfields".length()).trim();
+            XSQLBluePrintNode node = bluePrint
+                    .getBluePrintNodeByTableName(substr);
+            if (node == null) {
+                sout.println("Unknown Interface " + substr);
+                return;
+            }
+            List<String> fld = new ArrayList<String>();
+            for (XSQLColumn c : node.getColumns()) {
+                fld.add(c.getName());
+            }
+            String p[] = (String[]) fld.toArray(new String[fld.size()]);
+            Arrays.sort(p);
+            for (int i = 0; i < p.length; i++) {
+                sout.println(p[i]);
+            }
+        } else if (input.startsWith("jdbc")) {
+            String addr = input.substring(5).trim();
+            jdbcServer.connectToClient(addr);
+            sout.println("Connected To " + addr);
+        } else if (input.startsWith("fetch")) {
+            // fetchSize = Integer.parseInt(input.substring(6).trim());
+        } else if (input.startsWith("list vtables")) {
+
+            String iNames[] = bluePrint.getAllTableNames().toArray(
+                    new String[0]);
+            Arrays.sort(iNames);
+            sout.println();
+            for (int i = 0; i < iNames.length; i++) {
+                sout.println(iNames[i]);
+            }
+        } else if (input.startsWith("cd sid")) {
+            String substr = input.substring("cd sid".length()).trim();
+            for (NEEntry e : elements.values()) {
+                if (((Module) e.ne).getName().equals(substr)) {
+                    tc.currentModule = (Module) e.ne;
+                }
+            }
+        } else if (input.equals("list sid")) {
+            String arr[] = new String[elements.size()];
+
+            int i = 0;
+            for (NEEntry entry : elements.values()) {
+                arr[i] = entry.toString();
+                i++;
+            }
+            Arrays.sort(arr);
+            for (String s : arr) {
+                sout.println(s);
+            }
+        } else if (input.equals("help") || input.equals("?")) {
+            // sout.println(getLongDescription());
+        } else if (input.equals("avmdata")) {
+            try {
+                // myConnection.getManagedData();
+            } catch (Exception err) {
+            }
+        } else if (input.equals("innerjoin")) {
+            // innerJoin = !innerJoin;
+            // sout.println("Inner Join set to "+innerJoin);
+        } else if (input.equals("exit")) {
+            try {
+                sout.close();
+            } catch (Exception err) {
+            }
+        } else if (input.equals("tocsv")) {
+            toCsv = !toCsv;
+            sout.println("to csv file is " + toCsv);
+        } else if (input.indexOf("filename") != -1) {
+            exportToFileName = input.substring(input.indexOf(" ")).trim();
+            sout.println("Exporting to file:" + exportToFileName);
+        } else if (!input.equals("")) {
+            if (toCsv) {
+                if (exportToFileName != null) {
+                    try {
+                        PrintStream o = new PrintStream(new File(
+                                exportToFileName));
+                        executeSql(inputString.toString(), o);
+                        o.close();
+                    } catch (Exception err) {
+                        err.printStackTrace();
+                    }
+                } else {
+                    try {
+                        String fName = "export-" + System.currentTimeMillis()
+                                + ".csv";
+                        PrintStream o = new PrintStream(new File(fName));
+                        executeSql(inputString.toString(), o);
+                        o.close();
+                        sout.println("Exported to file " + fName);
+                    } catch (Exception err) {
+                        err.printStackTrace();
+                    }
+
+                }
+            } else {
+                executeSql(inputString.toString(), sout);
+            }
+        }
+        sout.println();
+    }
+
+    public void executeSql(String sql, PrintStream out) {
+        JDBCResultSet rs = new JDBCResultSet(sql);
+        try {
+            int count = 0;
+            jdbcServer.execute(rs, this);
+            boolean isFirst = true;
+            int loc = rs.getFields().size() - 1;
+            int totalWidth = 0;
+            for (XSQLColumn c : rs.getFields()) {
+                if (isFirst) {
+                    isFirst = false;
+                    if (toCsv) {
+                        out.print("\"");
+                    }
+                }
+
+                if (!toCsv) {
+                    out.print("|");
+                }
+
+                out.print(c.getName());
+
+                if (!toCsv) {
+                    int cw = c.getCharWidth();
+                    int cnw = c.getName().length();
+                    if (cnw > cw) {
+                        c.setCharWidth(cnw);
+                    }
+                    int gap = cw - cnw;
+                    for (int i = 0; i < gap; i++) {
+                        out.print(" ");
+                    }
+                }
+
+                totalWidth += c.getCharWidth() + 1;
+
+                if (loc > 0) {
+                    if (toCsv) {
+                        out.print("\",\"");
+                    }
+                }
+                loc--;
+            }
+
+            if (toCsv) {
+                out.println("\"");
+            } else {
+                totalWidth++;
+                out.println("|");
+                for (int i = 0; i < totalWidth; i++) {
+                    out.print("-");
+                }
+                out.println();
+            }
+
+            while (rs.next()) {
+                isFirst = true;
+                loc = rs.getFields().size() - 1;
+                for (XSQLColumn c : rs.getFields()) {
+                    if (isFirst) {
+                        isFirst = false;
+                        if (toCsv) {
+                            out.print("\"");
+                        }
+                    }
+
+                    if (!toCsv) {
+                        out.print("|");
+                    }
+
+                    Object sValue = rs.getObject(c.toString());
+                    if (sValue == null) {
+                        sValue = "";
+                    }
+                    out.print(sValue);
+
+                    int cw = c.getCharWidth();
+                    int vw = sValue.toString().length();
+                    int gap = cw - vw;
+                    for (int i = 0; i < gap; i++) {
+                        out.print(" ");
+                    }
+
+                    if (loc > 0) {
+                        if (toCsv) {
+                            out.print("\",\"");
+                        }
+                    }
+                    loc--;
+                }
+                if (toCsv) {
+                    out.println("\"");
+                } else {
+                    out.println("|");
+                }
+                count++;
+            }
+            out.println("Total Number Of Records=" + count);
+        } catch (Exception err) {
+            err.printStackTrace(out);
+        }
+    }
+
+    public static class NETask implements Runnable {
+
+        private JDBCResultSet rs = null;
+        private Object modelRoot = null;
+        private XSQLBluePrintNode main = null;
+        private XSQLBluePrint bluePrint = null;
+
+        public NETask(JDBCResultSet _rs, Object _modelRoot,
+                XSQLBluePrintNode _main, XSQLBluePrint _bluePrint) {
+            this.rs = _rs;
+            this.modelRoot = _modelRoot;
+            this.main = _main;
+            this.bluePrint = _bluePrint;
+        }
+
+        public void run() {
+            rs.addRecords(modelRoot, main, true, main.getBluePrintNodeName(),
+                    bluePrint);
+            synchronized (rs) {
+                rs.numberOfTasks--;
+                if (rs.numberOfTasks == 0) {
+                    rs.setFinished(true);
+                    rs.notifyAll();
+                }
+            }
+        }
+    }
+
+    private static class NEEntry {
+        private Object ne = null;
+
+        public NEEntry(Object _ne) {
+            this.ne = _ne;
+        }
+
+        public String toString() {
+            Module m = (Module) ne;
+            return m.getName() + "  [" + m.getNamespace().toString() + "]";
+        }
+    }
+
+    private class TelnetConnection extends Thread {
+
+        private Socket socket = null;
+        private InputStream in = null;
+        private PrintStream out = null;
+        private Module currentModule = null;
+
+        public TelnetConnection(Socket s) {
+            this.socket = s;
+            try {
+                this.in = s.getInputStream();
+                this.out = new PrintStream(s.getOutputStream());
+                this.start();
+            } catch (Exception err) {
+                XSQLAdapter.log(err);
+            }
+        }
+
+        public void run() {
+            StringBuffer inputString = new StringBuffer();
+            String prompt = "XSQL>";
+            try {
+                while (!stopped) {
+                    if (currentModule != null) {
+                        prompt = "XQL/" + currentModule.getName() + ">";
+                    }
+                    out.print(prompt);
+                    char c = 0;
+                    byte data[] = new byte[1];
+                    while (c != '\n') {
+                        try {
+                            in.read(data);
+                            c = (char) data[0];
+                            inputString.append(c);
+                        } catch (Exception err) {
+                            err.printStackTrace(out);
+                        }
+                    }
+
+                    processCommand(inputString, out, this);
+                    inputString = new StringBuffer();
+                }
+            } catch (Exception err) {
+                try {
+                    socket.close();
+                } catch (Exception err2) {
+                }
+            }
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLBluePrint.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLBluePrint.java
new file mode 100644 (file)
index 0000000..1a31662
--- /dev/null
@@ -0,0 +1,1314 @@
+package org.opendaylight.controller.md.sal.dom.xsql;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.RowIdLifetime;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class XSQLBluePrint implements DatabaseMetaData {
+
+    public static final String CACHE_FILE_NAME = "BluePrintCache.dat";
+
+    private Map<String, XSQLBluePrintNode> tableNameToBluePrint = new HashMap<String, XSQLBluePrintNode>();
+    private Map<String, Map<String,XSQLBluePrintNode>> odlNameToBluePrint = new HashMap<String, Map<String,XSQLBluePrintNode>>();
+
+    private boolean cacheLoadedSuccessfuly = false;
+    private DatabaseMetaData myProxy = null;
+
+    public static final String replaceAll(String source, String toReplace,
+        String withThis) {
+        int index = source.indexOf(toReplace);
+        int index2 = 0;
+        StringBuffer result = new StringBuffer();
+        while (index != -1) {
+            result.append(source.substring(index2, index));
+            result.append(withThis);
+            index2 = index + toReplace.length();
+            index = source.indexOf(toReplace, index2);
+        }
+        if (index2 < source.length()) {
+            result.append(source.substring(index2));
+        }
+        return result.toString();
+    }
+
+    public XSQLBluePrint() {
+    }
+
+    private class NQLBluePrintProxy implements InvocationHandler {
+        public Object invoke(Object proxy, Method method, Object[] args)
+            throws Throwable {
+            System.out.println("Method " + method);
+            return method.invoke(XSQLBluePrint.this, args);
+        }
+    }
+
+    public DatabaseMetaData getProxy() {
+        if (myProxy == null) {
+            try {
+                myProxy = (DatabaseMetaData) Proxy
+                    .newProxyInstance(getClass().getClassLoader(),
+                        new Class[] {DatabaseMetaData.class},
+                        new NQLBluePrintProxy());
+            } catch (Exception err) {
+                err.printStackTrace();
+            }
+        }
+        return myProxy;
+    }
+
+    /*
+    public void loadBluePrintCache(String hostName) {
+        try {
+            ObjectInputStream in = new ObjectInputStream(
+                new FileInputStream(hostName + "-" + CACHE_FILE_NAME));
+            cache = (Map) in.readObject();
+            in.close();
+            cacheLoadedSuccessfuly = true;
+        } catch (Exception err) {
+            //err.printStackTrace();
+        }
+    }*/
+
+    public XSQLBluePrintNode[] getBluePrintNodeByODLTableName(String odlTableName) {
+        Map<String,XSQLBluePrintNode> map = this.odlNameToBluePrint.get(odlTableName);
+        if(map==null) return null;
+        return map.values().toArray(new XSQLBluePrintNode[map.size()]);
+    }
+
+    public XSQLBluePrintNode getBluePrintNodeByTableName(String tableName) {
+        if (tableName.indexOf(".") != -1) {
+            tableName = tableName.substring(tableName.lastIndexOf(".") + 1);
+        }
+
+        XSQLBluePrintNode node = tableNameToBluePrint.get(tableName);
+
+        if (node != null) {
+            return node;
+        }
+
+        for (XSQLBluePrintNode n : tableNameToBluePrint.values()) {
+            if (n.getBluePrintNodeName().endsWith(tableName)) {
+                return n;
+            }
+        }
+
+        for (XSQLBluePrintNode n : tableNameToBluePrint.values()) {
+            if (n.getBluePrintNodeName().toLowerCase().endsWith(tableName.toLowerCase())) {
+                return n;
+            }
+        }
+
+        for (XSQLBluePrintNode n : tableNameToBluePrint.values()) {
+            if (n.getBluePrintNodeName().toLowerCase().equals(tableName.toLowerCase())) {
+                return n;
+            }
+        }
+
+        for (XSQLBluePrintNode n : tableNameToBluePrint.values()) {
+            if (n.getBluePrintNodeName().toLowerCase().indexOf(tableName.toLowerCase())!= -1) {
+                return n;
+            }
+        }
+        return null;
+    }
+
+
+    public boolean isCacheLoaded() {
+        return cacheLoadedSuccessfuly;
+    }
+
+    private static Map<Class, Set<Class>> superClassMap = new HashMap<Class, Set<Class>>();
+
+    public static Set<Class> getInheritance(Class myObjectClass,
+        Class returnType) {
+
+        if (returnType != null && myObjectClass.equals(returnType)) {
+            return new HashSet<Class>();
+        }
+        Set<Class> result = superClassMap.get(myObjectClass);
+        if (result != null) {
+            return result;
+        }
+        result = new HashSet<Class>();
+        superClassMap.put(myObjectClass, result);
+        if (returnType != null) {
+            if (!returnType.equals(myObjectClass)) {
+                Class mySuperClass = myObjectClass.getSuperclass();
+                while (mySuperClass != null) {
+                    result.add(mySuperClass);
+                    mySuperClass = mySuperClass.getSuperclass();
+                }
+                result.addAll(collectInterfaces(myObjectClass));
+            }
+        }
+        return result;
+    }
+
+    public static Set<Class> collectInterfaces(Class cls) {
+        Set<Class> result = new HashSet();
+        Class myInterfaces[] = cls.getInterfaces();
+        if (myInterfaces != null) {
+            for (Class in : myInterfaces) {
+                result.add(in);
+                result.addAll(collectInterfaces(in));
+            }
+        }
+        return result;
+    }
+
+    public void addToBluePrintCache(XSQLBluePrintNode blNode) {
+        this.tableNameToBluePrint.put(blNode.getBluePrintNodeName(), blNode);
+        Map<String,XSQLBluePrintNode> map = this.odlNameToBluePrint.get(blNode.getODLTableName());
+        if(map==null){
+            map = new HashMap<String,XSQLBluePrintNode>();
+            this.odlNameToBluePrint.put(blNode.getODLTableName(),map);
+        }
+        map.put(blNode.getBluePrintNodeName(), blNode);
+    }
+
+    public Class getGenericType(ParameterizedType type) {
+        Type[] typeArguments = type.getActualTypeArguments();
+        for (Type typeArgument : typeArguments) {
+            if (typeArgument instanceof ParameterizedType) {
+                ParameterizedType pType = (ParameterizedType) typeArgument;
+                return (Class) pType.getRawType();
+            } else if (typeArgument instanceof Class) {
+                return (Class) typeArgument;
+            }
+        }
+        return null;
+    }
+
+    public Class getMethodReturnTypeFromGeneric(Method m) {
+        Type rType = m.getGenericReturnType();
+        if (rType instanceof ParameterizedType) {
+            return getGenericType((ParameterizedType) rType);
+        }
+        return null;
+    }
+
+    public List<String> getAllTableNames() {
+        List<String> names = new ArrayList<String>();
+        for (XSQLBluePrintNode n : this.tableNameToBluePrint.values()) {
+            if (!n.isModule() && !n.getColumns().isEmpty()) {
+                names.add(n.getBluePrintNodeName());
+            }
+        }
+        return names;
+
+    }
+
+    public List<String> getInterfaceNames(XSQLBluePrintNode node) {
+        Set<XSQLBluePrintNode> children = node.getChildren();
+        List<String> names = new ArrayList<String>();
+        for (XSQLBluePrintNode n : children) {
+            if (!n.isModule() && !n.getColumns().isEmpty()) {
+                names.add(n.toString());
+            }
+            names.addAll(getInterfaceNames(n));
+        }
+        return names;
+    }
+
+    @Override
+    public boolean allProceduresAreCallable() throws SQLException {
+        return false;
+    }
+
+    @Override
+    public boolean allTablesAreSelectable() throws SQLException {
+        return true;
+    }
+
+    @Override
+    public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean deletesAreDetected(int type) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public ResultSet getAttributes(String catalog, String schemaPattern,
+        String typeNamePattern, String attributeNamePattern)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getBestRowIdentifier(String catalog, String schema,
+        String table, int scope, boolean nullable) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getCatalogs() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getCatalogSeparator() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getCatalogTerm() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getClientInfoProperties() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getColumnPrivileges(String catalog, String schema,
+        String table, String columnNamePattern) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getColumns(String catalog, String schemaPattern,
+        String tableNamePattern, String columnNamePattern)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Connection getConnection() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getCrossReference(String parentCatalog,
+        String parentSchema, String parentTable, String foreignCatalog,
+        String foreignSchema, String foreignTable) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getDatabaseMajorVersion() throws SQLException {
+        return 0;
+    }
+
+    @Override
+    public int getDatabaseMinorVersion() throws SQLException {
+        // TODO Auto-generated method stub
+        return 1;
+    }
+
+    @Override
+    public String getDatabaseProductName() throws SQLException {
+        return "VNE Query Language";
+    }
+
+    @Override
+    public String getDatabaseProductVersion() throws SQLException {
+        return "0.1";
+    }
+
+    @Override
+    public int getDefaultTransactionIsolation() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getDriverMajorVersion() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getDriverMinorVersion() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public String getDriverName() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getDriverVersion() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getExportedKeys(String catalog, String schema,
+        String table)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getExtraNameCharacters() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getFunctionColumns(String catalog, String schemaPattern,
+        String functionNamePattern, String columnNamePattern)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getFunctions(String catalog, String schemaPattern,
+        String functionNamePattern) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getIdentifierQuoteString() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getImportedKeys(String catalog, String schema,
+        String table)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getIndexInfo(String catalog, String schema, String table,
+        boolean unique, boolean approximate) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getJDBCMajorVersion() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getJDBCMinorVersion() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxBinaryLiteralLength() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxCatalogNameLength() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxCharLiteralLength() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxColumnNameLength() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxColumnsInGroupBy() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxColumnsInIndex() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxColumnsInOrderBy() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxColumnsInSelect() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxColumnsInTable() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxConnections() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxCursorNameLength() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxIndexLength() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxProcedureNameLength() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxRowSize() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxSchemaNameLength() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxStatementLength() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxStatements() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxTableNameLength() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxTablesInSelect() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxUserNameLength() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public String getNumericFunctions() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getPrimaryKeys(String catalog, String schema, String table)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getProcedureColumns(String catalog, String schemaPattern,
+        String procedureNamePattern, String columnNamePattern)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getProcedures(String catalog, String schemaPattern,
+        String procedureNamePattern) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getProcedureTerm() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getResultSetHoldability() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public RowIdLifetime getRowIdLifetime() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getSchemas() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getSchemas(String catalog, String schemaPattern)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getSchemaTerm() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getSearchStringEscape() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getSQLKeywords() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getSQLStateType() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public String getStringFunctions() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getSuperTables(String catalog, String schemaPattern,
+        String tableNamePattern) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getSuperTypes(String catalog, String schemaPattern,
+        String typeNamePattern) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getSystemFunctions() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getTablePrivileges(String catalog, String schemaPattern,
+        String tableNamePattern) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getTables(String catalog, String schemaPattern,
+        String tableNamePattern, String[] types) throws SQLException {
+        return new TablesResultSet(this);
+    }
+
+    @Override
+    public ResultSet getTableTypes() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getTimeDateFunctions() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getTypeInfo() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getUDTs(String catalog, String schemaPattern,
+        String typeNamePattern, int[] types) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getURL() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getUserName() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getVersionColumns(String catalog, String schema,
+        String table) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean insertsAreDetected(int type) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isCatalogAtStart() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isReadOnly() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean locatorsUpdateCopy() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean nullPlusNonNullIsNull() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean nullsAreSortedAtEnd() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean nullsAreSortedAtStart() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean nullsAreSortedHigh() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean nullsAreSortedLow() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean othersDeletesAreVisible(int type) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean othersInsertsAreVisible(int type) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean othersUpdatesAreVisible(int type) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean ownDeletesAreVisible(int type) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean ownInsertsAreVisible(int type) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean ownUpdatesAreVisible(int type) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean storesLowerCaseIdentifiers() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean storesMixedCaseIdentifiers() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean storesUpperCaseIdentifiers() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsAlterTableWithAddColumn() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsAlterTableWithDropColumn() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsANSI92FullSQL() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsANSI92IntermediateSQL() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsBatchUpdates() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsCatalogsInDataManipulation() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsCatalogsInPrivilegeDefinitions()
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsColumnAliasing() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsConvert() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsConvert(int fromType, int toType)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsCoreSQLGrammar() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsCorrelatedSubqueries() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsDataDefinitionAndDataManipulationTransactions()
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsDataManipulationTransactionsOnly()
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsDifferentTableCorrelationNames()
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsExpressionsInOrderBy() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsExtendedSQLGrammar() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsFullOuterJoins() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsGetGeneratedKeys() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsGroupBy() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsGroupByBeyondSelect() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsGroupByUnrelated() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsLikeEscapeClause() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsLimitedOuterJoins() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsMinimumSQLGrammar() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsMixedCaseIdentifiers() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsMultipleOpenResults() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsMultipleResultSets() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsMultipleTransactions() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsNamedParameters() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsNonNullableColumns() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsOrderByUnrelated() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsOuterJoins() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsPositionedDelete() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsPositionedUpdate() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsResultSetConcurrency(int type, int concurrency)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsResultSetHoldability(int holdability)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsResultSetType(int type) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsSavepoints() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsSchemasInDataManipulation() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsSchemasInProcedureCalls() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsSchemasInTableDefinitions() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsSelectForUpdate() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsStatementPooling() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsStoredFunctionsUsingCallSyntax()
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsStoredProcedures() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsSubqueriesInComparisons() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsSubqueriesInExists() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsSubqueriesInIns() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsTableCorrelationNames() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsTransactionIsolationLevel(int level)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsTransactions() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsUnion() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean supportsUnionAll() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean updatesAreDetected(int type) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean usesLocalFilePerTable() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean usesLocalFiles() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ResultSet getPseudoColumns(String catalog, String schemaPattern,
+        String tableNamePattern, String columnNamePattern)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean generatedKeyAlwaysReturned() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLBluePrintNode.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLBluePrintNode.java
new file mode 100644 (file)
index 0000000..fbd818e
--- /dev/null
@@ -0,0 +1,236 @@
+package org.opendaylight.controller.md.sal.dom.xsql;
+
+import java.io.Serializable;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+public class XSQLBluePrintNode implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    private Class<?> myInterface = null;
+    private String myInterfaceString = null;
+    private Set<XSQLBluePrintRelation> relations =
+        new HashSet<XSQLBluePrintRelation>();
+    private Set<XSQLBluePrintNode> inheritingNodes =
+        new HashSet<XSQLBluePrintNode>();
+    private Set<XSQLBluePrintNode> children = new HashSet<XSQLBluePrintNode>();
+    private XSQLBluePrintNode parent = null;
+
+    private int level = -1;
+    private transient Set<String> parentHierarchySet = null;
+    private String myInterfaceName = null;
+    private Set<XSQLColumn> columns = new HashSet<XSQLColumn>();
+
+    private transient Object odlNode = null;
+    private boolean module = false;
+    private String bluePrintTableName = null;
+    private String odlTableName = null;
+
+    public XSQLBluePrintNode(Class<?> _myInterface, int _level) {
+        this.myInterface = _myInterface;
+        this.myInterfaceString = _myInterface.getName();
+        this.myInterfaceName = myInterface.getSimpleName();
+        this.level = _level;
+    }
+
+    public XSQLBluePrintNode(Object _odlNode, int _level,XSQLBluePrintNode _parent) {
+        this.odlNode = _odlNode;
+        this.level = _level;
+        this.module = XSQLODLUtils.isModule(_odlNode);
+        this.parent = _parent;
+        this.bluePrintTableName = XSQLODLUtils.getBluePrintName(_odlNode);
+
+    }
+
+    public String getBluePrintNodeName(){
+        return this.bluePrintTableName;
+    }
+
+    public boolean isModule() {
+        return this.module;
+    }
+
+    public Set<XSQLBluePrintNode> getChildren() {
+        return this.children;
+    }
+
+    public String getODLTableName() {
+        if (this.odlTableName == null) {
+            this.odlTableName = XSQLODLUtils.getODLNodeName(this.odlNode);
+        }
+        return this.odlTableName;
+    }
+
+    public Object getODLNode() {
+        return this.odlNode;
+    }
+
+    public void AddChild(XSQLBluePrintNode ch) {
+        this.children.add(ch);
+    }
+
+    public boolean isModelChild(Class p) {
+        if (this.relations.size() == 0) {
+            return false;
+        }
+        for (XSQLBluePrintRelation parentRelation : this.relations) {
+            if (parentRelation.getParent().getInterface().equals(p)) {
+                return true;
+            }
+        }
+        for (XSQLBluePrintRelation dtr : this.relations) {
+            XSQLBluePrintNode parent = dtr.getParent();
+            if (!parent.getInterface().equals(this.getInterface()) && !parent
+                .getInterface().isAssignableFrom(this.getInterface()) &&
+                this.getInterface().isAssignableFrom(parent.getInterface())
+                && parent.isModelChild(p)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public Set<XSQLBluePrintRelation> getRelations() {
+        return this.relations;
+    }
+
+    public String getClassName() {
+        return this.myInterfaceString;
+    }
+
+    public void addInheritingNode(XSQLBluePrintNode node) {
+        this.inheritingNodes.add(node);
+    }
+
+    public Set<XSQLBluePrintNode> getInheritingNodes() {
+        return this.inheritingNodes;
+    }
+
+    public void addColumn(Object node, String tableName) {
+        XSQLColumn c = new XSQLColumn(node,getBluePrintNodeName(), this);
+        this.columns.add(c);
+    }
+
+    public void addColumn(String methodName) {
+        if (methodName.startsWith("get")) {
+            methodName = methodName.substring(3);
+        } else if (methodName.startsWith("is")) {
+            methodName = methodName.substring(2);
+        }
+        XSQLColumn c = new XSQLColumn(methodName, myInterfaceName, null);
+        this.columns.add(c);
+    }
+
+    public Collection<XSQLColumn> getColumns() {
+        return this.columns;
+    }
+
+    public XSQLColumn findColumnByName(String name) throws SQLException {
+
+        XSQLColumn exactMatch = null;
+        XSQLColumn indexOfMatch = null;
+        XSQLColumn exactLowercaseMatch = null;
+        XSQLColumn indexOfLowerCaseMatch = null;
+
+        for (XSQLColumn col : columns) {
+            if (col.getName().equals(name)) {
+                exactMatch = col;
+            }
+            if (col.getName().indexOf(name) != -1) {
+                indexOfMatch = col;
+            }
+            if (col.getName().toLowerCase().equals(name.toLowerCase())) {
+                exactLowercaseMatch = col;
+            }
+            if (col.getName().toLowerCase().indexOf(name.toLowerCase()) != -1) {
+                indexOfLowerCaseMatch = col;
+            }
+        }
+
+        if (exactMatch != null) {
+            return exactMatch;
+        }
+        if (exactLowercaseMatch != null) {
+            return exactLowercaseMatch;
+        }
+        if (indexOfMatch != null) {
+            return indexOfMatch;
+        }
+        if (indexOfLowerCaseMatch != null) {
+            return indexOfLowerCaseMatch;
+        }
+
+        throw new SQLException("Unknown field name '" + name + "'");
+    }
+
+
+    public void addParent(XSQLBluePrintNode parent, String property) {
+        try {
+            if (property.equals("ContainingTPs")) {
+                return;
+            }
+            //Method m = parent.getInterface().getMethod("get"+property, null);
+            //if(!m.getDeclaringClass().equals(parent.getInterface()))
+            //return;
+            XSQLBluePrintRelation rel =
+                new XSQLBluePrintRelation(parent, property, myInterface);
+            relations.add(rel);
+        } catch (Exception err) {
+            err.printStackTrace();
+        }
+    }
+
+    public XSQLBluePrintNode getParent() {
+        return this.parent;
+    }
+
+    public Set<XSQLBluePrintRelation> getClonedParents() {
+        Set<XSQLBluePrintRelation> result =
+            new HashSet<XSQLBluePrintRelation>();
+        result.addAll(this.relations);
+        return result;
+    }
+
+    public String toString() {
+        if (myInterfaceName != null) {
+            return myInterfaceName;
+        }
+        if (odlNode != null) {
+            return getBluePrintNodeName();
+        }
+        return "Unknown";
+    }
+
+    public Class getInterface() {
+        return this.myInterface;
+    }
+
+    public int getLevel() {
+        return this.level;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        XSQLBluePrintNode other = (XSQLBluePrintNode) obj;
+        if (odlNode != null) {
+            return getBluePrintNodeName().equals(other.getBluePrintNodeName());
+        } else if (this.odlTableName != null) {
+            return this.odlTableName.equals(other.odlTableName);
+        } else {
+            return other.myInterface.equals(myInterface);
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        if (myInterfaceString != null) {
+            return myInterfaceString.hashCode();
+        } else if (odlNode != null) {
+            return bluePrintTableName.hashCode();
+        }
+        return 0;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLBluePrintRelation.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLBluePrintRelation.java
new file mode 100644 (file)
index 0000000..1cb3aa5
--- /dev/null
@@ -0,0 +1,139 @@
+package org.opendaylight.controller.md.sal.dom.xsql;
+
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class XSQLBluePrintRelation implements Serializable {
+    private static final long serialVersionUID = 2L;
+    private XSQLBluePrintNode parent = null;
+    private String property = null;
+    private Class<?> childClass = null;
+
+    public XSQLBluePrintRelation(XSQLBluePrintNode _parent, String _property,
+        Class<?> _childClass) {
+        this.parent = _parent;
+        this.property = _property;
+        this.childClass = _childClass;
+    }
+
+    public Class<?> getNEClosestClass() {
+        Class<?> p = parent.getInterface();
+        return getNEClosestClass(p);
+    }
+
+
+    public static Class<?> getNEClosestClass(Class<?> p) {
+        while (!p.getInterfaces()[0]
+            .equals(Object.class/*XSQLBluePrint.STOP_INTERFACE*/)) {
+            p = p.getInterfaces()[0];
+        }
+        return p;
+    }
+
+    public XSQLBluePrintNode getParent() {
+        return parent;
+    }
+
+    public String getProperty() {
+        return property;
+    }
+
+    public Class<?> getChildClass() {
+        return this.childClass;
+    }
+
+    public boolean equals(Object obj) {
+        XSQLBluePrintRelation other = (XSQLBluePrintRelation) obj;
+        if (other.parent != null && this.parent == null) {
+            return false;
+        }
+        if (other.parent == null && this.parent != null) {
+            return false;
+        }
+
+        if (other.parent == null && this.parent == null) {
+            return property.equals(other.property);
+        }
+
+        if (other.parent.toString().equals(this.parent.toString())) {
+            return property.equals(other.property);
+        }
+
+        return false;
+    }
+
+    public int hashCode() {
+        if (parent != null) {
+            return parent.toString().hashCode() + property.hashCode();
+        }
+        return property.hashCode();
+    }
+
+    public String toString() {
+        if (parent != null) {
+            return parent.toString() + ":" + property;
+        } else {
+            return property;
+        }
+    }
+
+    public List execute(Object o) {
+        List result = new LinkedList();
+        if (o == null) {
+            return null;
+        }
+
+        if (Set.class.isAssignableFrom(o.getClass())) {
+            Set lst = (Set) o;
+            for (Object oo : lst) {
+                addToResult(result, execute(oo));
+            }
+            return result;
+        } else if (List.class.isAssignableFrom(o.getClass())) {
+            List lst = (List) o;
+            for (Object oo : lst) {
+                addToResult(result, execute(oo));
+            }
+            return result;
+        } else if (Map.class.isAssignableFrom(o.getClass())) {
+            Map map = (Map) o;
+            for (Object oo : map.values()) {
+                addToResult(result, execute(oo));
+            }
+            return result;
+        }
+
+        addToResult(result, XSQLCriteria.getValue(o, this.property));
+
+        return result;
+    }
+
+    public static void addToResult(List result, Object o) {
+        if (o == null) {
+            return;
+        }
+        if (Set.class.isAssignableFrom(o.getClass())) {
+            Set lst = (Set) o;
+            for (Object oo : lst) {
+                result.add(oo);
+            }
+        } else if (List.class.isAssignableFrom(o.getClass())) {
+            List lst = (List) o;
+            for (Object oo : lst) {
+                result.add(oo);
+            }
+        } else if (Map.class.isAssignableFrom(o.getClass())) {
+            Map map = (Map) o;
+            for (Object oo : map.values()) {
+                result.add(oo);
+            }
+        } else {
+            result.add(o);
+        }
+    }
+
+}
+
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLColumn.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLColumn.java
new file mode 100644 (file)
index 0000000..55ac600
--- /dev/null
@@ -0,0 +1,80 @@
+package org.opendaylight.controller.md.sal.dom.xsql;
+
+import java.io.Serializable;
+
+public class XSQLColumn implements Serializable, Comparable {
+    private String name = null;
+    private String tableName = null;
+    private int charWidth = -1;
+    private Class type = null;
+    private transient Object bluePrintNode = null;
+
+    public XSQLColumn(Object odlNode, String _tableName, Object _bluePrintNode) {
+        this.name = XSQLODLUtils.getNodeNameFromDSN(odlNode);
+        this.tableName = _tableName;
+        this.bluePrintNode = _bluePrintNode;
+        this.type = XSQLODLUtils.getTypeForODLColumn(odlNode);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getTableName() {
+        return tableName;
+    }
+
+    public void setCharWidth(int i) {
+        if (this.charWidth < i) {
+            this.charWidth = i;
+        }
+    }
+
+    public int getCharWidth() {
+        return this.charWidth;
+    }
+
+    @Override
+    public int hashCode() {
+        return this.name.hashCode() + this.tableName.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof XSQLColumn)) {
+            return false;
+        }
+        XSQLColumn other = (XSQLColumn) obj;
+        return tableName.equals(other.tableName) && name.equals(other.name);
+    }
+
+    public Object getBluePrintNode() {
+        return this.bluePrintNode;
+    }
+
+    @Override
+    public String toString() {
+        return tableName + "." + name;
+    }
+
+    @Override
+    public int compareTo(Object o) {
+        return this.toString().compareTo(o.toString());
+    }
+
+    public Object getResultSetValue(Object obj){
+        if(this.type.equals(String.class)){
+            return obj.toString();
+        }else
+        if(this.type.equals(int.class)){
+            return Integer.parseInt(obj.toString());
+        }else
+        if(this.type.equals(long.class)){
+            return Long.parseLong(obj.toString());
+        }else
+        if(this.type.equals(byte.class)){
+            return Byte.parseByte(obj.toString());
+        }
+        return null;
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLCriteria.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLCriteria.java
new file mode 100644 (file)
index 0000000..ed75254
--- /dev/null
@@ -0,0 +1,371 @@
+package org.opendaylight.controller.md.sal.dom.xsql;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class XSQLCriteria implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private static final String operators[] =
+        new String[] {" and ", " or ", ">=", "<=", "!=", "=", ">", "<", "like",
+            "is null", "not null", "skip"};
+    private static final String STRING_CHAR = "'";
+
+    public static final int OP_CODE_AND = 0;
+    public static final int OP_CODE_OR = 1;
+    public static final int OP_CODE_GTEQ = 2;
+    public static final int OP_CODE_LTEQ = 3;
+    public static final int OP_CODE_NOT_EQ = 4;
+    public static final int OP_CODE_EQUAL = 5;
+    public static final int OP_CODE_GT = 6;
+    public static final int OP_CODE_LT = 7;
+    public static final int OP_CODE_LIKE = 8;
+    public static final int OP_CODE_NULL = 9;
+    public static final int OP_CODE_NOT_NULL = 10;
+    public static final int OP_CODE_SKIP = 11;
+
+    private XSQLCriteria left = null;
+    private XSQLCriteria right = null;
+
+    private int operation = -1;
+
+    private Object leftValue = null;
+    private Object rightValue = null;
+    private String criteria = null;
+
+    private static final Map<Class<?>, Map<String, Method>> methodCache =
+        new ConcurrentHashMap<Class<?>, Map<String, Method>>();
+
+    public XSQLCriteria(final String data, final int parentOperation) {
+        criteria = data;
+        parse(data, parentOperation);
+    }
+
+    private void parse(String data, int parentOperation) {
+
+        data = data.trim();
+
+        int index1 = data.indexOf("(");
+        if (index1 != -1) {
+            String leftCondition = data.substring(0, index1).trim();
+            if (leftCondition.trim().equals("")) {
+                int index2 = data.lastIndexOf(")");
+                if (index2 < data.length() - 1) {
+                    String rtValue = data.substring(index2 + 1).trim();
+                    if (!rtValue.equals("")) {
+                        left =
+                            new XSQLCriteria(data.substring(index1 + 1, index2),
+                                parentOperation);
+                        data = data.substring(index2 + 1);
+                    } else {
+                        data = data.substring(1, index2);
+                    }
+                } else {
+                    data = data.substring(1, index2);
+                }
+            } else {
+                right = new XSQLCriteria(
+                    data.substring(index1 + 1, data.length() - 1),
+                    parentOperation);
+                data = data.substring(0, index1);
+            }
+        }
+
+        for (int i = 0; i < operators.length; i++) {
+            index1 = data.indexOf(operators[i]);
+            if (index1 != -1) {
+                this.operation = i;
+                if (left == null) {
+                    left = new XSQLCriteria(data.substring(0, index1),
+                        this.operation);
+                }
+                if (left.leftValue != null && left.rightValue == null
+                    && left.right == null) {
+                    leftValue = left.leftValue;
+                    left = null;
+                }
+                if (right == null) {
+                    right = new XSQLCriteria(
+                        data.substring(index1 + operators[i].length()),
+                        this.operation);
+                }
+                if (right.leftValue != null && right.rightValue == null
+                    && right.right == null) {
+                    rightValue = right.leftValue;
+                    right = null;
+                }
+                return;
+            }
+        }
+
+        if (data.startsWith("'") && data.endsWith("'")) {
+            data = data.substring(1, data.length() - 1);
+        }
+
+        if (parentOperation == OP_CODE_LIKE && data.startsWith("%") && data.endsWith("%")
+            && data.substring(1, data.length() - 1).indexOf("%") == -1) {
+            data = data.substring(1, data.length() - 1);
+        }
+
+        leftValue = data;
+    }
+
+    public static Object getValue(Object element, String propertyName) {
+        try {
+            Map<String, Method> cache = methodCache.get(element.getClass());
+            if (cache == null) {
+                cache = new ConcurrentHashMap<String, Method>();
+                methodCache.put(element.getClass(), cache);
+            }
+
+            Method m = cache.get(propertyName);
+            if (m == null) {
+                Method methods[] = element.getClass().getMethods();
+                for (Method mm : methods) {
+                    if (mm.getName().equals(propertyName) || mm.getName()
+                        .equals("get" + propertyName) || mm.getName()
+                        .equals("is" + propertyName)) {
+                        m = mm;
+                        m.setAccessible(true);
+                        cache.put(propertyName, m);
+                        break;
+                    }
+                }
+            }
+
+            Object value = null;
+            if (m == null) {
+                return null;
+            }
+            if (m.getParameterTypes() == null
+                || m.getParameterTypes().length == 0) {
+                value = m.invoke(element, null);
+            } else {
+                if (String.class.isAssignableFrom(m.getParameterTypes()[0])) {
+                    return null;
+                }
+                Object arg = m.getParameterTypes()[0].newInstance();
+                value = m.invoke(element, arg);
+            }
+            return value;
+        } catch (Exception err) {
+            err.printStackTrace();
+        }
+        return null;
+    }
+
+    public int isObjectFitCriteria(Object element, String propertyName) {
+        Object value = getValue(element, propertyName);
+        if (value != null) {
+            value = value.toString();
+        }
+        return checkValue(value);
+    }
+
+    public int checkValue(Object value) {
+        if (leftValue != null && rightValue != null) {
+            Object aSide = null;
+            Object bSide = null;
+            if (leftValue.equals("?")) {
+                aSide = value;
+            } else {
+                aSide = leftValue;
+            }
+
+            if (rightValue.equals("?")) {
+                bSide = value;
+            } else {
+                bSide = rightValue;
+            }
+            if (operation != OP_CODE_SKIP && operation != OP_CODE_NULL) {
+                if (aSide == null && bSide != null) {
+                    return 0;
+                } else if (aSide != null && bSide == null) {
+                    return 0;
+                } else if (aSide == null && bSide == null) {
+                    return 1;
+                }
+            }
+            switch (operation) {
+                case OP_CODE_EQUAL:
+                    if (aSide.equals(bSide)) {
+                        return 1;
+                    } else {
+                        return 0;
+                    }
+                case OP_CODE_NOT_EQ:
+                    if (!aSide.equals(bSide)) {
+                        return 1;
+                    } else {
+                        return 0;
+                    }
+                case OP_CODE_LIKE:
+                    if (aSide.toString().indexOf(bSide.toString()) != -1) {
+                        return 1;
+                    } else {
+                        return 0;
+                    }
+                case OP_CODE_NULL:
+                    if (aSide == null) {
+                        return 1;
+                    } else {
+                        return 0;
+                    }
+                case OP_CODE_NOT_NULL:
+                    if (aSide != null) {
+                        return 1;
+                    } else {
+                        return 0;
+                    }
+                case OP_CODE_GT:
+                    if (aSide == null || bSide == null) {
+                        return 0;
+                    }
+                    if (Double.parseDouble(aSide.toString().trim()) > Double
+                        .parseDouble(bSide.toString().trim())) {
+                        return 1;
+                    } else {
+                        return 0;
+                    }
+                case OP_CODE_GTEQ:
+                    if (aSide == null || bSide == null) {
+                        return 0;
+                    }
+                    if (Double.parseDouble(aSide.toString().trim()) >= Double
+                        .parseDouble(bSide.toString().trim())) {
+                        return 1;
+                    } else {
+                        return 0;
+                    }
+
+                case OP_CODE_LT:
+                    if (aSide == null || bSide == null) {
+                        return 0;
+                    }
+                    if (Double.parseDouble(aSide.toString().trim()) < Double
+                        .parseDouble(bSide.toString().trim())) {
+                        return 1;
+                    } else {
+                        return 0;
+                    }
+                case OP_CODE_LTEQ:
+                    if (aSide == null || bSide == null) {
+                        return 0;
+                    }
+                    if (Double.parseDouble(aSide.toString().trim()) <= Double
+                        .parseDouble(bSide.toString().trim())) {
+                        return 1;
+                    } else {
+                        return 0;
+                    }
+            }
+        }
+
+        int leftResult = 0;
+        if (left != null) {
+            leftResult = left.checkValue(value);
+        }
+
+        int rightResult = 0;
+        if (right != null) {
+            rightResult = right.checkValue(value);
+        }
+
+        if (operation == OP_CODE_SKIP) {
+            if (rightResult == 0) {
+                return 2;
+            } else {
+                return 3;
+            }
+        }
+
+        if (operation == OP_CODE_AND) {
+            if (leftResult == 0) {
+                return 0;
+            }
+            if (rightResult == 0) {
+                return 0;
+            }
+            if (leftResult >= 2) {
+                return leftResult;
+            }
+            if (rightResult >= 2) {
+                return rightResult;
+            }
+
+            return 1;
+        }
+
+        if (operation == OP_CODE_OR) {
+            if (leftResult == 0 && rightResult == 0) {
+                return 0;
+            }
+            if (leftResult >= 2) {
+                return leftResult;
+            }
+            if (rightResult >= 2) {
+                return rightResult;
+            }
+            return 1;
+        }
+
+        return 0;
+    }
+
+    public String toString() {
+        return criteria;
+    }
+
+    public String getCriteriaForProperty(XSQLColumn col) {
+        StringBuffer result = new StringBuffer();
+        if (criteria == null) {
+            return "";
+        }
+
+        if (leftValue != null && rightValue != null) {
+            if (leftValue.toString().toLowerCase().equals(col.getName().toLowerCase()) ||
+                leftValue.toString().toLowerCase().equals(col.toString().toLowerCase()) /*||
+                /*col.getName().toLowerCase().indexOf(leftValue.toString().toLowerCase()) != -1*/) {
+                result.append("? ").append(operators[operation]).append(" ").append(rightValue);
+            }else
+            if (rightValue.toString().toLowerCase().equals(col.getName().toLowerCase()) ||
+                    rightValue.toString().toLowerCase().equals(col.toString().toLowerCase()) /*||
+                    col.getName().toLowerCase().indexOf(rightValue.toString().toLowerCase()) != -1*/) {
+                    result.append("? ").append(operators[operation]).append(" ").append(leftValue);
+            }
+            return result.toString();
+        } else if (left != null && right != null) {
+            String leftString = left.getCriteriaForProperty(col);
+            String rightString = right.getCriteriaForProperty(col);
+            if (!leftString.equals("") && !rightString.equals("")) {
+                return leftString + " " + operators[operation] + " "
+                    + rightString;
+            } else if (!leftString.equals("")) {
+                return leftString;
+            } else if (!rightString.equals("")) {
+                return rightString;
+            }
+            return "";
+        } else if (leftValue != null && leftValue.toString().toLowerCase()
+            .equals(col.toString().toLowerCase()) && right != null) {
+            return "? " + operators[operation] + " (" + right
+                .getCriteriaForProperty(col) + ")";
+        } else if (rightValue != null && rightValue.toString().toLowerCase()
+            .equals(col.toString().toLowerCase()) && left != null) {
+            return "(" + left.getCriteriaForProperty(col) + ") "
+                + operators[operation] + " ?";
+        }
+        return "";
+    }
+
+    public static void main(String args[]) {
+        XSQLCriteria p =
+            new XSQLCriteria("ip like '%101%' or (354>=0 or 456>=3)", -1);
+        System.out.println(p.checkValue("192.268.4.4"));
+        p = new XSQLCriteria("? like '%267%'", -1);
+        System.out.println(p.checkValue("192.268.4.4"));
+
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLODLUtils.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLODLUtils.java
new file mode 100644 (file)
index 0000000..6a27230
--- /dev/null
@@ -0,0 +1,246 @@
+package org.opendaylight.controller.md.sal.dom.xsql;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.util.Uint16;
+import org.opendaylight.yangtools.yang.model.util.Uint32;
+import org.opendaylight.yangtools.yang.model.util.Uint64;
+import org.opendaylight.yangtools.yang.model.util.Uint8;
+
+public class XSQLODLUtils {
+
+    private static Map<Class<?>, Class<?>> types =
+        new ConcurrentHashMap<Class<?>, Class<?>>();
+
+    static {
+        types.put(QName.class, QName.class);
+        types.put(SchemaPath.class, SchemaPath.class);
+        types.put(Status.class, Status.class);
+    }
+
+    public static boolean isColumnType(Class cls) {
+        return types.containsKey(cls);
+    }
+
+    public static String getTableName(Object odlNode) {
+        if (odlNode instanceof Module) {
+            return ((Module) odlNode).getNamespace().toString();
+        } else if (odlNode instanceof DataSchemaNode) {
+            SchemaPath p = ((DataSchemaNode) odlNode).getPath();
+            return extractTableName(p);
+        } else {
+            int i = 0;
+        }
+        return null;
+    }
+
+    public static String extractTableName(SchemaPath path) {
+        List<QName> lst = path.getPath();
+        StringBuffer name = new StringBuffer();
+        int i = 0;
+        for (QName q : lst) {
+            name.append(q.getLocalName());
+            i++;
+            if (i < lst.size()) {
+                name.append("/");
+            }
+        }
+        return name.toString();
+    }
+
+    public static String getBluePrintName(Object odlNode){
+        if (odlNode instanceof Module) {
+            return ((Module) odlNode).getNamespace().toString();
+        } else if (odlNode instanceof DataSchemaNode) {
+            SchemaPath p = ((DataSchemaNode) odlNode).getPath();
+            return extractTableName(p);
+        }
+        return null;
+    }
+
+    public static String getODLNodeName(Object odlNode) {
+        if (odlNode instanceof Module) {
+            return ((Module) odlNode).getNamespace().toString();
+        } else if (odlNode instanceof DataSchemaNode) {
+            SchemaPath p = ((DataSchemaNode) odlNode).getPath();
+            List<QName> lst = p.getPath();
+            return lst.get(lst.size() - 1).toString();
+        }
+        return null;
+    }
+
+    public static List<QName> getPath(Object odlNode) {
+        return ((DataSchemaNode) odlNode).getPath().getPath();
+    }
+
+
+    public static String getODLTableName(Object odlNode) {
+        if (odlNode instanceof Module) {
+            return ((Module) odlNode).getNamespace().toString();
+        } else if (odlNode instanceof DataSchemaNode) {
+            return ((DataSchemaNode) odlNode).getPath().toString();
+        }
+        return null;
+    }
+
+    public static String getNodeNameFromDSN(Object o) {
+        DataSchemaNode node = (DataSchemaNode) o;
+        String nodeName = node.getQName().toString();
+        int index = nodeName.lastIndexOf(")");
+        return nodeName.substring(index + 1);
+    }
+
+    public static boolean isModule(Object o) {
+        if (o instanceof Module) {
+            return true;
+        }
+        return false;
+    }
+
+    public static boolean createOpenDaylightCache(XSQLBluePrint bluePrint,Object module) {
+        XSQLBluePrintNode node = new XSQLBluePrintNode(module, 0,null);
+        bluePrint.addToBluePrintCache(node);
+        collectODL(bluePrint, node, ((Module) module).getChildNodes(), 1);
+        return true;
+    }
+
+    private static void collectODL(XSQLBluePrint bluePrint,
+        XSQLBluePrintNode parent, Collection<DataSchemaNode> nodes, int level) {
+        if (nodes == null) {
+            return;
+        }
+        for (DataSchemaNode n : nodes) {
+            if (n instanceof DataNodeContainer /*|| n instanceof LeafListSchemaNode*/
+                || n instanceof ListSchemaNode) {
+                XSQLBluePrintNode bn = new XSQLBluePrintNode(n, level,parent);
+                bluePrint.addToBluePrintCache(bn);
+                parent.AddChild(bn);
+                if (n instanceof DataNodeContainer) {
+                    level++;
+                    collectODL(bluePrint, bn,
+                        ((DataNodeContainer) n).getChildNodes(), level);
+                    level--;
+                } else if (n instanceof ListSchemaNode) {
+                    level++;
+                    collectODL(bluePrint, bn,
+                        ((ListSchemaNode) n).getChildNodes(), level);
+                    level--;
+                }
+            } else {
+                if (parent != null) {
+                    parent.addColumn(n, parent.getParent().getBluePrintNodeName());
+                } else {
+                    XSQLAdapter.log("NO Parent!");
+                }
+            }
+        }
+    }
+
+    public static Map<String, Field> refFieldsCache =
+        new HashMap<String, Field>();
+
+    public static Field findField(Class<?> c, String name) {
+        if (c == null) {
+            return null;
+        }
+        String cacheKey = c.getName() + name;
+        Field f = refFieldsCache.get(cacheKey);
+        if (f != null) {
+            return f;
+        }
+
+        try {
+            f = c.getDeclaredField(name);
+            f.setAccessible(true);
+            refFieldsCache.put(cacheKey, f);
+            return f;
+        } catch (Exception err) {
+        }
+
+        Class<?> s = c.getSuperclass();
+        if (s != null) {
+            f = findField(s, name);
+            if (f != null) {
+                refFieldsCache.put(cacheKey, f);
+            }
+            return f;
+        }
+        return null;
+    }
+
+
+    public static Object get(Object o, String name) {
+        try {
+            Class<?> c = o.getClass();
+            Field f = findField(c, name);
+            return f.get(o);
+        } catch (Exception err) {
+            XSQLAdapter.log(err);
+        }
+        return null;
+    }
+
+    public static List<Object> getMChildren(Object o) {
+        Map<?, ?> children = getChildren(o);
+        List<Object> result = new LinkedList<Object>();
+        for (Object val : children.values()) {
+            result.add((Object) val);
+        }
+        return result;
+    }
+
+    public static Map<?, ?> getChildren(Object o) {
+        return (Map<?, ?>) get(o, "children");
+    }
+
+    public static Object getValue(Object o) {
+        return get(o, "value");
+    }
+
+    public static String getNodeIdentiofier(Object o) {
+        try{
+            return ((PathArgument) get(o, "nodeIdentifier")).getNodeType().toString();
+        }catch(Exception err){
+            return null;
+        }
+    }
+
+    public static String getNodeName(Object o) {
+        Object nodeID = get(o, "nodeIdentifier");
+        if (nodeID != null) {
+            String nodeName = nodeID.toString();
+            int index = nodeName.lastIndexOf(")");
+            return nodeName.substring(index + 1);
+        }
+        return "NULL";
+    }
+
+    public static Class getTypeForODLColumn(Object odlNode){
+        Object type = get(odlNode,"type");
+        if(type instanceof Uint32 || type instanceof Uint64){
+            return long.class;
+        }else
+        if(type instanceof Uint16){
+            return int.class;
+        }else
+        if(type instanceof Uint8){
+            return byte.class;
+        }
+        return String.class;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLThreadPool.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLThreadPool.java
new file mode 100644 (file)
index 0000000..c1db627
--- /dev/null
@@ -0,0 +1,110 @@
+package org.opendaylight.controller.md.sal.dom.xsql;
+
+import java.util.LinkedList;
+
+public class XSQLThreadPool {
+    private LinkedList<Runnable> tasks = new LinkedList<Runnable>();
+    private int threadCount = 0;
+    private int maxThreadCount = 10;
+    private String threadPoolName = "Simple Thread Pool";
+    private int waitTimeForIdle = 10000;
+    private int maxQueueSize = -1;
+    public Object waitForSlotSync = new Object();
+
+    public XSQLThreadPool(int _maxThreadCount, String name,
+        int _waitTimeForIdle) {
+        this.maxThreadCount = _maxThreadCount;
+        this.threadPoolName = name;
+        this.waitTimeForIdle = _waitTimeForIdle;
+    }
+
+    public void addTask(Runnable r) {
+        synchronized (tasks) {
+            tasks.add(r);
+            tasks.notifyAll();
+            if (threadCount < maxThreadCount) {
+                threadCount++;
+                new WorkerThread(threadCount).start();
+            }
+        }
+    }
+
+    private class WorkerThread extends Thread {
+
+        private long lastTimeExecuted = System.currentTimeMillis();
+
+        public WorkerThread(int threadNumber) {
+            super(
+                "Thread #" + threadNumber + " Of Threadpool " + threadPoolName);
+        }
+
+        public void run() {
+            Runnable runthis = null;
+            while (true) {
+                runthis = null;
+                if (maxQueueSize != -1) {
+                    synchronized (waitForSlotSync) {
+                        if (tasks.size() < maxQueueSize) {
+                            waitForSlotSync.notifyAll();
+                        }
+                    }
+                }
+                synchronized (tasks) {
+                    if (tasks.isEmpty()) {
+                        try {
+                            tasks.wait(2000);
+                        } catch (Exception err) {
+                        }
+                    }
+
+                    if (!tasks.isEmpty()) {
+                        runthis = tasks.removeFirst();
+                    }
+                }
+                if (runthis != null) {
+                    try {
+                        runthis.run();
+                    } catch (Exception err) {
+                        err.printStackTrace();
+                    }
+                    lastTimeExecuted = System.currentTimeMillis();
+                }
+                if (System.currentTimeMillis() - lastTimeExecuted
+                    > waitTimeForIdle) {
+                    break;
+                }
+            }
+            synchronized (tasks) {
+                threadCount--;
+            }
+        }
+    }
+
+    public int getNumberOfThreads() {
+        return threadCount;
+    }
+
+    public void waitForSlot() {
+        if (tasks.size() > maxQueueSize) {
+            synchronized (waitForSlotSync) {
+                try {
+                    waitForSlotSync.wait();
+                } catch (Exception err) {
+                    err.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public boolean isEmpty() {
+        if (this.threadCount == 0) {
+            return true;
+        }
+        return false;
+    }
+
+    public void setMaxQueueSize(int size) {
+        this.maxQueueSize = size;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCCommand.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCCommand.java
new file mode 100644 (file)
index 0000000..85ce0e5
--- /dev/null
@@ -0,0 +1,62 @@
+package org.opendaylight.controller.md.sal.dom.xsql.jdbc;
+
+import java.io.Serializable;
+import java.util.Map;
+
+public class JDBCCommand implements Serializable {
+    public int type = 0;
+    public static final int TYPE_EXECUTE_QUERY = 1;
+    public static final int TYPE_QUERY_REPLY = 2;
+    public static final int TYPE_QUERY_RECORD = 3;
+    public static final int TYPE_QUERY_FINISH = 4;
+    public static final int TYPE_QUERY_ERROR = 5;
+
+    private JDBCResultSet rs = null;
+    private Map record = null;
+    private int rsID = -1;
+    private Exception err = null;
+
+    public JDBCCommand(Exception _err, int _RSID) {
+        this.type = TYPE_QUERY_ERROR;
+        this.err = _err;
+        this.rsID = _RSID;
+    }
+
+    public JDBCCommand(JDBCResultSet _rs, int _type) {
+        this.type = TYPE_EXECUTE_QUERY;
+        this.rs = _rs;
+        this.type = _type;
+        this.rsID = rs.getID();
+    }
+
+    public JDBCCommand(Map _record, int _rsID) {
+        this.record = _record;
+        this.rsID = _rsID;
+        this.type = TYPE_QUERY_RECORD;
+    }
+
+    public JDBCCommand(int _rsID) {
+        this.rsID = _rsID;
+        this.type = TYPE_QUERY_FINISH;
+    }
+
+    public int getType() {
+        return this.type;
+    }
+
+    public JDBCResultSet getRS() {
+        return this.rs;
+    }
+
+    public Map getRecord() {
+        return this.record;
+    }
+
+    public int getRSID() {
+        return this.rsID;
+    }
+
+    public Exception getERROR() {
+        return this.err;
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCConnection.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCConnection.java
new file mode 100644 (file)
index 0000000..3e72dc9
--- /dev/null
@@ -0,0 +1,583 @@
+package org.opendaylight.controller.md.sal.dom.xsql.jdbc;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+import org.opendaylight.controller.md.sal.dom.xsql.XSQLAdapter;
+
+public class JDBCConnection extends Thread implements Connection {
+    private Socket socket = null;
+    private DataInputStream in = null;
+    private DataOutputStream out = null;
+    private LinkedList<byte[]> queue = new LinkedList<byte[]>();
+    private XSQLAdapter adapter = null;
+
+    public JDBCConnection(Socket s, XSQLAdapter _a) {
+        this.socket = s;
+        this.adapter = _a;
+        try {
+            in = new DataInputStream(
+                new BufferedInputStream(s.getInputStream()));
+            out = new DataOutputStream(
+                new BufferedOutputStream(s.getOutputStream()));
+            new JDBCObjectReader();
+            this.start();
+        } catch (Exception err) {
+            err.printStackTrace();
+        }
+    }
+
+    public JDBCConnection(String addr) throws Exception {
+        socket = new Socket(addr, 40004);
+        try {
+            in = new DataInputStream(
+                new BufferedInputStream(socket.getInputStream()));
+            out = new DataOutputStream(
+                new BufferedOutputStream(socket.getOutputStream()));
+            new JDBCObjectReader();
+            this.start();
+        } catch (Exception err) {
+            err.printStackTrace();
+        }
+    }
+
+    public JDBCConnection(boolean server) {
+        try {
+            ServerSocket s = new ServerSocket(50003);
+            socket = s.accept();
+            try {
+                in = new DataInputStream(
+                    new BufferedInputStream(socket.getInputStream()));
+                out = new DataOutputStream(
+                    new BufferedOutputStream(socket.getOutputStream()));
+                new JDBCObjectReader();
+                this.start();
+            } catch (Exception err) {
+                err.printStackTrace();
+            }
+        } catch (Exception err) {
+            err.printStackTrace();
+        }
+    }
+
+
+    private boolean isStopped() {
+        if (adapter != null && adapter.stopped) {
+            return true;
+        }
+        if (socket == null || socket.isClosed()) {
+            return true;
+        }
+        return false;
+    }
+
+    public void run() {
+        byte data[] = null;
+        while (!isStopped()) {
+            try {
+                int len = in.readInt();
+                data = new byte[len];
+                in.readFully(data);
+                addObject(data);
+
+            } catch (Exception err) {
+                System.out.println("Connection Lost or Closed.");
+                try {
+                    socket.close();
+                } catch (Exception err2) {
+                }
+                //err.printStackTrace();
+            }
+        }
+    }
+
+    private void addObject(byte[] data) {
+        synchronized (queue) {
+            queue.add(data);
+            queue.notifyAll();
+        }
+    }
+
+    private class JDBCObjectReader extends Thread {
+
+        public JDBCObjectReader() {
+            super("JDBCObjectReader");
+            start();
+        }
+
+        public void run() {
+            while (!isStopped()) {
+                byte data[] = null;
+                synchronized (queue) {
+                    if (queue.size() == 0) {
+                        try {
+                            queue.wait(1000);
+                        } catch (Exception err) {
+                        }
+                    }
+                    if (queue.size() > 0) {
+                        data = queue.removeFirst();
+                    }
+                }
+                if (data != null) {
+                    JDBCCommand command = (JDBCCommand) deSerialize(data);
+                    processCommand(command);
+                }
+            }
+        }
+
+        private Object deSerialize(byte data[]) {
+            try {
+                ByteArrayInputStream in = new ByteArrayInputStream(data);
+                ObjectInputStream oin = new ObjectInputStream(in);
+                return oin.readObject();
+            } catch (Exception err) {
+                err.printStackTrace();
+            }
+            return null;
+        }
+    }
+
+    public void processCommand(JDBCCommand cmd) {
+        switch (cmd.getType()) {
+            case JDBCCommand.TYPE_EXECUTE_QUERY:
+                try {
+                    JDBCServer.execute(cmd.getRS(), adapter);
+                    send(new JDBCCommand(cmd.getRS(),
+                        JDBCCommand.TYPE_QUERY_REPLY));
+                    QueryUpdater u = new QueryUpdater(cmd.getRS());
+                    new Thread(u).start();
+                } catch (Exception err) {
+                    send(new JDBCCommand(err, cmd.getRSID()));
+                }
+                break;
+            case JDBCCommand.TYPE_QUERY_REPLY:
+                JDBCResultSet rs1 = JDBCStatement.getQuery(cmd.getRS().getID());
+                rs1.updateData(cmd.getRS());
+                break;
+            case JDBCCommand.TYPE_QUERY_RECORD:
+                JDBCResultSet rs2 = JDBCStatement.getQuery(cmd.getRSID());
+                rs2.addRecord(cmd.getRecord());
+                break;
+            case JDBCCommand.TYPE_QUERY_FINISH:
+                JDBCResultSet rs3 = JDBCStatement.removeQuery(cmd.getRSID());
+                rs3.setFinished(true);
+                break;
+            case JDBCCommand.TYPE_QUERY_ERROR:
+                System.err.println("ERROR Executing Query\n");
+                cmd.getERROR().printStackTrace();
+                JDBCResultSet rs4 = JDBCStatement.removeQuery(cmd.getRSID());
+                rs4.setError(cmd.getERROR());
+                rs4.setFinished(true);
+                synchronized (rs4) {
+                    rs4.notifyAll();
+                }
+        }
+    }
+
+    private class QueryUpdater implements Runnable {
+
+        private JDBCResultSet rs = null;
+
+        public QueryUpdater(JDBCResultSet _rs) {
+            this.rs = _rs;
+        }
+
+        public void run() {
+            while (rs.next()) {
+                JDBCCommand rec = new JDBCCommand(rs.getCurrent(), rs.getID());
+                send(rec);
+            }
+            JDBCCommand end = new JDBCCommand(rs.getID());
+            send(end);
+        }
+    }
+
+    public void send(Object o) {
+        try {
+            ByteArrayOutputStream bout = new ByteArrayOutputStream();
+            ObjectOutputStream oout = new ObjectOutputStream(bout);
+            oout.writeObject(o);
+            byte data[] = bout.toByteArray();
+            synchronized (socket) {
+                out.writeInt(data.length);
+                out.write(data);
+                out.flush();
+            }
+        } catch (Exception err) {
+            err.printStackTrace();
+        }
+    }
+
+    @Override
+    public boolean isWrapperFor(Class<?> arg0) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public <T> T unwrap(Class<T> arg0) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void clearWarnings() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void close() throws SQLException {
+        try {
+            socket.close();
+        } catch (Exception err) {
+        }
+        socket = null;
+    }
+
+    @Override
+    public void commit() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public Array createArrayOf(String typeName, Object[] elements)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Blob createBlob() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Clob createClob() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NClob createNClob() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public SQLXML createSQLXML() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Statement createStatement() throws SQLException {
+        return new JDBCStatement(this);
+    }
+
+    @Override
+    public Statement createStatement(int resultSetType,
+        int resultSetConcurrency, int resultSetHoldability)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Statement createStatement(int resultSetType,
+        int resultSetConcurrency)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Struct createStruct(String typeName, Object[] attributes)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean getAutoCommit() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public String getCatalog() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Properties getClientInfo() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getClientInfo(String name) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getHoldability() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public DatabaseMetaData getMetaData() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getTransactionIsolation() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public Map<String, Class<?>> getTypeMap() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public SQLWarning getWarnings() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isClosed() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isReadOnly() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isValid(int timeout) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public String nativeSQL(String sql) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public CallableStatement prepareCall(String sql, int resultSetType,
+        int resultSetConcurrency, int resultSetHoldability)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public CallableStatement prepareCall(String sql, int resultSetType,
+        int resultSetConcurrency) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public CallableStatement prepareCall(String sql) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public PreparedStatement prepareStatement(String sql, int resultSetType,
+        int resultSetConcurrency, int resultSetHoldability)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public PreparedStatement prepareStatement(String sql, int resultSetType,
+        int resultSetConcurrency) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public PreparedStatement prepareStatement(String sql, String[] columnNames)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public PreparedStatement prepareStatement(String sql) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void rollback() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void rollback(Savepoint savepoint) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setAutoCommit(boolean autoCommit) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setCatalog(String catalog) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setClientInfo(Properties properties)
+        throws SQLClientInfoException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setClientInfo(String name, String value)
+        throws SQLClientInfoException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setHoldability(int holdability) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setReadOnly(boolean readOnly) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public Savepoint setSavepoint() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Savepoint setSavepoint(String name) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void setTransactionIsolation(int level) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setSchema(String schema) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public String getSchema() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void abort(Executor executor) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setNetworkTimeout(Executor executor, int milliseconds)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public int getNetworkTimeout() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+}
+
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCDriver.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCDriver.java
new file mode 100644 (file)
index 0000000..e4b4e24
--- /dev/null
@@ -0,0 +1,73 @@
+package org.opendaylight.controller.md.sal.dom.xsql.jdbc;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+public class JDBCDriver implements Driver {
+
+    public static JDBCDriver drv = new JDBCDriver();
+
+    public JDBCDriver() {
+        try {
+            DriverManager.registerDriver(this);
+        } catch (SQLException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public boolean acceptsURL(String arg0) throws SQLException {
+        return true;
+    }
+
+    @Override
+    public Connection connect(String url, Properties arg1) throws SQLException {
+        System.err.println("JDBC Connection");
+        try {
+            if (url.equals("svr")) {
+                return new JDBCConnection(true);
+            } else {
+                return new JDBCConnection(url);
+            }
+        } catch (Exception err) {
+            err.printStackTrace();
+        }
+        return null;
+    }
+
+    @Override
+    public int getMajorVersion() {
+        return 1;
+    }
+
+    @Override
+    public int getMinorVersion() {
+        return 0;
+    }
+
+    @Override
+    public DriverPropertyInfo[] getPropertyInfo(String arg0, Properties arg1)
+        throws SQLException {
+        DriverPropertyInfo i = new DriverPropertyInfo("NQL", "NQL");
+        return new DriverPropertyInfo[] {i};
+    }
+
+    @Override
+    public boolean jdbcCompliant() {
+        return false;
+    }
+
+    @Override
+    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCResultSet.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCResultSet.java
new file mode 100644 (file)
index 0000000..7603a3e
--- /dev/null
@@ -0,0 +1,1780 @@
+package org.opendaylight.controller.md.sal.dom.xsql.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.opendaylight.controller.md.sal.dom.xsql.XSQLBluePrint;
+import org.opendaylight.controller.md.sal.dom.xsql.XSQLBluePrintNode;
+import org.opendaylight.controller.md.sal.dom.xsql.XSQLColumn;
+import org.opendaylight.controller.md.sal.dom.xsql.XSQLCriteria;
+import org.opendaylight.controller.md.sal.dom.xsql.XSQLODLUtils;
+
+public class JDBCResultSet
+    implements Serializable, ResultSet, ResultSetMetaData {
+    private static final long serialVersionUID = -7450200738431047057L;
+
+    private String sql = null;
+    private List<XSQLBluePrintNode> tablesInQuery =
+        new ArrayList<XSQLBluePrintNode>();
+    private Map<String, XSQLBluePrintNode> tablesInQueryMap =
+        new ConcurrentHashMap<String, XSQLBluePrintNode>();
+    private List<XSQLColumn> fieldsInQuery = new ArrayList<XSQLColumn>();
+    private transient LinkedList<Map> records = new LinkedList<Map>();
+    private transient Map currentRecord = null;
+    private boolean finished = false;
+    private int id = 0;
+    private static Integer nextID = new Integer(0);
+    public int numberOfTasks = 0;
+    private Map<String, Map<XSQLColumn, List<XSQLCriteria>>> criteria =
+        new ConcurrentHashMap<String, Map<XSQLColumn, List<XSQLCriteria>>>();
+    private Exception err = null;
+    private List<Record> EMPTY_RESULT = new LinkedList<Record>();
+
+    public JDBCResultSet(String _sql) {
+        synchronized (JDBCResultSet.class) {
+            nextID++;
+            id = nextID;
+        }
+        this.sql = _sql;
+    }
+
+    public String getSQL() {
+        return this.sql;
+    }
+
+    public void setError(Exception _err) {
+        this.err = _err;
+    }
+
+    public Exception getError() {
+        return this.err;
+    }
+
+    public void updateData(JDBCResultSet rs) {
+        synchronized (this) {
+            this.tablesInQuery = rs.tablesInQuery;
+            this.tablesInQueryMap = rs.tablesInQueryMap;
+            this.fieldsInQuery = rs.fieldsInQuery;
+            this.notifyAll();
+        }
+    }
+
+    public int isObjectFitCriteria(Map objValues, String tableName) {
+        Map<XSQLColumn, List<XSQLCriteria>> tblCriteria = criteria.get(tableName);
+        if (tblCriteria == null) {
+            return 1;
+        }
+        for (Map.Entry<XSQLColumn, List<XSQLCriteria>> cc : tblCriteria
+            .entrySet()) {
+            for (XSQLCriteria c : cc.getValue()) {
+                Object value = objValues.get(cc.getKey().toString());
+                int result = c.checkValue(value);
+                if (result == 0) {
+                    return 0;
+                }
+            }
+        }
+        return 1;
+    }
+
+    public int isObjectFitCriteria(Object element, Class cls) {
+        Map<XSQLColumn, List<XSQLCriteria>> tblCriteria =
+            criteria.get(cls.getName());
+        if (tblCriteria == null) {
+            return 1;
+        }
+        for (Map.Entry<XSQLColumn, List<XSQLCriteria>> cc : tblCriteria
+            .entrySet()) {
+            for (XSQLCriteria c : cc.getValue()) {
+                int result =
+                    c.isObjectFitCriteria(element, cc.getKey().getName());
+                if (result == 0) {
+                    return 0;
+                }
+            }
+        }
+        return 1;
+    }
+
+    public Map<String, Map<XSQLColumn, List<XSQLCriteria>>> getCriteria() {
+        return this.criteria;
+    }
+
+    public int getID() {
+        return this.id;
+    }
+
+    public List<XSQLBluePrintNode> getTables() {
+        return tablesInQuery;
+    }
+
+    public void addTableToQuery(XSQLBluePrintNode node) {
+        if (this.tablesInQueryMap.containsKey(node.getBluePrintNodeName())) {
+            return;
+        }
+        this.tablesInQuery.add(node);
+        this.tablesInQueryMap.put(node.getBluePrintNodeName(), node);
+    }
+
+    public List<XSQLColumn> getFields() {
+        return this.fieldsInQuery;
+    }
+
+    public XSQLBluePrintNode getMainTable() {
+        if (tablesInQuery.size() == 1) {
+            return tablesInQuery.get(0);
+        }
+        XSQLBluePrintNode result = null;
+        for (XSQLBluePrintNode node : tablesInQuery) {
+            if (result == null) {
+                result = node;
+            } else if (result.getLevel() < node.getLevel()) {
+                result = node;
+            }
+        }
+        return result;
+    }
+
+    public boolean isFinished() {
+        return finished;
+    }
+
+    public void setFinished(boolean b) {
+        this.finished = b;
+    }
+
+    public int size() {
+        return this.records.size();
+    }
+
+    public void addRecord(Map r) {
+        synchronized (this) {
+            if (records == null) {
+                records = new LinkedList<Map>();
+            }
+            records.add(r);
+            this.notifyAll();
+        }
+    }
+
+
+    public void addRecord(ArrayList hierarchy) {
+        Map rec = new HashMap();
+        for (int i = hierarchy.size() - 1; i >= 0; i--) {
+            Object element = hierarchy.get(i);
+            for (XSQLColumn c : fieldsInQuery) {
+                if (c.getTableName()
+                    .equals(element.getClass().getSimpleName())) {
+                    try {
+                        Method m = element.getClass().getMethod(c.getName(), null);
+                        Object value = m.invoke(element, null);
+                        rec.put(c.getName(), value);
+                    } catch (Exception err) {
+                        err.printStackTrace();
+                    }
+                }
+            }
+        }
+        this.records.add(rec);
+    }
+
+    public boolean next() {
+        this.currentRecord = null;
+        if (records == null) {
+            records = new LinkedList<Map>();
+        }
+        while (!finished || records.size() > 0) {
+            synchronized (this) {
+                if (records.size() == 0) {
+                    try {
+                        this.wait(1000);
+                    } catch (Exception err) {
+                    }
+                    if (records.size() > 0) {
+                        try {
+                            currentRecord = records.removeFirst();
+                            return true;
+                        } finally {
+                            this.notifyAll();
+                        }
+                    }
+                } else {
+                    try {
+                        currentRecord = records.removeFirst();
+                        return true;
+                    } finally {
+                        this.notifyAll();
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    public Map getCurrent() {
+        return this.currentRecord;
+    }
+
+    private void createRecord(Object data, XSQLBluePrintNode node) {
+        Map rec = new HashMap();
+        for (XSQLColumn c : this.fieldsInQuery) {
+            if (c.getTableName().equals(node.getBluePrintNodeName())) {
+                try {
+                    Method m = node.getInterface().getMethod(c.getName(), null);
+                    Object value = m.invoke(data, null);
+                    if (value != null) {
+                        rec.put(c.getName(), value);
+                    } else {
+                        rec.put(c.getName(), "");
+                    }
+                } catch (Exception err) {
+                    err.printStackTrace();
+                }
+
+            }
+        }
+    }
+
+    public static class Record {
+        public Map data = new HashMap();
+        public Object element = null;
+
+        public Map getRecord() {
+            return this.data;
+        }
+    }
+
+    private Map collectColumnValues(Object node, XSQLBluePrintNode bpn) {
+        Map subChildren = XSQLODLUtils.getChildren(node);
+        Map result = new HashMap();
+        for (Object stc : subChildren.values()) {
+            if (stc.getClass().getName()
+                .endsWith("ImmutableAugmentationNode")) {
+                Map values = XSQLODLUtils.getChildren(stc);
+                for (Object key : values.keySet()) {
+                    Object val = values.get(key);
+                    if (val.getClass().getName()
+                        .endsWith("ImmutableLeafNode")) {
+                        Object value = XSQLODLUtils.getValue(val);
+                        String k = XSQLODLUtils.getNodeName(val);
+                        if (value != null) {
+                            result.put(bpn.getBluePrintNodeName() + "." + k,
+                                value.toString());
+                        }
+                    }
+                }
+            } else if (stc.getClass().getName().endsWith("ImmutableLeafNode")) {
+                String k = XSQLODLUtils.getNodeName(stc);
+                Object value = XSQLODLUtils.getValue(stc);
+                if (value != null) {
+                    result.put(bpn.getBluePrintNodeName() + "." + k, value.toString());
+                }
+            }
+        }
+        return result;
+    }
+
+    private void addToData(Record rec, XSQLBluePrintNode bpn, XSQLBluePrint bluePrint, Map fullRecord) {
+        XSQLBluePrintNode eNodes[] = bluePrint.getBluePrintNodeByODLTableName(XSQLODLUtils.getNodeIdentiofier(rec.element));
+        if (bpn != null) {
+            for (XSQLColumn c : fieldsInQuery) {
+                for(XSQLBluePrintNode eNode:eNodes){
+                    if (((XSQLBluePrintNode) c.getBluePrintNode()).getBluePrintNodeName().equals(eNode.getBluePrintNodeName())) {
+                        //Object value = Criteria.getValue(rec.element, c.getName());
+                        String columnName = c.toString();
+                        Object value = fullRecord.get(columnName);
+                        if (value != null) {
+                            try {
+                                Object rsValue = c.getResultSetValue(value);
+                                c.setCharWidth(rsValue.toString().length());
+                                rec.data.put(columnName, rsValue);
+                            } catch (Exception err) {
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private boolean beenHere(Set<String> beenHereElement, Object element) {
+        if (beenHereElement == null) {
+            beenHereElement = new HashSet<String>();
+        }
+
+        String elementKey = null;
+
+        try {
+            elementKey = element.toString();
+        } catch (Exception err) {
+            elementKey = "Unknown";
+        }
+
+        if (beenHereElement.contains(elementKey)) {
+            return true;
+        }
+
+        beenHereElement.add(elementKey);
+        return false;
+    }
+
+    public List<Object> getChildren(Object node, String tableName,XSQLBluePrint bluePrint) {
+
+        List<Object> children = XSQLODLUtils.getMChildren(node);
+        List<Object> result = new LinkedList<Object>();
+
+        for (Object child : children) {
+
+            String odlNodeName = XSQLODLUtils.getNodeIdentiofier(child);
+            if(odlNodeName==null) continue;
+
+            XSQLBluePrintNode eNodes[] = bluePrint.getBluePrintNodeByODLTableName(odlNodeName);
+            if(eNodes==null) continue;
+
+            boolean match = false;
+            for(XSQLBluePrintNode enode:eNodes){
+                if(tableName.startsWith(enode.toString())){
+                    match = true;
+                    break;
+                }
+            }
+
+            if(!match) continue;
+
+            if (child.getClass().getName().endsWith("ImmutableContainerNode")) {
+                result.add(child);
+            }else
+            if (child.getClass().getName().endsWith("ImmutableAugmentationNode")) {
+                List<Object> _children = XSQLODLUtils.getMChildren(child);
+                for (Object c : _children) {
+                    if (c.getClass().getName().endsWith("ImmutableContainerNode")) {
+                        result.add(c);
+                    }
+                }
+            } else if (child.getClass().getName().endsWith("ImmutableMapNode")) {
+                result.addAll(XSQLODLUtils.getMChildren(child));
+            }
+        }
+        return result;
+    }
+
+    public List<Record> addRecords(Object element, XSQLBluePrintNode node,boolean root, String tableName,XSQLBluePrint bluePrint) {
+
+        List<Record> result = new LinkedList<Record>();
+        String nodeID = XSQLODLUtils.getNodeIdentiofier(element);
+        if (node.getODLTableName().equals(nodeID)) {
+            XSQLBluePrintNode bluePrintNode = bluePrint.getBluePrintNodeByODLTableName(nodeID)[0];
+            Record rec = new Record();
+            rec.element = element;
+            XSQLBluePrintNode bpn = this.tablesInQueryMap.get(bluePrintNode.getBluePrintNodeName());
+            if (this.criteria.containsKey(bluePrintNode.getBluePrintNodeName()) || bpn != null) {
+                Map<?, ?> allKeyValues = collectColumnValues(element, bpn);
+                if (!(isObjectFitCriteria(allKeyValues, bpn.getBluePrintNodeName()) == 1)) {
+                    return EMPTY_RESULT;
+                }
+                addToData(rec, bpn, bluePrint,allKeyValues);
+            }
+            if (root) {
+                addRecord(rec.data);
+            } else {
+                result.add(rec);
+            }
+            return result;
+        }
+
+        XSQLBluePrintNode parent = node.getParent();
+        List<Record> subRecords = addRecords(element, parent, false, tableName,bluePrint);
+        for (Record subRec : subRecords) {
+            List<Object> subO = getChildren(subRec.element, tableName,bluePrint);
+            if (subO != null) {
+                for (Object subData : subO) {
+                    Record rec = new Record();
+                    rec.element = subData;
+                    rec.data.putAll(subRec.data);
+
+                    String recID = XSQLODLUtils.getNodeIdentiofier(rec.element);
+                    XSQLBluePrintNode eNodes[] = bluePrint.getBluePrintNodeByODLTableName(recID);
+                    XSQLBluePrintNode bpn = null;
+                    for(XSQLBluePrintNode eNode:eNodes){
+                        bpn = this.tablesInQueryMap.get(eNode.getBluePrintNodeName());
+                        if(bpn!=null)
+                            break;
+                    }
+                    boolean isObjectInCriteria = true;
+                    if (bpn != null) {
+                        Map allKeyValues = collectColumnValues(rec.element, bpn);
+                        if ((isObjectFitCriteria(allKeyValues, bpn.getBluePrintNodeName()) == 1)) {
+                            addToData(rec, bpn,bluePrint,allKeyValues);
+                        } else {
+                            isObjectInCriteria = false;
+                        }
+                    }
+
+                    if (isObjectInCriteria) {
+                        if (root) {
+                            if(!rec.data.isEmpty())
+                                addRecord(rec.data);
+                        } else {
+                            result.add(rec);
+                        }
+                    }
+                }
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean absolute(int row) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void afterLast() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void beforeFirst() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void cancelRowUpdates() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void clearWarnings() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void close() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void deleteRow() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public int findColumn(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public boolean first() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Array getArray(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Array getArray(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public InputStream getAsciiStream(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public InputStream getAsciiStream(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public BigDecimal getBigDecimal(int columnIndex, int scale)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public BigDecimal getBigDecimal(String columnLabel, int scale)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public InputStream getBinaryStream(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public InputStream getBinaryStream(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Blob getBlob(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Blob getBlob(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean getBoolean(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean getBoolean(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public byte getByte(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public byte getByte(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public byte[] getBytes(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public byte[] getBytes(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Reader getCharacterStream(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Reader getCharacterStream(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Clob getClob(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Clob getClob(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getConcurrency() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public String getCursorName() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Date getDate(int columnIndex, Calendar cal) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Date getDate(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Date getDate(String columnLabel, Calendar cal) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Date getDate(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public double getDouble(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public double getDouble(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getFetchDirection() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getFetchSize() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public float getFloat(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public float getFloat(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getHoldability() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getInt(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getInt(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public long getLong(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public long getLong(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public ResultSetMetaData getMetaData() throws SQLException {
+        return this;
+    }
+
+    @Override
+    public Reader getNCharacterStream(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Reader getNCharacterStream(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NClob getNClob(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NClob getNClob(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getNString(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getNString(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Object getObject(int columnIndex, Map<String, Class<?>> map)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Object getObject(int columnIndex) throws SQLException {
+        return currentRecord
+            .get(this.fieldsInQuery.get(columnIndex - 1).toString());
+    }
+
+    @Override
+    public Object getObject(String columnLabel, Map<String, Class<?>> map)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Object getObject(String columnLabel) throws SQLException {
+        return currentRecord.get(columnLabel);
+    }
+
+    @Override
+    public Ref getRef(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Ref getRef(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getRow() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public RowId getRowId(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public RowId getRowId(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public SQLXML getSQLXML(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public SQLXML getSQLXML(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public short getShort(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public short getShort(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public Statement getStatement() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getString(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getString(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Time getTime(int columnIndex, Calendar cal) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Time getTime(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Time getTime(String columnLabel, Calendar cal) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Time getTime(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Timestamp getTimestamp(int columnIndex, Calendar cal)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Timestamp getTimestamp(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Timestamp getTimestamp(String columnLabel, Calendar cal)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Timestamp getTimestamp(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getType() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public URL getURL(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public URL getURL(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public InputStream getUnicodeStream(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public InputStream getUnicodeStream(String columnLabel)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public SQLWarning getWarnings() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void insertRow() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean isAfterLast() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isBeforeFirst() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isClosed() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isFirst() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isLast() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean last() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void moveToCurrentRow() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void moveToInsertRow() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean previous() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void refreshRow() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean relative(int rows) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean rowDeleted() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean rowInserted() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean rowUpdated() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void setFetchDirection(int direction) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setFetchSize(int rows) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateArray(int columnIndex, Array x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateArray(String columnLabel, Array x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateAsciiStream(int columnIndex, InputStream x, int length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateAsciiStream(int columnIndex, InputStream x, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateAsciiStream(int columnIndex, InputStream x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateAsciiStream(String columnLabel, InputStream x, int length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateAsciiStream(String columnLabel, InputStream x,
+        long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateAsciiStream(String columnLabel, InputStream x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBigDecimal(int columnIndex, BigDecimal x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBigDecimal(String columnLabel, BigDecimal x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBinaryStream(int columnIndex, InputStream x, int length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBinaryStream(int columnIndex, InputStream x, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBinaryStream(int columnIndex, InputStream x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBinaryStream(String columnLabel, InputStream x,
+        int length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBinaryStream(String columnLabel, InputStream x,
+        long length) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBinaryStream(String columnLabel, InputStream x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBlob(int columnIndex, Blob x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBlob(int columnIndex, InputStream inputStream,
+        long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBlob(int columnIndex, InputStream inputStream)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBlob(String columnLabel, Blob x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBlob(String columnLabel, InputStream inputStream,
+        long length) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBlob(String columnLabel, InputStream inputStream)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBoolean(int columnIndex, boolean x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBoolean(String columnLabel, boolean x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateByte(int columnIndex, byte x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateByte(String columnLabel, byte x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBytes(int columnIndex, byte[] x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateBytes(String columnLabel, byte[] x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateCharacterStream(int columnIndex, Reader x, int length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateCharacterStream(int columnIndex, Reader x, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateCharacterStream(int columnIndex, Reader x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateCharacterStream(String columnLabel, Reader reader,
+        int length) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateCharacterStream(String columnLabel, Reader reader,
+        long length) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateCharacterStream(String columnLabel, Reader reader)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateClob(int columnIndex, Clob x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateClob(int columnIndex, Reader reader, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateClob(int columnIndex, Reader reader) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateClob(String columnLabel, Clob x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateClob(String columnLabel, Reader reader, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateClob(String columnLabel, Reader reader)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateDate(int columnIndex, Date x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateDate(String columnLabel, Date x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateDouble(int columnIndex, double x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateDouble(String columnLabel, double x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateFloat(int columnIndex, float x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateFloat(String columnLabel, float x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateInt(int columnIndex, int x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateInt(String columnLabel, int x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateLong(int columnIndex, long x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateLong(String columnLabel, long x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNCharacterStream(int columnIndex, Reader x, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNCharacterStream(int columnIndex, Reader x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNCharacterStream(String columnLabel, Reader reader,
+        long length) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNCharacterStream(String columnLabel, Reader reader)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNClob(int columnIndex, Reader reader, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNClob(int columnIndex, Reader reader)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNClob(String columnLabel, NClob nClob)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNClob(String columnLabel, Reader reader, long length)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNClob(String columnLabel, Reader reader)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNString(int columnIndex, String nString)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNString(String columnLabel, String nString)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNull(int columnIndex) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNull(String columnLabel) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateObject(int columnIndex, Object x, int scaleOrLength)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateObject(int columnIndex, Object x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateObject(String columnLabel, Object x, int scaleOrLength)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateObject(String columnLabel, Object x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateRef(int columnIndex, Ref x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateRef(String columnLabel, Ref x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateRow() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateRowId(int columnIndex, RowId x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateRowId(String columnLabel, RowId x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateSQLXML(int columnIndex, SQLXML xmlObject)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateSQLXML(String columnLabel, SQLXML xmlObject)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateShort(int columnIndex, short x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateShort(String columnLabel, short x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateString(int columnIndex, String x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateString(String columnLabel, String x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateTime(int columnIndex, Time x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateTime(String columnLabel, Time x) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateTimestamp(int columnIndex, Timestamp x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateTimestamp(String columnLabel, Timestamp x)
+        throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean wasNull() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public String getCatalogName(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getColumnClassName(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getColumnCount() throws SQLException {
+        return fieldsInQuery.size();
+    }
+
+    @Override
+    public int getColumnDisplaySize(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public String getColumnLabel(int column) throws SQLException {
+        return this.fieldsInQuery.get(column - 1).toString();
+    }
+
+    @Override
+    public String getColumnName(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getColumnType(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public String getColumnTypeName(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getPrecision(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getScale(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public String getSchemaName(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getTableName(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isAutoIncrement(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isCaseSensitive(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isCurrency(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isDefinitelyWritable(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public int isNullable(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public boolean isReadOnly(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isSearchable(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isSigned(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isWritable(int column) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <T> T getObject(String columnLabel, Class<T> type)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+
+    ////Metadata
+
+
+
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCServer.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCServer.java
new file mode 100644 (file)
index 0000000..26b8c70
--- /dev/null
@@ -0,0 +1,206 @@
+package org.opendaylight.controller.md.sal.dom.xsql.jdbc;
+
+import org.opendaylight.controller.md.sal.dom.xsql.XSQLAdapter;
+import org.opendaylight.controller.md.sal.dom.xsql.XSQLBluePrint;
+import org.opendaylight.controller.md.sal.dom.xsql.XSQLBluePrintNode;
+import org.opendaylight.controller.md.sal.dom.xsql.XSQLColumn;
+import org.opendaylight.controller.md.sal.dom.xsql.XSQLCriteria;
+
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class JDBCServer extends Thread {
+    private ServerSocket socket = null;
+    private XSQLAdapter adapter = null;
+
+    public JDBCServer(XSQLAdapter a) {
+        super("JDBC Server");
+        this.adapter = a;
+        start();
+    }
+
+    public void run() {
+        try {
+            socket = new ServerSocket(40004);
+            while (!adapter.stopped) {
+                Socket s = socket.accept();
+                new JDBCConnection(s, adapter);
+            }
+        } catch (Exception err) {
+            err.printStackTrace();
+        }
+    }
+
+    public void connectToClient(String addr) {
+        try {
+            Socket s = new Socket(addr, 50003);
+            new JDBCConnection(s, adapter);
+        } catch (Exception err) {
+            err.printStackTrace();
+        }
+    }
+
+    public static void execute(JDBCResultSet rs, XSQLAdapter adapter)
+        throws SQLException {
+        parseTables(rs, adapter.getBluePrint());
+        parseFields(rs, adapter.getBluePrint());
+        parseCriteria(rs, adapter.getBluePrint());
+        try {
+            adapter.execute(rs);
+        } catch (Exception err) {
+            throw new SQLException("Error", err);
+        }
+    }
+
+    public static void parseTables(JDBCResultSet rs, XSQLBluePrint bp)
+        throws SQLException {
+        String lowSQL = rs.getSQL().toLowerCase();
+        int from = lowSQL.indexOf("from");
+        int where = lowSQL.indexOf("where");
+        int subQuery = lowSQL.indexOf("select", 2);
+        int fromTo = lowSQL.indexOf(";");
+
+        if (where != -1 && subQuery != -1 && where < subQuery) {
+            fromTo = where;
+        } else if (where != -1 && subQuery != -1 && where > subQuery) {
+            fromTo = subQuery;
+        } else if (where != -1) {
+            fromTo = where;
+        } else if (subQuery != -1) {
+            fromTo = subQuery;
+        }
+
+        if (from == -1) {
+            throw new SQLException("Missing \"from\" statement.");
+        }
+
+        if (fromTo == -1) {
+            throw new SQLException("Missing terminating \";\".");
+        }
+
+        String tableNames = rs.getSQL().substring(from + 4, fromTo).trim();
+        StringTokenizer tokens = new StringTokenizer(tableNames, ",");
+        while (tokens.hasMoreTokens()) {
+            String tableName = tokens.nextToken().trim();
+            XSQLBluePrintNode table = bp.getBluePrintNodeByTableName(tableName);
+            if (table == null) {
+                throw new SQLException(
+                    "Unknown table name \"" + tableName + "\"");
+            }
+            rs.addTableToQuery(table);
+        }
+    }
+
+    public static void addCriteria(XSQLColumn col, XSQLCriteria c,
+        JDBCResultSet rs) {
+        Map<XSQLColumn, List<XSQLCriteria>> tblCriteria =
+            rs.getCriteria().get(col.getTableName());
+        if (tblCriteria == null) {
+            tblCriteria =
+                new ConcurrentHashMap<XSQLColumn, List<XSQLCriteria>>();
+            rs.getCriteria().put(col.getTableName(), tblCriteria);
+        }
+        List<XSQLCriteria> lstCriteria = tblCriteria.get(col);
+        if (lstCriteria == null) {
+            lstCriteria = new ArrayList<XSQLCriteria>();
+            tblCriteria.put(col, lstCriteria);
+        }
+        lstCriteria.add(c);
+    }
+
+    public static void parseFields(JDBCResultSet rs, XSQLBluePrint bp)
+        throws SQLException {
+        String lowSQL = rs.getSQL().toLowerCase();
+        if (!lowSQL.startsWith("select")) {
+            throw new SQLException("Missing 'select' statement.");
+        }
+        int from = lowSQL.indexOf("from");
+        if (from == -1) {
+            throw new SQLException("Missing 'from' statement.");
+        }
+        String fields = rs.getSQL().substring(6, from).trim();
+        StringTokenizer tokens = new StringTokenizer(fields, ",");
+        while (tokens.hasMoreTokens()) {
+            String token = tokens.nextToken().trim();
+            if (token.equals("*")) {
+                for (XSQLBluePrintNode table : rs.getTables()) {
+                    rs.getFields().addAll(table.getColumns());
+                }
+                return;
+            }
+            if (token.indexOf(".") != -1) {
+                XSQLBluePrintNode tbl = bp.getBluePrintNodeByTableName(
+                    token.substring(0, token.indexOf(".")).trim());
+                String p = token.substring(token.indexOf(".") + 1);
+                if (p.equals("*")) {
+                    for (XSQLColumn c : tbl.getColumns()) {
+                        rs.getFields().add(c);
+                    }
+                } else {
+                    XSQLColumn col = tbl.findColumnByName(p);
+                    rs.getFields().add(col);
+                }
+            } else {
+                XSQLColumn col = null;
+                for (XSQLBluePrintNode table : rs.getTables()) {
+                    try {
+                        col = table.findColumnByName(token);
+                    } catch (Exception err) {
+                    }
+                    if (col != null) {
+                        break;
+                    }
+                }
+                if (col == null) {
+                    throw new SQLException(
+                        "Unknown field name '" + token + "'.");
+                }
+
+                rs.getFields().add(col);
+            }
+        }
+    }
+
+    public static void parseCriteria(JDBCResultSet rs, XSQLBluePrint bp) {
+        String lowSQL = rs.getSQL().toLowerCase();
+        int where = lowSQL.indexOf("where");
+        int order = lowSQL.indexOf("order");
+        int subQuery = lowSQL.indexOf("select", 2);
+        int whereTo = lowSQL.indexOf(";");
+
+        if (where == -1) {
+            return;
+        }
+
+        if (where != -1 && subQuery != -1 && subQuery < where) {
+            return;
+        }
+
+        if (order != -1 && subQuery != -1 && order < subQuery) {
+            whereTo = order;
+        } else if (order != -1 && subQuery != -1 && order > subQuery) {
+            whereTo = subQuery;
+        } else if (order != -1) {
+            whereTo = order;
+        } else if (subQuery != -1) {
+            whereTo = subQuery;
+        }
+        String whereStatement =
+            rs.getSQL().substring(where + 5, whereTo).trim();
+        XSQLCriteria cr = new XSQLCriteria(whereStatement, -1);
+        for (XSQLBluePrintNode tbl : rs.getTables()) {
+            for (XSQLColumn col : tbl.getColumns()) {
+                String colCriteria = cr.getCriteriaForProperty(col);
+                if (colCriteria != null && !colCriteria.trim().equals("")) {
+                    addCriteria(col, new XSQLCriteria(colCriteria, -1), rs);
+                }
+            }
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCStatement.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/jdbc/JDBCStatement.java
new file mode 100644 (file)
index 0000000..a9ce1dd
--- /dev/null
@@ -0,0 +1,330 @@
+package org.opendaylight.controller.md.sal.dom.xsql.jdbc;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class JDBCStatement implements Statement {
+    private JDBCResultSet rs = null;
+    private transient JDBCConnection connection = null;
+    private static Map<Integer, JDBCResultSet> queries =
+        new ConcurrentHashMap<Integer, JDBCResultSet>();
+
+    public JDBCStatement(JDBCConnection con) {
+        this.connection = con;
+    }
+
+    public JDBCStatement() {
+
+    }
+
+    public static JDBCResultSet getQuery(int id) {
+        return queries.get(id);
+    }
+
+    public static JDBCResultSet removeQuery(int id) {
+        return queries.remove(id);
+    }
+
+    @Override
+    public java.sql.ResultSet executeQuery(String _sql) throws SQLException {
+        rs = new JDBCResultSet(_sql);
+        queries.put(rs.getID(), rs);
+        synchronized (rs) {
+            this.connection
+                .send(new JDBCCommand(rs, JDBCCommand.TYPE_EXECUTE_QUERY));
+            try {
+                rs.wait();
+            } catch (Exception err) {
+            }
+            if (rs.getError() != null) {
+                throw ((SQLException) rs.getError());
+            }
+        }
+        return rs;
+    }
+
+    @Override
+    public boolean execute(String _sql) throws SQLException {
+        return true;
+    }
+
+    public void addRecord(ArrayList hierarchy) {
+        rs.addRecord(hierarchy);
+    }
+
+    public int size() {
+        return rs.size();
+    }
+
+    public void setFinished(boolean b) {
+        this.rs.setFinished(b);
+    }
+
+    public JDBCResultSet getRS() {
+        return this.rs;
+    }
+
+    public ResultSet getResultSet() {
+        return this.rs;
+    }
+
+    @Override
+    public boolean isWrapperFor(Class<?> arg0) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public <T> T unwrap(Class<T> arg0) throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void addBatch(String sql) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void cancel() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void clearBatch() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void clearWarnings() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void close() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean execute(String sql, int autoGeneratedKeys)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean execute(String sql, int[] columnIndexes)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean execute(String sql, String[] columnNames)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public int[] executeBatch() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int executeUpdate(String sql, int autoGeneratedKeys)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int executeUpdate(String sql, int[] columnIndexes)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int executeUpdate(String sql, String[] columnNames)
+        throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int executeUpdate(String sql) throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public Connection getConnection() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getFetchDirection() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getFetchSize() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public java.sql.ResultSet getGeneratedKeys() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getMaxFieldSize() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getMaxRows() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public boolean getMoreResults() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean getMoreResults(int current) throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public int getQueryTimeout() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getResultSetConcurrency() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getResultSetHoldability() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getResultSetType() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int getUpdateCount() throws SQLException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public SQLWarning getWarnings() throws SQLException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isClosed() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isPoolable() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void setCursorName(String name) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setEscapeProcessing(boolean enable) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setFetchDirection(int direction) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setFetchSize(int rows) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setMaxFieldSize(int max) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setMaxRows(int max) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setPoolable(boolean poolable) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setQueryTimeout(int seconds) throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void closeOnCompletion() throws SQLException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean isCloseOnCompletion() throws SQLException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/xsql/XSQLProvider.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/xsql/XSQLProvider.java
new file mode 100644 (file)
index 0000000..b421e56
--- /dev/null
@@ -0,0 +1,41 @@
+package org.opendaylight.xsql;
+
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.xsql.rev140626.XSQL;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.xsql.rev140626.XSQLBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Created by root on 6/26/14.
+ */
+public class XSQLProvider implements AutoCloseable {
+
+    public static final InstanceIdentifier<XSQL> ID = InstanceIdentifier.builder(XSQL.class).build();
+    private static final Logger LOG = LoggerFactory.getLogger(XSQLProvider.class);
+
+    public void close() {
+    }
+
+    public XSQL buildXSQL(DataProviderService dps) {
+            XSQLBuilder builder = new XSQLBuilder();
+            builder.setPort("34343");
+            XSQL xsql = builder.build();
+            if (dps != null) {
+                final DataModificationTransaction t = dps.beginTransaction();
+                t.removeOperationalData(ID);
+                t.putOperationalData(ID,xsql);
+
+                try {
+                    t.commit().get();
+                } catch (InterruptedException | ExecutionException e) {
+                   LOG.warn("Failed to update toaster status, operational otherwise", e);
+                }
+            }
+        return xsql;
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/yang/gen/v1/http/netconfcentral/org/ns/xsql/rev140626/XSQLModule.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/yang/gen/v1/http/netconfcentral/org/ns/xsql/rev140626/XSQLModule.java
new file mode 100644 (file)
index 0000000..399f49b
--- /dev/null
@@ -0,0 +1,30 @@
+package org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.xsql.rev140626;
+
+import org.opendaylight.controller.md.sal.dom.xsql.XSQLAdapter;
+import org.opendaylight.xsql.XSQLProvider;
+
+public class XSQLModule extends org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.xsql.rev140626.AbstractXSQLModule {
+    public XSQLModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public XSQLModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.xsql.rev140626.XSQLModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        XSQLAdapter xsqlAdapter = XSQLAdapter.getInstance();
+        getSchemaServiceDependency().registerSchemaServiceListener(xsqlAdapter);
+        xsqlAdapter.setDataBroker(getAsyncDataBrokerDependency());
+        XSQLProvider p = new XSQLProvider();
+        p.buildXSQL(getDataBrokerDependency());
+        return p;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/yang/gen/v1/http/netconfcentral/org/ns/xsql/rev140626/XSQLModuleFactory.java b/opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/yang/gen/v1/http/netconfcentral/org/ns/xsql/rev140626/XSQLModuleFactory.java
new file mode 100644 (file)
index 0000000..ac0d9c1
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: XSQL yang module local name: XSQL
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Thu Jun 26 14:56:25 PDT 2014
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.xsql.rev140626;
+public class XSQLModuleFactory extends org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.xsql.rev140626.AbstractXSQLModuleFactory {
+
+}
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/resources/04-xsql.xml b/opendaylight/md-sal/sal-dom-xsql/src/main/resources/04-xsql.xml
new file mode 100644 (file)
index 0000000..d7d547d
--- /dev/null
@@ -0,0 +1,29 @@
+<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:XSQL="http://netconfcentral.org/ns/XSQL">
+                        XSQL:XSQL
+                    </type>
+                    <name>XSQL</name>
+                    <data-broker>
+                       <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>
+                    <async-data-broker>
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
+                        <name>inmemory-data-broker</name>
+                    </async-data-broker>
+                    <schema-service>
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+                        <name>yang-schema-service</name>
+                    </schema-service>
+                </module>
+            </modules>
+        </data>
+    </configuration>
+    <required-capabilities>
+        <capability>http://netconfcentral.org/ns/XSQL?module=XSQL&amp;revision=2014-06-26</capability>
+    </required-capabilities>
+</snapshot>
diff --git a/opendaylight/md-sal/sal-dom-xsql/src/main/yang/XSQL.yang b/opendaylight/md-sal/sal-dom-xsql/src/main/yang/XSQL.yang
new file mode 100644 (file)
index 0000000..0437e10
--- /dev/null
@@ -0,0 +1,72 @@
+module XSQL{
+    yang-version 1;
+    namespace "http://netconfcentral.org/ns/XSQL";
+    prefix XSQL;
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
+    import rpc-context { prefix rpcx; revision-date 2013-06-17; }
+    import opendaylight-md-sal-dom {prefix sal;}
+    import opendaylight-md-sal-common {prefix common;}
+
+    organization "Netconf Central";
+    contact "Sharon Aicler <saichler@cisco.com>";
+    description "YANG version of the XSQL status";
+
+    revision "2014-06-26" {
+          description "XSQL module initial version";
+    }
+
+    container XSQL {
+        presence "Indicates the XSQL service is available";
+        description "Container to indicate the XSQL availability";
+        leaf port {
+            type string;
+            config false;
+            mandatory true;
+            description "The port the XSQL binds on";
+        }
+    }
+
+    identity XSQL {
+        base config:module-type;
+        config:java-name-prefix XSQL;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case XSQL {
+            when "/config:modules/config:module/config:type = 'XSQL'";
+
+                       container data-broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory false;
+                        config:required-identity mdsal:binding-data-broker;
+                    }
+                }
+            }         
+
+            container async-data-broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory false;
+                        config:required-identity sal:dom-async-data-broker;
+                    }
+                }
+
+            }
+
+            container schema-service {
+                uses config:service-ref {
+                    refine type {
+                        mandatory false;
+                        config:required-identity sal:schema-service;
+                    }
+                }
+
+            }
+
+        }
+    }
+
+}
index dadef821eb349e048d8395f6ab1c24cb39eb89b4..906847426c6087d9b486de7aeb3237f28f971a7f 100644 (file)
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-simple</artifactId>
-      <version>${slf4j.version}</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>binding-generator-impl</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-test-model</artifactId>
+      <scope>test</scope>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
 
   <build>
index 3ed02dfb411fcb26cda91cc8cf227cf9f2ef4a0e..01a5989dcd8a6b5afa67a50844e540cbd68c80c5 100644 (file)
@@ -1,14 +1,17 @@
 package org.opendaylight.controller.config.yang.inmemory_datastore_provider;
 
-import com.google.common.util.concurrent.MoreExecutors;
+import java.util.concurrent.Executors;
+
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
 
+import com.google.common.util.concurrent.MoreExecutors;
+
 public class InMemoryConfigDataStoreProviderModule extends org.opendaylight.controller.config.yang.inmemory_datastore_provider.AbstractInMemoryConfigDataStoreProviderModule {
-    public InMemoryConfigDataStoreProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+    public InMemoryConfigDataStoreProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
     }
 
-    public InMemoryConfigDataStoreProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.inmemory_datastore_provider.InMemoryConfigDataStoreProviderModule oldModule, java.lang.AutoCloseable oldInstance) {
+    public InMemoryConfigDataStoreProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final org.opendaylight.controller.config.yang.inmemory_datastore_provider.InMemoryConfigDataStoreProviderModule oldModule, final java.lang.AutoCloseable oldInstance) {
         super(identifier, dependencyResolver, oldModule, oldInstance);
     }
 
@@ -19,7 +22,7 @@ public class InMemoryConfigDataStoreProviderModule extends org.opendaylight.cont
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-      InMemoryDOMDataStore   ids = new InMemoryDOMDataStore("DOM-CFG", MoreExecutors.sameThreadExecutor());
+      InMemoryDOMDataStore   ids = new InMemoryDOMDataStore("DOM-CFG", MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()));
       getSchemaServiceDependency().registerSchemaServiceListener(ids);
       return ids;
     }
index eea95990a1509a4231c2d5452ce661cb6c3270c5..b39c9bbbd8ca7f0cbe504470ec5f9237e88c0a70 100644 (file)
@@ -1,14 +1,17 @@
 package org.opendaylight.controller.config.yang.inmemory_datastore_provider;
 
-import com.google.common.util.concurrent.MoreExecutors;
+import java.util.concurrent.Executors;
+
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
 
+import com.google.common.util.concurrent.MoreExecutors;
+
 public class InMemoryOperationalDataStoreProviderModule extends org.opendaylight.controller.config.yang.inmemory_datastore_provider.AbstractInMemoryOperationalDataStoreProviderModule {
-    public InMemoryOperationalDataStoreProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+    public InMemoryOperationalDataStoreProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
     }
 
-    public InMemoryOperationalDataStoreProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.inmemory_datastore_provider.InMemoryOperationalDataStoreProviderModule oldModule, java.lang.AutoCloseable oldInstance) {
+    public InMemoryOperationalDataStoreProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final org.opendaylight.controller.config.yang.inmemory_datastore_provider.InMemoryOperationalDataStoreProviderModule oldModule, final java.lang.AutoCloseable oldInstance) {
         super(identifier, dependencyResolver, oldModule, oldInstance);
     }
 
@@ -19,8 +22,8 @@ public class InMemoryOperationalDataStoreProviderModule extends org.opendaylight
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-      InMemoryDOMDataStore ids = new InMemoryDOMDataStore("DOM-OPER", MoreExecutors.sameThreadExecutor());
-      getSchemaServiceDependency().registerSchemaServiceListener(ids);
+      InMemoryDOMDataStore ids = new InMemoryDOMDataStore("DOM-OPER", MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()));
+      getOperationalSchemaServiceDependency().registerSchemaServiceListener(ids);
       return ids;
     }
 
index 375376f383aa8beedcc8dccba4d1c37aeec0c788..27325d84a9ddf3ecf11133ab2d55137477b3fe25 100644 (file)
@@ -8,7 +8,7 @@
 package org.opendaylight.controller.md.sal.dom.store.impl;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -17,10 +17,10 @@ class ChangeListenerNotifyTask implements Runnable {
 
     private static final Logger LOG = LoggerFactory.getLogger(ChangeListenerNotifyTask.class);
     private final Iterable<? extends DataChangeListenerRegistration<?>> listeners;
-    private final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> event;
+    private final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> event;
 
     public ChangeListenerNotifyTask(final Iterable<? extends DataChangeListenerRegistration<?>> listeners,
-            final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> event) {
+            final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> event) {
         this.listeners = listeners;
         this.event = event;
     }
index af479743aa12a824a0e7610e057b7bbdd299e448..5faebcef36c65294a36d7b3036453f45f8b20352 100644 (file)
@@ -15,14 +15,14 @@ import java.util.Set;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.base.Preconditions;
 
 public final class DOMImmutableDataChangeEvent implements
-        AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> {
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> {
 
 
     private static final RemoveEventFactory REMOVE_EVENT_FACTORY = new RemoveEventFactory();
@@ -30,10 +30,10 @@ public final class DOMImmutableDataChangeEvent implements
 
     private final NormalizedNode<?, ?> original;
     private final NormalizedNode<?, ?> updated;
-    private final Map<InstanceIdentifier, ? extends NormalizedNode<?, ?>> originalData;
-    private final Map<InstanceIdentifier, NormalizedNode<?, ?>> createdData;
-    private final Map<InstanceIdentifier, NormalizedNode<?, ?>> updatedData;
-    private final Set<InstanceIdentifier> removedPaths;
+    private final Map<YangInstanceIdentifier, NormalizedNode<?, ?>> originalData;
+    private final Map<YangInstanceIdentifier, NormalizedNode<?, ?>> createdData;
+    private final Map<YangInstanceIdentifier, NormalizedNode<?, ?>> updatedData;
+    private final Set<YangInstanceIdentifier> removedPaths;
     private final DataChangeScope scope;
 
 
@@ -67,22 +67,22 @@ public final class DOMImmutableDataChangeEvent implements
     }
 
     @Override
-    public Map<InstanceIdentifier, ? extends NormalizedNode<?, ?>> getOriginalData() {
+    public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getOriginalData() {
         return originalData;
     }
 
     @Override
-    public Map<InstanceIdentifier, NormalizedNode<?, ?>> getCreatedData() {
+    public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getCreatedData() {
         return createdData;
     }
 
     @Override
-    public Map<InstanceIdentifier, NormalizedNode<?, ?>> getUpdatedData() {
+    public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getUpdatedData() {
         return updatedData;
     }
 
     @Override
-    public Set<InstanceIdentifier> getRemovedPaths() {
+    public Set<YangInstanceIdentifier> getRemovedPaths() {
         return removedPaths;
     }
 
@@ -98,7 +98,7 @@ public final class DOMImmutableDataChangeEvent implements
      *
      */
     public interface SimpleEventFactory {
-        DOMImmutableDataChangeEvent create(InstanceIdentifier path, NormalizedNode<PathArgument,?> data);
+        DOMImmutableDataChangeEvent create(YangInstanceIdentifier path, NormalizedNode<PathArgument,?> data);
     }
 
     /**
@@ -133,10 +133,10 @@ public final class DOMImmutableDataChangeEvent implements
         private NormalizedNode<?, ?> after;
         private NormalizedNode<?, ?> before;
 
-        private final Map<InstanceIdentifier, NormalizedNode<?, ?>> original = new HashMap<>();
-        private final Map<InstanceIdentifier, NormalizedNode<?, ?>> created = new HashMap<>();
-        private final Map<InstanceIdentifier, NormalizedNode<?, ?>> updated = new HashMap<>();
-        private final Set<InstanceIdentifier> removed = new HashSet<>();
+        private final Map<YangInstanceIdentifier, NormalizedNode<?, ?>> original = new HashMap<>();
+        private final Map<YangInstanceIdentifier, NormalizedNode<?, ?>> created = new HashMap<>();
+        private final Map<YangInstanceIdentifier, NormalizedNode<?, ?>> updated = new HashMap<>();
+        private final Set<YangInstanceIdentifier> removed = new HashSet<>();
 
         private Builder(final DataChangeScope scope) {
             Preconditions.checkNotNull(scope, "Data change scope should not be null.");
@@ -167,18 +167,18 @@ public final class DOMImmutableDataChangeEvent implements
             return this;
         }
 
-        public Builder addCreated(final InstanceIdentifier path, final NormalizedNode<?, ?> node) {
+        public Builder addCreated(final YangInstanceIdentifier path, final NormalizedNode<?, ?> node) {
             created.put(path, node);
             return this;
         }
 
-        public Builder addRemoved(final InstanceIdentifier path, final NormalizedNode<?, ?> node) {
+        public Builder addRemoved(final YangInstanceIdentifier path, final NormalizedNode<?, ?> node) {
             original.put(path, node);
             removed.add(path);
             return this;
         }
 
-        public Builder addUpdated(final InstanceIdentifier path, final NormalizedNode<?, ?> before,
+        public Builder addUpdated(final YangInstanceIdentifier path, final NormalizedNode<?, ?> before,
                 final NormalizedNode<?, ?> after) {
             original.put(path, before);
             updated.put(path, after);
@@ -189,7 +189,7 @@ public final class DOMImmutableDataChangeEvent implements
     private static final class RemoveEventFactory implements SimpleEventFactory {
 
         @Override
-        public DOMImmutableDataChangeEvent create(final InstanceIdentifier path, final NormalizedNode<PathArgument, ?> data) {
+        public DOMImmutableDataChangeEvent create(final YangInstanceIdentifier path, final NormalizedNode<PathArgument, ?> data) {
             return builder(DataChangeScope.BASE) //
                     .setBefore(data) //
                     .addRemoved(path, data) //
@@ -201,7 +201,7 @@ public final class DOMImmutableDataChangeEvent implements
     private static final class CreateEventFactory implements SimpleEventFactory {
 
         @Override
-        public DOMImmutableDataChangeEvent create(final InstanceIdentifier path, final NormalizedNode<PathArgument, ?> data) {
+        public DOMImmutableDataChangeEvent create(final YangInstanceIdentifier path, final NormalizedNode<PathArgument, ?> data) {
             return builder(DataChangeScope.BASE) //
                     .setAfter(data) //
                     .addCreated(path, data) //
index d8f024017ffa6a39fd2f2b8a0febce04414e9eb7..b26f43b2b73eb723f8116039b42fc650276606e5 100644 (file)
@@ -10,14 +10,14 @@ package org.opendaylight.controller.md.sal.dom.store.impl;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
-public interface DataChangeListenerRegistration<L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> extends ListenerRegistration<L> {
+public interface DataChangeListenerRegistration<L extends AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>> extends ListenerRegistration<L> {
     @Override
     L getInstance();
 
-    InstanceIdentifier getPath();
+    YangInstanceIdentifier getPath();
 
     DataChangeScope getScope();
 }
index bef37980e5cb6b13c569fe8fb45eb3609609775e..c44d0909d688773d0cc37034cae21541f0823e6f 100644 (file)
@@ -35,7 +35,7 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
 import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
@@ -108,8 +108,8 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
         executor.shutdownNow();
     }
     @Override
-    public <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> ListenerRegistration<L> registerChangeListener(
-            final InstanceIdentifier path, final L listener, final DataChangeScope scope) {
+    public <L extends AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>> ListenerRegistration<L> registerChangeListener(
+            final YangInstanceIdentifier path, final L listener, final DataChangeScope scope) {
 
         /*
          * Make sure commit is not occurring right now. Listener has to be
index 71a3534c811448d6f941f6166e145021db0653d7..ff64cd64c412d57b12da080468f188d457948c6b 100644 (file)
@@ -7,23 +7,28 @@
  */
 package org.opendaylight.controller.md.sal.dom.store.impl;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Multimap;
+import static org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.builder;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.Builder;
 import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.SimpleEventFactory;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree.Node;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree.Walker;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
@@ -32,16 +37,12 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.Callable;
-
-import static org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.builder;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
 
 /**
  * Resolve Data Change Events based on modifications and listeners
@@ -238,7 +239,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
      *            - After state of current node
      * @return Data Change Event of this node and all it's children
      */
-    private DOMImmutableDataChangeEvent resolveAnyChangeEvent(final InstanceIdentifier path,
+    private DOMImmutableDataChangeEvent resolveAnyChangeEvent(final YangInstanceIdentifier path,
             final Collection<ListenerTree.Node> listeners, final DataTreeCandidateNode node) {
 
         if (node.getModificationType() != ModificationType.UNMODIFIED &&
@@ -273,7 +274,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
         throw new IllegalStateException(String.format("Unhandled node state %s at %s", node.getModificationType(), path));
     }
 
-    private DOMImmutableDataChangeEvent resolveReplacedEvent(final InstanceIdentifier path,
+    private DOMImmutableDataChangeEvent resolveReplacedEvent(final YangInstanceIdentifier path,
             final Collection<Node> listeners, final NormalizedNode<?, ?> beforeData,
             final NormalizedNode<?, ?> afterData) {
 
@@ -301,7 +302,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
         }
     }
 
-    private DOMImmutableDataChangeEvent resolveNodeContainerReplaced(final InstanceIdentifier path,
+    private DOMImmutableDataChangeEvent resolveNodeContainerReplaced(final YangInstanceIdentifier path,
             final Collection<Node> listeners,
             final NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>> beforeCont,
                     final NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>> afterCont) {
@@ -313,7 +314,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
         for (NormalizedNode<PathArgument, ?> beforeChild : beforeCont.getValue()) {
             PathArgument childId = beforeChild.getIdentifier();
             alreadyProcessed.add(childId);
-            InstanceIdentifier childPath = path.node(childId);
+            YangInstanceIdentifier childPath = path.node(childId);
             Collection<ListenerTree.Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
             Optional<NormalizedNode<PathArgument, ?>> afterChild = afterCont.getChild(childId);
             DOMImmutableDataChangeEvent childChange = resolveNodeContainerChildUpdated(childPath, childListeners,
@@ -332,7 +333,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
                 // and it was not present in previous loop, that means it is
                 // created.
                 Collection<ListenerTree.Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
-                InstanceIdentifier childPath = path.node(childId);
+                YangInstanceIdentifier childPath = path.node(childId);
                 childChanges.add(resolveSameEventRecursivelly(childPath , childListeners, afterChild,
                         DOMImmutableDataChangeEvent.getCreateEventFactory()));
             }
@@ -354,7 +355,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
         return replaceEvent;
     }
 
-    private DOMImmutableDataChangeEvent resolveNodeContainerChildUpdated(final InstanceIdentifier path,
+    private DOMImmutableDataChangeEvent resolveNodeContainerChildUpdated(final YangInstanceIdentifier path,
             final Collection<Node> listeners, final NormalizedNode<PathArgument, ?> before,
             final Optional<NormalizedNode<PathArgument, ?>> after) {
 
@@ -378,14 +379,14 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
      * @param afterState
      * @return
      */
-    private DOMImmutableDataChangeEvent resolveCreateEvent(final InstanceIdentifier path,
+    private DOMImmutableDataChangeEvent resolveCreateEvent(final YangInstanceIdentifier path,
             final Collection<ListenerTree.Node> listeners, final NormalizedNode<?, ?> afterState) {
         @SuppressWarnings({ "unchecked", "rawtypes" })
         final NormalizedNode<PathArgument, ?> node = (NormalizedNode) afterState;
         return resolveSameEventRecursivelly(path, listeners, node, DOMImmutableDataChangeEvent.getCreateEventFactory());
     }
 
-    private DOMImmutableDataChangeEvent resolveDeleteEvent(final InstanceIdentifier path,
+    private DOMImmutableDataChangeEvent resolveDeleteEvent(final YangInstanceIdentifier path,
             final Collection<ListenerTree.Node> listeners, final NormalizedNode<?, ?> beforeState) {
 
         @SuppressWarnings({ "unchecked", "rawtypes" })
@@ -393,7 +394,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
         return resolveSameEventRecursivelly(path, listeners, node, DOMImmutableDataChangeEvent.getRemoveEventFactory());
     }
 
-    private DOMImmutableDataChangeEvent resolveSameEventRecursivelly(final InstanceIdentifier path,
+    private DOMImmutableDataChangeEvent resolveSameEventRecursivelly(final YangInstanceIdentifier path,
             final Collection<Node> listeners, final NormalizedNode<PathArgument, ?> node,
             final SimpleEventFactory eventFactory) {
         final DOMImmutableDataChangeEvent event = eventFactory.create(path, node);
@@ -426,7 +427,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
         return propagateEvent;
     }
 
-    private DOMImmutableDataChangeEvent resolveSubtreeChangeEvent(final InstanceIdentifier path,
+    private DOMImmutableDataChangeEvent resolveSubtreeChangeEvent(final YangInstanceIdentifier path,
             final Collection<ListenerTree.Node> listeners, final DataTreeCandidateNode modification) {
 
         Preconditions.checkArgument(modification.getDataBefore().isPresent(), "Subtree change with before-data not present at path %s", path);
@@ -438,17 +439,19 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
         Builder subtree = builder(DataChangeScope.SUBTREE).
                 setBefore(modification.getDataBefore().get()).
                 setAfter(modification.getDataAfter().get());
-
+        boolean oneModified = false;
         for (DataTreeCandidateNode childMod : modification.getChildNodes()) {
             PathArgument childId = childMod.getIdentifier();
-            InstanceIdentifier childPath = path.node(childId);
+            YangInstanceIdentifier childPath = path.node(childId);
             Collection<ListenerTree.Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
 
+
             switch (childMod.getModificationType()) {
             case WRITE:
             case MERGE:
             case DELETE:
                 one.merge(resolveAnyChangeEvent(childPath, childListeners, childMod));
+                oneModified = true;
                 break;
             case SUBTREE_MODIFIED:
                 subtree.merge(resolveSubtreeChangeEvent(childPath, childListeners, childMod));
@@ -458,11 +461,20 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
                 break;
             }
         }
-        DOMImmutableDataChangeEvent oneChangeEvent = one.build();
-        subtree.merge(oneChangeEvent);
+        final DOMImmutableDataChangeEvent oneChangeEvent;
+        if(oneModified) {
+            one.addUpdated(path, modification.getDataBefore().get(), modification.getDataAfter().get());
+            oneChangeEvent = one.build();
+            subtree.merge(oneChangeEvent);
+        } else {
+            oneChangeEvent = null;
+            subtree.addUpdated(path, modification.getDataBefore().get(), modification.getDataAfter().get());
+        }
         DOMImmutableDataChangeEvent subtreeEvent = subtree.build();
         if (!listeners.isEmpty()) {
-            addPartialTask(listeners, oneChangeEvent);
+            if(oneChangeEvent != null) {
+                addPartialTask(listeners, oneChangeEvent);
+            }
             addPartialTask(listeners, subtreeEvent);
         }
         return subtreeEvent;
index c76c70b700174512eee0f86b2622feb60c4352de..39d6483c525ed648ea8c7f922ce8c57ee0064af0 100644 (file)
@@ -12,7 +12,7 @@ import static com.google.common.base.Preconditions.checkState;
 
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -48,7 +48,7 @@ DOMStoreReadTransaction {
     }
 
     @Override
-    public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final InstanceIdentifier path) {
+    public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final YangInstanceIdentifier path) {
         checkNotNull(path, "Path must not be null.");
         checkState(stableSnapshot != null, "Transaction is closed");
         return Futures.immediateFuture(stableSnapshot.readNode(path));
index 1456386ff9b573d839401f1a47b18deb2764e626..ec17d7a3f7e4cbaccc2c5a4ffa1f65cddbd8d60e 100644 (file)
@@ -9,7 +9,7 @@ package org.opendaylight.controller.md.sal.dom.store.impl;
 
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -41,7 +41,7 @@ DOMStoreReadWriteTransaction {
     }
 
     @Override
-    public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final InstanceIdentifier path) {
+    public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final YangInstanceIdentifier path) {
         LOG.debug("Tx: {} Read: {}", getIdentifier(), path);
         try {
             return Futures.immediateFuture(getMutatedView().readNode(path));
index 16675d3a8563f0a4142d86e248243c790085e940..34532ab98fdc45502e3794a8ea967e4e3da4f805 100644 (file)
@@ -12,7 +12,7 @@ import static com.google.common.base.Preconditions.checkState;
 
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -62,7 +62,7 @@ class SnapshotBackedWriteTransaction extends AbstractDOMStoreTransaction impleme
     }
 
     @Override
-    public void write(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
+    public void write(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
         checkNotReady();
         try {
             LOG.debug("Tx: {} Write: {}:{}", getIdentifier(), path, data);
@@ -79,7 +79,7 @@ class SnapshotBackedWriteTransaction extends AbstractDOMStoreTransaction impleme
     }
 
     @Override
-    public void merge(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
+    public void merge(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
         checkNotReady();
         try {
             LOG.debug("Tx: {} Merge: {}:{}", getIdentifier(), path, data);
@@ -96,7 +96,7 @@ class SnapshotBackedWriteTransaction extends AbstractDOMStoreTransaction impleme
     }
 
     @Override
-    public void delete(final InstanceIdentifier path) {
+    public void delete(final YangInstanceIdentifier path) {
         checkNotReady();
         try {
             LOG.debug("Tx: {} Delete: {}", getIdentifier(), path);
index e6221f6920152aab2d60936af78646c3dd394ea2..39152767dd0b063c373adaed9fd5704b8702719c 100644 (file)
@@ -9,19 +9,7 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
-import org.opendaylight.controller.md.sal.dom.store.impl.DataChangeListenerRegistration;
-import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import javax.annotation.concurrent.GuardedBy;
 import java.lang.ref.Reference;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
@@ -32,6 +20,20 @@ import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
+import javax.annotation.concurrent.GuardedBy;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.store.impl.DataChangeListenerRegistration;
+import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * A set of listeners organized as a tree by node to which they listen. This class
  * allows for efficient lookup of listeners when we walk the DataTreeCandidate.
@@ -62,7 +64,7 @@ public final class ListenerTree  {
      * @param scope Scope of triggering event.
      * @return Listener registration
      */
-    public <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> DataChangeListenerRegistration<L> registerDataChangeListener(final InstanceIdentifier path,
+    public <L extends AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>> DataChangeListenerRegistration<L> registerDataChangeListener(final YangInstanceIdentifier path,
             final L listener, final DataChangeScope scope) {
 
         // Take the write lock
@@ -70,7 +72,7 @@ public final class ListenerTree  {
 
         try {
             Node walkNode = rootNode;
-            for (final PathArgument arg : path.getPath()) {
+            for (final PathArgument arg : path.getPathArguments()) {
                 walkNode = walkNode.ensureChild(arg);
             }
 
@@ -82,7 +84,7 @@ public final class ListenerTree  {
                 }
 
                 @Override
-                public InstanceIdentifier getPath() {
+                public YangInstanceIdentifier getPath() {
                     return path;
                 }
 
@@ -249,7 +251,7 @@ public final class ListenerTree  {
 
     }
 
-    private abstract static class DataChangeListenerRegistrationImpl<T extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> extends AbstractListenerRegistration<T> //
+    private abstract static class DataChangeListenerRegistrationImpl<T extends AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>> extends AbstractListenerRegistration<T> //
     implements DataChangeListenerRegistration<T> {
         public DataChangeListenerRegistrationImpl(final T listener) {
             super(listener);
index 03220a3e5d1b2bd3a8d39b2da43e279ac4dd769f..d4f57b53fed168dae3f1402123f9164f8c772455 100644 (file)
@@ -58,7 +58,10 @@ module opendaylight-inmemory-datastore-provider {
             case inmemory-operational-datastore-provider {
                 when "/config:modules/config:module/config:type = 'inmemory-operational-datastore-provider'";
 
-                container schema-service {
+                // Yang does not allow two cases from same namespaces with same children
+                // Schema-service dependency renamed to operational-schema-service
+                // to prevent conflict with schema-service container from inmemory-config-datastore-provider
+                container operational-schema-service {
                   uses config:service-ref {
                        refine type {
                               mandatory false;
diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/AbstractDataChangeListenerTest.java b/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/AbstractDataChangeListenerTest.java
new file mode 100644 (file)
index 0000000..3176ca7
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.impl;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.opendaylight.controller.md.sal.dom.store.impl.DatastoreTestTask.WriteTransactionCustomizer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.Top;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.TwoLevelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.top.level.list.NestedList;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import com.google.common.util.concurrent.MoreExecutors;
+
+public abstract class AbstractDataChangeListenerTest {
+
+    protected static final YangInstanceIdentifier TOP_LEVEL = YangInstanceIdentifier
+            .of(Top.QNAME);
+    private static final QName NAME_QNAME = QName.create(Top.QNAME, "name");
+    protected static final String FOO = "foo";
+    protected static final String BAR = "bar";
+    protected static final String BAZ = "baz";
+
+    private InMemoryDOMDataStore datastore;
+    private SchemaContext schemaContext;
+
+    @Before
+    public final void setup() throws Exception {
+        YangModuleInfo moduleInfo = BindingReflections
+                .getModuleInfo(TwoLevelList.class);
+        ModuleInfoBackedContext context = ModuleInfoBackedContext.create();
+        context.registerModuleInfo(moduleInfo);
+        schemaContext = context.tryToCreateSchemaContext().get();
+        datastore = new InMemoryDOMDataStore("TEST",
+                MoreExecutors.sameThreadExecutor());
+        datastore.onGlobalContextUpdated(schemaContext);
+    }
+
+    public final DatastoreTestTask newTestTask() {
+        return new DatastoreTestTask(datastore).cleanup(DatastoreTestTask
+                .simpleDelete(TOP_LEVEL));
+    }
+
+
+    public static final YangInstanceIdentifier path(final String topName,
+            final String nestedName) {
+        return path(topName).node(NestedList.QNAME).node(
+                new NodeIdentifierWithPredicates(NestedList.QNAME, NAME_QNAME,
+                        nestedName));
+    }
+
+    public static final YangInstanceIdentifier path(final String topName) {
+        return TOP_LEVEL.node(TopLevelList.QNAME).node(
+                new NodeIdentifierWithPredicates(TopLevelList.QNAME,
+                        NAME_QNAME, topName));
+    }
+
+    protected static DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> top() {
+        return Builders.containerBuilder().withNodeIdentifier(
+                new NodeIdentifier(Top.QNAME));
+    }
+
+
+
+    protected static void assertEmpty(final Collection<?> set) {
+        Assert.assertTrue(set.isEmpty());
+    }
+
+    protected static void assertEmpty(final Map<?,?> set) {
+        Assert.assertTrue(set.isEmpty());
+    }
+
+    protected static <K> void assertContains(final Collection<K> set, final K... values) {
+        for (K key : values) {
+            Assert.assertTrue(set.contains(key));
+        }
+
+    }
+
+    protected static <K> void assertNotContains(final Collection<K> set, final K... values) {
+        for (K key : values) {
+            Assert.assertFalse(set.contains(key));
+        }
+    }
+
+    protected static <K> void assertContains(final Map<K,?> map, final K... values) {
+        for (K key : values) {
+            Assert.assertTrue(map.containsKey(key));
+        }
+    }
+
+    protected static <K> void assertNotContains(final Map<K,?> map, final K... values) {
+        for (K key : values) {
+            Assert.assertFalse(map.containsKey(key));
+        }
+    }
+
+    protected static CollectionNodeBuilder<MapEntryNode, MapNode> topLevelMap() {
+        return ImmutableNodes.mapNodeBuilder(TopLevelList.QNAME);
+    }
+
+    protected static CollectionNodeBuilder<MapEntryNode, OrderedMapNode> nestedMap() {
+        return Builders.orderedMapBuilder().withNodeIdentifier(new NodeIdentifier(NestedList.QNAME));
+    }
+
+    public static DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> topLevelList(
+            final String key) {
+        return ImmutableNodes.mapEntryBuilder(TopLevelList.QNAME, NAME_QNAME,
+                key);
+    }
+
+    public static DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> nestedList(
+            final String key) {
+        return ImmutableNodes
+                .mapEntryBuilder(NestedList.QNAME, NAME_QNAME, key);
+    }
+
+    public static final WriteTransactionCustomizer writeOneTopMultipleNested(
+            final String topName, final String... nestedName) {
+        CollectionNodeBuilder<MapEntryNode, OrderedMapNode> nestedMapBuilder = nestedMap();
+        for (String nestedItem : nestedName) {
+            nestedMapBuilder.addChild(nestedList(nestedItem).build());
+        }
+
+        final ContainerNode data = top().addChild(
+                topLevelMap().addChild(
+                        topLevelList(topName)
+                                .addChild(nestedMapBuilder.build()).build())
+                        .build()).build();
+
+        return DatastoreTestTask.simpleWrite(TOP_LEVEL, data);
+    }
+
+    public static final  WriteTransactionCustomizer deleteNested(final String topName,
+            final String nestedName) {
+        return DatastoreTestTask.simpleDelete(path(topName, nestedName));
+    }
+}
diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/DatastoreTestTask.java b/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/DatastoreTestTask.java
new file mode 100644 (file)
index 0000000..26987a6
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.impl;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
+import org.opendaylight.controller.sal.core.spi.data.DOMStore;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.SettableFuture;
+
+public class DatastoreTestTask {
+
+    private final DOMStore store;
+    private AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> changeListener;
+
+    private WriteTransactionCustomizer setup;
+    private WriteTransactionCustomizer write;
+    private ReadTransactionVerifier read;
+    private WriteTransactionCustomizer cleanup;
+    private YangInstanceIdentifier changePath;
+    private DataChangeScope changeScope;
+    private boolean postSetup = false;
+    private final ChangeEventListener internalListener;
+
+    public DatastoreTestTask(final DOMStore datastore) {
+        this.store = datastore;
+        internalListener = new ChangeEventListener();
+    }
+
+    public DatastoreTestTask changeListener(final YangInstanceIdentifier path, final DataChangeScope scope,
+            final AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> changeListener) {
+        this.changeListener = changeListener;
+        this.changePath = path;
+        this.changeScope = scope;
+        return this;
+    }
+
+    public DatastoreTestTask changeListener(final YangInstanceIdentifier path, final DataChangeScope scope) {
+        this.changePath = path;
+        this.changeScope = scope;
+        return this;
+    }
+
+    public DatastoreTestTask setup(final WriteTransactionCustomizer setup) {
+        this.setup = setup;
+        return this;
+    }
+
+    public DatastoreTestTask test(final WriteTransactionCustomizer write) {
+        this.write = write;
+        return this;
+    }
+
+    public DatastoreTestTask read(final ReadTransactionVerifier read) {
+        this.read = read;
+        return this;
+    }
+
+    public DatastoreTestTask cleanup(final WriteTransactionCustomizer cleanup) {
+        this.cleanup = cleanup;
+        return this;
+    }
+
+    public void run() throws InterruptedException, ExecutionException {
+        if (setup != null) {
+            execute(setup);
+        }
+        ListenerRegistration<ChangeEventListener> registration = null;
+        if (changePath != null) {
+            registration = store.registerChangeListener(changePath, internalListener, changeScope);
+        }
+
+        Preconditions.checkState(write != null, "Write Transaction must be set.");
+        postSetup = true;
+        execute(write);
+        if (registration != null) {
+            registration.close();
+        }
+        if (changeListener != null) {
+            changeListener.onDataChanged(internalListener.receivedChange.get());
+        }
+        if (read != null) {
+            read.verify(store.newReadOnlyTransaction());
+        }
+        if (cleanup != null) {
+            execute(cleanup);
+        }
+    }
+
+    public Future<AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>>> getChangeEvent() {
+        return internalListener.receivedChange;
+    }
+
+    private void execute(final WriteTransactionCustomizer writeCustomizer) throws InterruptedException,
+            ExecutionException {
+        DOMStoreReadWriteTransaction tx = store.newReadWriteTransaction();
+        writeCustomizer.customize(tx);
+        DOMStoreThreePhaseCommitCohort cohort = tx.ready();
+        assertTrue(cohort.canCommit().get());
+        cohort.preCommit().get();
+        cohort.commit().get();
+    }
+
+    public interface WriteTransactionCustomizer {
+        public void customize(DOMStoreReadWriteTransaction tx);
+    }
+
+    public interface ReadTransactionVerifier {
+        public void verify(DOMStoreReadTransaction tx);
+    }
+
+    private final class ChangeEventListener implements
+            AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>> {
+
+        protected final SettableFuture<AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>>> receivedChange = SettableFuture
+                .create();
+
+        @Override
+        public void onDataChanged(final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
+            if (postSetup) {
+                receivedChange.set(change);
+            }
+        }
+    }
+
+    public static final WriteTransactionCustomizer simpleWrite(final YangInstanceIdentifier path,
+            final NormalizedNode<?, ?> data) {
+        return new WriteTransactionCustomizer() {
+
+            @Override
+            public void customize(final DOMStoreReadWriteTransaction tx) {
+                tx.write(path, data);
+            }
+        };
+    }
+
+    public static final WriteTransactionCustomizer simpleMerge(final YangInstanceIdentifier path,
+            final NormalizedNode<?, ?> data) {
+        return new WriteTransactionCustomizer() {
+
+            @Override
+            public void customize(final DOMStoreReadWriteTransaction tx) {
+                tx.merge(path, data);
+            }
+        };
+    }
+
+    public static final WriteTransactionCustomizer simpleDelete(final YangInstanceIdentifier path) {
+        return new WriteTransactionCustomizer() {
+            @Override
+            public void customize(final DOMStoreReadWriteTransaction tx) {
+                tx.delete(path);
+            }
+        };
+    }
+}
diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/DefaultDataChangeListenerTestSuite.java b/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/DefaultDataChangeListenerTestSuite.java
new file mode 100644 (file)
index 0000000..54d2043
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.impl;
+
+import java.util.concurrent.ExecutionException;
+
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.dom.store.impl.DatastoreTestTask.WriteTransactionCustomizer;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
+
+public abstract class DefaultDataChangeListenerTestSuite extends AbstractDataChangeListenerTest {
+
+    protected static final String FOO_SIBLING = "foo-sibling";
+
+    abstract protected void customizeTask(DatastoreTestTask task);
+
+    @Test
+    public final void putTopLevelOneNested() throws InterruptedException, ExecutionException {
+
+        DatastoreTestTask task = newTestTask().test(writeOneTopMultipleNested(FOO, BAR));
+        customizeTask(task);
+        task.run();
+        putTopLevelOneNested(task);
+    }
+
+    @Test
+    public final void existingTopWriteSibling() throws InterruptedException, ExecutionException {
+        DatastoreTestTask task = newTestTask().setup(writeOneTopMultipleNested(FOO)).test(
+                new WriteTransactionCustomizer() {
+                    @Override
+                    public void customize(final DOMStoreReadWriteTransaction tx) {
+                        tx.write(path(FOO_SIBLING), topLevelList(FOO_SIBLING).build());
+                    }
+                });
+        customizeTask(task);
+        task.run();
+        existingTopWriteSibling(task);
+    }
+
+    protected abstract void existingTopWriteSibling(DatastoreTestTask task) throws InterruptedException, ExecutionException;
+
+
+    @Test
+    public final void existingTopWriteTwoNested() throws InterruptedException, ExecutionException {
+        DatastoreTestTask task = newTestTask().setup(writeOneTopMultipleNested(FOO)).test(
+                new WriteTransactionCustomizer() {
+                    @Override
+                    public void customize(final DOMStoreReadWriteTransaction tx) {
+                        tx.write(path(FOO,BAR), nestedList(BAR).build());
+                        tx.write(path(FOO,BAZ), nestedList(BAZ).build());
+                    }
+                });
+        customizeTask(task);
+        task.run();
+        existingTopWriteTwoNested(task);
+    }
+
+    protected abstract void existingTopWriteTwoNested(DatastoreTestTask task) throws InterruptedException, ExecutionException;
+
+
+    @Test
+    public final void existingOneNestedWriteAdditionalNested() throws InterruptedException, ExecutionException {
+        DatastoreTestTask task = newTestTask().setup(writeOneTopMultipleNested(FOO, BAR)).test(
+                new WriteTransactionCustomizer() {
+                    @Override
+                    public void customize(final DOMStoreReadWriteTransaction tx) {
+                        tx.write(path(FOO,BAZ), nestedList(BAZ).build());
+                    }
+                });
+        customizeTask(task);
+        task.run();
+        existingOneNestedWriteAdditionalNested(task);
+    }
+
+    protected abstract void existingOneNestedWriteAdditionalNested(DatastoreTestTask task) throws InterruptedException, ExecutionException;
+
+    protected abstract void putTopLevelOneNested(DatastoreTestTask task) throws InterruptedException,
+            ExecutionException;
+
+    @Test
+    public final void replaceTopLevelNestedChanged() throws InterruptedException, ExecutionException {
+        DatastoreTestTask task = newTestTask().setup(writeOneTopMultipleNested(FOO, BAR)).test(
+                writeOneTopMultipleNested(FOO, BAZ));
+        customizeTask(task);
+        task.run();
+        replaceTopLevelNestedChanged(task);
+    }
+
+    protected abstract void replaceTopLevelNestedChanged(DatastoreTestTask task) throws InterruptedException,
+            ExecutionException;
+
+    @Test
+    public final void putTopLevelWithTwoNested() throws InterruptedException, ExecutionException {
+
+        DatastoreTestTask task = newTestTask().test(writeOneTopMultipleNested(FOO, BAR, BAZ));
+        customizeTask(task);
+        task.run();
+        putTopLevelWithTwoNested(task);
+    }
+
+    protected abstract void putTopLevelWithTwoNested(DatastoreTestTask task) throws InterruptedException,
+            ExecutionException;
+
+    @Test
+    public final void twoNestedExistsOneIsDeleted() throws InterruptedException, ExecutionException {
+
+        DatastoreTestTask task = newTestTask().setup(writeOneTopMultipleNested(FOO, BAR, BAZ)).test(
+                deleteNested(FOO, BAZ));
+        customizeTask(task);
+        task.run();
+        twoNestedExistsOneIsDeleted(task);
+    }
+
+    protected abstract void twoNestedExistsOneIsDeleted(DatastoreTestTask task) throws InterruptedException,
+            ExecutionException;
+
+    @Test
+    public final void nestedListExistsRootDeleted() throws InterruptedException, ExecutionException {
+
+        DatastoreTestTask task = newTestTask().cleanup(null).setup(writeOneTopMultipleNested(FOO, BAR, BAZ))
+                .test(DatastoreTestTask.simpleDelete(TOP_LEVEL));
+        customizeTask(task);
+        task.run();
+        nestedListExistsRootDeleted(task);
+    }
+
+    protected abstract void nestedListExistsRootDeleted(DatastoreTestTask task) throws InterruptedException,
+            ExecutionException;
+}
index 369a7da138731dd6149d4b426096af7cc2a553dc..96369dea5fabc7d3ce25272f5e0cceaf5291a0c6 100644 (file)
@@ -1,8 +1,18 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.md.sal.dom.store.impl;
 
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.ExecutionException;
+
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -14,11 +24,9 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-import java.util.concurrent.ExecutionException;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
 
 
 public class InMemoryDataStoreTest {
@@ -237,7 +245,7 @@ public class InMemoryDataStoreTest {
   /**
    * Reads /test from readTx Read should return container.
    */
-  private static Optional<NormalizedNode<?, ?>> assertTestContainerExists(DOMStoreReadTransaction readTx)
+  private static Optional<NormalizedNode<?, ?>> assertTestContainerExists(final DOMStoreReadTransaction readTx)
       throws InterruptedException, ExecutionException {
 
     ListenableFuture<Optional<NormalizedNode<?, ?>>> writeTxContainer = readTx.read(TestModel.TEST_PATH);
diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/RootScopeSubtreeTest.java b/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/RootScopeSubtreeTest.java
new file mode 100644 (file)
index 0000000..905dc0d
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.impl;
+
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class RootScopeSubtreeTest extends DefaultDataChangeListenerTestSuite {
+
+    @Override
+    protected void customizeTask(final DatastoreTestTask task) {
+        task.changeListener(TOP_LEVEL, DataChangeScope.SUBTREE);
+    }
+
+    @Override
+    public void putTopLevelOneNested(final DatastoreTestTask task) throws InterruptedException, ExecutionException {
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertContains(change.getCreatedData(), TOP_LEVEL, path(FOO), path(FOO, BAR));
+        assertEmpty(change.getUpdatedData());
+        assertEmpty(change.getRemovedPaths());
+    }
+
+    @Override
+    public void replaceTopLevelNestedChanged(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertContains(change.getCreatedData(), path(FOO, BAZ));
+        assertContains(change.getUpdatedData(), TOP_LEVEL, path(FOO));
+        assertContains(change.getRemovedPaths(), path(FOO, BAR));
+    }
+
+    @Override
+    protected void putTopLevelWithTwoNested(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertContains(change.getCreatedData(), TOP_LEVEL, path(FOO), path(FOO, BAR), path(FOO, BAZ));
+        assertEmpty(change.getUpdatedData());
+        assertEmpty(change.getRemovedPaths());
+    }
+
+    @Override
+    protected void twoNestedExistsOneIsDeleted(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertEmpty(change.getCreatedData());
+        assertContains(change.getUpdatedData(), TOP_LEVEL, path(FOO));
+        assertContains(change.getRemovedPaths(), path(FOO, BAZ));
+    }
+
+    @Override
+    protected void nestedListExistsRootDeleted(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertEmpty(change.getCreatedData());
+        assertEmpty(change.getUpdatedData());
+        assertContains(change.getRemovedPaths(), TOP_LEVEL, path(FOO), path(FOO, BAR), path(FOO, BAZ));
+    }
+
+    @Override
+    protected void existingOneNestedWriteAdditionalNested(final DatastoreTestTask task) throws InterruptedException, ExecutionException {
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertContains(change.getCreatedData(), path(FOO,BAZ));
+        assertNotContains(change.getCreatedData(), path(FOO,BAR));
+        assertContains(change.getUpdatedData(), TOP_LEVEL, path(FOO));
+        assertEmpty(change.getRemovedPaths());
+    }
+
+    @Override
+    protected void existingTopWriteTwoNested(final DatastoreTestTask task) throws InterruptedException, ExecutionException {
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertContains(change.getCreatedData(), path(FOO,BAR),path(FOO,BAZ));
+        assertContains(change.getUpdatedData(), TOP_LEVEL, path(FOO));
+        assertNotContains(change.getUpdatedData(), path(FOO,BAR));
+        assertEmpty(change.getRemovedPaths());
+    }
+
+    @Override
+    protected void existingTopWriteSibling(final DatastoreTestTask task) throws InterruptedException, ExecutionException {
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertContains(change.getCreatedData(), path(FOO_SIBLING));
+        assertContains(change.getUpdatedData(), TOP_LEVEL);
+        assertNotContains(change.getUpdatedData(), path(FOO));
+        assertEmpty(change.getRemovedPaths());
+    }
+}
diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaUpdateForTransactionTest.java b/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaUpdateForTransactionTest.java
new file mode 100644 (file)
index 0000000..5cba93a
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.impl;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.util.concurrent.ExecutionException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.rpcservice.rev140701.RockTheHouseInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.Top;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import com.google.common.base.Throwables;
+import com.google.common.util.concurrent.MoreExecutors;
+
+public class SchemaUpdateForTransactionTest {
+
+    private static final YangInstanceIdentifier TOP_PATH = YangInstanceIdentifier.of(Top.QNAME);
+    private SchemaContext schemaContext;
+    private InMemoryDOMDataStore domStore;
+
+    @Before
+    public void setupStore() {
+        domStore = new InMemoryDOMDataStore("TEST", MoreExecutors.sameThreadExecutor());
+        loadSchemas(RockTheHouseInput.class);
+    }
+
+    public void loadSchemas(final Class<?>... classes) {
+        YangModuleInfo moduleInfo;
+        try {
+            ModuleInfoBackedContext context = ModuleInfoBackedContext.create();
+            for (Class<?> clz : classes) {
+                moduleInfo = BindingReflections.getModuleInfo(clz);
+
+                context.registerModuleInfo(moduleInfo);
+            }
+            schemaContext = context.tryToCreateSchemaContext().get();
+            domStore.onGlobalContextUpdated(schemaContext);
+        } catch (Exception e) {
+            Throwables.propagateIfPossible(e);
+        }
+    }
+
+    /**
+     * Test suite tests allocating transaction when schema context
+     * does not contain module necessary for client write,
+     * then triggering update of global schema context
+     * and then performing write (according to new module).
+     *
+     * If transaction between allocation and schema context was
+     * unmodified, it is safe to change its schema context
+     * to new one (e.g. it will be same as if allocated after
+     * schema context update.)
+     *
+     * @throws InterruptedException
+     * @throws ExecutionException
+     */
+    @Test
+    public void testTransactionSchemaUpdate() throws InterruptedException, ExecutionException {
+
+        assertNotNull(domStore);
+
+        // We allocate transaction, initial schema context does not
+        // contain Lists model
+        DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction();
+        assertNotNull(writeTx);
+
+        // we trigger schema context update to contain Lists model
+        loadSchemas(RockTheHouseInput.class, Top.class);
+
+        /**
+         *
+         * Writes /test in writeTx, this write should not fail
+         * with IllegalArgumentException since /test is in
+         * schema context.
+         *
+         */
+        writeTx.write(TOP_PATH, ImmutableNodes.containerNode(Top.QNAME));
+
+    }
+
+}
index 3feeb2967273fa60c998ccd5176030e51f244e9a..66e71a399f060ea955253854b8fb915f28eeca1d 100644 (file)
@@ -8,7 +8,7 @@
 package org.opendaylight.controller.md.sal.dom.store.impl;
 
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
@@ -29,8 +29,8 @@ public class TestModel {
     public static final QName VALUE_QNAME = QName.create(TEST_QNAME, "value");
     private static final String DATASTORE_TEST_YANG = "/odl-datastore-test.yang";
 
-    public static final InstanceIdentifier TEST_PATH = InstanceIdentifier.of(TEST_QNAME);
-    public static final InstanceIdentifier OUTER_LIST_PATH = InstanceIdentifier.builder(TEST_PATH).node(OUTER_LIST_QNAME).build();
+    public static final YangInstanceIdentifier TEST_PATH = YangInstanceIdentifier.of(TEST_QNAME);
+    public static final YangInstanceIdentifier OUTER_LIST_PATH = YangInstanceIdentifier.builder(TEST_PATH).node(OUTER_LIST_QNAME).build();
     public static final QName TWO_QNAME = QName.create(TEST_QNAME, "two");
     public static final QName THREE_QNAME = QName.create(TEST_QNAME, "three");
 
diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/WildcardedScopeBaseTest.java b/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/WildcardedScopeBaseTest.java
new file mode 100644 (file)
index 0000000..7c8676e
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class WildcardedScopeBaseTest extends DefaultDataChangeListenerTestSuite {
+
+    private static final YangInstanceIdentifier TOP_LEVEL_LIST_ALL = TOP_LEVEL.node(TopLevelList.QNAME).node(
+            TopLevelList.QNAME);
+
+    @Override
+    protected void customizeTask(final DatastoreTestTask task) {
+        task.changeListener(TOP_LEVEL_LIST_ALL, DataChangeScope.BASE);
+    }
+
+    @Override
+    public void putTopLevelOneNested(final DatastoreTestTask task) throws InterruptedException, ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertNotNull(change);
+
+        assertNotContains(change.getCreatedData(), TOP_LEVEL);
+        assertContains(change.getCreatedData(), path(FOO), path(FOO, BAR));
+
+        assertEmpty(change.getUpdatedData());
+        assertEmpty(change.getRemovedPaths());
+
+    }
+
+    @Override
+    public void replaceTopLevelNestedChanged(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+        assertNotNull(change);
+
+        assertContains(change.getCreatedData(), path(FOO, BAZ));
+        assertContains(change.getUpdatedData(), path(FOO));
+        assertNotContains(change.getUpdatedData(), TOP_LEVEL);
+        assertContains(change.getRemovedPaths(), path(FOO, BAR));
+
+    }
+
+    @Override
+    protected void putTopLevelWithTwoNested(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+        assertNotNull(change);
+        assertFalse(change.getCreatedData().isEmpty());
+
+        assertContains(change.getCreatedData(), path(FOO), path(FOO, BAR), path(FOO, BAZ));
+        assertNotContains(change.getCreatedData(), TOP_LEVEL);
+        assertEmpty(change.getUpdatedData());
+        assertEmpty(change.getRemovedPaths());
+
+    }
+
+    @Override
+    protected void twoNestedExistsOneIsDeleted(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        Future<?> future = task.getChangeEvent();
+        /*
+         * Base listener should be notified only and only if actual node changed its state,
+         * since deletion of child, did not result in change of node we are listening
+         * for, we should not be getting data change event
+         * and this means settable future containing receivedDataChangeEvent is not done.
+         *
+         */
+        assertFalse(future.isDone());
+    }
+
+    @Override
+    public void nestedListExistsRootDeleted(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertEmpty(change.getCreatedData());
+        assertEmpty(change.getUpdatedData());
+
+        assertNotContains(change.getUpdatedData(), TOP_LEVEL);
+        assertContains(change.getRemovedPaths(), path(FOO),path(FOO, BAZ),path(FOO,BAR));
+    }
+
+    @Override
+    protected void existingOneNestedWriteAdditionalNested(final DatastoreTestTask task) {
+        Future<?> future = task.getChangeEvent();
+        /*
+         * One listener should be notified only and only if actual node changed its state,
+         * since deletion of nested child (in this case /nested-list/nested-list[foo],
+         * did not result in change of node we are listening
+         * for, we should not be getting data change event
+         * and this means settable future containing receivedDataChangeEvent is not done.
+         *
+         */
+        assertFalse(future.isDone());
+    }
+
+    @Override
+    protected void existingTopWriteTwoNested(final DatastoreTestTask task) throws InterruptedException, ExecutionException {
+        Future<?> future = task.getChangeEvent();
+        /*
+         * One listener should be notified only and only if actual node changed its state,
+         * since deletion of nested child (in this case /nested-list/nested-list[foo],
+         * did not result in change of node we are listening
+         * for, we should not be getting data change event
+         * and this means settable future containing receivedDataChangeEvent is not done.
+         *
+         */
+        assertFalse(future.isDone());
+    }
+
+    @Override
+    protected void existingTopWriteSibling(final DatastoreTestTask task) throws InterruptedException, ExecutionException {
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertContains(change.getCreatedData(), path(FOO_SIBLING));
+        assertNotContains(change.getUpdatedData(), path(FOO), TOP_LEVEL);
+        assertEmpty(change.getRemovedPaths());
+    }
+}
diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/WildcardedScopeOneTest.java b/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/WildcardedScopeOneTest.java
new file mode 100644 (file)
index 0000000..ac18d5c
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class WildcardedScopeOneTest extends DefaultDataChangeListenerTestSuite {
+
+    private static final YangInstanceIdentifier TOP_LEVEL_LIST_ALL = TOP_LEVEL.node(TopLevelList.QNAME).node(
+            TopLevelList.QNAME);
+
+    @Override
+    protected void customizeTask(final DatastoreTestTask task) {
+        task.changeListener(TOP_LEVEL_LIST_ALL, DataChangeScope.ONE);
+    }
+
+    @Override
+    public void putTopLevelOneNested(final DatastoreTestTask task) throws InterruptedException, ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertNotNull(change);
+
+        assertNotContains(change.getCreatedData(), TOP_LEVEL);
+        assertContains(change.getCreatedData(), path(FOO), path(FOO, BAR));
+
+        assertEmpty(change.getUpdatedData());
+        assertEmpty(change.getRemovedPaths());
+
+    }
+
+    @Override
+    public void replaceTopLevelNestedChanged(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+        assertNotNull(change);
+
+        assertContains(change.getCreatedData(), path(FOO, BAZ));
+        assertContains(change.getUpdatedData(), path(FOO));
+        assertNotContains(change.getUpdatedData(), TOP_LEVEL);
+        assertContains(change.getRemovedPaths(), path(FOO, BAR));
+
+    }
+
+    @Override
+    protected void putTopLevelWithTwoNested(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+        assertNotNull(change);
+        assertFalse(change.getCreatedData().isEmpty());
+
+        assertContains(change.getCreatedData(), path(FOO), path(FOO, BAR), path(FOO, BAZ));
+        assertNotContains(change.getCreatedData(), TOP_LEVEL);
+        assertEmpty(change.getUpdatedData());
+        assertEmpty(change.getRemovedPaths());
+
+    }
+
+    @Override
+    protected void twoNestedExistsOneIsDeleted(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        Future<?> future = task.getChangeEvent();
+        /*
+         * One listener should be notified only and only if actual node changed its state,
+         * since deletion of nested child (in this case /nested-list/nested-list[foo],
+         * did not result in change of node we are listening
+         * for, we should not be getting data change event
+         * and this means settable future containing receivedDataChangeEvent is not done.
+         *
+         */
+        assertFalse(future.isDone());
+    }
+
+    @Override
+    public void nestedListExistsRootDeleted(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertEmpty(change.getCreatedData());
+        assertEmpty(change.getUpdatedData());
+
+        assertNotContains(change.getUpdatedData(), TOP_LEVEL);
+        assertContains(change.getRemovedPaths(), path(FOO),path(FOO, BAZ),path(FOO,BAR));
+    }
+
+    @Override
+    protected void existingOneNestedWriteAdditionalNested(final DatastoreTestTask task) {
+        Future<?> future = task.getChangeEvent();
+        /*
+         * One listener should be notified only and only if actual node changed its state,
+         * since deletion of nested child (in this case /nested-list/nested-list[foo],
+         * did not result in change of node we are listening
+         * for, we should not be getting data change event
+         * and this means settable future containing receivedDataChangeEvent is not done.
+         *
+         */
+        assertFalse(future.isDone());
+    }
+
+    @Override
+    protected void existingTopWriteTwoNested(final DatastoreTestTask task) throws InterruptedException, ExecutionException {
+        Future<?> future = task.getChangeEvent();
+        /*
+         * One listener should be notified only and only if actual node changed its state,
+         * since deletion of nested child (in this case /nested-list/nested-list[foo],
+         * did not result in change of node we are listening
+         * for, we should not be getting data change event
+         * and this means settable future containing receivedDataChangeEvent is not done.
+         *
+         */
+        assertFalse(future.isDone());
+    }
+
+    @Override
+    protected void existingTopWriteSibling(final DatastoreTestTask task) throws InterruptedException, ExecutionException {
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertContains(change.getCreatedData(), path(FOO_SIBLING));
+        assertNotContains(change.getUpdatedData(),path(FOO), TOP_LEVEL);
+        assertEmpty(change.getRemovedPaths());
+    }
+}
diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/WildcardedScopeSubtreeTest.java b/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/WildcardedScopeSubtreeTest.java
new file mode 100644 (file)
index 0000000..7e67242
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class WildcardedScopeSubtreeTest extends DefaultDataChangeListenerTestSuite {
+
+    private static final YangInstanceIdentifier TOP_LEVEL_LIST_ALL = TOP_LEVEL.node(TopLevelList.QNAME).node(
+            TopLevelList.QNAME);
+
+    @Override
+    protected void customizeTask(final DatastoreTestTask task) {
+        task.changeListener(TOP_LEVEL_LIST_ALL, DataChangeScope.SUBTREE);
+    }
+
+    @Override
+    public void putTopLevelOneNested(final DatastoreTestTask task) throws InterruptedException, ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertNotContains(change.getCreatedData(), TOP_LEVEL);
+        assertContains(change.getCreatedData(), path(FOO), path(FOO, BAR));
+        assertEmpty(change.getUpdatedData());
+        assertEmpty(change.getRemovedPaths());
+
+    }
+
+    @Override
+    public void replaceTopLevelNestedChanged(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+        assertNotNull(change);
+
+        assertContains(change.getCreatedData(), path(FOO, BAZ));
+        assertContains(change.getUpdatedData(), path(FOO));
+        assertNotContains(change.getUpdatedData(), TOP_LEVEL);
+        assertContains(change.getRemovedPaths(), path(FOO, BAR));
+
+    }
+
+    @Override
+    protected void putTopLevelWithTwoNested(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+        assertNotNull(change);
+        assertFalse(change.getCreatedData().isEmpty());
+
+        assertContains(change.getCreatedData(), path(FOO), path(FOO, BAR), path(FOO, BAZ));
+        assertNotContains(change.getCreatedData(), TOP_LEVEL);
+        assertEmpty(change.getUpdatedData());
+        assertEmpty(change.getRemovedPaths());
+
+    }
+
+    @Override
+    protected void twoNestedExistsOneIsDeleted(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+        assertNotNull(change);
+        assertTrue(change.getCreatedData().isEmpty());
+        assertContains(change.getUpdatedData(), path(FOO));
+        assertNotContains(change.getUpdatedData(), TOP_LEVEL);
+        assertContains(change.getRemovedPaths(),path(FOO, BAZ));
+    }
+
+    @Override
+    public void nestedListExistsRootDeleted(final DatastoreTestTask task) throws InterruptedException,
+            ExecutionException {
+
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertEmpty(change.getCreatedData());
+        assertEmpty(change.getUpdatedData());
+
+        assertNotContains(change.getUpdatedData(), TOP_LEVEL);
+        assertContains(change.getRemovedPaths(), path(FOO),path(FOO, BAZ),path(FOO,BAR));
+    }
+
+    @Override
+    protected void existingOneNestedWriteAdditionalNested(final DatastoreTestTask task) throws InterruptedException, ExecutionException {
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertContains(change.getCreatedData(), path(FOO,BAZ));
+        assertNotContains(change.getCreatedData(), path(FOO,BAR));
+        assertContains(change.getUpdatedData(), path(FOO));
+        assertNotContains(change.getUpdatedData(), TOP_LEVEL);
+        assertEmpty(change.getRemovedPaths());
+    }
+
+    @Override
+    protected void existingTopWriteTwoNested(final DatastoreTestTask task) throws InterruptedException, ExecutionException {
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertContains(change.getCreatedData(), path(FOO,BAR),path(FOO,BAZ));
+        assertContains(change.getUpdatedData(), path(FOO));
+        assertNotContains(change.getUpdatedData(), TOP_LEVEL, path(FOO,BAR));
+        assertEmpty(change.getRemovedPaths());
+    }
+
+    @Override
+    protected void existingTopWriteSibling(final DatastoreTestTask task) throws InterruptedException, ExecutionException {
+        AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change = task.getChangeEvent().get();
+
+        assertContains(change.getCreatedData(), path(FOO_SIBLING));
+        assertNotContains(change.getUpdatedData(), path(FOO), TOP_LEVEL);
+        assertEmpty(change.getRemovedPaths());
+    }
+}
index 0bf4b3238dd5f78a3e7b95626bd0d04a2ca8591a..10fe4a587a1f0c8ba7b52ac7e10314adbe1c9b62 100644 (file)
@@ -13,7 +13,6 @@
 
   <dependencies>
     <dependency>
-
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-client</artifactId>
       <version>${netconf.version}</version>
       <groupId>org.opendaylight.controller.model</groupId>
       <artifactId>model-inventory</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-broker-impl</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yang-data-impl</artifactId>
       <type>test-jar</type>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-broker-impl</artifactId>
-      <type>jar</type>
-      <scope>test</scope>
-    </dependency>
     <dependency>
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>mockito-configuration</artifactId>
index dca8fcafef4a88e31ecc6898dc52bc12b7aa5936..de4ac7ac18a106f88f530ac4dc16ea047976b091 100644 (file)
@@ -7,15 +7,19 @@
  */
 package org.opendaylight.controller.sal.connect.netconf;
 
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.FutureCallback;
 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.io.InputStream;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.concurrent.ExecutorService;
-
 import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.controller.sal.connect.api.MessageTransformer;
 import org.opendaylight.controller.sal.connect.api.RemoteDevice;
 import org.opendaylight.controller.sal.connect.api.RemoteDeviceCommunicator;
@@ -36,9 +40,6 @@ import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-
 /**
  *  This is a mediator between NetconfDeviceCommunicator and NetconfDeviceSalFacade
  */
@@ -53,6 +54,7 @@ public final class NetconfDevice implements RemoteDevice<NetconfSessionCapabilit
     private final MessageTransformer<NetconfMessage> messageTransformer;
     private final SchemaContextProviderFactory schemaContextProviderFactory;
     private final SchemaSourceProviderFactory<InputStream> sourceProviderFactory;
+    private final NotificationHandler notificationHandler;
 
     public static NetconfDevice createNetconfDevice(final RemoteDeviceId id,
             final AbstractCachingSchemaSourceProvider<String, InputStream> schemaSourceProvider,
@@ -79,6 +81,7 @@ public final class NetconfDevice implements RemoteDevice<NetconfSessionCapabilit
         this.sourceProviderFactory = sourceProviderFactory;
         this.processingExecutor = MoreExecutors.listeningDecorator(processingExecutor);
         this.schemaContextProviderFactory = schemaContextProviderFactory;
+        this.notificationHandler = new NotificationHandler(salFacade, messageTransformer, id);
     }
 
     @Override
@@ -99,6 +102,7 @@ public final class NetconfDevice implements RemoteDevice<NetconfSessionCapabilit
                 final SchemaContextProvider schemaContextProvider = setUpSchemaContext(delegate, remoteSessionCapabilities);
                 updateMessageTransformer(schemaContextProvider);
                 salFacade.onDeviceConnected(schemaContextProvider, remoteSessionCapabilities, deviceRpc);
+                notificationHandler.onRemoteSchemaUp();
             }
         });
 
@@ -142,7 +146,63 @@ public final class NetconfDevice implements RemoteDevice<NetconfSessionCapabilit
 
     @Override
     public void onNotification(final NetconfMessage notification) {
-        final CompositeNode parsedNotification = messageTransformer.toNotification(notification);
-        salFacade.onNotification(parsedNotification);
+        notificationHandler.handleNotification(notification);
+    }
+
+    /**
+     * Handles incoming notifications. Either caches them(until onRemoteSchemaUp is called) or passes to sal Facade.
+     */
+    private final static class NotificationHandler {
+
+        private final RemoteDeviceHandler<?> salFacade;
+        private final List<NetconfMessage> cache = new LinkedList<>();
+        private final MessageTransformer<NetconfMessage> messageTransformer;
+        private boolean passNotifications = false;
+        private final RemoteDeviceId id;
+
+        NotificationHandler(final RemoteDeviceHandler<?> salFacade, final MessageTransformer<NetconfMessage> messageTransformer, final RemoteDeviceId id) {
+            this.salFacade = salFacade;
+            this.messageTransformer = messageTransformer;
+            this.id = id;
+        }
+
+        synchronized void handleNotification(final NetconfMessage notification) {
+            if(passNotifications) {
+                passNotification(messageTransformer.toNotification(notification));
+            } else {
+                cacheNotification(notification);
+            }
+        }
+
+        /**
+         * Forward all cached notifications and pass all notifications from this point directly to sal facade.
+         */
+        synchronized void onRemoteSchemaUp() {
+            passNotifications = true;
+
+            for (final NetconfMessage cachedNotification : cache) {
+                passNotification(messageTransformer.toNotification(cachedNotification));
+            }
+
+            cache.clear();
+        }
+
+        private void cacheNotification(final NetconfMessage notification) {
+            Preconditions.checkState(passNotifications == false);
+
+            logger.debug("{}: Caching notification {}, remote schema not yet fully built", id, notification);
+            if(logger.isTraceEnabled()) {
+                logger.trace("{}: Caching notification {}", id, XmlUtil.toString(notification.getDocument()));
+            }
+
+            cache.add(notification);
+        }
+
+        private void passNotification(final CompositeNode parsedNotification) {
+            logger.debug("{}: Forwarding notification {}", id, parsedNotification);
+            Preconditions.checkNotNull(parsedNotification);
+            salFacade.onNotification(parsedNotification);
+        }
+
     }
 }
index 4da727f5c24e56e37c4e11acd6150d9afded1cd8..8045f8cb4a9556160b44fb46d4d3bbc12374435a 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.sal.connect.netconf.listener;
 
 import java.util.ArrayDeque;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Queue;
@@ -22,19 +21,18 @@ import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
 import org.opendaylight.controller.netconf.client.NetconfClientSession;
 import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.opendaylight.controller.sal.common.util.RpcErrors;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.connect.api.RemoteDevice;
 import org.opendaylight.controller.sal.connect.api.RemoteDeviceCommunicator;
 import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.FailedRpcResult;
 import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -82,8 +80,12 @@ public class NetconfDeviceCommunicator implements NetconfClientSessionListener,
     }
 
     public void initializeRemoteConnection(final NetconfClientDispatcher dispatch,
-                                           final NetconfReconnectingClientConfiguration config) {
-        dispatch.createReconnectingClient(config);
+                                           final NetconfClientConfiguration config) {
+        if(config instanceof NetconfReconnectingClientConfiguration) {
+            dispatch.createReconnectingClient((NetconfReconnectingClientConfiguration) config);
+        } else {
+            dispatch.createClient(config);
+        }
     }
 
     private void tearDown( String reason ) {
@@ -135,9 +137,10 @@ public class NetconfDeviceCommunicator implements NetconfClientSessionListener,
 
     private RpcResult<NetconfMessage> createErrorRpcResult( RpcError.ErrorType errorType, String message )
     {
-        return new FailedRpcResult<NetconfMessage>( RpcErrors.getRpcError( null,
-                NetconfDocumentedException.ErrorTag.operation_failed.getTagValue(),
-                null, RpcError.ErrorSeverity.ERROR, message, errorType, null ) );
+        return RpcResultBuilder.<NetconfMessage>failed()
+                .withError( errorType, NetconfDocumentedException.ErrorTag.operation_failed.getTagValue(),
+                            message )
+                .build();
     }
 
     @Override
@@ -203,8 +206,8 @@ public class NetconfDeviceCommunicator implements NetconfClientSessionListener,
                 logger.warn( "{}: Invalid request-reply match, reply message contains different message-id, request: {}, response: {}",
                              id, msgToS( request.request ), msgToS( message ), e );
 
-                request.future.set( new FailedRpcResult<NetconfMessage>(
-                                                           NetconfMessageTransformUtil.toRpcError( e ) ) );
+                request.future.set( RpcResultBuilder.<NetconfMessage>failed()
+                        .withRpcError( NetconfMessageTransformUtil.toRpcError( e ) ).build() );
                 return;
             }
 
@@ -215,12 +218,12 @@ public class NetconfDeviceCommunicator implements NetconfClientSessionListener,
                 logger.warn( "{}: Error reply from remote device, request: {}, response: {}", id,
                              msgToS( request.request ), msgToS( message ), e );
 
-                request.future.set( new FailedRpcResult<NetconfMessage>(
-                                                          NetconfMessageTransformUtil.toRpcError( e ) ) );
+                request.future.set( RpcResultBuilder.<NetconfMessage>failed()
+                        .withRpcError( NetconfMessageTransformUtil.toRpcError( e ) ).build() );
                 return;
             }
 
-            request.future.set(Rpcs.getRpcResult( true, message, Collections.<RpcError>emptySet() ) );
+            request.future.set( RpcResultBuilder.<NetconfMessage>success( message ).build() );
         }
     }
 
index 82903ea4ec174a373dc0648901cde3c5c02d0348..8964a80228bf848538dc83dfc6db71c05f93a102 100644 (file)
@@ -1,7 +1,15 @@
 package org.opendaylight.controller.sal.connect.netconf.listener;
 
-import java.util.Arrays;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.Set;
 
 import org.opendaylight.controller.netconf.client.NetconfClientSession;
@@ -10,24 +18,50 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-
 public final class NetconfSessionCapabilities {
+    private static final class ParameterMatcher {
+        private final Predicate<String> predicate;
+        private final int skipLength;
+
+        ParameterMatcher(final String name) {
+            predicate = new Predicate<String>() {
+                @Override
+                public boolean apply(final String input) {
+                    return input.startsWith(name);
+                }
+            };
 
-    private static final Logger logger = LoggerFactory.getLogger(NetconfSessionCapabilities.class);
+            this.skipLength = name.length();
+        }
 
-    private final Set<String> capabilities;
+        private String from(final Iterable<String> params) {
+            final Optional<String> o = Iterables.tryFind(params, predicate);
+            if (!o.isPresent()) {
+                return null;
+            }
+
+            return o.get().substring(skipLength);
+        }
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfSessionCapabilities.class);
+    private static final ParameterMatcher MODULE_PARAM = new ParameterMatcher("module=");
+    private static final ParameterMatcher REVISION_PARAM = new ParameterMatcher("revision=");
+    private static final ParameterMatcher BROKEN_REVISON_PARAM = new ParameterMatcher("amp;revision=");
+    private static final Splitter AMP_SPLITTER = Splitter.on('&');
+    private static final Predicate<String> CONTAINS_REVISION = new Predicate<String>() {
+        @Override
+        public boolean apply(final String input) {
+            return input.contains("revision=");
+        }
+    };
 
     private final Set<QName> moduleBasedCaps;
+    private final Set<String> capabilities;
 
     private NetconfSessionCapabilities(final Set<String> capabilities, final Set<QName> moduleBasedCaps) {
-        this.capabilities = capabilities;
-        this.moduleBasedCaps = moduleBasedCaps;
+        this.capabilities = Preconditions.checkNotNull(capabilities);
+        this.moduleBasedCaps = Preconditions.checkNotNull(moduleBasedCaps);
     }
 
     public Set<QName> getModuleBasedCaps() {
@@ -65,47 +99,45 @@ public final class NetconfSessionCapabilities {
     }
 
     public static NetconfSessionCapabilities fromStrings(final Collection<String> capabilities) {
-        final Set<QName> moduleBasedCaps = Sets.newHashSet();
+        final Set<QName> moduleBasedCaps = new HashSet<>();
 
         for (final String capability : capabilities) {
-            if(isModuleBasedCapability(capability)) {
-                final String[] parts = capability.split("\\?");
-                final String namespace = parts[0];
-                final FluentIterable<String> queryParams = FluentIterable.from(Arrays.asList(parts[1].split("&")));
-
-                String revision = getStringAndTransform(queryParams, "revision=", "revision=");
-
-                final String moduleName = getStringAndTransform(queryParams, "module=", "module=");
+            final int qmark = capability.indexOf('?');
+            if (qmark == -1) {
+                continue;
+            }
 
-                if (revision == null) {
-                    logger.debug("Netconf device was not reporting revision correctly, trying to get amp;revision=");
-                    revision = getStringAndTransform(queryParams, "amp;revision=", "amp;revision=");
+            final String namespace = capability.substring(0, qmark);
+            final Iterable<String> queryParams = AMP_SPLITTER.split(capability.substring(qmark + 1));
+            final String moduleName = MODULE_PARAM.from(queryParams);
+            if (moduleName == null) {
+                continue;
+            }
 
-                    if (revision == null) {
-                        logger.warn("Netconf device returned revision incorrectly escaped for {}", capability);
-                    }
-                }
+            String revision = REVISION_PARAM.from(queryParams);
+            if (revision != null) {
                 moduleBasedCaps.add(QName.create(namespace, revision, moduleName));
+                continue;
             }
-        }
-
-        return new NetconfSessionCapabilities(Sets.newHashSet(capabilities), moduleBasedCaps);
-    }
 
-    private static boolean isModuleBasedCapability(final String capability) {
-        return capability.contains("?") && capability.contains("module=") && capability.contains("revision=");
-    }
+            /*
+             * We have seen devices which mis-escape revision, but the revision may not
+             * even be there. First check if there is a substring that matches revision.
+             */
+            if (!Iterables.any(queryParams, CONTAINS_REVISION)) {
+                continue;
+            }
 
-    private static String getStringAndTransform(final Iterable<String> queryParams, final String match,
-                                                final String substringToRemove) {
-        final Optional<String> found = Iterables.tryFind(queryParams, new Predicate<String>() {
-            @Override
-            public boolean apply(final String input) {
-                return input.startsWith(match);
+            LOG.debug("Netconf device was not reporting revision correctly, trying to get amp;revision=");
+            revision = BROKEN_REVISON_PARAM.from(queryParams);
+            if (revision == null) {
+                LOG.warn("Netconf device returned revision incorrectly escaped for {}, ignoring it", capability);
             }
-        });
 
-        return found.isPresent() ? found.get().replaceAll(substringToRemove, "") : null;
-    }
+            // FIXME: do we really want to continue here?
+            moduleBasedCaps.add(QName.create(namespace, revision, moduleName));
+        }
 
+        return new NetconfSessionCapabilities(ImmutableSet.copyOf(capabilities), ImmutableSet.copyOf(moduleBasedCaps));
+    }
 }
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceCommitHandler.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceCommitHandler.java
deleted file mode 100644 (file)
index 8b6ac7d..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf.sal;
-
-import java.util.concurrent.ExecutionException;
-
-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.common.util.RpcErrors;
-import org.opendaylight.controller.sal.connect.util.FailedRpcResult;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.yangtools.yang.common.RpcError;
-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.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class NetconfDeviceCommitHandler implements DataCommitHandler<InstanceIdentifier,CompositeNode> {
-
-    private static final Logger logger= LoggerFactory.getLogger(NetconfDeviceCommitHandler.class);
-
-    private final RemoteDeviceId id;
-    private final RpcImplementation rpc;
-    private final boolean rollbackSupported;
-
-    public NetconfDeviceCommitHandler(final RemoteDeviceId id, final RpcImplementation rpc, final boolean rollbackSupported) {
-        this.id = id;
-        this.rpc = rpc;
-        this.rollbackSupported = rollbackSupported;
-    }
-
-    @Override
-    public DataCommitTransaction<InstanceIdentifier, CompositeNode> requestCommit(
-            final DataModification<InstanceIdentifier, CompositeNode> modification) {
-
-        final NetconfDeviceTwoPhaseCommitTransaction twoPhaseCommit = new NetconfDeviceTwoPhaseCommitTransaction(id, rpc,
-                modification, true, rollbackSupported);
-        try {
-            twoPhaseCommit.prepare();
-        } catch (final InterruptedException e) {
-            Thread.currentThread().interrupt();
-            throw new RuntimeException(id + ": Interrupted while waiting for response", e);
-        } catch (final ExecutionException e) {
-            logger.warn("{}: Error executing pre commit operation on remote device", id, e);
-            return new FailingTransaction(twoPhaseCommit, e);
-        }
-
-        return twoPhaseCommit;
-    }
-
-    /**
-     * Always fail commit transaction that rolls back delegate transaction afterwards
-     */
-    private class FailingTransaction implements DataCommitTransaction<InstanceIdentifier, CompositeNode> {
-        private final NetconfDeviceTwoPhaseCommitTransaction twoPhaseCommit;
-        private final ExecutionException e;
-
-        public FailingTransaction(final NetconfDeviceTwoPhaseCommitTransaction twoPhaseCommit, final ExecutionException e) {
-            this.twoPhaseCommit = twoPhaseCommit;
-            this.e = e;
-        }
-
-        @Override
-        public DataModification<InstanceIdentifier, CompositeNode> getModification() {
-            return twoPhaseCommit.getModification();
-        }
-
-        @Override
-        public RpcResult<Void> finish() throws IllegalStateException {
-            return new FailedRpcResult<>(RpcErrors.getRpcError(null, null, null, RpcError.ErrorSeverity.ERROR,
-                    id + ": Unexpected operation error during pre-commit operations", RpcError.ErrorType.APPLICATION, e));
-        }
-
-        @Override
-        public RpcResult<Void> rollback() throws IllegalStateException {
-            return twoPhaseCommit.rollback();
-        }
-    }
-}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataBroker.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataBroker.java
new file mode 100644 (file)
index 0000000..ee0c8b7
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+
+package org.opendaylight.controller.sal.connect.netconf.sal;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionCapabilities;
+import org.opendaylight.controller.sal.connect.netconf.sal.tx.NetconfDeviceReadOnlyTx;
+import org.opendaylight.controller.sal.connect.netconf.sal.tx.NetconfDeviceReadWriteTx;
+import org.opendaylight.controller.sal.connect.netconf.sal.tx.NetconfDeviceWriteOnlyTx;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+final class NetconfDeviceDataBroker implements DOMDataBroker {
+    private final RemoteDeviceId id;
+    private final RpcImplementation rpc;
+    private final NetconfSessionCapabilities netconfSessionPreferences;
+    private final DataNormalizer normalizer;
+
+    public NetconfDeviceDataBroker(final RemoteDeviceId id, final RpcImplementation rpc, final SchemaContext schemaContext, NetconfSessionCapabilities netconfSessionPreferences) {
+        this.id = id;
+        this.rpc = rpc;
+        this.netconfSessionPreferences = netconfSessionPreferences;
+        normalizer = new DataNormalizer(schemaContext);
+    }
+
+    @Override
+    public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
+        return new NetconfDeviceReadOnlyTx(rpc, normalizer);
+    }
+
+    @Override
+    public DOMDataReadWriteTransaction newReadWriteTransaction() {
+        return new NetconfDeviceReadWriteTx(newReadOnlyTransaction(), newWriteOnlyTransaction());
+    }
+
+    @Override
+    public DOMDataWriteTransaction newWriteOnlyTransaction() {
+        // FIXME detect if candidate is supported, true is hardcoded
+        return new NetconfDeviceWriteOnlyTx(id, rpc, normalizer, true, netconfSessionPreferences.isRollbackSupported());
+    }
+
+    @Override
+    public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(final LogicalDatastoreType store, final YangInstanceIdentifier path, final DOMDataChangeListener listener, final DataChangeScope triggeringScope) {
+        throw new UnsupportedOperationException("Data change listeners not supported for netconf mount point");
+    }
+
+    @Override
+    public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
+        // TODO implement
+        throw new UnsupportedOperationException("Transaction chains not supported for netconf mount point");
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataReader.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataReader.java
deleted file mode 100644 (file)
index 2909bac..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf.sal;
-
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.CONFIG_SOURCE_RUNNING;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DATA_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toFilterStructure;
-
-import java.util.concurrent.ExecutionException;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataReader;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-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.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-
-public final class NetconfDeviceDataReader implements DataReader<InstanceIdentifier,CompositeNode> {
-
-    private final RpcImplementation rpc;
-    private final RemoteDeviceId id;
-
-    public NetconfDeviceDataReader(final RemoteDeviceId id, final RpcImplementation rpc) {
-        this.id = id;
-        this.rpc = rpc;
-    }
-
-    @Override
-    public CompositeNode readConfigurationData(final InstanceIdentifier path) {
-        final RpcResult<CompositeNode> result;
-        try {
-            result = rpc.invokeRpc(NETCONF_GET_CONFIG_QNAME,
-                    NetconfMessageTransformUtil.wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, toFilterStructure(path))).get();
-        } catch (final InterruptedException e) {
-            throw onInterruptedException(e);
-        } catch (final ExecutionException e) {
-            throw new RuntimeException(id + ": Read configuration data " + path + " failed", e);
-        }
-
-        final CompositeNode data = result.getResult().getFirstCompositeByName(NETCONF_DATA_QNAME);
-        return data == null ? null : (CompositeNode) findNode(data, path);
-    }
-
-    private RuntimeException onInterruptedException(final InterruptedException e) {
-        Thread.currentThread().interrupt();
-        return new RuntimeException(id + ": Interrupted while waiting for response", e);
-    }
-
-    @Override
-    public CompositeNode readOperationalData(final InstanceIdentifier path) {
-        final RpcResult<CompositeNode> result;
-        try {
-            result = rpc.invokeRpc(NETCONF_GET_QNAME, NetconfMessageTransformUtil.wrap(NETCONF_GET_QNAME, toFilterStructure(path))).get();
-        } catch (final InterruptedException e) {
-            throw onInterruptedException(e);
-        } catch (final ExecutionException e) {
-            throw new RuntimeException(id + ": Read operational data " + path + " failed", e);
-        }
-
-        final CompositeNode data = result.getResult().getFirstCompositeByName(NETCONF_DATA_QNAME);
-        return (CompositeNode) findNode(data, path);
-    }
-
-    private static Node<?> findNode(final CompositeNode node, final InstanceIdentifier identifier) {
-
-        Node<?> current = node;
-        for (final InstanceIdentifier.PathArgument arg : identifier.getPath()) {
-            if (current instanceof SimpleNode<?>) {
-                return null;
-            } else if (current instanceof CompositeNode) {
-                final CompositeNode currentComposite = (CompositeNode) current;
-
-                current = currentComposite.getFirstCompositeByName(arg.getNodeType());
-                if (current == null) {
-                    current = currentComposite.getFirstCompositeByName(arg.getNodeType().withoutRevision());
-                }
-                if (current == null) {
-                    current = currentComposite.getFirstSimpleByName(arg.getNodeType());
-                }
-                if (current == null) {
-                    current = currentComposite.getFirstSimpleByName(arg.getNodeType().withoutRevision());
-                }
-                if (current == null) {
-                    return null;
-                }
-            }
-        }
-        return current;
-    }
-}
index e491496eed79af22628301f3497437d33aefa4b0..04d5e5e449e1f00305a8be995b3861d7ef24e47b 100644 (file)
@@ -8,27 +8,28 @@
 package org.opendaylight.controller.sal.connect.netconf.sal;
 
 import com.google.common.base.Function;
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.FluentIterable;
+import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.FutureCallback;
 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.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.inventory.rev140108.NetconfNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.inventory.rev140108.NetconfNodeBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -42,123 +43,86 @@ final class NetconfDeviceDatastoreAdapter implements AutoCloseable {
     private static final Logger logger  = LoggerFactory.getLogger(NetconfDeviceDatastoreAdapter.class);
 
     private final RemoteDeviceId id;
-    private final DataProviderService dataService;
-    private final ListeningExecutorService executor;
+    private final DataBroker dataService;
 
-    NetconfDeviceDatastoreAdapter(final RemoteDeviceId deviceId, final DataProviderService dataService,
-            final ExecutorService executor) {
+    NetconfDeviceDatastoreAdapter(final RemoteDeviceId deviceId, final DataBroker dataService) {
         this.id = Preconditions.checkNotNull(deviceId);
         this.dataService = Preconditions.checkNotNull(dataService);
-        this.executor = MoreExecutors.listeningDecorator(Preconditions.checkNotNull(executor));
 
-        // Initial data change scheduled
-        submitDataChangeToExecutor(this.executor, new Runnable() {
-            @Override
-            public void run() {
-                initDeviceData();
-            }
-        }, deviceId);
+        initDeviceData();
     }
 
     public void updateDeviceState(final boolean up, final Set<QName> capabilities) {
-        submitDataChangeToExecutor(this.executor, new Runnable() {
-            @Override
-            public void run() {
-                updateDeviceStateInternal(up, capabilities);
-            }
-        }, id);
-    }
-
-    private void updateDeviceStateInternal(final boolean up, final Set<QName> capabilities) {
         final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node data = buildDataForDeviceState(
                 up, capabilities, id);
 
-        final DataModificationTransaction transaction = dataService.beginTransaction();
-        logger.trace("{}: Update device state transaction {} putting operational data started.", id, transaction.getIdentifier());
-        transaction.removeOperationalData(id.getBindingPath());
-        transaction.putOperationalData(id.getBindingPath(), data);
-        logger.trace("{}: Update device state transaction {} putting operational data ended.", id, transaction.getIdentifier());
+        final ReadWriteTransaction transaction = dataService.newReadWriteTransaction();
+        logger.trace("{}: Update device state transaction {} merging operational data started.", id, transaction.getIdentifier());
+        transaction.merge(LogicalDatastoreType.OPERATIONAL, id.getBindingPath(), data);
+        logger.trace("{}: Update device state transaction {} merging operational data ended.", id, transaction.getIdentifier());
 
         commitTransaction(transaction, "update");
     }
 
     private void removeDeviceConfigAndState() {
-        final DataModificationTransaction transaction = dataService.beginTransaction();
+        final WriteTransaction transaction = dataService.newWriteOnlyTransaction();
         logger.trace("{}: Close device state transaction {} removing all data started.", id, transaction.getIdentifier());
-        transaction.removeConfigurationData(id.getBindingPath());
-        transaction.removeOperationalData(id.getBindingPath());
+        transaction.delete(LogicalDatastoreType.CONFIGURATION, id.getBindingPath());
+        transaction.delete(LogicalDatastoreType.OPERATIONAL, id.getBindingPath());
         logger.trace("{}: Close device state transaction {} removing all data ended.", id, transaction.getIdentifier());
 
         commitTransaction(transaction, "close");
     }
 
     private void initDeviceData() {
-        final DataModificationTransaction transaction = dataService.beginTransaction();
+        final WriteTransaction transaction = dataService.newWriteOnlyTransaction();
 
-        final InstanceIdentifier<Node> path = id.getBindingPath();
+        createNodesListIfNotPresent(transaction);
 
+        final InstanceIdentifier<Node> path = id.getBindingPath();
         final Node nodeWithId = getNodeWithId(id);
-        if (operationalNodeNotExisting(transaction, path)) {
-            transaction.putOperationalData(path, nodeWithId);
-        }
-        if (configurationNodeNotExisting(transaction, path)) {
-            transaction.putConfigurationData(path, nodeWithId);
-        }
 
-        commitTransaction(transaction, "init");
-    }
+        logger.trace("{}: Init device state transaction {} putting if absent operational data started.", id, transaction.getIdentifier());
+        transaction.merge(LogicalDatastoreType.OPERATIONAL, path, nodeWithId);
+        logger.trace("{}: Init device state transaction {} putting operational data ended.", id, transaction.getIdentifier());
 
-    private void commitTransaction(final DataModificationTransaction transaction, final String txType) {
-        // attempt commit
-        final RpcResult<TransactionStatus> result;
-        try {
-            result = transaction.commit().get();
-        } catch (InterruptedException | ExecutionException e) {
-            logger.error("{}: Transaction({}) failed", id, txType, e);
-            throw new IllegalStateException(id + " Transaction(" + txType + ") not committed correctly", e);
-        }
-
-        // verify success result + committed state
-        if (isUpdateSuccessful(result)) {
-            logger.trace("{}: Transaction({}) {} SUCCESSFUL", id, txType, transaction.getIdentifier());
-        } else {
-            logger.error("{}: Transaction({}) {} FAILED!", id, txType, transaction.getIdentifier());
-            throw new IllegalStateException(id + "  Transaction(" + txType + ") not committed correctly, " +
-                    "Errors: " + result.getErrors());
-        }
-    }
+        logger.trace("{}: Init device state transaction {} putting if absent config data started.", id, transaction.getIdentifier());
+        transaction.merge(LogicalDatastoreType.CONFIGURATION, path, nodeWithId);
+        logger.trace("{}: Init device state transaction {} putting config data ended.", id, transaction.getIdentifier());
 
-    @Override
-    public void close() throws Exception {
-        // Remove device data from datastore
-        submitDataChangeToExecutor(executor, new Runnable() {
-            @Override
-            public void run() {
-                removeDeviceConfigAndState();
-            }
-        }, id);
+        commitTransaction(transaction, "init");
     }
 
-    private static boolean isUpdateSuccessful(final RpcResult<TransactionStatus> result) {
-        return result.getResult() == TransactionStatus.COMMITED && result.isSuccessful();
+    private void createNodesListIfNotPresent(final WriteTransaction writeTx) {
+        final Nodes nodes = new NodesBuilder().build();
+        final InstanceIdentifier<Nodes> path = InstanceIdentifier.builder(Nodes.class).build();
+        logger.trace("{}: Merging {} container to ensure its presence", id, Nodes.QNAME, writeTx.getIdentifier());
+        writeTx.merge(LogicalDatastoreType.CONFIGURATION, path, nodes);
+        writeTx.merge(LogicalDatastoreType.OPERATIONAL, path, nodes);
     }
 
-    private static void submitDataChangeToExecutor(final ListeningExecutorService executor, final Runnable r,
-            final RemoteDeviceId id) {
-        // Submit data change
-        final ListenableFuture<?> f = executor.submit(r);
-        // Verify update execution
-        Futures.addCallback(f, new FutureCallback<Object>() {
+    private void commitTransaction(final WriteTransaction transaction, final String txType) {
+        logger.trace("{}: Committing Transaction {}:{}", id, txType, transaction.getIdentifier());
+        final CheckedFuture<Void, TransactionCommitFailedException> result = transaction.submit();
+
+        Futures.addCallback(result, new FutureCallback<Void>() {
             @Override
-            public void onSuccess(final Object result) {
-                logger.debug("{}: Device data updated successfully", id);
+            public void onSuccess(final Void result) {
+                logger.trace("{}: Transaction({}) {} SUCCESSFUL", id, txType, transaction.getIdentifier());
             }
 
             @Override
             public void onFailure(final Throwable t) {
-                logger.warn("{}: Device data update failed", id, t);
+                logger.error("{}: Transaction({}) {} FAILED!", id, txType, transaction.getIdentifier(), t);
+                throw new IllegalStateException(id + "  Transaction(" + txType + ") not committed correctly", t);
             }
         });
+
+    }
+
+    @Override
+    public void close() throws Exception {
+        removeDeviceConfigAndState();
     }
 
     public static org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node buildDataForDeviceState(
@@ -179,14 +143,11 @@ final class NetconfDeviceDatastoreAdapter implements AutoCloseable {
         return nodeBuilder.build();
     }
 
-    private static boolean configurationNodeNotExisting(final DataModificationTransaction transaction,
-            final InstanceIdentifier<Node> path) {
-        return null == transaction.readConfigurationData(path);
-    }
-
-    private static boolean operationalNodeNotExisting(final DataModificationTransaction transaction,
+    private static ListenableFuture<Optional<Node>> readNodeData(
+            final LogicalDatastoreType store,
+            final ReadWriteTransaction transaction,
             final InstanceIdentifier<Node> path) {
-        return null == transaction.readOperationalData(path);
+        return transaction.read(store, path);
     }
 
     private static Node getNodeWithId(final RemoteDeviceId id) {
index 6a62b1e20bba755367111924f78a49a6e2de7d5c..a0453bce550f3c91120fdc4808ab0f9650fff715 100644 (file)
@@ -9,17 +9,19 @@ package org.opendaylight.controller.sal.connect.netconf.sal;
 
 import com.google.common.base.Function;
 import com.google.common.util.concurrent.Futures;
+
 import java.util.Collections;
 import java.util.Set;
 
 import javax.annotation.Nullable;
+
 import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.connect.api.MessageTransformer;
 import org.opendaylight.controller.sal.connect.api.RemoteDeviceCommunicator;
 import org.opendaylight.controller.sal.core.api.RpcImplementation;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 import com.google.common.util.concurrent.ListenableFuture;
@@ -42,6 +44,8 @@ public final class NetconfDeviceRpc implements RpcImplementation {
         return Collections.emptySet();
     }
 
+    // TODO change this to work with NormalizedNode api. Then we can loose DataNormalizer from Transactions
+
     @Override
     public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(final QName rpc, final CompositeNode input) {
         final NetconfMessage message = transformRequest(rpc, input);
@@ -66,7 +70,8 @@ public final class NetconfDeviceRpc implements RpcImplementation {
         if (netconfMessageRpcResult.isSuccessful()) {
             return transformer.toRpcResult(netconfMessageRpcResult.getResult(), rpc);
         } else {
-            return Rpcs.getRpcResult(false, netconfMessageRpcResult.getErrors());
+            return RpcResultBuilder.<CompositeNode> failed()
+                                      .withRpcErrors(netconfMessageRpcResult.getErrors()).build();
         }
     }
 
index 37b87045d5f0f9061f9c276183fb6fc156879060..dbef290197b91ea2e7eb55e19fbb9363cadace16 100644 (file)
@@ -7,32 +7,40 @@
  */
 package org.opendaylight.controller.sal.connect.netconf.sal;
 
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutorService;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
 import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionCapabilities;
 import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+import org.opendaylight.controller.sal.dom.broker.impl.NotificationRouterImpl;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
+import org.opendaylight.controller.sal.dom.broker.spi.NotificationRouter;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 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.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
 public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDeviceHandler<NetconfSessionCapabilities> {
 
     private static final Logger logger= LoggerFactory.getLogger(NetconfDeviceSalFacade.class);
-    private static final InstanceIdentifier ROOT_PATH = InstanceIdentifier.builder().toInstance();
 
     private final RemoteDeviceId id;
     private final NetconfDeviceSalProvider salProvider;
@@ -58,24 +66,50 @@ public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDevice
     @Override
     public synchronized void onDeviceConnected(final SchemaContextProvider remoteSchemaContextProvider,
                                                final NetconfSessionCapabilities netconfSessionPreferences, final RpcImplementation deviceRpc) {
-        salProvider.getMountInstance().setSchemaContext(remoteSchemaContextProvider.getSchemaContext());
+        final SchemaContext schemaContext = remoteSchemaContextProvider.getSchemaContext();
+
+        // TODO remove deprecated SchemaContextProvider from SchemaAwareRpcBroker
+        // TODO move SchemaAwareRpcBroker from sal-broker-impl, now we have depend on the whole sal-broker-impl
+        final RpcProvisionRegistry rpcRegistry = new SchemaAwareRpcBroker(id.getPath().toString(), new org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider() {
+            @Override
+            public SchemaContext getSchemaContext() {
+                return schemaContext;
+            }
+        });
+        registerRpcsToSal(schemaContext, rpcRegistry, deviceRpc);
+        final DOMDataBroker domBroker = new NetconfDeviceDataBroker(id, deviceRpc, schemaContext, netconfSessionPreferences);
+
+        // TODO NotificationPublishService and NotificationRouter have the same interface
+        final NotificationPublishService notificationService = new NotificationPublishService() {
+
+            private final NotificationRouter innerRouter = new NotificationRouterImpl();
+
+            @Override
+            public void publish(final CompositeNode notification) {
+                innerRouter.publish(notification);
+            }
+
+            @Override
+            public ListenerRegistration<NotificationListener> addNotificationListener(final QName notification, final NotificationListener listener) {
+                return innerRouter.addNotificationListener(notification, listener);
+            }
+        };
+
+        salProvider.getMountInstance().onDeviceConnected(schemaContext, domBroker, rpcRegistry, notificationService);
         salProvider.getDatastoreAdapter().updateDeviceState(true, netconfSessionPreferences.getModuleBasedCaps());
-        registerDataHandlersToSal(deviceRpc, netconfSessionPreferences);
-        registerRpcsToSal(deviceRpc);
     }
 
     @Override
     public void onDeviceDisconnected() {
         salProvider.getDatastoreAdapter().updateDeviceState(false, Collections.<QName>emptySet());
+        salProvider.getMountInstance().onDeviceDisconnected();
     }
 
-    private void registerRpcsToSal(final RpcImplementation deviceRpc) {
-        final MountProvisionInstance mountInstance = salProvider.getMountInstance();
-
+    private void registerRpcsToSal(final SchemaContext schemaContext, final RpcProvisionRegistry rpcRegistry, final RpcImplementation deviceRpc) {
         final Map<QName, String> failedRpcs = Maps.newHashMap();
-        for (final RpcDefinition rpcDef : mountInstance.getSchemaContext().getOperations()) {
+        for (final RpcDefinition rpcDef : schemaContext.getOperations()) {
             try {
-                salRegistrations.add(mountInstance.addRpcImplementation(rpcDef.getQName(), deviceRpc));
+                salRegistrations.add(rpcRegistry.addRpcImplementation(rpcDef.getQName(), deviceRpc));
                 logger.debug("{}: Rpc {} from netconf registered successfully", id, rpcDef.getQName());
             } catch (final Exception e) {
                 // Only debug per rpc, warn for all of them at the end to pollute log a little less (e.g. routed rpcs)
@@ -94,18 +128,6 @@ public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDevice
         }
     }
 
-    private void registerDataHandlersToSal(final RpcImplementation deviceRpc,
-            final NetconfSessionCapabilities netconfSessionPreferences) {
-        final NetconfDeviceDataReader dataReader = new NetconfDeviceDataReader(id, deviceRpc);
-        final NetconfDeviceCommitHandler commitHandler = new NetconfDeviceCommitHandler(id, deviceRpc,
-                netconfSessionPreferences.isRollbackSupported());
-
-        final MountProvisionInstance mountInstance = salProvider.getMountInstance();
-        salRegistrations.add(mountInstance.registerConfigurationReader(ROOT_PATH, dataReader));
-        salRegistrations.add(mountInstance.registerOperationalReader(ROOT_PATH, dataReader));
-        salRegistrations.add(mountInstance.registerCommitHandler(ROOT_PATH, commitHandler));
-    }
-
     @Override
     public void close() {
         for (final AutoCloseable reg : Lists.reverse(salRegistrations)) {
index 01af84c9acf72057ec02b4b9123525f81cf00cd7..cf9174dd50d707ef36c5e80deefce3ea8f8be20c 100644 (file)
@@ -7,58 +7,62 @@
  */
 package org.opendaylight.controller.sal.connect.netconf.sal;
 
+import com.google.common.base.Preconditions;
 import java.util.Collection;
 import java.util.Collections;
-
 import java.util.concurrent.ExecutorService;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.controller.sal.core.api.Provider;
-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.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
 import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Preconditions;
-
 final class NetconfDeviceSalProvider implements AutoCloseable, Provider, BindingAwareProvider {
 
     private static final Logger logger = LoggerFactory.getLogger(NetconfDeviceSalProvider.class);
 
     private final RemoteDeviceId id;
     private final ExecutorService executor;
-    private volatile MountProvisionInstance mountInstance;
     private volatile NetconfDeviceDatastoreAdapter datastoreAdapter;
+    private MountInstance mountInstance;
 
     public NetconfDeviceSalProvider(final RemoteDeviceId deviceId, final ExecutorService executor) {
         this.id = deviceId;
         this.executor = executor;
     }
 
-    public MountProvisionInstance getMountInstance() {
+    public MountInstance getMountInstance() {
         Preconditions.checkState(mountInstance != null,
-                "%s: Sal provider was not initialized by sal. Cannot publish notification", id);
+                "%s: Mount instance was not initialized by sal. Cannot get mount instance", id);
         return mountInstance;
     }
 
     public NetconfDeviceDatastoreAdapter getDatastoreAdapter() {
         Preconditions.checkState(datastoreAdapter != null,
-                "%s: Sal provider %s was not initialized by sal. Cannot publish notification", id);
+                "%s: Sal provider %s was not initialized by sal. Cannot get datastore adapter", id);
         return datastoreAdapter;
     }
 
     @Override
     public void onSessionInitiated(final Broker.ProviderSession session) {
-        final MountProvisionService mountService = session.getService(MountProvisionService.class);
+        logger.debug("{}: (BI)Session with sal established {}", id, session);
+
+        final DOMMountPointService mountService = session.getService(DOMMountPointService.class);
         if (mountService != null) {
-            mountInstance = mountService.createOrGetMountPoint(id.getPath());
+            mountInstance = new MountInstance(mountService, id);
         }
-
-        logger.debug("{}: (BI)Session with sal established {}", id, session);
     }
 
     @Override
@@ -78,20 +82,78 @@ final class NetconfDeviceSalProvider implements AutoCloseable, Provider, Binding
 
     @Override
     public void onSessionInitiated(final BindingAwareBroker.ProviderContext session) {
-        final DataProviderService dataBroker = session.getSALService(DataProviderService.class);
-        datastoreAdapter = new NetconfDeviceDatastoreAdapter(id, dataBroker, executor);
-
         logger.debug("{}: Session with sal established {}", id, session);
+
+        final DataBroker dataBroker = session.getSALService(DataBroker.class);
+        datastoreAdapter = new NetconfDeviceDatastoreAdapter(id, dataBroker);
     }
 
     @Override
-    public void onSessionInitialized(final BindingAwareBroker.ConsumerContext session) {
-    }
+    public void onSessionInitialized(final BindingAwareBroker.ConsumerContext session) {}
 
     public void close() throws Exception {
-        mountInstance = null;
+        mountInstance.close();
         datastoreAdapter.close();
         datastoreAdapter = null;
     }
 
+    static final class MountInstance implements AutoCloseable {
+
+        private DOMMountPointService mountService;
+        private final RemoteDeviceId id;
+        private ObjectRegistration<DOMMountPoint> registration;
+        private NotificationPublishService notificationSerivce;
+
+        MountInstance(final DOMMountPointService mountService, final RemoteDeviceId id) {
+            this.mountService = Preconditions.checkNotNull(mountService);
+            this.id = Preconditions.checkNotNull(id);
+        }
+
+        synchronized void onDeviceConnected(final SchemaContext initialCtx,
+                final DOMDataBroker broker, final RpcProvisionRegistry rpc,
+                final NotificationPublishService notificationSerivce) {
+
+            Preconditions.checkNotNull(mountService, "Closed");
+            Preconditions.checkState(registration == null, "Already initialized");
+
+            final DOMMountPointService.DOMMountPointBuilder mountBuilder = mountService.createMountPoint(id.getPath());
+            mountBuilder.addInitialSchemaContext(initialCtx);
+
+            mountBuilder.addService(DOMDataBroker.class, broker);
+            mountBuilder.addService(RpcProvisionRegistry.class, rpc);
+            this.notificationSerivce = notificationSerivce;
+            mountBuilder.addService(NotificationPublishService.class, notificationSerivce);
+
+            registration = mountBuilder.register();
+        }
+
+        synchronized void onDeviceDisconnected() {
+            if(registration == null) {
+                return;
+            }
+
+            try {
+                registration.close();
+            } catch (final Exception e) {
+                // Only log and ignore
+                logger.warn("Unable to unregister mount instance for {}. Ignoring exception", id.getPath(), e);
+            } finally {
+                registration = null;
+            }
+        }
+
+        @Override
+        synchronized public void close() throws Exception {
+            if(registration != null) {
+                onDeviceDisconnected();
+            }
+            mountService = null;
+        }
+
+        public synchronized void publish(final CompositeNode domNotification) {
+            Preconditions.checkNotNull(notificationSerivce, "Device not set up yet, cannot handle notification {}", domNotification);
+            notificationSerivce.publish(domNotification);
+        }
+    }
+
 }
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTwoPhaseCommitTransaction.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTwoPhaseCommitTransaction.java
deleted file mode 100644 (file)
index 1a3b108..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf.sal;
-
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_CONFIG_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DEFAULT_OPERATION_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_ERROR_OPTION_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_OPERATION_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_TARGET_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.ROLLBACK_ON_ERROR_OPTION;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
-import org.opendaylight.controller.sal.common.util.RpcErrors;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.FailedRpcResult;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
-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.api.SimpleNode;
-import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
-import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
-import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *  Remote transaction that delegates data change to remote device using netconf messages.
- */
-final class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction<InstanceIdentifier, CompositeNode> {
-
-    private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceTwoPhaseCommitTransaction.class);
-
-    private final DataModification<InstanceIdentifier, CompositeNode> modification;
-    private final RpcImplementation rpc;
-    private final boolean rollbackSupported;
-    private final RemoteDeviceId id;
-    private final CompositeNode targetNode;
-
-    public NetconfDeviceTwoPhaseCommitTransaction(final RemoteDeviceId id, final RpcImplementation rpc,
-            final DataModification<InstanceIdentifier, CompositeNode> modification,
-            final boolean candidateSupported, final boolean rollbackOnErrorSupported) {
-        this.id = id;
-        this.rpc = Preconditions.checkNotNull(rpc);
-        this.modification = Preconditions.checkNotNull(modification);
-        this.targetNode = getTargetNode(candidateSupported);
-        this.rollbackSupported = rollbackOnErrorSupported;
-    }
-
-    /**
-     * Prepare phase, sends 1 or more netconf edit config operations to modify the data
-     *
-     * In case of failure or unexpected error response, ExecutionException is thrown
-     */
-    void prepare() throws InterruptedException, ExecutionException {
-        for (final InstanceIdentifier toRemove : modification.getRemovedConfigurationData()) {
-            sendDelete(toRemove);
-        }
-        for(final Entry<InstanceIdentifier, CompositeNode> toUpdate : modification.getUpdatedConfigurationData().entrySet()) {
-            sendMerge(toUpdate.getKey(),toUpdate.getValue());
-        }
-    }
-
-    private void sendMerge(final InstanceIdentifier key, final CompositeNode value) throws InterruptedException, ExecutionException {
-        sendEditRpc(createEditConfigStructure(key, Optional.<String>absent(), Optional.of(value)), Optional.<String>absent());
-    }
-
-    private void sendDelete(final InstanceIdentifier toDelete) throws InterruptedException, ExecutionException {
-        // FIXME use org.opendaylight.yangtools.yang.data.api.ModifyAction instead of strings
-        // TODO add string lowercase value to ModifyAction enum entries
-        sendEditRpc(createEditConfigStructure(toDelete, Optional.of("delete"), Optional.<CompositeNode>absent()), Optional.of("none"));
-    }
-
-    private void sendEditRpc(final CompositeNode editStructure, final Optional<String> defaultOperation) throws InterruptedException, ExecutionException {
-        final ImmutableCompositeNode editConfigRequest = createEditConfigRequest(editStructure, defaultOperation);
-        final RpcResult<CompositeNode> rpcResult = rpc.invokeRpc(NETCONF_EDIT_CONFIG_QNAME, editConfigRequest).get();
-
-        // Check result
-        if(rpcResult.isSuccessful() == false) {
-            throw new ExecutionException(
-                    String.format("%s: Pre-commit rpc failed, request: %s, errors: %s", id, editConfigRequest, rpcResult.getErrors()), null);
-        }
-    }
-
-    private ImmutableCompositeNode createEditConfigRequest(final CompositeNode editStructure, Optional<String> defaultOperation) {
-        final CompositeNodeBuilder<ImmutableCompositeNode> ret = ImmutableCompositeNode.builder();
-
-        // Target
-        final Node<?> targetWrapperNode = ImmutableCompositeNode.create(NETCONF_TARGET_QNAME, ImmutableList.<Node<?>>of(targetNode));
-        ret.add(targetWrapperNode);
-
-        // Default operation
-        if(defaultOperation.isPresent()) {
-            SimpleNode<String> defOp = NodeFactory.createImmutableSimpleNode(NETCONF_DEFAULT_OPERATION_QNAME, null, defaultOperation.get());
-            ret.add(defOp);
-        }
-
-        // Error option
-        if(rollbackSupported) {
-            ret.addLeaf(NETCONF_ERROR_OPTION_QNAME, ROLLBACK_ON_ERROR_OPTION);
-        }
-
-        ret.setQName(NETCONF_EDIT_CONFIG_QNAME);
-        // Edit content
-        ret.add(editStructure);
-        return ret.toInstance();
-    }
-
-    private CompositeNode createEditConfigStructure(final InstanceIdentifier dataPath, final Optional<String> operation,
-                                                    final Optional<CompositeNode> lastChildOverride) {
-        Preconditions.checkArgument(dataPath.getPath().isEmpty() == false, "Instance identifier with empty path %s", dataPath);
-
-        List<PathArgument> reversedPath = Lists.reverse(dataPath.getPath());
-
-        // Create deepest edit element with expected edit operation
-        CompositeNode previous = getDeepestEditElement(reversedPath.get(0), operation, lastChildOverride);
-
-        // Remove already processed deepest child
-        reversedPath = Lists.newArrayList(reversedPath);
-        reversedPath.remove(0);
-
-        // Create edit structure in reversed order
-        for (final PathArgument arg : reversedPath) {
-            final CompositeNodeBuilder<ImmutableCompositeNode> builder = ImmutableCompositeNode.builder();
-            builder.setQName(arg.getNodeType());
-
-            addPredicatesToCompositeNodeBuilder(getPredicates(arg), builder);
-
-            builder.add(previous);
-            previous = builder.toInstance();
-        }
-        return ImmutableCompositeNode.create(NETCONF_CONFIG_QNAME, ImmutableList.<Node<?>>of(previous));
-    }
-
-    private void addPredicatesToCompositeNodeBuilder(final Map<QName, Object> predicates, final CompositeNodeBuilder<ImmutableCompositeNode> builder) {
-        for (final Entry<QName, Object> entry : predicates.entrySet()) {
-            builder.addLeaf(entry.getKey(), entry.getValue());
-        }
-    }
-
-    private Map<QName, Object> getPredicates(final PathArgument arg) {
-        Map<QName, Object> predicates = Collections.emptyMap();
-        if (arg instanceof NodeIdentifierWithPredicates) {
-            predicates = ((NodeIdentifierWithPredicates) arg).getKeyValues();
-        }
-        return predicates;
-    }
-
-    private CompositeNode getDeepestEditElement(final PathArgument arg, final Optional<String> operation, final Optional<CompositeNode> lastChildOverride) {
-        final CompositeNodeBuilder<ImmutableCompositeNode> builder = ImmutableCompositeNode.builder();
-        builder.setQName(arg.getNodeType());
-
-        final Map<QName, Object> predicates = getPredicates(arg);
-        addPredicatesToCompositeNodeBuilder(predicates, builder);
-
-        if (operation.isPresent()) {
-            builder.setAttribute(NETCONF_OPERATION_QNAME, operation.get());
-        }
-        if (lastChildOverride.isPresent()) {
-            final List<Node<?>> children = lastChildOverride.get().getValue();
-            for(final Node<?> child : children) {
-                if(!predicates.containsKey(child.getKey())) {
-                    builder.add(child);
-                }
-            }
-        }
-
-        return builder.toInstance();
-    }
-
-    /**
-     * Send commit rpc to finish the transaction
-     * In case of failure or unexpected error response, ExecutionException is thrown
-     */
-    @Override
-    public RpcResult<Void> finish() {
-        try {
-            final RpcResult<?> rpcResult = rpc.invokeRpc(NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME, getCommitRequest()).get();
-            return new RpcResultVoidWrapper(rpcResult);
-        } catch (final InterruptedException e) {
-            Thread.currentThread().interrupt();
-            throw new RuntimeException(id + ": Interrupted while waiting for response", e);
-        } catch (final ExecutionException e) {
-            LOG.warn("{}: Failed to finish commit operation", id, e);
-            return new FailedRpcResult<>(RpcErrors.getRpcError(null, null, null, RpcError.ErrorSeverity.ERROR,
-                    id + ": Unexpected operation error during commit operation", RpcError.ErrorType.APPLICATION, e));
-        }
-    }
-
-    private ImmutableCompositeNode getCommitRequest() {
-        final CompositeNodeBuilder<ImmutableCompositeNode> commitInput = ImmutableCompositeNode.builder();
-        commitInput.setQName(NETCONF_COMMIT_QNAME);
-        return commitInput.toInstance();
-    }
-
-    @Override
-    public DataModification<InstanceIdentifier, CompositeNode> getModification() {
-        return this.modification;
-    }
-
-    @Override
-    public RpcResult<Void> rollback() throws IllegalStateException {
-        // TODO BUG-732 implement rollback by sending discard changes
-        return null;
-    }
-
-    public CompositeNode getTargetNode(final boolean candidateSupported) {
-        if(candidateSupported) {
-            return ImmutableCompositeNode.create(NETCONF_CANDIDATE_QNAME, ImmutableList.<Node<?>>of());
-        } else {
-            return ImmutableCompositeNode.create(NETCONF_RUNNING_QNAME, ImmutableList.<Node<?>>of());
-        }
-    }
-
-    private static final class RpcResultVoidWrapper implements RpcResult<Void> {
-
-        private final RpcResult<?> rpcResult;
-
-        public RpcResultVoidWrapper(final RpcResult<?> rpcResult) {
-            this.rpcResult = rpcResult;
-        }
-
-        @Override
-        public boolean isSuccessful() {
-            return rpcResult.isSuccessful();
-        }
-
-        @Override
-        public Void getResult() {
-            return null;
-        }
-
-        @Override
-        public Collection<RpcError> getErrors() {
-            return rpcResult.getErrors();
-        }
-    }
-}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadOnlyTx.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadOnlyTx.java
new file mode 100644 (file)
index 0000000..3248453
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+package org.opendaylight.controller.sal.connect.netconf.sal.tx;
+
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.CONFIG_SOURCE_RUNNING;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DATA_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toFilterStructure;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class NetconfDeviceReadOnlyTx implements DOMDataReadOnlyTransaction {
+
+    private static final Logger LOG  = LoggerFactory.getLogger(NetconfDeviceReadOnlyTx.class);
+
+    private final RpcImplementation rpc;
+    private final DataNormalizer normalizer;
+
+    public NetconfDeviceReadOnlyTx(final RpcImplementation rpc, final DataNormalizer normalizer) {
+        this.rpc = rpc;
+        this.normalizer = normalizer;
+    }
+
+    public ListenableFuture<Optional<NormalizedNode<?, ?>>> readConfigurationData(final YangInstanceIdentifier path) {
+        final ListenableFuture<RpcResult<CompositeNode>> future = rpc.invokeRpc(NETCONF_GET_CONFIG_QNAME,
+                NetconfMessageTransformUtil.wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, toFilterStructure(path)));
+
+        return Futures.transform(future, new Function<RpcResult<CompositeNode>, Optional<NormalizedNode<?, ?>>>() {
+            @Override
+            public Optional<NormalizedNode<?, ?>> apply(final RpcResult<CompositeNode> result) {
+                final CompositeNode data = result.getResult().getFirstCompositeByName(NETCONF_DATA_QNAME);
+                final CompositeNode node = (CompositeNode) findNode(data, path);
+
+                return data == null ?
+                        Optional.<NormalizedNode<?, ?>>absent() :
+                        transform(path, node);
+            }
+        });
+    }
+
+    private Optional<NormalizedNode<?, ?>> transform(final YangInstanceIdentifier path, final CompositeNode node) {
+        if(node == null) {
+            return Optional.absent();
+        }
+        try {
+            return Optional.<NormalizedNode<?, ?>>of(normalizer.toNormalized(path, node).getValue());
+        } catch (final Exception e) {
+            LOG.error("Unable to normalize data for {}, data: {}", path, node, e);
+            throw e;
+        }
+    }
+
+    public ListenableFuture<Optional<NormalizedNode<?, ?>>> readOperationalData(final YangInstanceIdentifier path) {
+        final ListenableFuture<RpcResult<CompositeNode>> future = rpc.invokeRpc(NETCONF_GET_QNAME, NetconfMessageTransformUtil.wrap(NETCONF_GET_QNAME, toFilterStructure(path)));
+
+        return Futures.transform(future, new Function<RpcResult<CompositeNode>, Optional<NormalizedNode<?, ?>>>() {
+            @Override
+            public Optional<NormalizedNode<?, ?>> apply(final RpcResult<CompositeNode> result) {
+                final CompositeNode data = result.getResult().getFirstCompositeByName(NETCONF_DATA_QNAME);
+                final CompositeNode node = (CompositeNode) findNode(data, path);
+
+                return data == null ?
+                        Optional.<NormalizedNode<?, ?>>absent() :
+                        transform(path, node);
+            }
+        });
+    }
+
+    private static Node<?> findNode(final CompositeNode node, final YangInstanceIdentifier identifier) {
+
+        Node<?> current = node;
+        for (final YangInstanceIdentifier.PathArgument arg : identifier.getPathArguments()) {
+            if (current instanceof SimpleNode<?>) {
+                return null;
+            } else if (current instanceof CompositeNode) {
+                final CompositeNode currentComposite = (CompositeNode) current;
+
+                current = currentComposite.getFirstCompositeByName(arg.getNodeType());
+                if (current == null) {
+                    current = currentComposite.getFirstCompositeByName(arg.getNodeType().withoutRevision());
+                }
+                if (current == null) {
+                    current = currentComposite.getFirstSimpleByName(arg.getNodeType());
+                }
+                if (current == null) {
+                    current = currentComposite.getFirstSimpleByName(arg.getNodeType().withoutRevision());
+                }
+                if (current == null) {
+                    return null;
+                }
+            }
+        }
+        return current;
+    }
+
+    @Override
+    public void close() {
+        // NOOP
+    }
+
+    @Override
+    public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        final YangInstanceIdentifier legacyPath = toLegacyPath(normalizer, path);
+
+        switch (store) {
+            case CONFIGURATION : {
+                return readConfigurationData(legacyPath);
+            }
+            case OPERATIONAL : {
+                return readOperationalData(legacyPath);
+            }
+        }
+
+        throw new IllegalArgumentException(String.format("Cannot read data %s for %s datastore, unknown datastore type", path, store));
+    }
+
+    static YangInstanceIdentifier toLegacyPath(final DataNormalizer normalizer, final YangInstanceIdentifier path) {
+        try {
+            return normalizer.toLegacy(path);
+        } catch (final DataNormalizationException e) {
+            throw new IllegalArgumentException("Cannot normalize path " + path, e);
+        }
+    }
+
+    @Override
+    public Object getIdentifier() {
+        return this;
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadWriteTx.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadWriteTx.java
new file mode 100644 (file)
index 0000000..4054cf9
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+
+package org.opendaylight.controller.sal.connect.netconf.sal.tx;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class NetconfDeviceReadWriteTx implements DOMDataReadWriteTransaction {
+
+    private final DOMDataReadTransaction delegateReadTx;
+    private final DOMDataWriteTransaction delegateWriteTx;
+
+    public NetconfDeviceReadWriteTx(final DOMDataReadTransaction delegateReadTx, final DOMDataWriteTransaction delegateWriteTx) {
+        this.delegateReadTx = delegateReadTx;
+        this.delegateWriteTx = delegateWriteTx;
+    }
+
+    @Override
+    public boolean cancel() {
+        return delegateWriteTx.cancel();
+    }
+
+    @Override
+    public void put(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        delegateWriteTx.put(store, path, data);
+    }
+
+    @Override
+    public void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        delegateWriteTx.merge(store, path, data);
+    }
+
+    @Override
+    public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        delegateWriteTx.delete(store, path);
+    }
+
+    @Override
+    public CheckedFuture<Void, TransactionCommitFailedException> submit() {
+        return delegateWriteTx.submit();
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<TransactionStatus>> commit() {
+        return delegateWriteTx.commit();
+    }
+
+    @Override
+    public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        return delegateReadTx.read(store, path);
+    }
+
+    @Override
+    public Object getIdentifier() {
+        return this;
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceWriteOnlyTx.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceWriteOnlyTx.java
new file mode 100644 (file)
index 0000000..c8d9028
--- /dev/null
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+
+package org.opendaylight.controller.sal.connect.netconf.sal.tx;
+
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_CONFIG_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DEFAULT_OPERATION_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_ERROR_OPTION_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_OPERATION_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_TARGET_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.ROLLBACK_ON_ERROR_OPTION;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import javax.annotation.Nullable;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfDeviceWriteOnlyTx implements DOMDataWriteTransaction {
+
+    private static final Logger LOG  = LoggerFactory.getLogger(NetconfDeviceWriteOnlyTx.class);
+
+    private final RemoteDeviceId id;
+    private final RpcImplementation rpc;
+    private final DataNormalizer normalizer;
+    private final boolean rollbackSupported;
+    private final CompositeNode targetNode;
+
+    public NetconfDeviceWriteOnlyTx(final RemoteDeviceId id, final RpcImplementation rpc, final DataNormalizer normalizer, final boolean candidateSupported, final boolean rollbackOnErrorSupported) {
+        this.id = id;
+        this.rpc = rpc;
+        this.normalizer = normalizer;
+        this.targetNode = getTargetNode(candidateSupported);
+        this.rollbackSupported = rollbackOnErrorSupported;
+    }
+
+    // FIXME add logging
+
+    @Override
+    public boolean cancel() {
+        if(isCommitted()) {
+            return false;
+        }
+
+        return discardChanges();
+    }
+
+    private boolean isCommitted() {
+        // TODO 732
+        return true;
+    }
+
+    private boolean discardChanges() {
+        // TODO 732
+        return true;
+    }
+
+    // TODO should the edit operations be blocking ?
+
+    @Override
+    public void put(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        Preconditions.checkArgument(store == LogicalDatastoreType.CONFIGURATION, "Can merge only configuration, not %s", store);
+
+        try {
+            final YangInstanceIdentifier legacyPath = NetconfDeviceReadOnlyTx.toLegacyPath(normalizer, path);
+            final CompositeNode legacyData = normalizer.toLegacy(path, data);
+            sendEditRpc(createEditConfigStructure(legacyPath, Optional.of(ModifyAction.REPLACE), Optional.fromNullable(legacyData)), Optional.of(ModifyAction.NONE));
+        } catch (final ExecutionException e) {
+            LOG.warn("Error putting data to {}, data: {}, discarding changes", path, data, e);
+            discardChanges();
+            throw new RuntimeException("Error while replacing " + path, e);
+        }
+    }
+
+    @Override
+    public void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        Preconditions.checkArgument(store == LogicalDatastoreType.CONFIGURATION, "Can merge only configuration, not %s", store);
+
+        try {
+            final YangInstanceIdentifier legacyPath = NetconfDeviceReadOnlyTx.toLegacyPath(normalizer, path);
+            final CompositeNode legacyData = normalizer.toLegacy(path, data);
+            sendEditRpc(
+                    createEditConfigStructure(legacyPath, Optional.<ModifyAction> absent(), Optional.fromNullable(legacyData)), Optional.<ModifyAction> absent());
+        } catch (final ExecutionException e) {
+            LOG.warn("Error merging data to {}, data: {}, discarding changes", path, data, e);
+            discardChanges();
+            throw new RuntimeException("Error while merging " + path, e);
+        }
+    }
+
+    @Override
+    public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        Preconditions.checkArgument(store == LogicalDatastoreType.CONFIGURATION, "Can merge only configuration, not %s", store);
+
+        try {
+            sendEditRpc(createEditConfigStructure(NetconfDeviceReadOnlyTx.toLegacyPath(normalizer, path), Optional.of(ModifyAction.DELETE), Optional.<CompositeNode>absent()), Optional.of(ModifyAction.NONE));
+        } catch (final ExecutionException e) {
+            LOG.warn("Error deleting data {}, discarding changes", path, e);
+            discardChanges();
+            throw new RuntimeException("Error while deleting " + path, e);
+        }
+    }
+
+    @Override
+    public CheckedFuture<Void, TransactionCommitFailedException> submit() {
+        final ListenableFuture<Void> commmitFutureAsVoid = Futures.transform(commit(), new Function<RpcResult<TransactionStatus>, Void>() {
+            @Nullable
+            @Override
+            public Void apply(@Nullable final RpcResult<TransactionStatus> input) {
+                return null;
+            }
+        });
+
+        return Futures.makeChecked(commmitFutureAsVoid, new Function<Exception, TransactionCommitFailedException>() {
+            @Override
+            public TransactionCommitFailedException apply(final Exception input) {
+                return new TransactionCommitFailedException("Submit of transaction " + getIdentifier() + " failed", input);
+            }
+        });
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<TransactionStatus>> commit() {
+        // FIXME do not allow commit if closed or failed
+
+        final ListenableFuture<RpcResult<CompositeNode>> rpcResult = rpc.invokeRpc(NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME, getCommitRequest());
+        return Futures.transform(rpcResult, new Function<RpcResult<CompositeNode>, RpcResult<TransactionStatus>>() {
+            @Override
+            public RpcResult<TransactionStatus> apply(@Nullable final RpcResult<CompositeNode> input) {
+                if(input.isSuccessful()) {
+                    return RpcResultBuilder.success(TransactionStatus.COMMITED).build();
+                } else {
+                    final RpcResultBuilder<TransactionStatus> failed = RpcResultBuilder.failed();
+                    for (final RpcError rpcError : input.getErrors()) {
+                        failed.withError(rpcError.getErrorType(), rpcError.getTag(), rpcError.getMessage(), rpcError.getApplicationTag(), rpcError.getInfo(), rpcError.getCause());
+                    }
+                    return failed.build();
+                }
+            }
+        });
+
+        // FIXME 732 detect commit failure
+    }
+
+    private void sendEditRpc(final CompositeNode editStructure, final Optional<ModifyAction> defaultOperation) throws ExecutionException {
+        final CompositeNode editConfigRequest = createEditConfigRequest(editStructure, defaultOperation);
+        final RpcResult<CompositeNode> rpcResult;
+        try {
+            rpcResult = rpc.invokeRpc(NETCONF_EDIT_CONFIG_QNAME, editConfigRequest).get();
+        } catch (final InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new RuntimeException(id + ": Interrupted while waiting for response", e);
+        }
+
+        // Check result
+        if(rpcResult.isSuccessful() == false) {
+            throw new ExecutionException(
+                    String.format("%s: Pre-commit rpc failed, request: %s, errors: %s", id, editConfigRequest, rpcResult.getErrors()), null);
+        }
+    }
+
+    private CompositeNode createEditConfigStructure(final YangInstanceIdentifier dataPath, final Optional<ModifyAction> operation,
+                                                    final Optional<CompositeNode> lastChildOverride) {
+        Preconditions.checkArgument(Iterables.isEmpty(dataPath.getPathArguments()) == false, "Instance identifier with empty path %s", dataPath);
+
+        List<YangInstanceIdentifier.PathArgument> reversedPath = Lists.reverse(dataPath.getPath());
+
+        // Create deepest edit element with expected edit operation
+        CompositeNode previous = getDeepestEditElement(reversedPath.get(0), operation, lastChildOverride);
+
+        // Remove already processed deepest child
+        reversedPath = Lists.newArrayList(reversedPath);
+        reversedPath.remove(0);
+
+        // Create edit structure in reversed order
+        for (final YangInstanceIdentifier.PathArgument arg : reversedPath) {
+            final CompositeNodeBuilder<ImmutableCompositeNode> builder = ImmutableCompositeNode.builder();
+            builder.setQName(arg.getNodeType());
+
+            addPredicatesToCompositeNodeBuilder(getPredicates(arg), builder);
+
+            builder.add(previous);
+            previous = builder.toInstance();
+        }
+        return ImmutableCompositeNode.create(NETCONF_CONFIG_QNAME, ImmutableList.<Node<?>>of(previous));
+    }
+
+    private void addPredicatesToCompositeNodeBuilder(final Map<QName, Object> predicates, final CompositeNodeBuilder<ImmutableCompositeNode> builder) {
+        for (final Map.Entry<QName, Object> entry : predicates.entrySet()) {
+            builder.addLeaf(entry.getKey(), entry.getValue());
+        }
+    }
+
+    private Map<QName, Object> getPredicates(final YangInstanceIdentifier.PathArgument arg) {
+        Map<QName, Object> predicates = Collections.emptyMap();
+        if (arg instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) {
+            predicates = ((YangInstanceIdentifier.NodeIdentifierWithPredicates) arg).getKeyValues();
+        }
+        return predicates;
+    }
+
+    private CompositeNode getDeepestEditElement(final YangInstanceIdentifier.PathArgument arg, final Optional<ModifyAction> operation, final Optional<CompositeNode> lastChildOverride) {
+        final CompositeNodeBuilder<ImmutableCompositeNode> builder = ImmutableCompositeNode.builder();
+        builder.setQName(arg.getNodeType());
+
+        final Map<QName, Object> predicates = getPredicates(arg);
+        addPredicatesToCompositeNodeBuilder(predicates, builder);
+
+        if (operation.isPresent()) {
+            builder.setAttribute(NETCONF_OPERATION_QNAME, modifyOperationToXmlString(operation.get()));
+        }
+        if (lastChildOverride.isPresent()) {
+            final List<Node<?>> children = lastChildOverride.get().getValue();
+            for(final Node<?> child : children) {
+                if(!predicates.containsKey(child.getKey())) {
+                    builder.add(child);
+                }
+            }
+        }
+
+        return builder.toInstance();
+    }
+
+    private CompositeNode createEditConfigRequest(final CompositeNode editStructure, final Optional<ModifyAction> defaultOperation) {
+        final CompositeNodeBuilder<ImmutableCompositeNode> ret = ImmutableCompositeNode.builder();
+
+        // Target
+        final Node<?> targetWrapperNode = ImmutableCompositeNode.create(NETCONF_TARGET_QNAME, ImmutableList.<Node<?>>of(targetNode));
+        ret.add(targetWrapperNode);
+
+        // Default operation
+        if(defaultOperation.isPresent()) {
+            final SimpleNode<String> defOp = NodeFactory.createImmutableSimpleNode(NETCONF_DEFAULT_OPERATION_QNAME, null, modifyOperationToXmlString(defaultOperation.get()));
+            ret.add(defOp);
+        }
+
+        // Error option
+        if(rollbackSupported) {
+            ret.addLeaf(NETCONF_ERROR_OPTION_QNAME, ROLLBACK_ON_ERROR_OPTION);
+        }
+
+        ret.setQName(NETCONF_EDIT_CONFIG_QNAME);
+        // Edit content
+        ret.add(editStructure);
+        return ret.toInstance();
+    }
+
+    private String modifyOperationToXmlString(final ModifyAction operation) {
+        return operation.name().toLowerCase();
+    }
+
+    public CompositeNode getTargetNode(final boolean candidateSupported) {
+        if(candidateSupported) {
+            return ImmutableCompositeNode.create(NETCONF_CANDIDATE_QNAME, ImmutableList.<Node<?>>of());
+        } else {
+            return ImmutableCompositeNode.create(NETCONF_RUNNING_QNAME, ImmutableList.<Node<?>>of());
+        }
+    }
+
+    private ImmutableCompositeNode getCommitRequest() {
+        final CompositeNodeBuilder<ImmutableCompositeNode> commitInput = ImmutableCompositeNode.builder();
+        commitInput.setQName(NETCONF_COMMIT_QNAME);
+        return commitInput.toInstance();
+    }
+
+
+    @Override
+    public Object getIdentifier() {
+        return this;
+    }
+}
index 21f94474f893a4b2c4dde263a477cc6336ce39d8..80d0f67ac49c72b47d35e6ca094ec4610099c1b1 100644 (file)
@@ -8,18 +8,19 @@
 package org.opendaylight.controller.sal.connect.netconf.schema.mapping;
 
 import com.google.common.base.Optional;
-import java.util.Collections;
+
 import java.util.List;
 import java.util.Set;
+
 import javax.activation.UnsupportedDataTypeException;
+
 import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.connect.api.MessageTransformer;
 import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
 import org.opendaylight.controller.sal.connect.util.MessageCounter;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
@@ -55,7 +56,7 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
     private static CompositeNode toNotification(final NetconfMessage message, final SchemaContext ctx) {
         final Set<NotificationDefinition> notifications = ctx.getNotifications();
         final Document document = message.getDocument();
-        return XmlDocumentUtils.notificationToDomNodes(document, Optional.fromNullable(notifications));
+        return XmlDocumentUtils.notificationToDomNodes(document, Optional.fromNullable(notifications), ctx);
     }
 
     @Override
@@ -90,7 +91,7 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
             return toRpcResult(message, rpc, schemaContext.get());
         } else {
             final CompositeNode node = (CompositeNode) XmlDocumentUtils.toDomNode(message.getDocument());
-            return Rpcs.getRpcResult(true, node, Collections.<RpcError>emptySet());
+            return RpcResultBuilder.success( node ).build();
         }
     }
 
@@ -114,7 +115,7 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
             compositeNode = (CompositeNode) XmlDocumentUtils.toDomNode(message.getDocument());
         }
 
-        return Rpcs.getRpcResult(true, compositeNode, Collections.<RpcError> emptySet());
+        return RpcResultBuilder.success( compositeNode ).build();
     }
 
     @Override
index ee6daa1e3d0dd81d60ca7c298402d837dbc6a457..a6924d9d37a3b3e81921c049d1bc1f5b3a5571a2 100644 (file)
@@ -7,6 +7,13 @@
  */
 package org.opendaylight.controller.sal.connect.netconf.util;
 
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -19,12 +26,12 @@ import javax.annotation.Nullable;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
-import org.opendaylight.controller.sal.common.util.RpcErrors;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
@@ -36,13 +43,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
 public class NetconfMessageTransformUtil {
 
     private NetconfMessageTransformUtil() {
@@ -74,16 +74,15 @@ public class NetconfMessageTransformUtil {
             .create("urn:ietf:params:netconf:capability:rollback-on-error:1.0");
     public static String ROLLBACK_ON_ERROR_OPTION = "rollback-on-error";
 
-    public static Node<?> toFilterStructure(final InstanceIdentifier identifier) {
+    public static Node<?> toFilterStructure(final YangInstanceIdentifier identifier) {
         Node<?> previous = null;
-        if (identifier.getPath().isEmpty()) {
+        if (Iterables.isEmpty(identifier.getPathArguments())) {
             return null;
         }
 
-        for (final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument component : Lists
-                .reverse(identifier.getPath())) {
-            if (component instanceof InstanceIdentifier.NodeIdentifierWithPredicates) {
-                previous = toNode((InstanceIdentifier.NodeIdentifierWithPredicates)component, previous);
+        for (final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument component : identifier.getReversePathArguments()) {
+            if (component instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) {
+                previous = toNode((YangInstanceIdentifier.NodeIdentifierWithPredicates)component, previous);
             } else {
                 previous = toNode(component, previous);
             }
@@ -91,7 +90,7 @@ public class NetconfMessageTransformUtil {
         return filter("subtree", previous);
     }
 
-    static Node<?> toNode(final InstanceIdentifier.NodeIdentifierWithPredicates argument, final Node<?> node) {
+    static Node<?> toNode(final YangInstanceIdentifier.NodeIdentifierWithPredicates argument, final Node<?> node) {
         final List<Node<?>> list = new ArrayList<>();
         for (final Map.Entry<QName, Object> arg : argument.getKeyValues().entrySet()) {
             list.add(new SimpleNodeTOImpl(arg.getKey(), null, arg.getValue()));
@@ -103,15 +102,15 @@ public class NetconfMessageTransformUtil {
     }
 
     public static void checkValidReply(final NetconfMessage input, final NetconfMessage output)
-        throws NetconfDocumentedException {
+            throws NetconfDocumentedException {
         final String inputMsgId = input.getDocument().getDocumentElement().getAttribute("message-id");
         final String outputMsgId = output.getDocument().getDocumentElement().getAttribute("message-id");
 
         if(inputMsgId.equals(outputMsgId) == false) {
             Map<String,String> errorInfo = ImmutableMap.<String,String>builder()
-                .put( "actual-message-id", outputMsgId )
-                .put( "expected-message-id", inputMsgId )
-                .build();
+                    .put( "actual-message-id", outputMsgId )
+                    .put( "expected-message-id", inputMsgId )
+                    .build();
 
             throw new NetconfDocumentedException( "Response message contained unknown \"message-id\"",
                     null, NetconfDocumentedException.ErrorType.protocol,
@@ -126,7 +125,7 @@ public class NetconfMessageTransformUtil {
         }
     }
 
-    public static RpcError toRpcError( NetconfDocumentedException ex )
+    public static RpcError toRpcError( final NetconfDocumentedException ex )
     {
         StringBuilder infoBuilder = new StringBuilder();
         Map<String, String> errorInfo = ex.getErrorInfo();
@@ -134,44 +133,50 @@ public class NetconfMessageTransformUtil {
         {
             for( Entry<String,String> e: errorInfo.entrySet() ) {
                 infoBuilder.append( '<' ).append( e.getKey() ).append( '>' ).append( e.getValue() )
-                           .append( "</" ).append( e.getKey() ).append( '>' );
+                .append( "</" ).append( e.getKey() ).append( '>' );
 
             }
         }
 
-        return RpcErrors.getRpcError( null, ex.getErrorTag().getTagValue(), infoBuilder.toString(),
-                                      toRpcErrorSeverity( ex.getErrorSeverity() ), ex.getLocalizedMessage(),
-                                      toRpcErrorType( ex.getErrorType() ), ex.getCause() );
+        ErrorSeverity severity = toRpcErrorSeverity( ex.getErrorSeverity() );
+        return severity == ErrorSeverity.ERROR ?
+                RpcResultBuilder.newError(
+                        toRpcErrorType( ex.getErrorType() ), ex.getErrorTag().getTagValue(),
+                        ex.getLocalizedMessage(), null, infoBuilder.toString(), ex.getCause() ) :
+                            RpcResultBuilder.newWarning(
+                                    toRpcErrorType( ex.getErrorType() ), ex.getErrorTag().getTagValue(),
+                                    ex.getLocalizedMessage(), null, infoBuilder.toString(), ex.getCause() );
     }
 
-    private static ErrorSeverity toRpcErrorSeverity( NetconfDocumentedException.ErrorSeverity severity ) {
+    private static ErrorSeverity toRpcErrorSeverity( final NetconfDocumentedException.ErrorSeverity severity ) {
         switch( severity ) {
-            case warning:
-                return RpcError.ErrorSeverity.WARNING;
-            default:
-                return RpcError.ErrorSeverity.ERROR;
+        case warning:
+            return RpcError.ErrorSeverity.WARNING;
+        default:
+            return RpcError.ErrorSeverity.ERROR;
         }
     }
 
-    private static RpcError.ErrorType toRpcErrorType( NetconfDocumentedException.ErrorType type )
+    private static RpcError.ErrorType toRpcErrorType( final NetconfDocumentedException.ErrorType type )
     {
         switch( type ) {
-            case protocol:
-                return RpcError.ErrorType.PROTOCOL;
-            case rpc:
-                return RpcError.ErrorType.RPC;
-            case transport:
-                return RpcError.ErrorType.TRANSPORT;
-            default:
-                return RpcError.ErrorType.APPLICATION;
+        case protocol:
+            return RpcError.ErrorType.PROTOCOL;
+        case rpc:
+            return RpcError.ErrorType.RPC;
+        case transport:
+            return RpcError.ErrorType.TRANSPORT;
+        default:
+            return RpcError.ErrorType.APPLICATION;
         }
     }
 
     public static CompositeNode flattenInput(final CompositeNode node) {
         final QName inputQName = QName.create(node.getNodeType(), "input");
         final CompositeNode input = node.getFirstCompositeByName(inputQName);
-        if (input == null)
+        if (input == null) {
             return node;
+        }
         if (input instanceof CompositeNode) {
 
             final List<Node<?>> nodes = ImmutableList.<Node<?>> builder() //
@@ -179,7 +184,7 @@ public class NetconfMessageTransformUtil {
                     .addAll(Collections2.filter(node.getValue(), new Predicate<Node<?>>() {
                         @Override
                         public boolean apply(@Nullable final Node<?> input) {
-                            return input.getNodeType() != inputQName;
+                            return !inputQName.equals(input.getNodeType());
                         }
                     })) //
                     .build();
@@ -190,7 +195,7 @@ public class NetconfMessageTransformUtil {
         return input;
     }
 
-    static Node<?> toNode(final InstanceIdentifier.PathArgument argument, final Node<?> node) {
+    static Node<?> toNode(final YangInstanceIdentifier.PathArgument argument, final Node<?> node) {
         if (node != null) {
             return new CompositeNodeTOImpl(argument.getNodeType(), null, Collections.<Node<?>> singletonList(node));
         } else {
index bd075d0606b08f3f94982e32d18ecdb468b9830a..1896e69f325aee65946e264499b1022c2e696f9e 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.controller.sal.connect.netconf.util;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -36,11 +37,11 @@ class NodeContainerProxy implements ContainerSchemaNode {
         this.qName = Preconditions.checkNotNull(qName, "qName");
     }
 
-    public NodeContainerProxy(final QName qName, final Set<DataSchemaNode> childNodes) {
+    public NodeContainerProxy(final QName qName, final Collection<DataSchemaNode> childNodes) {
         this(qName, asMap(childNodes));
     }
 
-    private static Map<QName, DataSchemaNode> asMap(final Set<DataSchemaNode> childNodes) {
+    private static Map<QName, DataSchemaNode> asMap(final Collection<DataSchemaNode> childNodes) {
         final Map<QName, DataSchemaNode> mapped = Maps.newHashMap();
         for (final DataSchemaNode childNode : childNodes) {
             mapped.put(childNode.getQName(), childNode);
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/FailedRpcResult.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/FailedRpcResult.java
deleted file mode 100644 (file)
index 49b16d4..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.util;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
-public final class FailedRpcResult<T> implements RpcResult<T> {
-
-    private final RpcError rpcError;
-
-    public FailedRpcResult(final RpcError rpcError) {
-        this.rpcError = rpcError;
-    }
-
-    @Override
-    public boolean isSuccessful() {
-        return false;
-    }
-
-    @Override
-    public T getResult() {
-        return null;
-    }
-
-    @Override
-    public Collection<RpcError> getErrors() {
-        return Collections.singletonList(rpcError);
-    }
-}
index 4670846c7c54a312bad4268671baea44e8dfbd87..175cb8e2077c83df44117e81baa7d0b0cd3ef6ae 100644 (file)
@@ -20,7 +20,7 @@ import org.opendaylight.yangtools.yang.common.QName;
 public class RemoteDeviceId {
 
     private final String name;
-    private final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path;
+    private final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path;
     private final InstanceIdentifier<Node> bindingPath;
     private final NodeKey key;
 
@@ -40,9 +40,9 @@ public class RemoteDeviceId {
         return InstanceIdentifier.builder(Nodes.class).child(Node.class, key).build();
     }
 
-    private static org.opendaylight.yangtools.yang.data.api.InstanceIdentifier createBIPath(final String name) {
-        final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder builder =
-                org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder();
+    private static org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier createBIPath(final String name) {
+        final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder builder =
+                org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.builder();
         builder.node(Nodes.QNAME).nodeWithKey(Node.QNAME, QName.create(Node.QNAME.getNamespace(), Node.QNAME.getRevision(), "id"), name);
 
         return builder.build();
@@ -56,7 +56,7 @@ public class RemoteDeviceId {
         return bindingPath;
     }
 
-    public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier getPath() {
+    public org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier getPath() {
         return path;
     }
 
index c1b9f7b47ba8b8009b620655a729703e1809346f..46ea4ff73c40ae0d29ec267d834a19e2d88faa19 100644 (file)
@@ -12,6 +12,7 @@ import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import java.io.InputStream;
@@ -27,7 +28,6 @@ import org.junit.Test;
 import org.mockito.Mockito;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.connect.api.MessageTransformer;
 import org.opendaylight.controller.sal.connect.api.RemoteDeviceCommunicator;
 import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
@@ -38,8 +38,8 @@ import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransf
 import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.controller.sal.core.api.RpcImplementation;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -65,8 +65,8 @@ public class NetconfDeviceTest {
         }
     }
 
-    private static final  RpcResult<NetconfMessage> rpcResult = Rpcs.getRpcResult(true, netconfMessage, Collections.<RpcError>emptySet());
-    private static final  RpcResult<CompositeNode> rpcResultC = Rpcs.getRpcResult(true, compositeNode, Collections.<RpcError>emptySet());
+    private static final  RpcResult<NetconfMessage> rpcResult = RpcResultBuilder.success(netconfMessage).build();
+    private static final  RpcResult<CompositeNode> rpcResultC = RpcResultBuilder.success(compositeNode).build();
 
     public static final String TEST_NAMESPACE = "test:namespace";
     public static final String TEST_MODULE = "test-module";
@@ -83,6 +83,32 @@ public class NetconfDeviceTest {
         Mockito.verify(facade, Mockito.timeout(5000)).onDeviceDisconnected();
     }
 
+    @Test
+    public void testNotificationBeforeSchema() throws Exception {
+        final RemoteDeviceHandler<NetconfSessionCapabilities> facade = getFacade();
+        final RemoteDeviceCommunicator<NetconfMessage> listener = getListener();
+
+        final MessageTransformer<NetconfMessage> messageTransformer = getMessageTransformer();
+        final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), messageTransformer, getSchemaContextProviderFactory(), getSourceProviderFactory());
+
+        device.onNotification(netconfMessage);
+        device.onNotification(netconfMessage);
+
+        verify(facade, times(0)).onNotification(any(CompositeNode.class));
+
+        final NetconfSessionCapabilities sessionCaps = getSessionCaps(true,
+                Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&amp;revision=" + TEST_REVISION));
+
+        device.onRemoteSessionUp(sessionCaps, listener);
+
+        verify(messageTransformer, timeout(10000).times(2)).toNotification(netconfMessage);
+        verify(facade, timeout(10000).times(2)).onNotification(compositeNode);
+
+        device.onNotification(netconfMessage);
+        verify(messageTransformer, timeout(10000).times(3)).toNotification(netconfMessage);
+        verify(facade, timeout(10000).times(3)).onNotification(compositeNode);
+    }
+
     @Test
     public void testNetconfDeviceReconnect() throws Exception {
         final RemoteDeviceHandler<NetconfSessionCapabilities> facade = getFacade();
@@ -137,6 +163,7 @@ public class NetconfDeviceTest {
         final RemoteDeviceHandler<NetconfSessionCapabilities> remoteDeviceHandler = mockCloseableClass(RemoteDeviceHandler.class);
         doNothing().when(remoteDeviceHandler).onDeviceConnected(any(SchemaContextProvider.class), any(NetconfSessionCapabilities.class), any(RpcImplementation.class));
         doNothing().when(remoteDeviceHandler).onDeviceDisconnected();
+        doNothing().when(remoteDeviceHandler).onNotification(any(CompositeNode.class));
         return remoteDeviceHandler;
     }
 
@@ -174,6 +201,7 @@ public class NetconfDeviceTest {
         final MessageTransformer<NetconfMessage> messageTransformer = mockClass(MessageTransformer.class);
         doReturn(netconfMessage).when(messageTransformer).toRpcRequest(any(QName.class), any(CompositeNode.class));
         doReturn(rpcResultC).when(messageTransformer).toRpcResult(any(NetconfMessage.class), any(QName.class));
+        doReturn(compositeNode).when(messageTransformer).toNotification(any(NetconfMessage.class));
         doNothing().when(messageTransformer).onGlobalContextUpdated(any(SchemaContext.class));
         return messageTransformer;
     }
@@ -198,4 +226,4 @@ public class NetconfDeviceTest {
         doReturn(Futures.immediateFuture(rpcResult)).when(remoteDeviceCommunicator).sendRequest(any(NetconfMessage.class), any(QName.class));
         return remoteDeviceCommunicator;
     }
-}
\ No newline at end of file
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToNotificationTest.java b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToNotificationTest.java
new file mode 100644 (file)
index 0000000..521a55d
--- /dev/null
@@ -0,0 +1,64 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.controller.sal.connect.netconf.schema.mapping.NetconfMessageTransformer;
+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.model.parser.api.YangContextParser;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.w3c.dom.Document;
+
+/**
+ * @author Lukas Sedlak <lsedlak@cisco.com>
+ */
+public class NetconfToNotificationTest {
+
+    NetconfMessageTransformer messageTransformer;
+
+    NetconfMessage userNotification;
+
+    @Before
+    public void setup() throws Exception {
+        final List<InputStream> modelsToParse = Collections.singletonList(getClass().getResourceAsStream("/schemas/user-notification.yang"));
+        final YangContextParser parser = new YangParserImpl();
+        final Set<Module> modules = parser.parseYangModelsFromStreams(modelsToParse);
+        assertTrue(!modules.isEmpty());
+        final SchemaContext schemaContext = parser.resolveSchemaContext(modules);
+        assertNotNull(schemaContext);
+
+        messageTransformer = new NetconfMessageTransformer();
+        messageTransformer.onGlobalContextUpdated(schemaContext);
+
+        final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        InputStream notifyPayloadStream = getClass().getResourceAsStream("/notification-payload.xml");
+        assertNotNull(notifyPayloadStream);
+
+        final Document doc = XmlUtil.readXmlToDocument(notifyPayloadStream);
+        assertNotNull(doc);
+        userNotification = new NetconfMessage(doc);
+    }
+
+    @Test
+    public void test() throws Exception {
+        final CompositeNode root = messageTransformer.toNotification(userNotification);
+
+        assertNotNull(root);
+        assertEquals(6, root.size());
+        assertEquals("user-visited-page", root.getKey().getLocalName());
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToRpcRequestTest.java b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToRpcRequestTest.java
new file mode 100644 (file)
index 0000000..18a3b9f
--- /dev/null
@@ -0,0 +1,81 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.sal.connect.netconf.schema.mapping.NetconfMessageTransformer;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+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 org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+/**
+ * Test case for reported bug 1355
+ *
+ * @author Lukas Sedlak
+ * @see <a
+ *      https://bugs.opendaylight.org/show_bug.cgi?id=1355</a>
+ */
+public class NetconfToRpcRequestTest {
+
+    private String TEST_MODEL_NAMESPACE = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:rpc-test";
+    private String REVISION = "2014-07-14";
+    private QName INPUT_QNAME = QName.create(TEST_MODEL_NAMESPACE, REVISION, "input");
+    private QName STREAM_NAME = QName.create(TEST_MODEL_NAMESPACE, REVISION, "stream-name");
+    private QName RPC_NAME = QName.create(TEST_MODEL_NAMESPACE, REVISION, "subscribe");
+
+    NetconfMessageTransformer messageTransformer;
+
+    @SuppressWarnings("deprecation")
+    @Before
+    public void setup() throws Exception {
+        final List<InputStream> modelsToParse = Collections
+            .singletonList(getClass().getResourceAsStream("/schemas/rpc-notification-subscription.yang"));
+        final YangContextParser parser = new YangParserImpl();
+        final Set<Module> modules = parser.parseYangModelsFromStreams(modelsToParse);
+        assertTrue(!modules.isEmpty());
+        final SchemaContext schemaContext = parser.resolveSchemaContext(modules);
+        assertNotNull(schemaContext);
+
+        messageTransformer = new NetconfMessageTransformer();
+        messageTransformer.onGlobalContextUpdated(schemaContext);
+    }
+
+    @Test
+    public void test() throws Exception {
+        final CompositeNodeBuilder<ImmutableCompositeNode> rootBuilder = ImmutableCompositeNode.builder();
+        rootBuilder.setQName(RPC_NAME);
+
+        final CompositeNodeBuilder<ImmutableCompositeNode> inputBuilder = ImmutableCompositeNode.builder();
+        inputBuilder.setQName(INPUT_QNAME);
+        inputBuilder.addLeaf(STREAM_NAME, "NETCONF");
+
+        rootBuilder.add(inputBuilder.toInstance());
+        final ImmutableCompositeNode root = rootBuilder.toInstance();
+
+        final CompositeNode flattenedNode = NetconfMessageTransformUtil.flattenInput(root);
+        assertNotNull(flattenedNode);
+        assertEquals(1, flattenedNode.size());
+
+        final List<CompositeNode> inputNode = flattenedNode.getCompositesByName(INPUT_QNAME);
+        assertNotNull(inputNode);
+        assertTrue(inputNode.isEmpty());
+
+        final NetconfMessage message = messageTransformer.toRpcRequest(RPC_NAME, root);
+        assertNotNull(message);
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/resources/notification-payload.xml b/opendaylight/md-sal/sal-netconf-connector/src/test/resources/notification-payload.xml
new file mode 100644 (file)
index 0000000..837fcc1
--- /dev/null
@@ -0,0 +1,14 @@
+<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
+<eventTime>2014-07-08T11:20:48UTC</eventTime>
+<user-visited-page xmlns="org:opendaylight:notification:test:ns:yang:user-notification">
+  <ui:incoming-user xmlns:ui="org:opendaylight:notification:test:ns:yang:user-notification">ui:public-user</ui:incoming-user>
+  <ip-address>172.23.29.104</ip-address>
+  <mac>00:11:00:ff:dd:02</mac>
+  <browser-id>Chrome 35.0.1916.153 m</browser-id>
+  <region>
+    <name>Slovakia</name>
+    <time-zone>UTC/GMT+2</time-zone>
+  </region>
+  <visiting-date>2014-07-08 11:20:48</visiting-date>
+</user-visited-page>
+</notification>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/resources/schemas/rpc-notification-subscription.yang b/opendaylight/md-sal/sal-netconf-connector/src/test/resources/schemas/rpc-notification-subscription.yang
new file mode 100644 (file)
index 0000000..b13d90f
--- /dev/null
@@ -0,0 +1,38 @@
+module rpc-notification-subscription {
+
+  namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:rpc-test";
+  prefix "rpc";
+
+  organization
+    "Cisco Systems, Inc.";
+
+  contact
+    "lsedlak@cisco.com";
+
+  description
+    "Test model for testing of rpc INPUT parameter during subscription call.";
+
+  revision 2014-07-14 {
+    description
+      "Initial revision.";
+  }
+
+  rpc subscribe {
+    description
+      "Test rpc to init subscription";
+
+    input {
+      leaf stream-name {
+        type string;
+        default "NETCONF";
+        description
+          "Optional stream name param.";
+      }
+
+      anyxml data {
+        description
+          "Optional additional data.";
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/resources/schemas/user-notification.yang b/opendaylight/md-sal/sal-netconf-connector/src/test/resources/schemas/user-notification.yang
new file mode 100644 (file)
index 0000000..50d2206
--- /dev/null
@@ -0,0 +1,56 @@
+module user-notification {
+    yang-version 1;
+    namespace "org:opendaylight:notification:test:ns:yang:user-notification";
+    prefix "user";
+
+    organization "Cisco Systems";
+    contact "Lukas Sedlak";
+    description "Test model for testing notifications";
+
+    revision "2014-07-08" {
+        description "Initial revision";
+    }
+
+    identity user-identity {
+        description "Identity of user incoming to Web Page";
+    }
+
+    identity public-user {
+        base user-identity;
+        description "Identity of random public non-registered user";
+    }
+
+    notification user-visited-page {
+        leaf incoming-user {
+            type identityref {
+                base "user-identity";
+            }
+        }
+
+        leaf ip-address {
+            type string;
+        }
+
+        leaf mac {
+            type string;
+        }
+
+        leaf browser-id {
+            type string;
+        }
+
+        container region {
+            leaf name {
+                type string;
+            }
+
+            leaf time-zone {
+                type string;
+            }
+        }
+
+        leaf visiting-date {
+            type string;
+        }
+    }
+}
\ No newline at end of file
index 778d8c6162c988bb282d5995e7d3e3ab5615ba43..d0be2cbcbb02cdc4310f130aa25c8e4f25fd386b 100644 (file)
@@ -20,4 +20,9 @@ machine
 
  protoc --proto_path=src/main/resources --java_out=src/main/java src/main/resources/*.proto
 
-5. Run mvn clean install and resolve any trailing spaces issues & build the .jar
+5. Run mvn clean install  & build the .jar
+
+6. !!!WARNING!!! - never edit the generated sources files of protocol buffer
+
+7. !!!NOTE!!! if you are planning to add new .proto file  option java_package should begin with
+   org.opendaylight.controller.protobuff.messages to properly exclude from sonar.
index 671a9441d8733f25449d6542687c529c38d49068..28e629a92c92fa7b165a390e12e2fd89a15e2ba5 100644 (file)
   <packaging>bundle</packaging>
 
   <dependencies>
+    <dependency>
+      <groupId>com.google.code.findbugs</groupId>
+      <artifactId>jsr305</artifactId>
+      <version>2.0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
     <dependency>
       <groupId>com.google.protobuf</groupId>
       <artifactId>protobuf-java</artifactId>
       <version>2.5.0</version>
     </dependency>
+    <dependency>
+      <groupId>commons-lang</groupId>
+      <artifactId>commons-lang</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>util</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-binding</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-data-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-data-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-model-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-model-util</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-parser-impl</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>xmlunit</groupId>
+      <artifactId>xmlunit</artifactId>
+      <version>1.5</version>
+    </dependency>
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <version>${slf4j.version}</version>
+      <scope>test</scope>
+    </dependency>
+      <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>util</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-common</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-data-api</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-data-impl</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-model-api</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-model-util</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-binding</artifactId>
+      </dependency>
+
+      <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>sal-akka-raft</artifactId>
+          <version>1.1-SNAPSHOT</version>
+      </dependency>
+
+      <dependency>
+          <groupId>com.google.guava</groupId>
+          <artifactId>guava</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>junit</groupId>
+          <artifactId>junit</artifactId>
+          <scope>test</scope>
+      </dependency>
+
+      <dependency>
+          <groupId>xmlunit</groupId>
+          <artifactId>xmlunit</artifactId>
+          <version>1.5</version>
+      </dependency>
+
+      <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-parser-impl</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>commons-lang</groupId>
+          <artifactId>commons-lang</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>org.slf4j</groupId>
+          <artifactId>slf4j-simple</artifactId>
+          <version>${slf4j.version}</version>
+          <scope>test</scope>
+      </dependency>
+      <dependency>
+          <groupId>com.google.code.findbugs</groupId>
+          <artifactId>jsr305</artifactId>
+          <version>2.0.1</version>
+      </dependency>
   </dependencies>
 
 </project>
index 72e2c87ecba11018079e9d2c95c844e0bdbfd188..f0907db6648e974298bb399f0956e719cd6e1552 100755 (executable)
 # or run command
 #       protoc --proto_path=src/main/resources --java_out=src/main/java src/main/resources/*.proto
 #
-#5. Run mvn clean install and resolve any trailing spaces issues & build the .jar
+#5. Run mvn clean install & build the .jar
+#
+#6  !!!WARNING!!!! never edit the source files generated
+#
+#7. !!!NOTE!!! if you are planning to add new .proto file  option java_package should begin with
+#   org.opendaylight.controller.protobuff.messages to properly exclude from sonar.
 ########################################################################################################
 
 protoc --proto_path=src/main/resources --java_out=src/main/java src/main/resources/*.proto
 
-echo "Done generating Java source files."
\ No newline at end of file
+echo "Done generating Java source files."
+
+#to remove trailing spaces in the code files
+find src/main/java -type f -name '*.java' -exec sed --in-place 's/[[:space:]]\+$//' {} \+
+
+#to remove trailing spaces in the generated code on OSX
+find src/main/java -type f -print0 |xargs -0 perl -pi -e 's/ +$//'
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NodeToNormalizedNodeBuilder.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NodeToNormalizedNodeBuilder.java
new file mode 100644 (file)
index 0000000..ce12080
--- /dev/null
@@ -0,0 +1,846 @@
+package org.opendaylight.controller.cluster.datastore.node;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.opendaylight.controller.cluster.datastore.node.utils.NodeIdentifierFactory;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+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.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * NormalizedNodeBuilder is a builder that walks through a tree like structure and constructs a
+ * NormalizedNode from it.
+ * <p/>
+ * A large part of this code has been copied over from a similar class in sal-common-impl which was
+ * originally supposed to convert a CompositeNode to NormalizedNode
+ *
+ * @param <T>
+ */
+public abstract class NodeToNormalizedNodeBuilder<T extends PathArgument>
+    implements Identifiable<T> {
+
+    private final T identifier;
+
+    protected static final Logger logger = LoggerFactory
+        .getLogger(NodeToNormalizedNodeBuilder.class);
+
+    @Override
+    public T getIdentifier() {
+        return identifier;
+    }
+
+    ;
+
+    protected NodeToNormalizedNodeBuilder(final T identifier) {
+        super();
+        this.identifier = identifier;
+
+    }
+
+    /**
+     * @return Should return true if the node that this operation corresponds to is a mixin
+     */
+    public boolean isMixin() {
+        return false;
+    }
+
+
+    /**
+     * @return Should return true if the node that this operation corresponds to has a 'key'
+     * associated with it. This is typically true for a list-item or leaf-list entry in yang
+     */
+    public boolean isKeyedEntry() {
+        return false;
+    }
+
+    protected Set<QName> getQNameIdentifiers() {
+        return Collections.singleton(identifier.getNodeType());
+    }
+
+    public abstract NodeToNormalizedNodeBuilder<?> getChild(
+        final PathArgument child);
+
+    public abstract NodeToNormalizedNodeBuilder<?> getChild(QName child);
+
+    public abstract NormalizedNode<?, ?> normalize(QName nodeType, Node node);
+
+
+
+    private static abstract class SimpleTypeNormalization<T extends PathArgument>
+        extends NodeToNormalizedNodeBuilder<T> {
+
+        protected SimpleTypeNormalization(final T identifier) {
+            super(identifier);
+        }
+
+        @Override
+        public NormalizedNode<?, ?> normalize(final QName nodeType,
+            final Node node) {
+            checkArgument(node != null);
+            return normalizeImpl(nodeType, node);
+        }
+
+        protected abstract NormalizedNode<?, ?> normalizeImpl(QName nodeType,
+            Node node);
+
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(
+            final PathArgument child) {
+            return null;
+        }
+
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
+            return null;
+        }
+
+        @Override
+        public NormalizedNode<?, ?> createDefault(
+            final PathArgument currentArg) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+    }
+
+
+    private static final class LeafNormalization extends
+        SimpleTypeNormalization<NodeIdentifier> {
+
+        private final LeafSchemaNode schema;
+
+        protected LeafNormalization(final LeafSchemaNode schema, final NodeIdentifier identifier) {
+            super(identifier);
+            this.schema = schema;
+        }
+
+        @Override
+        protected NormalizedNode<?, ?> normalizeImpl(final QName nodeType,
+            final Node node) {
+            Object value = NodeValueCodec.toTypeSafeValue(this.schema, this.schema.getType(), node);
+            return ImmutableNodes.leafNode(nodeType, value);
+
+        }
+
+    }
+
+
+    private static final class LeafListEntryNormalization extends
+        SimpleTypeNormalization<NodeWithValue> {
+
+        private final LeafListSchemaNode schema;
+
+        public LeafListEntryNormalization(final LeafListSchemaNode potential) {
+            super(new NodeWithValue(potential.getQName(), null));
+            this.schema = potential;
+        }
+
+        @Override
+        protected NormalizedNode<?, ?> normalizeImpl(final QName nodeType,
+            final Node node) {
+            final Object data = node.getValue();
+            if (data == null) {
+                Preconditions.checkArgument(false,
+                    "No data available in leaf list entry for " + nodeType);
+            }
+
+            Object value = NodeValueCodec.toTypeSafeValue(this.schema, this.schema.getType(), node);
+
+            NodeWithValue nodeId = new NodeWithValue(nodeType, value);
+            return Builders.leafSetEntryBuilder().withNodeIdentifier(nodeId)
+                .withValue(value).build();
+        }
+
+
+        @Override
+        public boolean isKeyedEntry() {
+            return true;
+        }
+    }
+
+
+    private static abstract class NodeToNormalizationNodeOperation<T extends PathArgument>
+        extends NodeToNormalizedNodeBuilder<T> {
+
+        protected NodeToNormalizationNodeOperation(final T identifier) {
+            super(identifier);
+        }
+
+        @SuppressWarnings({"rawtypes", "unchecked"})
+        @Override
+        public final NormalizedNodeContainer<?, ?, ?> normalize(
+            final QName nodeType, final Node node) {
+            checkArgument(node != null);
+
+            if (!node.getType().equals(AugmentationNode.class.getSimpleName())
+                && !node.getType().equals(ContainerNode.class.getSimpleName())
+                && !node.getType().equals(MapNode.class.getSimpleName())) {
+                checkArgument(nodeType != null);
+            }
+
+            NormalizedNodeContainerBuilder builder = createBuilder(node);
+
+            Set<NodeToNormalizedNodeBuilder<?>> usedMixins = new HashSet<>();
+
+            logNode(node);
+
+            if (node.getChildCount() == 0 && (
+                node.getType().equals(LeafSetEntryNode.class.getSimpleName())
+                    || node.getType().equals(LeafNode.class.getSimpleName()))) {
+                PathArgument childPathArgument =
+                    NodeIdentifierFactory.getArgument(node.getPath());
+
+                final NormalizedNode child;
+                if (childPathArgument instanceof NodeWithValue) {
+                    final NodeWithValue nodeWithValue =
+                        new NodeWithValue(childPathArgument.getNodeType(),
+                            node.getValue());
+                    child =
+                        Builders.leafSetEntryBuilder()
+                            .withNodeIdentifier(nodeWithValue)
+                            .withValue(node.getValue()).build();
+                } else {
+                    child =
+                        ImmutableNodes.leafNode(childPathArgument.getNodeType(),
+                            node.getValue());
+                }
+                builder.addChild(child);
+            }
+
+            final List<Node> children = node.getChildList();
+            for (Node nodeChild : children) {
+
+                PathArgument childPathArgument =
+                    NodeIdentifierFactory.getArgument(nodeChild.getPath());
+
+                QName childNodeType = null;
+                NodeToNormalizedNodeBuilder childOp = null;
+
+                if (childPathArgument instanceof AugmentationIdentifier) {
+                    childOp = getChild(childPathArgument);
+                    checkArgument(childOp instanceof AugmentationNormalization, childPathArgument);
+                } else {
+                    childNodeType = childPathArgument.getNodeType();
+                    childOp = getChild(childNodeType);
+                }
+                // We skip unknown nodes if this node is mixin since
+                // it's nodes and parent nodes are interleaved
+                if (childOp == null && isMixin()) {
+                    continue;
+                } else if (childOp == null) {
+                    logger.error(
+                        "childOp is null and this operation is not a mixin : this = {}",
+                        this.toString());
+                }
+
+                checkArgument(childOp != null,
+                    "Node %s is not allowed inside %s",
+                    childNodeType, getIdentifier());
+
+                if (childOp.isMixin()) {
+                    if (usedMixins.contains(childOp)) {
+                        // We already run / processed that mixin, so to avoid
+                        // duplicate we are
+                        // skipping next nodes.
+                        continue;
+                    }
+                    // builder.addChild(childOp.normalize(nodeType, treeCacheNode));
+                    final NormalizedNode childNode =
+                        childOp.normalize(childNodeType, nodeChild);
+                    if (childNode != null)
+                        builder.addChild(childNode);
+                    usedMixins.add(childOp);
+                } else {
+                    final NormalizedNode childNode =
+                        childOp.normalize(childNodeType, nodeChild);
+                    if (childNode != null)
+                        builder.addChild(childNode);
+                }
+            }
+
+
+            try {
+                return (NormalizedNodeContainer<?, ?, ?>) builder.build();
+            } catch (Exception e) {
+                return null;
+            }
+
+        }
+
+        private void logNode(Node node) {
+            //let us find out the type of the node
+            logger.debug("We got a {} , with identifier {} with {} children",
+                node.getType(), node.getPath(),
+                node.getChildList());
+        }
+
+        @SuppressWarnings("rawtypes")
+        protected abstract NormalizedNodeContainerBuilder createBuilder(
+            final Node node);
+
+    }
+
+
+    private static abstract class DataContainerNormalizationOperation<T extends PathArgument>
+        extends NodeToNormalizationNodeOperation<T> {
+
+        private final DataNodeContainer schema;
+        private final Map<QName, NodeToNormalizedNodeBuilder<?>> byQName;
+        private final Map<PathArgument, NodeToNormalizedNodeBuilder<?>> byArg;
+
+        protected DataContainerNormalizationOperation(final T identifier,
+            final DataNodeContainer schema) {
+            super(identifier);
+            this.schema = schema;
+            this.byArg = new ConcurrentHashMap<>();
+            this.byQName = new ConcurrentHashMap<>();
+        }
+
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(
+            final PathArgument child) {
+            NodeToNormalizedNodeBuilder<?> potential = byArg.get(child);
+            if (potential != null) {
+                return potential;
+            }
+            potential = fromSchema(schema, child);
+            return register(potential);
+        }
+
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
+            if (child == null) {
+                return null;
+            }
+
+            NodeToNormalizedNodeBuilder<?> potential = byQName.get(child);
+            if (potential != null) {
+                return potential;
+            }
+            potential = fromSchemaAndPathArgument(schema, child);
+            return register(potential);
+        }
+
+        private NodeToNormalizedNodeBuilder<?> register(
+            final NodeToNormalizedNodeBuilder<?> potential) {
+            if (potential != null) {
+                byArg.put(potential.getIdentifier(), potential);
+                for (QName qName : potential.getQNameIdentifiers()) {
+                    byQName.put(qName, potential);
+                }
+            }
+            return potential;
+        }
+
+    }
+
+
+    private static final class ListItemNormalization extends
+        DataContainerNormalizationOperation<NodeIdentifierWithPredicates> {
+
+        private final List<QName> keyDefinition;
+        private final ListSchemaNode schemaNode;
+
+        protected ListItemNormalization(
+            final NodeIdentifierWithPredicates identifier,
+            final ListSchemaNode schema) {
+            super(identifier, schema);
+            this.schemaNode = schema;
+            keyDefinition = schema.getKeyDefinition();
+        }
+
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(
+            final Node node) {
+            NodeIdentifierWithPredicates nodeIdentifierWithPredicates =
+                (NodeIdentifierWithPredicates) NodeIdentifierFactory
+                    .createPathArgument(node
+                        .getPath(), schemaNode);
+            return Builders.mapEntryBuilder()
+                .withNodeIdentifier(
+                    nodeIdentifierWithPredicates
+            );
+        }
+
+        @Override
+        public NormalizedNode<?, ?> createDefault(
+            final PathArgument currentArg) {
+            DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode>
+                builder =
+                Builders.mapEntryBuilder().withNodeIdentifier(
+                    (NodeIdentifierWithPredicates) currentArg);
+            for (Entry<QName, Object> keyValue : ((NodeIdentifierWithPredicates) currentArg)
+                .getKeyValues().entrySet()) {
+                if (keyValue.getValue() == null) {
+                    throw new NullPointerException(
+                        "Null value found for path : "
+                            + currentArg);
+                }
+                builder.addChild(Builders.leafBuilder()
+                    //
+                    .withNodeIdentifier(new NodeIdentifier(keyValue.getKey()))
+                    .withValue(keyValue.getValue()).build());
+            }
+            return builder.build();
+        }
+
+
+        @Override
+        public boolean isKeyedEntry() {
+            return true;
+        }
+    }
+
+
+    private static final class ContainerNormalization extends
+        DataContainerNormalizationOperation<NodeIdentifier> {
+
+        protected ContainerNormalization(final ContainerSchemaNode schema) {
+            super(new NodeIdentifier(schema.getQName()), schema);
+        }
+
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(
+            final Node node) {
+            return Builders.containerBuilder()
+                .withNodeIdentifier(getIdentifier());
+        }
+
+        @Override
+        public NormalizedNode<?, ?> createDefault(
+            final PathArgument currentArg) {
+            return Builders.containerBuilder()
+                .withNodeIdentifier((NodeIdentifier) currentArg).build();
+        }
+
+    }
+
+
+    private static abstract class MixinNormalizationOp<T extends PathArgument>
+        extends NodeToNormalizationNodeOperation<T> {
+
+        protected MixinNormalizationOp(final T identifier) {
+            super(identifier);
+        }
+
+        @Override
+        public final boolean isMixin() {
+            return true;
+        }
+
+    }
+
+
+    private static final class LeafListMixinNormalization extends
+        MixinNormalizationOp<NodeIdentifier> {
+
+        private final NodeToNormalizedNodeBuilder<?> innerOp;
+
+        public LeafListMixinNormalization(final LeafListSchemaNode potential) {
+            super(new NodeIdentifier(potential.getQName()));
+            innerOp = new LeafListEntryNormalization(potential);
+        }
+
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(
+            final Node node) {
+            return Builders.leafSetBuilder()
+                .withNodeIdentifier(getIdentifier());
+        }
+
+        @Override
+        public NormalizedNode<?, ?> createDefault(
+            final PathArgument currentArg) {
+            return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier())
+                .build();
+        }
+
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(
+            final PathArgument child) {
+            if (child instanceof NodeWithValue) {
+                return innerOp;
+            }
+            return null;
+        }
+
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
+            if (getIdentifier().getNodeType().equals(child)) {
+                return innerOp;
+            }
+            return null;
+        }
+
+    }
+
+
+    private static final class AugmentationNormalization extends
+        MixinNormalizationOp<AugmentationIdentifier> {
+
+        private final Map<QName, NodeToNormalizedNodeBuilder<?>> byQName;
+        private final Map<PathArgument, NodeToNormalizedNodeBuilder<?>> byArg;
+
+        public AugmentationNormalization(final AugmentationSchema augmentation,
+            final DataNodeContainer schema) {
+            super(augmentationIdentifierFrom(augmentation));
+
+            ImmutableMap.Builder<QName, NodeToNormalizedNodeBuilder<?>>
+                byQNameBuilder =
+                ImmutableMap.builder();
+            ImmutableMap.Builder<PathArgument, NodeToNormalizedNodeBuilder<?>>
+                byArgBuilder =
+                ImmutableMap.builder();
+
+            for (DataSchemaNode augNode : augmentation.getChildNodes()) {
+                DataSchemaNode resolvedNode =
+                    schema.getDataChildByName(augNode.getQName());
+                NodeToNormalizedNodeBuilder<?> resolvedOp =
+                    fromDataSchemaNode(resolvedNode);
+                byArgBuilder.put(resolvedOp.getIdentifier(), resolvedOp);
+                for (QName resQName : resolvedOp.getQNameIdentifiers()) {
+                    byQNameBuilder.put(resQName, resolvedOp);
+                }
+            }
+            byQName = byQNameBuilder.build();
+            byArg = byArgBuilder.build();
+
+        }
+
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(
+            final PathArgument child) {
+            return byArg.get(child);
+        }
+
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
+            return byQName.get(child);
+        }
+
+        @Override
+        protected Set<QName> getQNameIdentifiers() {
+            return getIdentifier().getPossibleChildNames();
+        }
+
+        @SuppressWarnings("rawtypes")
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(
+            final Node node) {
+            return Builders.augmentationBuilder()
+                .withNodeIdentifier(getIdentifier());
+        }
+
+        @Override
+        public NormalizedNode<?, ?> createDefault(
+            final PathArgument currentArg) {
+            return Builders.augmentationBuilder()
+                .withNodeIdentifier(getIdentifier())
+                .build();
+        }
+
+    }
+
+
+    private static final class ListMixinNormalization extends
+        MixinNormalizationOp<NodeIdentifier> {
+
+        private final ListItemNormalization innerNode;
+
+        public ListMixinNormalization(final ListSchemaNode list) {
+            super(new NodeIdentifier(list.getQName()));
+            this.innerNode =
+                new ListItemNormalization(new NodeIdentifierWithPredicates(
+                    list.getQName(), Collections.<QName, Object>emptyMap()),
+                    list);
+        }
+
+        @SuppressWarnings("rawtypes")
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(
+            final Node node) {
+            return Builders.mapBuilder().withNodeIdentifier(getIdentifier());
+        }
+
+        @Override
+        public NormalizedNode<?, ?> createDefault(
+            final PathArgument currentArg) {
+            return Builders.mapBuilder().withNodeIdentifier(getIdentifier())
+                .build();
+        }
+
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(
+            final PathArgument child) {
+            if (child.getNodeType().equals(getIdentifier().getNodeType())) {
+                return innerNode;
+            }
+            return null;
+        }
+
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
+            if (getIdentifier().getNodeType().equals(child)) {
+                return innerNode;
+            }
+            return null;
+        }
+
+    }
+
+
+    private static class ChoiceNodeNormalization extends
+        MixinNormalizationOp<NodeIdentifier> {
+
+        private final ImmutableMap<QName, NodeToNormalizedNodeBuilder<?>>
+            byQName;
+        private final ImmutableMap<PathArgument, NodeToNormalizedNodeBuilder<?>>
+            byArg;
+
+        protected ChoiceNodeNormalization(
+            final org.opendaylight.yangtools.yang.model.api.ChoiceNode schema) {
+            super(new NodeIdentifier(schema.getQName()));
+            ImmutableMap.Builder<QName, NodeToNormalizedNodeBuilder<?>>
+                byQNameBuilder =
+                ImmutableMap.builder();
+            ImmutableMap.Builder<PathArgument, NodeToNormalizedNodeBuilder<?>>
+                byArgBuilder =
+                ImmutableMap.builder();
+
+            for (ChoiceCaseNode caze : schema.getCases()) {
+                for (DataSchemaNode cazeChild : caze.getChildNodes()) {
+                    NodeToNormalizedNodeBuilder<?> childOp =
+                        fromDataSchemaNode(cazeChild);
+                    byArgBuilder.put(childOp.getIdentifier(), childOp);
+                    for (QName qname : childOp.getQNameIdentifiers()) {
+                        byQNameBuilder.put(qname, childOp);
+                    }
+                }
+            }
+            byQName = byQNameBuilder.build();
+            byArg = byArgBuilder.build();
+        }
+
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(
+            final PathArgument child) {
+            return byArg.get(child);
+        }
+
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
+            return byQName.get(child);
+        }
+
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(
+            final Node node) {
+            return Builders.choiceBuilder().withNodeIdentifier(getIdentifier());
+        }
+
+        @Override
+        public NormalizedNode<?, ?> createDefault(
+            final PathArgument currentArg) {
+            return Builders.choiceBuilder().withNodeIdentifier(getIdentifier())
+                .build();
+        }
+    }
+
+    /**
+     * Find an appropriate NormalizedNodeBuilder using both the schema and the
+     * Path Argument
+     *
+     * @param schema
+     * @param child
+     * @return
+     */
+    public static NodeToNormalizedNodeBuilder<?> fromSchemaAndPathArgument(
+        final DataNodeContainer schema, final QName child) {
+        DataSchemaNode potential = schema.getDataChildByName(child);
+        if (potential == null) {
+            Iterable<org.opendaylight.yangtools.yang.model.api.ChoiceNode>
+                choices =
+                FluentIterable.from(schema.getChildNodes()).filter(
+                    org.opendaylight.yangtools.yang.model.api.ChoiceNode.class);
+            potential = findChoice(choices, child);
+        }
+        if (potential == null) {
+            if (logger.isTraceEnabled()) {
+                logger.trace("BAD CHILD = {}", child.toString());
+            }
+        }
+
+        checkArgument(potential != null,
+            "Supplied QName %s is not valid according to schema %s", child,
+            schema);
+
+        // If the schema in an instance of DataSchemaNode and the potential
+        // is augmenting something then there is a chance that this may be
+        // and augmentation node
+        if ((schema instanceof DataSchemaNode)
+            && potential.isAugmenting()) {
+
+            AugmentationNormalization augmentation =
+                fromAugmentation(schema, (AugmentationTarget) schema,
+                    potential);
+
+            // If an augmentation normalization (builder) is not found then
+            // we fall through to the regular processing
+            if(augmentation != null){
+                return augmentation;
+            }
+        }
+        return fromDataSchemaNode(potential);
+    }
+
+    /**
+     * Given a bunch of choice nodes and a the name of child find a choice node for that child which
+     * has a non-null value
+     *
+     * @param choices
+     * @param child
+     * @return
+     */
+    private static org.opendaylight.yangtools.yang.model.api.ChoiceNode findChoice(
+        final Iterable<org.opendaylight.yangtools.yang.model.api.ChoiceNode> choices,
+        final QName child) {
+        org.opendaylight.yangtools.yang.model.api.ChoiceNode foundChoice = null;
+        choiceLoop:
+        for (org.opendaylight.yangtools.yang.model.api.ChoiceNode choice : choices) {
+            for (ChoiceCaseNode caze : choice.getCases()) {
+                if (caze.getDataChildByName(child) != null) {
+                    foundChoice = choice;
+                    break choiceLoop;
+                }
+            }
+        }
+        return foundChoice;
+    }
+
+
+    /**
+     * Create an AugmentationIdentifier based on the AugmentationSchema
+     *
+     * @param augmentation
+     * @return
+     */
+    public static AugmentationIdentifier augmentationIdentifierFrom(
+        final AugmentationSchema augmentation) {
+        ImmutableSet.Builder<QName> potentialChildren = ImmutableSet.builder();
+        for (DataSchemaNode child : augmentation.getChildNodes()) {
+            potentialChildren.add(child.getQName());
+        }
+        return new AugmentationIdentifier(potentialChildren.build());
+    }
+
+    /**
+     * Create an AugmentationNormalization based on the schema of the DataContainer, the
+     * AugmentationTarget and the potential schema node
+     *
+     * @param schema
+     * @param augments
+     * @param potential
+     * @return
+     */
+    private static AugmentationNormalization fromAugmentation(
+        final DataNodeContainer schema, final AugmentationTarget augments,
+        final DataSchemaNode potential) {
+        AugmentationSchema augmentation = null;
+        for (AugmentationSchema aug : augments.getAvailableAugmentations()) {
+            DataSchemaNode child = aug.getDataChildByName(potential.getQName());
+            if (child != null) {
+                augmentation = aug;
+                break;
+            }
+
+        }
+        if (augmentation != null) {
+            return new AugmentationNormalization(augmentation, schema);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @param schema
+     * @param child
+     * @return
+     */
+    private static NodeToNormalizedNodeBuilder<?> fromSchema(
+        final DataNodeContainer schema, final PathArgument child) {
+        if (child instanceof AugmentationIdentifier) {
+            QName childQName = ((AugmentationIdentifier) child)
+                .getPossibleChildNames().iterator().next();
+
+            return fromSchemaAndPathArgument(schema, childQName);
+        }
+        return fromSchemaAndPathArgument(schema, child.getNodeType());
+    }
+
+    public static NodeToNormalizedNodeBuilder<?> fromDataSchemaNode(
+        final DataSchemaNode potential) {
+        if (potential instanceof ContainerSchemaNode) {
+            return new ContainerNormalization((ContainerSchemaNode) potential);
+        } else if (potential instanceof ListSchemaNode) {
+            return new ListMixinNormalization((ListSchemaNode) potential);
+        } else if (potential instanceof LeafSchemaNode) {
+            return new LeafNormalization((LeafSchemaNode) potential,
+                new NodeIdentifier(potential.getQName()));
+        } else if (potential instanceof org.opendaylight.yangtools.yang.model.api.ChoiceNode) {
+            return new ChoiceNodeNormalization(
+                (org.opendaylight.yangtools.yang.model.api.ChoiceNode) potential);
+        } else if (potential instanceof LeafListSchemaNode) {
+            return new LeafListMixinNormalization(
+                (LeafListSchemaNode) potential);
+        }
+        return null;
+    }
+
+    public static NodeToNormalizedNodeBuilder<?> from(final SchemaContext ctx) {
+        return new ContainerNormalization(ctx);
+    }
+
+    public abstract NormalizedNode<?, ?> createDefault(PathArgument currentArg);
+
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NodeValueCodec.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NodeValueCodec.java
new file mode 100644 (file)
index 0000000..7b6f5c4
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.node;
+
+import org.opendaylight.controller.cluster.datastore.node.utils.QNameFactory;
+import org.opendaylight.controller.cluster.datastore.util.InstanceIdentifierUtils;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.yangtools.yang.data.api.codec.BitsCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.IdentityrefType;
+import org.opendaylight.yangtools.yang.model.util.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.util.Leafref;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NodeValueCodec {
+    protected static final Logger logger = LoggerFactory
+        .getLogger(NodeValueCodec.class);
+
+    public static Object toTypeSafeValue(DataSchemaNode schema, TypeDefinition type, NormalizedNodeMessages.Node node){
+
+        String value = node.getValue();
+
+        if(schema != null && value != null){
+            TypeDefinition<?> baseType = type;
+
+            while (baseType.getBaseType() != null) {
+                baseType = baseType.getBaseType();
+            }
+
+            TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> codec =
+                TypeDefinitionAwareCodec.from(type);
+
+            if(codec instanceof BitsCodec){
+                if(value.contains("[]")){
+                    value = "";
+                } else {
+                    value = value.replace("[", "");
+                    value = value.replace("]", "");
+                    value = value.replace(",", " ");
+                }
+            }
+
+            if (codec != null) {
+                return codec.deserialize(value);
+            } else if(baseType instanceof Leafref) {
+                return value;
+            } else if(baseType instanceof IdentityrefType) {
+                return QNameFactory.create(value);
+            } else if(baseType instanceof InstanceIdentifier) {
+                return InstanceIdentifierUtils.fromSerializable(node.getInstanceIdentifierValue());
+            } else {
+                logger.error("Could not figure out how to transform value " + value +  " for schemaType " + type);
+            }
+        }
+
+        return value;
+    }
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NormalizedNodeToNodeCodec.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NormalizedNodeToNodeCodec.java
new file mode 100644 (file)
index 0000000..fc4b395
--- /dev/null
@@ -0,0 +1,64 @@
+package org.opendaylight.controller.cluster.datastore.node;
+
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.controller.cluster.datastore.node.utils.PathUtils;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NormalizedNodeToNodeCodec {
+    private final SchemaContext ctx;
+    private static final Logger logger = LoggerFactory.getLogger(NormalizedNodeToNodeCodec.class);
+
+    public NormalizedNodeToNodeCodec(final SchemaContext ctx){
+        this.ctx = ctx;
+
+    }
+
+    public NormalizedNodeMessages.Container encode(YangInstanceIdentifier id, NormalizedNode node){
+        String parentPath = "";
+
+        if(id != null){
+            parentPath = PathUtils.getParentPath(id.toString());
+        }
+
+
+        NormalizedNodeToProtocolBufferNode encoder = new NormalizedNodeToProtocolBufferNode();
+        encoder.encode(parentPath, node);
+
+        return encoder.getContainer();
+
+
+    }
+
+    public NormalizedNode<?,?> decode(YangInstanceIdentifier id, NormalizedNodeMessages.Node node){
+            NodeToNormalizedNodeBuilder currentOp = NodeToNormalizedNodeBuilder.from(ctx);
+
+            for(YangInstanceIdentifier.PathArgument pathArgument : id.getPathArguments()){
+                currentOp = currentOp.getChild(pathArgument);
+            }
+
+            QName nodeType = null;
+
+            if(id.getPath().size() < 1){
+                nodeType = null;
+            } else {
+                final YangInstanceIdentifier.PathArgument pathArgument = id.getPath().get(id.getPath().size() - 1);
+                if(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier){
+                    nodeType = null;
+                } else {
+                    nodeType = pathArgument.getNodeType();
+                }
+            }
+            if((node != null)&& (!node.getType().isEmpty())){
+               return currentOp.normalize(nodeType, node);
+            } else{
+              return null;
+            }
+    }
+
+
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NormalizedNodeToProtocolBufferNode.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NormalizedNodeToProtocolBufferNode.java
new file mode 100644 (file)
index 0000000..fb15312
--- /dev/null
@@ -0,0 +1,254 @@
+package org.opendaylight.controller.cluster.datastore.node;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.cluster.datastore.util.InstanceIdentifierUtils;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MixinNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+
+import java.util.Map;
+
+/**
+ * NormalizedNodeToProtocolBufferNode walks the NormalizedNode tree converting it to the
+ * NormalizedMessage.Node
+ * <p/>
+ * {@link org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode } is a tree like structure that provides a generic structure for a yang data
+ * model
+ */
+public class NormalizedNodeToProtocolBufferNode {
+
+
+    private final Node.Builder builderRoot;
+    private NormalizedNodeMessages.Container container;
+
+    public NormalizedNodeToProtocolBufferNode() {
+
+        builderRoot = Node.newBuilder();
+    }
+
+    public void encode(String parentPath, NormalizedNode<?, ?> normalizedNode) {
+        if (parentPath == null) {
+            parentPath = "";
+        }
+
+        NormalizedNodeMessages.Container.Builder containerBuilder =
+            NormalizedNodeMessages.Container.newBuilder();
+
+        if (normalizedNode != null) {
+
+            navigateNormalizedNode(0, parentPath, normalizedNode, builderRoot);
+            // here we need to put back the Node Tree in Container
+
+            container =
+                containerBuilder.setParentPath(parentPath).setNormalizedNode(
+                    builderRoot.build()).build();
+        } else {
+            //this can happen when an attempt was made to read from datastore and normalized node was null.
+            container = containerBuilder.setParentPath(parentPath).build();
+
+        }
+
+    }
+
+
+    private void navigateDataContainerNode(int level, final String parentPath,
+        final DataContainerNode<?> dataContainerNode,
+        Node.Builder builderParent) {
+
+        String newParentPath =
+            parentPath + "/" + dataContainerNode.getIdentifier().toString();
+        String type = getDataContainerType(dataContainerNode).getSimpleName();
+        builderParent.setPath(dataContainerNode.getIdentifier().toString())
+            .setType(type);
+
+        final Iterable<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>>
+            value =
+            dataContainerNode.getValue();
+        for (NormalizedNode<?, ?> node : value) {
+            Node.Builder builderChild = Node.newBuilder();
+            if (node instanceof MixinNode
+                && node instanceof NormalizedNodeContainer) {
+
+                navigateNormalizedNodeContainerMixin(level, newParentPath,
+                    (NormalizedNodeContainer<?, ?, ?>) node, builderChild);
+            } else {
+                navigateNormalizedNode(level, newParentPath, node,
+                    builderChild);
+            }
+            builderParent.addChild(builderChild);
+        }
+    }
+
+    private Class getDataContainerType(
+        NormalizedNodeContainer<?, ?, ?> dataContainerNode) {
+        if (dataContainerNode instanceof ChoiceNode) {
+            return ChoiceNode.class;
+        } else if (dataContainerNode instanceof AugmentationNode) {
+            return AugmentationNode.class;
+        } else if (dataContainerNode instanceof ContainerNode) {
+            return ContainerNode.class;
+        } else if (dataContainerNode instanceof MapEntryNode) {
+            return MapEntryNode.class;
+        } else if (dataContainerNode instanceof UnkeyedListEntryNode) {
+            return UnkeyedListEntryNode.class;
+        } else if (dataContainerNode instanceof MapNode) {
+            return MapNode.class;
+        } else if (dataContainerNode instanceof LeafSetNode) {
+            return LeafSetNode.class;
+        }
+        throw new IllegalArgumentException(
+            "could not find the data container node type "
+                + dataContainerNode.toString()
+        );
+    }
+
+    private void navigateNormalizedNodeContainerMixin(int level,
+        final String parentPath,
+        NormalizedNodeContainer<?, ?, ?> node, Node.Builder builderParent) {
+        String newParentPath =
+            parentPath + "/" + node.getIdentifier().toString();
+
+        builderParent.setPath(node.getIdentifier().toString()).setType(
+            this.getDataContainerType(node).getSimpleName());
+        final Iterable<? extends NormalizedNode<?, ?>> value = node.getValue();
+        for (NormalizedNode normalizedNode : value) {
+            // child node builder
+            Node.Builder builderChild = Node.newBuilder();
+            if (normalizedNode instanceof MixinNode
+                && normalizedNode instanceof NormalizedNodeContainer) {
+                navigateNormalizedNodeContainerMixin(level + 1, newParentPath,
+                    (NormalizedNodeContainer) normalizedNode, builderChild);
+            } else {
+                navigateNormalizedNode(level, newParentPath, normalizedNode,
+                    builderChild);
+            }
+            builderParent.addChild(builderChild);
+
+        }
+
+
+
+    }
+
+
+    private void navigateNormalizedNode(int level,
+        String parentPath, NormalizedNode<?, ?> normalizedNode,
+        Node.Builder builderParent) {
+
+        if (normalizedNode instanceof DataContainerNode) {
+
+            final DataContainerNode<?> dataContainerNode =
+                (DataContainerNode) normalizedNode;
+
+            navigateDataContainerNode(level + 1, parentPath, dataContainerNode,
+                builderParent);
+        } else if (normalizedNode instanceof MixinNode
+            && normalizedNode instanceof NormalizedNodeContainer) {
+
+            navigateNormalizedNodeContainerMixin(level, parentPath,
+                (NormalizedNodeContainer<?, ?, ?>) normalizedNode,
+                builderParent);
+        } else {
+            if (normalizedNode instanceof LeafNode) {
+                buildLeafNode(parentPath, normalizedNode, builderParent);
+            } else if (normalizedNode instanceof LeafSetEntryNode) {
+                buildLeafSetEntryNode(parentPath, normalizedNode,
+                    builderParent);
+            }
+
+        }
+
+    }
+
+    private void buildLeafSetEntryNode(String parentPath,
+        NormalizedNode<?, ?> normalizedNode,
+        Node.Builder builderParent) {
+        String path =
+            parentPath + "/" + normalizedNode.getIdentifier().toString();
+        LeafSetEntryNode leafSetEntryNode = (LeafSetEntryNode) normalizedNode;
+        Map<QName, String> attributes = leafSetEntryNode.getAttributes();
+        if (!attributes.isEmpty()) {
+            NormalizedNodeMessages.Attribute.Builder builder = null;
+            for (Map.Entry<QName, String> attribute : attributes.entrySet()) {
+                builder = NormalizedNodeMessages.Attribute.newBuilder();
+
+                builder
+                    .setName(attribute.getKey().toString())
+                    .setValue(normalizedNode.getValue().toString());
+
+                builderParent.addAttributes(builder.build());
+            }
+        }
+        buildNodeValue(normalizedNode, builderParent);
+    }
+
+    private void buildLeafNode(String parentPath,
+        NormalizedNode<?, ?> normalizedNode,
+        Node.Builder builderParent) {
+        Preconditions.checkNotNull(parentPath);
+        Preconditions.checkNotNull(normalizedNode);
+        String path =
+            parentPath + "/" + normalizedNode.getIdentifier().toString();
+        LeafNode leafNode = (LeafNode) normalizedNode;
+        Map<QName, String> attributes = leafNode.getAttributes();
+        if (!attributes.isEmpty()) {
+            NormalizedNodeMessages.Attribute.Builder builder = null;
+            for (Map.Entry<QName, String> attribute : attributes.entrySet()) {
+                builder = NormalizedNodeMessages.Attribute.newBuilder();
+                builder
+                    .setName(attribute.getKey().toString())
+                    .setValue(attribute.getValue().toString());
+
+                builderParent.addAttributes(builder.build());
+            }
+        }
+
+        Object value = normalizedNode.getValue();
+        if (value == null) {
+            builderParent
+                .setPath(normalizedNode.getIdentifier().toString())
+                .setType(LeafNode.class.getSimpleName())
+                .setValueType(String.class.getSimpleName())
+                .setValue("");
+        } else {
+            buildNodeValue(normalizedNode, builderParent);
+        }
+    }
+
+    private void buildNodeValue(NormalizedNode<?, ?> normalizedNode,
+        Node.Builder builderParent) {
+
+        Object value = normalizedNode.getValue();
+
+        builderParent
+            .setPath(normalizedNode.getIdentifier().toString())
+            .setType(LeafNode.class.getSimpleName())
+            .setValueType((value.getClass().getSimpleName()))
+            .setValue(value.toString());
+
+        if(value.getClass().equals(YangInstanceIdentifier.class)){
+            builderParent.setInstanceIdentifierValue(
+                InstanceIdentifierUtils
+                    .toSerializable((YangInstanceIdentifier) value));
+        }
+    }
+
+    public NormalizedNodeMessages.Container getContainer() {
+        return container;
+    }
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/AugmentationIdentifierGenerator.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/AugmentationIdentifierGenerator.java
new file mode 100644 (file)
index 0000000..a34307f
--- /dev/null
@@ -0,0 +1,42 @@
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class AugmentationIdentifierGenerator {
+    private final String id;
+    private static final Pattern pattern = Pattern.compile("AugmentationIdentifier\\Q{\\EchildNames=\\Q[\\E(.*)\\Q]}\\E");
+    private final Matcher matcher;
+    private final boolean doesMatch;
+
+    public AugmentationIdentifierGenerator(String id){
+        this.id = id;
+        matcher = pattern.matcher(this.id);
+        doesMatch = matcher.matches();
+    }
+
+    public boolean matches(){
+        return doesMatch;
+    }
+
+    public YangInstanceIdentifier.AugmentationIdentifier getPathArgument(){
+        Set<QName> childNames = new HashSet<QName>();
+        final String childQNames = matcher.group(1);
+
+        final String[] splitChildQNames = childQNames.split(",");
+
+        for(String name : splitChildQNames){
+            childNames.add(
+                org.opendaylight.controller.cluster.datastore.node.utils.QNameFactory
+                    .create(name.trim()));
+        }
+
+        return new YangInstanceIdentifier.AugmentationIdentifier(null, childNames);
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierFactory.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierFactory.java
new file mode 100644 (file)
index 0000000..175e242
--- /dev/null
@@ -0,0 +1,59 @@
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class NodeIdentifierFactory {
+    private static final Map<String, YangInstanceIdentifier.PathArgument> cache = new HashMap<>();
+    public static YangInstanceIdentifier.PathArgument getArgument(String id){
+        YangInstanceIdentifier.PathArgument value = cache.get(id);
+        if(value == null){
+            synchronized (cache){
+                value = cache.get(id);
+                if(value == null) {
+                    value = createPathArgument(id, null);
+                    cache.put(id, value);
+                }
+            }
+        }
+        return value;
+    }
+
+    public static YangInstanceIdentifier.PathArgument getArgument(String id, DataSchemaNode schemaNode){
+        YangInstanceIdentifier.PathArgument value = cache.get(id);
+        if(value == null){
+            synchronized (cache){
+                value = cache.get(id);
+                if(value == null) {
+                    value = createPathArgument(id, schemaNode);
+                    cache.put(id, value);
+                }
+            }
+        }
+        return value;
+    }
+
+    public static YangInstanceIdentifier.PathArgument createPathArgument(String id, DataSchemaNode schemaNode){
+        final NodeIdentifierWithPredicatesGenerator
+            nodeIdentifierWithPredicatesGenerator = new NodeIdentifierWithPredicatesGenerator(id, schemaNode);
+        if(nodeIdentifierWithPredicatesGenerator.matches()){
+            return nodeIdentifierWithPredicatesGenerator.getPathArgument();
+        }
+
+        final NodeIdentifierWithValueGenerator
+            nodeWithValueGenerator = new NodeIdentifierWithValueGenerator(id, schemaNode);
+        if(nodeWithValueGenerator.matches()){
+            return nodeWithValueGenerator.getPathArgument();
+        }
+
+        final AugmentationIdentifierGenerator augmentationIdentifierGenerator = new AugmentationIdentifierGenerator(id);
+        if(augmentationIdentifierGenerator.matches()){
+            return augmentationIdentifierGenerator.getPathArgument();
+        }
+
+        return new NodeIdentifierGenerator(id).getArgument();
+    }
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierGenerator.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierGenerator.java
new file mode 100644 (file)
index 0000000..9edec1e
--- /dev/null
@@ -0,0 +1,18 @@
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public class NodeIdentifierGenerator {
+    private final String id;
+    private final QName qName;
+
+    public NodeIdentifierGenerator(String id){
+        this.id = id;
+        this.qName = QNameFactory.create(id);
+    }
+
+    public YangInstanceIdentifier.PathArgument getArgument(){
+        return new YangInstanceIdentifier.NodeIdentifier(qName);
+    }
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierWithPredicatesGenerator.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierWithPredicatesGenerator.java
new file mode 100644 (file)
index 0000000..4bfcf39
--- /dev/null
@@ -0,0 +1,70 @@
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class NodeIdentifierWithPredicatesGenerator{
+    private final String id;
+    private static final Pattern pattern = Pattern.compile("(.*)\\Q[{\\E(.*)\\Q}]\\E");
+    private final Matcher matcher;
+    private final boolean doesMatch;
+    private final ListSchemaNode listSchemaNode;
+
+    public NodeIdentifierWithPredicatesGenerator(String id, DataSchemaNode schemaNode){
+        this.id = id;
+        matcher = pattern.matcher(this.id);
+        doesMatch = matcher.matches();
+
+        if(schemaNode instanceof  ListSchemaNode){
+            this.listSchemaNode = (ListSchemaNode) schemaNode;
+        } else {
+            this.listSchemaNode = null;
+        }
+    }
+
+
+    public boolean matches(){
+        return doesMatch;
+    }
+
+    public YangInstanceIdentifier.NodeIdentifierWithPredicates getPathArgument(){
+        final String group = matcher.group(2);
+        final String[] keyValues = group.split(",");
+        Map<QName, Object> nameValues = new HashMap<>();
+
+        for(String keyValue : keyValues){
+            int eqIndex = keyValue.lastIndexOf('=');
+            try {
+                final QName key = QNameFactory
+                    .create(keyValue.substring(0, eqIndex));
+                nameValues.put(key, getValue(key, keyValue.substring(eqIndex + 1)));
+            } catch(IllegalArgumentException e){
+                System.out.println("Error processing identifier : " + id);
+                throw e;
+            }
+        }
+
+        return new YangInstanceIdentifier.NodeIdentifierWithPredicates(QNameFactory.create(matcher.group(1)), nameValues);
+    }
+
+
+    private Object getValue(QName key, String value){
+        if(listSchemaNode != null){
+            for(DataSchemaNode node : listSchemaNode.getChildNodes()){
+                if(node instanceof LeafSchemaNode && node.getQName().equals(key)){
+                    return TypeDefinitionAwareCodec.from(LeafSchemaNode.class.cast(node).getType()).deserialize(value);
+                }
+            }
+        }
+        return value;
+    }
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierWithValueGenerator.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierWithValueGenerator.java
new file mode 100644 (file)
index 0000000..b2ec564
--- /dev/null
@@ -0,0 +1,48 @@
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class NodeIdentifierWithValueGenerator{
+        private final String id;
+    private final DataSchemaNode schemaNode;
+    private static final Pattern pattern = Pattern.compile("(.*)\\Q[\\E(.*)\\Q]\\E");
+        private final Matcher matcher;
+        private final boolean doesMatch;
+
+        public NodeIdentifierWithValueGenerator(String id, DataSchemaNode schemaNode){
+            this.id = id;
+            this.schemaNode = schemaNode;
+            matcher = pattern.matcher(this.id);
+            doesMatch = matcher.matches();
+        }
+
+        public boolean matches(){
+            return doesMatch;
+        }
+
+        public YangInstanceIdentifier.PathArgument getPathArgument(){
+            final String name = matcher.group(1);
+            final String value = matcher.group(2);
+
+            return new YangInstanceIdentifier.NodeWithValue(
+                QNameFactory.create(name), getValue(value));
+        }
+
+        private Object getValue(String value){
+            if(schemaNode != null){
+                if(schemaNode instanceof LeafListSchemaNode){
+                    return TypeDefinitionAwareCodec
+                        .from(LeafListSchemaNode.class.cast(schemaNode).getType()).deserialize(value);
+
+                }
+            }
+        return value;
+        }
+
+    }
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NormalizedNodeGetter.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NormalizedNodeGetter.java
new file mode 100644 (file)
index 0000000..e82a23d
--- /dev/null
@@ -0,0 +1,28 @@
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class NormalizedNodeGetter implements
+    NormalizedNodeVisitor {
+    private final String path;
+    NormalizedNode output;
+
+    public NormalizedNodeGetter(String path){
+        Preconditions.checkNotNull(path);
+        this.path = path;
+    }
+
+    @Override
+    public void visitNode(int level, String parentPath, NormalizedNode normalizedNode) {
+        String nodePath = parentPath + "/"+ normalizedNode.getIdentifier().toString();
+
+        if(nodePath.toString().equals(path)){
+            output = normalizedNode;
+        }
+    }
+
+    public NormalizedNode getOutput(){
+        return output;
+    }
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NormalizedNodeNavigator.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NormalizedNodeNavigator.java
new file mode 100644 (file)
index 0000000..4ccc707
--- /dev/null
@@ -0,0 +1,81 @@
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MixinNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
+
+/**
+ * NormalizedNodeNavigator walks a {@link NormalizedNodeVisitor} through the NormalizedNode
+ *
+ * {@link NormalizedNode } is a tree like structure that provides a generic structure for a yang data model
+ *
+ * For examples of visitors
+ * @see NormalizedNodePrinter
+ *
+ *
+ */
+public class NormalizedNodeNavigator {
+
+  private final org.opendaylight.controller.cluster.datastore.node.utils.NormalizedNodeVisitor
+      visitor;
+
+  public NormalizedNodeNavigator(
+      org.opendaylight.controller.cluster.datastore.node.utils.NormalizedNodeVisitor visitor){
+    Preconditions.checkNotNull(visitor, "visitor should not be null");
+    this.visitor = visitor;
+  }
+  public void navigate(String parentPath, NormalizedNode<?,?> normalizedNode){
+    if(parentPath == null){
+      parentPath = "";
+    }
+    navigateNormalizedNode(0, parentPath, normalizedNode);
+  }
+
+  private void navigateDataContainerNode(int level, final String parentPath, final DataContainerNode<?> dataContainerNode){
+    visitor.visitNode(level, parentPath ,dataContainerNode);
+
+    String newParentPath = parentPath + "/" + dataContainerNode.getIdentifier().toString();
+
+    final Iterable<DataContainerChild<? extends YangInstanceIdentifier.PathArgument,?>> value = dataContainerNode.getValue();
+    for(NormalizedNode<?,?> node : value){
+      if(node instanceof MixinNode && node instanceof NormalizedNodeContainer){
+        navigateNormalizedNodeContainerMixin(level, newParentPath, (NormalizedNodeContainer<?, ?, ?>) node);
+      } else {
+        navigateNormalizedNode(level, newParentPath, node);
+      }
+    }
+
+  }
+
+  private void navigateNormalizedNodeContainerMixin(int level, final String parentPath, NormalizedNodeContainer<?, ?, ?> node) {
+    visitor.visitNode(level, parentPath, node);
+
+    String newParentPath = parentPath + "/" + node.getIdentifier().toString();
+
+    final Iterable<? extends NormalizedNode<?, ?>> value = node.getValue();
+    for(NormalizedNode normalizedNode : value){
+      if(normalizedNode instanceof MixinNode && normalizedNode instanceof NormalizedNodeContainer){
+        navigateNormalizedNodeContainerMixin(level + 1, newParentPath, (NormalizedNodeContainer) normalizedNode);
+      } else {
+        navigateNormalizedNode(level, newParentPath, normalizedNode);
+      }
+    }
+
+  }
+
+
+  private void navigateNormalizedNode(int level, String parentPath, NormalizedNode<?,?> normalizedNode){
+    if(normalizedNode instanceof DataContainerNode){
+
+      final DataContainerNode<?> dataContainerNode = (DataContainerNode) normalizedNode;
+
+      navigateDataContainerNode(level + 1, parentPath, dataContainerNode);
+    } else {
+      visitor.visitNode(level+1, parentPath, normalizedNode);
+    }
+  }
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NormalizedNodePrinter.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NormalizedNodePrinter.java
new file mode 100644 (file)
index 0000000..7735a12
--- /dev/null
@@ -0,0 +1,26 @@
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class NormalizedNodePrinter implements NormalizedNodeVisitor {
+
+    private String spaces(int n){
+        StringBuilder builder = new StringBuilder();
+        for(int i=0;i<n;i++){
+            builder.append(' ');
+        }
+        return builder.toString();
+    }
+
+    @Override
+    public void visitNode(int level, String parentPath, NormalizedNode normalizedNode) {
+        System.out.println(spaces((level) * 4) + normalizedNode.getClass().toString() + ":" + normalizedNode.getIdentifier());
+        if(normalizedNode instanceof LeafNode || normalizedNode instanceof LeafSetEntryNode){
+            System.out.println(spaces((level) * 4) + " parentPath = " + parentPath);
+            System.out.println(spaces((level) * 4) + " key = " + normalizedNode.getClass().toString() + ":" + normalizedNode.getIdentifier());
+            System.out.println(spaces((level) * 4) + " value = " + normalizedNode.getValue());
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NormalizedNodeVisitor.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/NormalizedNodeVisitor.java
new file mode 100644 (file)
index 0000000..69b00be
--- /dev/null
@@ -0,0 +1,7 @@
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public interface NormalizedNodeVisitor {
+    public void visitNode(int level, String parentPath, NormalizedNode normalizedNode);
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/PathUtils.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/PathUtils.java
new file mode 100644 (file)
index 0000000..ba81836
--- /dev/null
@@ -0,0 +1,19 @@
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+public class PathUtils {
+    public static String getParentPath(String currentElementPath){
+        String parentPath = "";
+
+        if(currentElementPath != null){
+            String[] parentPaths = currentElementPath.split("/");
+            if(parentPaths.length > 2){
+                for(int i=0;i<parentPaths.length-1;i++){
+                    if(parentPaths[i].length() > 0){
+                        parentPath += "/" + parentPaths[i];
+                    }
+                }
+            }
+        }
+        return parentPath;
+    }
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/QNameFactory.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/QNameFactory.java
new file mode 100644 (file)
index 0000000..8dba056
--- /dev/null
@@ -0,0 +1,24 @@
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+import org.opendaylight.yangtools.yang.common.QName;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class QNameFactory {
+    private static final Map<String, QName> cache = new HashMap<>();
+
+    public static QName create(String name){
+        QName value = cache.get(name);
+        if(value == null){
+            synchronized (cache){
+                value = cache.get(name);
+                if(value == null) {
+                    value = QName.create(name);
+                    cache.put(name, value);
+                }
+            }
+        }
+        return value;
+    }
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/registration/ListenerRegistrationMessages.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/registration/ListenerRegistrationMessages.java
deleted file mode 100644 (file)
index afcb455..0000000
+++ /dev/null
@@ -1,681 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: ListenerRegistration.proto
-
-package org.opendaylight.controller.cluster.datastore.registration;
-
-public final class ListenerRegistrationMessages {
-  private ListenerRegistrationMessages() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistry registry) {
-  }
-  public interface CloseOrBuilder
-      extends com.google.protobuf.MessageOrBuilder {
-  }
-  /**
-   * Protobuf type {@code org.opendaylight.controller.mdsal.Close}
-   */
-  public static final class Close extends
-      com.google.protobuf.GeneratedMessage
-      implements CloseOrBuilder {
-    // Use Close.newBuilder() to construct.
-    private Close(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-      this.unknownFields = builder.getUnknownFields();
-    }
-    private Close(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final Close defaultInstance;
-    public static Close getDefaultInstance() {
-      return defaultInstance;
-    }
-
-    public Close getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
-    }
-    private Close(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_Close_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_Close_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close.class, org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close.Builder.class);
-    }
-
-    public static com.google.protobuf.Parser<Close> PARSER =
-        new com.google.protobuf.AbstractParser<Close>() {
-      public Close parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new Close(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<Close> getParserForType() {
-      return PARSER;
-    }
-
-    private void initFields() {
-    }
-    private byte memoizedIsInitialized = -1;
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized != -1) return isInitialized == 1;
-
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      getSerializedSize();
-      getUnknownFields().writeTo(output);
-    }
-
-    private int memoizedSerializedSize = -1;
-    public int getSerializedSize() {
-      int size = memoizedSerializedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
-    }
-
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() { return Builder.create(); }
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close prototype) {
-      return newBuilder().mergeFrom(prototype);
-    }
-    public Builder toBuilder() { return newBuilder(this); }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code org.opendaylight.controller.mdsal.Close}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_Close_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_Close_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close.class, org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close.Builder.class);
-      }
-
-      // Construct using org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      private static Builder create() {
-        return new Builder();
-      }
-
-      public Builder clear() {
-        super.clear();
-        return this;
-      }
-
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_Close_descriptor;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close.getDefaultInstance();
-      }
-
-      public org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close build() {
-        org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close buildPartial() {
-        org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close result = new org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close(this);
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close other) {
-        if (other == org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close.getDefaultInstance()) return this;
-        this.mergeUnknownFields(other.getUnknownFields());
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.Close) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.Close)
-    }
-
-    static {
-      defaultInstance = new Close(true);
-      defaultInstance.initFields();
-    }
-
-    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.Close)
-  }
-
-  public interface CloseReplyOrBuilder
-      extends com.google.protobuf.MessageOrBuilder {
-  }
-  /**
-   * Protobuf type {@code org.opendaylight.controller.mdsal.CloseReply}
-   */
-  public static final class CloseReply extends
-      com.google.protobuf.GeneratedMessage
-      implements CloseReplyOrBuilder {
-    // Use CloseReply.newBuilder() to construct.
-    private CloseReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-      this.unknownFields = builder.getUnknownFields();
-    }
-    private CloseReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final CloseReply defaultInstance;
-    public static CloseReply getDefaultInstance() {
-      return defaultInstance;
-    }
-
-    public CloseReply getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
-    }
-    private CloseReply(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseReply_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseReply_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply.class, org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply.Builder.class);
-    }
-
-    public static com.google.protobuf.Parser<CloseReply> PARSER =
-        new com.google.protobuf.AbstractParser<CloseReply>() {
-      public CloseReply parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new CloseReply(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<CloseReply> getParserForType() {
-      return PARSER;
-    }
-
-    private void initFields() {
-    }
-    private byte memoizedIsInitialized = -1;
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized != -1) return isInitialized == 1;
-
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      getSerializedSize();
-      getUnknownFields().writeTo(output);
-    }
-
-    private int memoizedSerializedSize = -1;
-    public int getSerializedSize() {
-      int size = memoizedSerializedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
-    }
-
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() { return Builder.create(); }
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply prototype) {
-      return newBuilder().mergeFrom(prototype);
-    }
-    public Builder toBuilder() { return newBuilder(this); }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code org.opendaylight.controller.mdsal.CloseReply}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReplyOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseReply_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseReply_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply.class, org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply.Builder.class);
-      }
-
-      // Construct using org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      private static Builder create() {
-        return new Builder();
-      }
-
-      public Builder clear() {
-        super.clear();
-        return this;
-      }
-
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseReply_descriptor;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply.getDefaultInstance();
-      }
-
-      public org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply build() {
-        org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply buildPartial() {
-        org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply result = new org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply(this);
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply other) {
-        if (other == org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply.getDefaultInstance()) return this;
-        this.mergeUnknownFields(other.getUnknownFields());
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.registration.ListenerRegistrationMessages.CloseReply) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CloseReply)
-    }
-
-    static {
-      defaultInstance = new CloseReply(true);
-      defaultInstance.initFields();
-    }
-
-    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CloseReply)
-  }
-
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_org_opendaylight_controller_mdsal_Close_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_org_opendaylight_controller_mdsal_Close_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_org_opendaylight_controller_mdsal_CloseReply_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_org_opendaylight_controller_mdsal_CloseReply_fieldAccessorTable;
-
-  public static com.google.protobuf.Descriptors.FileDescriptor
-      getDescriptor() {
-    return descriptor;
-  }
-  private static com.google.protobuf.Descriptors.FileDescriptor
-      descriptor;
-  static {
-    java.lang.String[] descriptorData = {
-      "\n\032ListenerRegistration.proto\022!org.openda" +
-      "ylight.controller.mdsal\"\007\n\005Close\"\014\n\nClos" +
-      "eReplyBZ\n:org.opendaylight.controller.cl" +
-      "uster.datastore.registrationB\034ListenerRe" +
-      "gistrationMessages"
-    };
-    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
-      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
-        public com.google.protobuf.ExtensionRegistry assignDescriptors(
-            com.google.protobuf.Descriptors.FileDescriptor root) {
-          descriptor = root;
-          internal_static_org_opendaylight_controller_mdsal_Close_descriptor =
-            getDescriptor().getMessageTypes().get(0);
-          internal_static_org_opendaylight_controller_mdsal_Close_fieldAccessorTable = new
-            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-              internal_static_org_opendaylight_controller_mdsal_Close_descriptor,
-              new java.lang.String[] { });
-          internal_static_org_opendaylight_controller_mdsal_CloseReply_descriptor =
-            getDescriptor().getMessageTypes().get(1);
-          internal_static_org_opendaylight_controller_mdsal_CloseReply_fieldAccessorTable = new
-            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-              internal_static_org_opendaylight_controller_mdsal_CloseReply_descriptor,
-              new java.lang.String[] { });
-          return null;
-        }
-      };
-    com.google.protobuf.Descriptors.FileDescriptor
-      .internalBuildGeneratedFileFrom(descriptorData,
-        new com.google.protobuf.Descriptors.FileDescriptor[] {
-        }, assigner);
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/transaction/ShardTransactionMessages.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/transaction/ShardTransactionMessages.java
deleted file mode 100644 (file)
index 3a226db..0000000
+++ /dev/null
@@ -1,3606 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: ShardTransactionMessages.proto
-
-package org.opendaylight.controller.cluster.datastore.transaction;
-
-public final class ShardTransactionMessages {
-  private ShardTransactionMessages() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistry registry) {
-  }
-  public interface CloseTransactionOrBuilder
-      extends com.google.protobuf.MessageOrBuilder {
-  }
-  /**
-   * Protobuf type {@code org.opendaylight.controller.mdsal.CloseTransaction}
-   */
-  public static final class CloseTransaction extends
-      com.google.protobuf.GeneratedMessage
-      implements CloseTransactionOrBuilder {
-    // Use CloseTransaction.newBuilder() to construct.
-    private CloseTransaction(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-      this.unknownFields = builder.getUnknownFields();
-    }
-    private CloseTransaction(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final CloseTransaction defaultInstance;
-    public static CloseTransaction getDefaultInstance() {
-      return defaultInstance;
-    }
-
-    public CloseTransaction getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
-    }
-    private CloseTransaction(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransaction_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransaction_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction.Builder.class);
-    }
-
-    public static com.google.protobuf.Parser<CloseTransaction> PARSER =
-        new com.google.protobuf.AbstractParser<CloseTransaction>() {
-      public CloseTransaction parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new CloseTransaction(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<CloseTransaction> getParserForType() {
-      return PARSER;
-    }
-
-    private void initFields() {
-    }
-    private byte memoizedIsInitialized = -1;
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized != -1) return isInitialized == 1;
-
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      getSerializedSize();
-      getUnknownFields().writeTo(output);
-    }
-
-    private int memoizedSerializedSize = -1;
-    public int getSerializedSize() {
-      int size = memoizedSerializedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
-    }
-
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() { return Builder.create(); }
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction prototype) {
-      return newBuilder().mergeFrom(prototype);
-    }
-    public Builder toBuilder() { return newBuilder(this); }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code org.opendaylight.controller.mdsal.CloseTransaction}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransaction_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransaction_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction.Builder.class);
-      }
-
-      // Construct using org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      private static Builder create() {
-        return new Builder();
-      }
-
-      public Builder clear() {
-        super.clear();
-        return this;
-      }
-
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransaction_descriptor;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction.getDefaultInstance();
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction build() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction buildPartial() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction result = new org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction(this);
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction other) {
-        if (other == org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction.getDefaultInstance()) return this;
-        this.mergeUnknownFields(other.getUnknownFields());
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransaction) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CloseTransaction)
-    }
-
-    static {
-      defaultInstance = new CloseTransaction(true);
-      defaultInstance.initFields();
-    }
-
-    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CloseTransaction)
-  }
-
-  public interface CloseTransactionReplyOrBuilder
-      extends com.google.protobuf.MessageOrBuilder {
-  }
-  /**
-   * Protobuf type {@code org.opendaylight.controller.mdsal.CloseTransactionReply}
-   */
-  public static final class CloseTransactionReply extends
-      com.google.protobuf.GeneratedMessage
-      implements CloseTransactionReplyOrBuilder {
-    // Use CloseTransactionReply.newBuilder() to construct.
-    private CloseTransactionReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-      this.unknownFields = builder.getUnknownFields();
-    }
-    private CloseTransactionReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final CloseTransactionReply defaultInstance;
-    public static CloseTransactionReply getDefaultInstance() {
-      return defaultInstance;
-    }
-
-    public CloseTransactionReply getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
-    }
-    private CloseTransactionReply(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply.Builder.class);
-    }
-
-    public static com.google.protobuf.Parser<CloseTransactionReply> PARSER =
-        new com.google.protobuf.AbstractParser<CloseTransactionReply>() {
-      public CloseTransactionReply parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new CloseTransactionReply(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<CloseTransactionReply> getParserForType() {
-      return PARSER;
-    }
-
-    private void initFields() {
-    }
-    private byte memoizedIsInitialized = -1;
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized != -1) return isInitialized == 1;
-
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      getSerializedSize();
-      getUnknownFields().writeTo(output);
-    }
-
-    private int memoizedSerializedSize = -1;
-    public int getSerializedSize() {
-      int size = memoizedSerializedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
-    }
-
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() { return Builder.create(); }
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply prototype) {
-      return newBuilder().mergeFrom(prototype);
-    }
-    public Builder toBuilder() { return newBuilder(this); }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code org.opendaylight.controller.mdsal.CloseTransactionReply}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReplyOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply.Builder.class);
-      }
-
-      // Construct using org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      private static Builder create() {
-        return new Builder();
-      }
-
-      public Builder clear() {
-        super.clear();
-        return this;
-      }
-
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_descriptor;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply.getDefaultInstance();
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply build() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply buildPartial() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply result = new org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply(this);
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply other) {
-        if (other == org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply.getDefaultInstance()) return this;
-        this.mergeUnknownFields(other.getUnknownFields());
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CloseTransactionReply) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CloseTransactionReply)
-    }
-
-    static {
-      defaultInstance = new CloseTransactionReply(true);
-      defaultInstance.initFields();
-    }
-
-    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CloseTransactionReply)
-  }
-
-  public interface CreateTransactionOrBuilder
-      extends com.google.protobuf.MessageOrBuilder {
-  }
-  /**
-   * Protobuf type {@code org.opendaylight.controller.mdsal.CreateTransaction}
-   */
-  public static final class CreateTransaction extends
-      com.google.protobuf.GeneratedMessage
-      implements CreateTransactionOrBuilder {
-    // Use CreateTransaction.newBuilder() to construct.
-    private CreateTransaction(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-      this.unknownFields = builder.getUnknownFields();
-    }
-    private CreateTransaction(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final CreateTransaction defaultInstance;
-    public static CreateTransaction getDefaultInstance() {
-      return defaultInstance;
-    }
-
-    public CreateTransaction getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
-    }
-    private CreateTransaction(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransaction_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransaction_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction.Builder.class);
-    }
-
-    public static com.google.protobuf.Parser<CreateTransaction> PARSER =
-        new com.google.protobuf.AbstractParser<CreateTransaction>() {
-      public CreateTransaction parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new CreateTransaction(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<CreateTransaction> getParserForType() {
-      return PARSER;
-    }
-
-    private void initFields() {
-    }
-    private byte memoizedIsInitialized = -1;
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized != -1) return isInitialized == 1;
-
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      getSerializedSize();
-      getUnknownFields().writeTo(output);
-    }
-
-    private int memoizedSerializedSize = -1;
-    public int getSerializedSize() {
-      int size = memoizedSerializedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
-    }
-
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() { return Builder.create(); }
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction prototype) {
-      return newBuilder().mergeFrom(prototype);
-    }
-    public Builder toBuilder() { return newBuilder(this); }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code org.opendaylight.controller.mdsal.CreateTransaction}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransaction_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransaction_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction.Builder.class);
-      }
-
-      // Construct using org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      private static Builder create() {
-        return new Builder();
-      }
-
-      public Builder clear() {
-        super.clear();
-        return this;
-      }
-
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransaction_descriptor;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction.getDefaultInstance();
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction build() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction buildPartial() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction result = new org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction(this);
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction other) {
-        if (other == org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction.getDefaultInstance()) return this;
-        this.mergeUnknownFields(other.getUnknownFields());
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransaction) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CreateTransaction)
-    }
-
-    static {
-      defaultInstance = new CreateTransaction(true);
-      defaultInstance.initFields();
-    }
-
-    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CreateTransaction)
-  }
-
-  public interface CreateTransactionReplyOrBuilder
-      extends com.google.protobuf.MessageOrBuilder {
-
-    // required string transactionPath = 1;
-    /**
-     * <code>required string transactionPath = 1;</code>
-     */
-    boolean hasTransactionPath();
-    /**
-     * <code>required string transactionPath = 1;</code>
-     */
-    java.lang.String getTransactionPath();
-    /**
-     * <code>required string transactionPath = 1;</code>
-     */
-    com.google.protobuf.ByteString
-        getTransactionPathBytes();
-  }
-  /**
-   * Protobuf type {@code org.opendaylight.controller.mdsal.CreateTransactionReply}
-   */
-  public static final class CreateTransactionReply extends
-      com.google.protobuf.GeneratedMessage
-      implements CreateTransactionReplyOrBuilder {
-    // Use CreateTransactionReply.newBuilder() to construct.
-    private CreateTransactionReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-      this.unknownFields = builder.getUnknownFields();
-    }
-    private CreateTransactionReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final CreateTransactionReply defaultInstance;
-    public static CreateTransactionReply getDefaultInstance() {
-      return defaultInstance;
-    }
-
-    public CreateTransactionReply getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
-    }
-    private CreateTransactionReply(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
-      int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-            case 10: {
-              bitField0_ |= 0x00000001;
-              transactionPath_ = input.readBytes();
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply.Builder.class);
-    }
-
-    public static com.google.protobuf.Parser<CreateTransactionReply> PARSER =
-        new com.google.protobuf.AbstractParser<CreateTransactionReply>() {
-      public CreateTransactionReply parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new CreateTransactionReply(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<CreateTransactionReply> getParserForType() {
-      return PARSER;
-    }
-
-    private int bitField0_;
-    // required string transactionPath = 1;
-    public static final int TRANSACTIONPATH_FIELD_NUMBER = 1;
-    private java.lang.Object transactionPath_;
-    /**
-     * <code>required string transactionPath = 1;</code>
-     */
-    public boolean hasTransactionPath() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
-    }
-    /**
-     * <code>required string transactionPath = 1;</code>
-     */
-    public java.lang.String getTransactionPath() {
-      java.lang.Object ref = transactionPath_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs =
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        if (bs.isValidUtf8()) {
-          transactionPath_ = s;
-        }
-        return s;
-      }
-    }
-    /**
-     * <code>required string transactionPath = 1;</code>
-     */
-    public com.google.protobuf.ByteString
-        getTransactionPathBytes() {
-      java.lang.Object ref = transactionPath_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b =
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        transactionPath_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    private void initFields() {
-      transactionPath_ = "";
-    }
-    private byte memoizedIsInitialized = -1;
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized != -1) return isInitialized == 1;
-
-      if (!hasTransactionPath()) {
-        memoizedIsInitialized = 0;
-        return false;
-      }
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      getSerializedSize();
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        output.writeBytes(1, getTransactionPathBytes());
-      }
-      getUnknownFields().writeTo(output);
-    }
-
-    private int memoizedSerializedSize = -1;
-    public int getSerializedSize() {
-      int size = memoizedSerializedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBytesSize(1, getTransactionPathBytes());
-      }
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
-    }
-
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() { return Builder.create(); }
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply prototype) {
-      return newBuilder().mergeFrom(prototype);
-    }
-    public Builder toBuilder() { return newBuilder(this); }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code org.opendaylight.controller.mdsal.CreateTransactionReply}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReplyOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply.Builder.class);
-      }
-
-      // Construct using org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      private static Builder create() {
-        return new Builder();
-      }
-
-      public Builder clear() {
-        super.clear();
-        transactionPath_ = "";
-        bitField0_ = (bitField0_ & ~0x00000001);
-        return this;
-      }
-
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_descriptor;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply.getDefaultInstance();
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply build() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply buildPartial() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply result = new org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply(this);
-        int from_bitField0_ = bitField0_;
-        int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-          to_bitField0_ |= 0x00000001;
-        }
-        result.transactionPath_ = transactionPath_;
-        result.bitField0_ = to_bitField0_;
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply other) {
-        if (other == org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply.getDefaultInstance()) return this;
-        if (other.hasTransactionPath()) {
-          bitField0_ |= 0x00000001;
-          transactionPath_ = other.transactionPath_;
-          onChanged();
-        }
-        this.mergeUnknownFields(other.getUnknownFields());
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        if (!hasTransactionPath()) {
-
-          return false;
-        }
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.CreateTransactionReply) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-      private int bitField0_;
-
-      // required string transactionPath = 1;
-      private java.lang.Object transactionPath_ = "";
-      /**
-       * <code>required string transactionPath = 1;</code>
-       */
-      public boolean hasTransactionPath() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>required string transactionPath = 1;</code>
-       */
-      public java.lang.String getTransactionPath() {
-        java.lang.Object ref = transactionPath_;
-        if (!(ref instanceof java.lang.String)) {
-          java.lang.String s = ((com.google.protobuf.ByteString) ref)
-              .toStringUtf8();
-          transactionPath_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>required string transactionPath = 1;</code>
-       */
-      public com.google.protobuf.ByteString
-          getTransactionPathBytes() {
-        java.lang.Object ref = transactionPath_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b =
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          transactionPath_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>required string transactionPath = 1;</code>
-       */
-      public Builder setTransactionPath(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-        transactionPath_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>required string transactionPath = 1;</code>
-       */
-      public Builder clearTransactionPath() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        transactionPath_ = getDefaultInstance().getTransactionPath();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>required string transactionPath = 1;</code>
-       */
-      public Builder setTransactionPathBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-        transactionPath_ = value;
-        onChanged();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CreateTransactionReply)
-    }
-
-    static {
-      defaultInstance = new CreateTransactionReply(true);
-      defaultInstance.initFields();
-    }
-
-    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CreateTransactionReply)
-  }
-
-  public interface ReadyTransactionOrBuilder
-      extends com.google.protobuf.MessageOrBuilder {
-  }
-  /**
-   * Protobuf type {@code org.opendaylight.controller.mdsal.ReadyTransaction}
-   */
-  public static final class ReadyTransaction extends
-      com.google.protobuf.GeneratedMessage
-      implements ReadyTransactionOrBuilder {
-    // Use ReadyTransaction.newBuilder() to construct.
-    private ReadyTransaction(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-      this.unknownFields = builder.getUnknownFields();
-    }
-    private ReadyTransaction(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final ReadyTransaction defaultInstance;
-    public static ReadyTransaction getDefaultInstance() {
-      return defaultInstance;
-    }
-
-    public ReadyTransaction getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
-    }
-    private ReadyTransaction(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction.Builder.class);
-    }
-
-    public static com.google.protobuf.Parser<ReadyTransaction> PARSER =
-        new com.google.protobuf.AbstractParser<ReadyTransaction>() {
-      public ReadyTransaction parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new ReadyTransaction(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<ReadyTransaction> getParserForType() {
-      return PARSER;
-    }
-
-    private void initFields() {
-    }
-    private byte memoizedIsInitialized = -1;
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized != -1) return isInitialized == 1;
-
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      getSerializedSize();
-      getUnknownFields().writeTo(output);
-    }
-
-    private int memoizedSerializedSize = -1;
-    public int getSerializedSize() {
-      int size = memoizedSerializedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
-    }
-
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() { return Builder.create(); }
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction prototype) {
-      return newBuilder().mergeFrom(prototype);
-    }
-    public Builder toBuilder() { return newBuilder(this); }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code org.opendaylight.controller.mdsal.ReadyTransaction}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction.Builder.class);
-      }
-
-      // Construct using org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      private static Builder create() {
-        return new Builder();
-      }
-
-      public Builder clear() {
-        super.clear();
-        return this;
-      }
-
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_descriptor;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction.getDefaultInstance();
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction build() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction buildPartial() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction result = new org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction(this);
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction other) {
-        if (other == org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction.getDefaultInstance()) return this;
-        this.mergeUnknownFields(other.getUnknownFields());
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransaction) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.ReadyTransaction)
-    }
-
-    static {
-      defaultInstance = new ReadyTransaction(true);
-      defaultInstance.initFields();
-    }
-
-    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.ReadyTransaction)
-  }
-
-  public interface ReadyTransactionReplyOrBuilder
-      extends com.google.protobuf.MessageOrBuilder {
-
-    // required string actorPath = 1;
-    /**
-     * <code>required string actorPath = 1;</code>
-     */
-    boolean hasActorPath();
-    /**
-     * <code>required string actorPath = 1;</code>
-     */
-    java.lang.String getActorPath();
-    /**
-     * <code>required string actorPath = 1;</code>
-     */
-    com.google.protobuf.ByteString
-        getActorPathBytes();
-  }
-  /**
-   * Protobuf type {@code org.opendaylight.controller.mdsal.ReadyTransactionReply}
-   */
-  public static final class ReadyTransactionReply extends
-      com.google.protobuf.GeneratedMessage
-      implements ReadyTransactionReplyOrBuilder {
-    // Use ReadyTransactionReply.newBuilder() to construct.
-    private ReadyTransactionReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-      this.unknownFields = builder.getUnknownFields();
-    }
-    private ReadyTransactionReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final ReadyTransactionReply defaultInstance;
-    public static ReadyTransactionReply getDefaultInstance() {
-      return defaultInstance;
-    }
-
-    public ReadyTransactionReply getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
-    }
-    private ReadyTransactionReply(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
-      int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-            case 10: {
-              bitField0_ |= 0x00000001;
-              actorPath_ = input.readBytes();
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply.Builder.class);
-    }
-
-    public static com.google.protobuf.Parser<ReadyTransactionReply> PARSER =
-        new com.google.protobuf.AbstractParser<ReadyTransactionReply>() {
-      public ReadyTransactionReply parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new ReadyTransactionReply(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<ReadyTransactionReply> getParserForType() {
-      return PARSER;
-    }
-
-    private int bitField0_;
-    // required string actorPath = 1;
-    public static final int ACTORPATH_FIELD_NUMBER = 1;
-    private java.lang.Object actorPath_;
-    /**
-     * <code>required string actorPath = 1;</code>
-     */
-    public boolean hasActorPath() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
-    }
-    /**
-     * <code>required string actorPath = 1;</code>
-     */
-    public java.lang.String getActorPath() {
-      java.lang.Object ref = actorPath_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs =
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        if (bs.isValidUtf8()) {
-          actorPath_ = s;
-        }
-        return s;
-      }
-    }
-    /**
-     * <code>required string actorPath = 1;</code>
-     */
-    public com.google.protobuf.ByteString
-        getActorPathBytes() {
-      java.lang.Object ref = actorPath_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b =
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        actorPath_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    private void initFields() {
-      actorPath_ = "";
-    }
-    private byte memoizedIsInitialized = -1;
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized != -1) return isInitialized == 1;
-
-      if (!hasActorPath()) {
-        memoizedIsInitialized = 0;
-        return false;
-      }
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      getSerializedSize();
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        output.writeBytes(1, getActorPathBytes());
-      }
-      getUnknownFields().writeTo(output);
-    }
-
-    private int memoizedSerializedSize = -1;
-    public int getSerializedSize() {
-      int size = memoizedSerializedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBytesSize(1, getActorPathBytes());
-      }
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
-    }
-
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() { return Builder.create(); }
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply prototype) {
-      return newBuilder().mergeFrom(prototype);
-    }
-    public Builder toBuilder() { return newBuilder(this); }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code org.opendaylight.controller.mdsal.ReadyTransactionReply}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReplyOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply.Builder.class);
-      }
-
-      // Construct using org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      private static Builder create() {
-        return new Builder();
-      }
-
-      public Builder clear() {
-        super.clear();
-        actorPath_ = "";
-        bitField0_ = (bitField0_ & ~0x00000001);
-        return this;
-      }
-
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_descriptor;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply.getDefaultInstance();
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply build() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply buildPartial() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply result = new org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply(this);
-        int from_bitField0_ = bitField0_;
-        int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-          to_bitField0_ |= 0x00000001;
-        }
-        result.actorPath_ = actorPath_;
-        result.bitField0_ = to_bitField0_;
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply other) {
-        if (other == org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply.getDefaultInstance()) return this;
-        if (other.hasActorPath()) {
-          bitField0_ |= 0x00000001;
-          actorPath_ = other.actorPath_;
-          onChanged();
-        }
-        this.mergeUnknownFields(other.getUnknownFields());
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        if (!hasActorPath()) {
-
-          return false;
-        }
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadyTransactionReply) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-      private int bitField0_;
-
-      // required string actorPath = 1;
-      private java.lang.Object actorPath_ = "";
-      /**
-       * <code>required string actorPath = 1;</code>
-       */
-      public boolean hasActorPath() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>required string actorPath = 1;</code>
-       */
-      public java.lang.String getActorPath() {
-        java.lang.Object ref = actorPath_;
-        if (!(ref instanceof java.lang.String)) {
-          java.lang.String s = ((com.google.protobuf.ByteString) ref)
-              .toStringUtf8();
-          actorPath_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>required string actorPath = 1;</code>
-       */
-      public com.google.protobuf.ByteString
-          getActorPathBytes() {
-        java.lang.Object ref = actorPath_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b =
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          actorPath_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>required string actorPath = 1;</code>
-       */
-      public Builder setActorPath(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-        actorPath_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>required string actorPath = 1;</code>
-       */
-      public Builder clearActorPath() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        actorPath_ = getDefaultInstance().getActorPath();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>required string actorPath = 1;</code>
-       */
-      public Builder setActorPathBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-        actorPath_ = value;
-        onChanged();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.ReadyTransactionReply)
-    }
-
-    static {
-      defaultInstance = new ReadyTransactionReply(true);
-      defaultInstance.initFields();
-    }
-
-    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.ReadyTransactionReply)
-  }
-
-  public interface DeleteDataOrBuilder
-      extends com.google.protobuf.MessageOrBuilder {
-
-    // required string instanceIdentifierPath = 1;
-    /**
-     * <code>required string instanceIdentifierPath = 1;</code>
-     */
-    boolean hasInstanceIdentifierPath();
-    /**
-     * <code>required string instanceIdentifierPath = 1;</code>
-     */
-    java.lang.String getInstanceIdentifierPath();
-    /**
-     * <code>required string instanceIdentifierPath = 1;</code>
-     */
-    com.google.protobuf.ByteString
-        getInstanceIdentifierPathBytes();
-  }
-  /**
-   * Protobuf type {@code org.opendaylight.controller.mdsal.DeleteData}
-   */
-  public static final class DeleteData extends
-      com.google.protobuf.GeneratedMessage
-      implements DeleteDataOrBuilder {
-    // Use DeleteData.newBuilder() to construct.
-    private DeleteData(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-      this.unknownFields = builder.getUnknownFields();
-    }
-    private DeleteData(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final DeleteData defaultInstance;
-    public static DeleteData getDefaultInstance() {
-      return defaultInstance;
-    }
-
-    public DeleteData getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
-    }
-    private DeleteData(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
-      int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-            case 10: {
-              bitField0_ |= 0x00000001;
-              instanceIdentifierPath_ = input.readBytes();
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteData_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteData_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData.Builder.class);
-    }
-
-    public static com.google.protobuf.Parser<DeleteData> PARSER =
-        new com.google.protobuf.AbstractParser<DeleteData>() {
-      public DeleteData parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new DeleteData(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<DeleteData> getParserForType() {
-      return PARSER;
-    }
-
-    private int bitField0_;
-    // required string instanceIdentifierPath = 1;
-    public static final int INSTANCEIDENTIFIERPATH_FIELD_NUMBER = 1;
-    private java.lang.Object instanceIdentifierPath_;
-    /**
-     * <code>required string instanceIdentifierPath = 1;</code>
-     */
-    public boolean hasInstanceIdentifierPath() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
-    }
-    /**
-     * <code>required string instanceIdentifierPath = 1;</code>
-     */
-    public java.lang.String getInstanceIdentifierPath() {
-      java.lang.Object ref = instanceIdentifierPath_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs =
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        if (bs.isValidUtf8()) {
-          instanceIdentifierPath_ = s;
-        }
-        return s;
-      }
-    }
-    /**
-     * <code>required string instanceIdentifierPath = 1;</code>
-     */
-    public com.google.protobuf.ByteString
-        getInstanceIdentifierPathBytes() {
-      java.lang.Object ref = instanceIdentifierPath_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b =
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        instanceIdentifierPath_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    private void initFields() {
-      instanceIdentifierPath_ = "";
-    }
-    private byte memoizedIsInitialized = -1;
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized != -1) return isInitialized == 1;
-
-      if (!hasInstanceIdentifierPath()) {
-        memoizedIsInitialized = 0;
-        return false;
-      }
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      getSerializedSize();
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        output.writeBytes(1, getInstanceIdentifierPathBytes());
-      }
-      getUnknownFields().writeTo(output);
-    }
-
-    private int memoizedSerializedSize = -1;
-    public int getSerializedSize() {
-      int size = memoizedSerializedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBytesSize(1, getInstanceIdentifierPathBytes());
-      }
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
-    }
-
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() { return Builder.create(); }
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData prototype) {
-      return newBuilder().mergeFrom(prototype);
-    }
-    public Builder toBuilder() { return newBuilder(this); }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code org.opendaylight.controller.mdsal.DeleteData}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteData_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteData_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData.Builder.class);
-      }
-
-      // Construct using org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      private static Builder create() {
-        return new Builder();
-      }
-
-      public Builder clear() {
-        super.clear();
-        instanceIdentifierPath_ = "";
-        bitField0_ = (bitField0_ & ~0x00000001);
-        return this;
-      }
-
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteData_descriptor;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData.getDefaultInstance();
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData build() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData buildPartial() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData result = new org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData(this);
-        int from_bitField0_ = bitField0_;
-        int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-          to_bitField0_ |= 0x00000001;
-        }
-        result.instanceIdentifierPath_ = instanceIdentifierPath_;
-        result.bitField0_ = to_bitField0_;
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData other) {
-        if (other == org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData.getDefaultInstance()) return this;
-        if (other.hasInstanceIdentifierPath()) {
-          bitField0_ |= 0x00000001;
-          instanceIdentifierPath_ = other.instanceIdentifierPath_;
-          onChanged();
-        }
-        this.mergeUnknownFields(other.getUnknownFields());
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        if (!hasInstanceIdentifierPath()) {
-
-          return false;
-        }
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteData) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-      private int bitField0_;
-
-      // required string instanceIdentifierPath = 1;
-      private java.lang.Object instanceIdentifierPath_ = "";
-      /**
-       * <code>required string instanceIdentifierPath = 1;</code>
-       */
-      public boolean hasInstanceIdentifierPath() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>required string instanceIdentifierPath = 1;</code>
-       */
-      public java.lang.String getInstanceIdentifierPath() {
-        java.lang.Object ref = instanceIdentifierPath_;
-        if (!(ref instanceof java.lang.String)) {
-          java.lang.String s = ((com.google.protobuf.ByteString) ref)
-              .toStringUtf8();
-          instanceIdentifierPath_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>required string instanceIdentifierPath = 1;</code>
-       */
-      public com.google.protobuf.ByteString
-          getInstanceIdentifierPathBytes() {
-        java.lang.Object ref = instanceIdentifierPath_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b =
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          instanceIdentifierPath_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>required string instanceIdentifierPath = 1;</code>
-       */
-      public Builder setInstanceIdentifierPath(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-        instanceIdentifierPath_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>required string instanceIdentifierPath = 1;</code>
-       */
-      public Builder clearInstanceIdentifierPath() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        instanceIdentifierPath_ = getDefaultInstance().getInstanceIdentifierPath();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>required string instanceIdentifierPath = 1;</code>
-       */
-      public Builder setInstanceIdentifierPathBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-        instanceIdentifierPath_ = value;
-        onChanged();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.DeleteData)
-    }
-
-    static {
-      defaultInstance = new DeleteData(true);
-      defaultInstance.initFields();
-    }
-
-    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.DeleteData)
-  }
-
-  public interface DeleteDataReplyOrBuilder
-      extends com.google.protobuf.MessageOrBuilder {
-  }
-  /**
-   * Protobuf type {@code org.opendaylight.controller.mdsal.DeleteDataReply}
-   */
-  public static final class DeleteDataReply extends
-      com.google.protobuf.GeneratedMessage
-      implements DeleteDataReplyOrBuilder {
-    // Use DeleteDataReply.newBuilder() to construct.
-    private DeleteDataReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-      this.unknownFields = builder.getUnknownFields();
-    }
-    private DeleteDataReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final DeleteDataReply defaultInstance;
-    public static DeleteDataReply getDefaultInstance() {
-      return defaultInstance;
-    }
-
-    public DeleteDataReply getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
-    }
-    private DeleteDataReply(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply.Builder.class);
-    }
-
-    public static com.google.protobuf.Parser<DeleteDataReply> PARSER =
-        new com.google.protobuf.AbstractParser<DeleteDataReply>() {
-      public DeleteDataReply parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new DeleteDataReply(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<DeleteDataReply> getParserForType() {
-      return PARSER;
-    }
-
-    private void initFields() {
-    }
-    private byte memoizedIsInitialized = -1;
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized != -1) return isInitialized == 1;
-
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      getSerializedSize();
-      getUnknownFields().writeTo(output);
-    }
-
-    private int memoizedSerializedSize = -1;
-    public int getSerializedSize() {
-      int size = memoizedSerializedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
-    }
-
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() { return Builder.create(); }
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply prototype) {
-      return newBuilder().mergeFrom(prototype);
-    }
-    public Builder toBuilder() { return newBuilder(this); }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code org.opendaylight.controller.mdsal.DeleteDataReply}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReplyOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply.Builder.class);
-      }
-
-      // Construct using org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      private static Builder create() {
-        return new Builder();
-      }
-
-      public Builder clear() {
-        super.clear();
-        return this;
-      }
-
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_descriptor;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply.getDefaultInstance();
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply build() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply buildPartial() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply result = new org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply(this);
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply other) {
-        if (other == org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply.getDefaultInstance()) return this;
-        this.mergeUnknownFields(other.getUnknownFields());
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.DeleteDataReply) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.DeleteDataReply)
-    }
-
-    static {
-      defaultInstance = new DeleteDataReply(true);
-      defaultInstance.initFields();
-    }
-
-    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.DeleteDataReply)
-  }
-
-  public interface ReadDataOrBuilder
-      extends com.google.protobuf.MessageOrBuilder {
-
-    // required string intanceIdentifier = 1;
-    /**
-     * <code>required string intanceIdentifier = 1;</code>
-     */
-    boolean hasIntanceIdentifier();
-    /**
-     * <code>required string intanceIdentifier = 1;</code>
-     */
-    java.lang.String getIntanceIdentifier();
-    /**
-     * <code>required string intanceIdentifier = 1;</code>
-     */
-    com.google.protobuf.ByteString
-        getIntanceIdentifierBytes();
-  }
-  /**
-   * Protobuf type {@code org.opendaylight.controller.mdsal.ReadData}
-   */
-  public static final class ReadData extends
-      com.google.protobuf.GeneratedMessage
-      implements ReadDataOrBuilder {
-    // Use ReadData.newBuilder() to construct.
-    private ReadData(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
-      super(builder);
-      this.unknownFields = builder.getUnknownFields();
-    }
-    private ReadData(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final ReadData defaultInstance;
-    public static ReadData getDefaultInstance() {
-      return defaultInstance;
-    }
-
-    public ReadData getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
-    }
-    private ReadData(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
-      int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-            case 10: {
-              bitField0_ |= 0x00000001;
-              intanceIdentifier_ = input.readBytes();
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadData_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadData_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData.Builder.class);
-    }
-
-    public static com.google.protobuf.Parser<ReadData> PARSER =
-        new com.google.protobuf.AbstractParser<ReadData>() {
-      public ReadData parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new ReadData(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<ReadData> getParserForType() {
-      return PARSER;
-    }
-
-    private int bitField0_;
-    // required string intanceIdentifier = 1;
-    public static final int INTANCEIDENTIFIER_FIELD_NUMBER = 1;
-    private java.lang.Object intanceIdentifier_;
-    /**
-     * <code>required string intanceIdentifier = 1;</code>
-     */
-    public boolean hasIntanceIdentifier() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
-    }
-    /**
-     * <code>required string intanceIdentifier = 1;</code>
-     */
-    public java.lang.String getIntanceIdentifier() {
-      java.lang.Object ref = intanceIdentifier_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs =
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        if (bs.isValidUtf8()) {
-          intanceIdentifier_ = s;
-        }
-        return s;
-      }
-    }
-    /**
-     * <code>required string intanceIdentifier = 1;</code>
-     */
-    public com.google.protobuf.ByteString
-        getIntanceIdentifierBytes() {
-      java.lang.Object ref = intanceIdentifier_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b =
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        intanceIdentifier_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    private void initFields() {
-      intanceIdentifier_ = "";
-    }
-    private byte memoizedIsInitialized = -1;
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized != -1) return isInitialized == 1;
-
-      if (!hasIntanceIdentifier()) {
-        memoizedIsInitialized = 0;
-        return false;
-      }
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      getSerializedSize();
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        output.writeBytes(1, getIntanceIdentifierBytes());
-      }
-      getUnknownFields().writeTo(output);
-    }
-
-    private int memoizedSerializedSize = -1;
-    public int getSerializedSize() {
-      int size = memoizedSerializedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBytesSize(1, getIntanceIdentifierBytes());
-      }
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
-    }
-
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() { return Builder.create(); }
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData prototype) {
-      return newBuilder().mergeFrom(prototype);
-    }
-    public Builder toBuilder() { return newBuilder(this); }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code org.opendaylight.controller.mdsal.ReadData}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadDataOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadData_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadData_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData.Builder.class);
-      }
-
-      // Construct using org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      private static Builder create() {
-        return new Builder();
-      }
-
-      public Builder clear() {
-        super.clear();
-        intanceIdentifier_ = "";
-        bitField0_ = (bitField0_ & ~0x00000001);
-        return this;
-      }
-
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadData_descriptor;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData.getDefaultInstance();
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData build() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData buildPartial() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData result = new org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData(this);
-        int from_bitField0_ = bitField0_;
-        int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-          to_bitField0_ |= 0x00000001;
-        }
-        result.intanceIdentifier_ = intanceIdentifier_;
-        result.bitField0_ = to_bitField0_;
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData other) {
-        if (other == org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData.getDefaultInstance()) return this;
-        if (other.hasIntanceIdentifier()) {
-          bitField0_ |= 0x00000001;
-          intanceIdentifier_ = other.intanceIdentifier_;
-          onChanged();
-        }
-        this.mergeUnknownFields(other.getUnknownFields());
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        if (!hasIntanceIdentifier()) {
-          return false;
-        }
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionMessages.ReadData) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-      private int bitField0_;
-
-      // required string intanceIdentifier = 1;
-      private java.lang.Object intanceIdentifier_ = "";
-      /**
-       * <code>required string intanceIdentifier = 1;</code>
-       */
-      public boolean hasIntanceIdentifier() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>required string intanceIdentifier = 1;</code>
-       */
-      public java.lang.String getIntanceIdentifier() {
-        java.lang.Object ref = intanceIdentifier_;
-        if (!(ref instanceof java.lang.String)) {
-          java.lang.String s = ((com.google.protobuf.ByteString) ref)
-              .toStringUtf8();
-          intanceIdentifier_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>required string intanceIdentifier = 1;</code>
-       */
-      public com.google.protobuf.ByteString
-          getIntanceIdentifierBytes() {
-        java.lang.Object ref = intanceIdentifier_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b =
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          intanceIdentifier_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>required string intanceIdentifier = 1;</code>
-       */
-      public Builder setIntanceIdentifier(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-        intanceIdentifier_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>required string intanceIdentifier = 1;</code>
-       */
-      public Builder clearIntanceIdentifier() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        intanceIdentifier_ = getDefaultInstance().getIntanceIdentifier();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>required string intanceIdentifier = 1;</code>
-       */
-      public Builder setIntanceIdentifierBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-        intanceIdentifier_ = value;
-        onChanged();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.ReadData)
-    }
-
-    static {
-      defaultInstance = new ReadData(true);
-      defaultInstance.initFields();
-    }
-
-    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.ReadData)
-  }
-
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_org_opendaylight_controller_mdsal_CloseTransaction_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_org_opendaylight_controller_mdsal_CloseTransaction_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_org_opendaylight_controller_mdsal_CreateTransaction_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_org_opendaylight_controller_mdsal_CreateTransaction_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_org_opendaylight_controller_mdsal_DeleteData_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_org_opendaylight_controller_mdsal_DeleteData_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_org_opendaylight_controller_mdsal_ReadData_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_org_opendaylight_controller_mdsal_ReadData_fieldAccessorTable;
-
-  public static com.google.protobuf.Descriptors.FileDescriptor
-      getDescriptor() {
-    return descriptor;
-  }
-  private static com.google.protobuf.Descriptors.FileDescriptor
-      descriptor;
-  static {
-    java.lang.String[] descriptorData = {
-      "\n\036ShardTransactionMessages.proto\022!org.op" +
-      "endaylight.controller.mdsal\"\022\n\020CloseTran" +
-      "saction\"\027\n\025CloseTransactionReply\"\023\n\021Crea" +
-      "teTransaction\"1\n\026CreateTransactionReply\022" +
-      "\027\n\017transactionPath\030\001 \002(\t\"\022\n\020ReadyTransac" +
-      "tion\"*\n\025ReadyTransactionReply\022\021\n\tactorPa" +
-      "th\030\001 \002(\t\",\n\nDeleteData\022\036\n\026instanceIdenti" +
-      "fierPath\030\001 \002(\t\"\021\n\017DeleteDataReply\"%\n\010Rea" +
-      "dData\022\031\n\021intanceIdentifier\030\001 \002(\tBU\n9org." +
-      "opendaylight.controller.cluster.datastor",
-      "e.transactionB\030ShardTransactionMessages"
-    };
-    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
-      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
-        public com.google.protobuf.ExtensionRegistry assignDescriptors(
-            com.google.protobuf.Descriptors.FileDescriptor root) {
-          descriptor = root;
-          internal_static_org_opendaylight_controller_mdsal_CloseTransaction_descriptor =
-            getDescriptor().getMessageTypes().get(0);
-          internal_static_org_opendaylight_controller_mdsal_CloseTransaction_fieldAccessorTable = new
-            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-              internal_static_org_opendaylight_controller_mdsal_CloseTransaction_descriptor,
-              new java.lang.String[] { });
-          internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_descriptor =
-            getDescriptor().getMessageTypes().get(1);
-          internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_fieldAccessorTable = new
-            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-              internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_descriptor,
-              new java.lang.String[] { });
-          internal_static_org_opendaylight_controller_mdsal_CreateTransaction_descriptor =
-            getDescriptor().getMessageTypes().get(2);
-          internal_static_org_opendaylight_controller_mdsal_CreateTransaction_fieldAccessorTable = new
-            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-              internal_static_org_opendaylight_controller_mdsal_CreateTransaction_descriptor,
-              new java.lang.String[] { });
-          internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_descriptor =
-            getDescriptor().getMessageTypes().get(3);
-          internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_fieldAccessorTable = new
-            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-              internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_descriptor,
-              new java.lang.String[] { "TransactionPath", });
-          internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_descriptor =
-            getDescriptor().getMessageTypes().get(4);
-          internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_fieldAccessorTable = new
-            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-              internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_descriptor,
-              new java.lang.String[] { });
-          internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_descriptor =
-            getDescriptor().getMessageTypes().get(5);
-          internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_fieldAccessorTable = new
-            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-              internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_descriptor,
-              new java.lang.String[] { "ActorPath", });
-          internal_static_org_opendaylight_controller_mdsal_DeleteData_descriptor =
-            getDescriptor().getMessageTypes().get(6);
-          internal_static_org_opendaylight_controller_mdsal_DeleteData_fieldAccessorTable = new
-            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-              internal_static_org_opendaylight_controller_mdsal_DeleteData_descriptor,
-              new java.lang.String[] { "InstanceIdentifierPath", });
-          internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_descriptor =
-            getDescriptor().getMessageTypes().get(7);
-          internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_fieldAccessorTable = new
-            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-              internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_descriptor,
-              new java.lang.String[] { });
-          internal_static_org_opendaylight_controller_mdsal_ReadData_descriptor =
-            getDescriptor().getMessageTypes().get(8);
-          internal_static_org_opendaylight_controller_mdsal_ReadData_fieldAccessorTable = new
-            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-              internal_static_org_opendaylight_controller_mdsal_ReadData_descriptor,
-              new java.lang.String[] { "IntanceIdentifier", });
-          return null;
-        }
-      };
-    com.google.protobuf.Descriptors.FileDescriptor
-      .internalBuildGeneratedFileFrom(descriptorData,
-        new com.google.protobuf.Descriptors.FileDescriptor[] {
-        }, assigner);
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/util/EncoderDecoderUtil.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/util/EncoderDecoderUtil.java
new file mode 100644 (file)
index 0000000..d9a067b
--- /dev/null
@@ -0,0 +1,330 @@
+package org.opendaylight.controller.cluster.datastore.util;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.serializer.DomFromNormalizedNodeSerializerFactory;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+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.SchemaContext;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.ByteArrayInputStream;
+import java.io.StringWriter;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse
+ * Public License v1.0 which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+/*
+ *
+ * <code>EncoderDecoderUtil</code> helps in wrapping the NormalizedNode into a SimpleNormalizedNode
+ * protobuf message containing the XML representation of the NormalizeNode
+ *
+ * @author: syedbahm
+ */
+public class EncoderDecoderUtil {
+    static DocumentBuilderFactory factory;
+
+    private static DomFromNormalizedNodeSerializerFactory serializerFactory =
+        DomFromNormalizedNodeSerializerFactory
+            .getInstance(XmlDocumentUtils.getDocument(),
+                DomUtils.defaultValueCodecProvider());
+
+    private static DomToNormalizedNodeParserFactory parserFactory =
+        DomToNormalizedNodeParserFactory
+            .getInstance(DomUtils.defaultValueCodecProvider());
+
+    static {
+        factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        factory.setCoalescing(true);
+        factory.setIgnoringElementContentWhitespace(true);
+        factory.setIgnoringComments(true);
+    }
+
+    private static DataSchemaNode findChildNode(Collection<DataSchemaNode> children,
+        String name) {
+        List<DataNodeContainer> containers = Lists.newArrayList();
+
+        for (DataSchemaNode dataSchemaNode : children) {
+            if (dataSchemaNode.getQName().getLocalName().equals(name))
+                return dataSchemaNode;
+            if (dataSchemaNode instanceof DataNodeContainer) {
+                containers.add((DataNodeContainer) dataSchemaNode);
+            } else if (dataSchemaNode instanceof ChoiceNode) {
+                containers.addAll(((ChoiceNode) dataSchemaNode).getCases());
+            }
+        }
+
+        for (DataNodeContainer container : containers) {
+            DataSchemaNode retVal =
+                findChildNode(container.getChildNodes(), name);
+            if (retVal != null) {
+                return retVal;
+            }
+        }
+
+        return null;
+    }
+
+    private static DataSchemaNode getSchemaNode(SchemaContext context,
+        QName qname) {
+
+        for (Module module : context
+            .findModuleByNamespace(qname.getNamespace())) {
+            // we will take the first child as the start of the
+            if (module.getChildNodes() != null || !module.getChildNodes()
+                .isEmpty()) {
+
+                DataSchemaNode found =
+                    findChildNode(module.getChildNodes(), qname.getLocalName());
+                return found;
+            }
+        }
+        return null;
+    }
+
+    private static String toString(Element xml) {
+        try {
+            Transformer transformer =
+                TransformerFactory.newInstance().newTransformer();
+            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+
+            StreamResult result = new StreamResult(new StringWriter());
+            DOMSource source = new DOMSource(xml);
+            transformer.transform(source, result);
+
+            return result.getWriter().toString();
+        } catch (IllegalArgumentException | TransformerFactoryConfigurationError
+            | TransformerException e) {
+            throw new RuntimeException("Unable to serialize xml element " + xml,
+                e);
+        }
+    }
+
+  private static String toString(Iterable<Element> xmlIterable) {
+    try {
+      Transformer transformer =
+          TransformerFactory.newInstance().newTransformer();
+      transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+
+      StreamResult result = new StreamResult(new StringWriter());
+      Iterator iterator = xmlIterable.iterator();
+      DOMSource source;
+      if(iterator.hasNext()) {
+        source = new DOMSource((org.w3c.dom.Node) iterator.next());
+        transformer.transform(source, result);
+        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+      }
+
+      while(iterator.hasNext()) {
+        source = new DOMSource((org.w3c.dom.Node) iterator.next());
+        transformer.transform(source, result);
+      }
+      System.out.println(result.getWriter().toString());
+      return result.getWriter().toString();
+    } catch (IllegalArgumentException | TransformerFactoryConfigurationError
+        | TransformerException e) {
+      throw new RuntimeException("Unable to serialize xml element(s) " + xmlIterable.toString(),
+          e);
+    }
+  }
+
+    private static Iterable<Element> serialize(DataSchemaNode schemaNode, NormalizedNode normalizedNode){
+        if(schemaNode instanceof ContainerSchemaNode){      //1
+            return serializerFactory
+                .getContainerNodeSerializer()
+                .serialize((ContainerSchemaNode) schemaNode,
+                    (ContainerNode) normalizedNode);
+        } else if(schemaNode instanceof ChoiceNode){        //2
+            return serializerFactory
+                .getChoiceNodeSerializer()
+                .serialize((ChoiceNode) schemaNode,
+                    (org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode) normalizedNode);
+        } else if(schemaNode instanceof LeafSchemaNode){    //3
+            return serializerFactory
+                .getLeafNodeSerializer()
+                .serialize((LeafSchemaNode) schemaNode, (LeafNode) normalizedNode);
+        } else if(schemaNode instanceof ListSchemaNode){    //4
+            return serializerFactory
+                .getMapNodeSerializer()
+                .serialize((ListSchemaNode) schemaNode, (MapNode) normalizedNode);
+        } else if(schemaNode instanceof LeafListSchemaNode){    //5
+            return serializerFactory
+                .getLeafSetNodeSerializer()
+                .serialize((LeafListSchemaNode) schemaNode, (LeafSetNode) normalizedNode);
+        } else if(schemaNode instanceof AugmentationSchema){//6
+            return serializerFactory
+                .getAugmentationNodeSerializer()
+                .serialize((AugmentationSchema) schemaNode, (AugmentationNode) normalizedNode);
+        } else if(schemaNode instanceof ListSchemaNode && normalizedNode instanceof LeafSetEntryNode){    //7
+            return serializerFactory
+                .getLeafSetEntryNodeSerializer()
+                .serialize((LeafListSchemaNode) schemaNode, (LeafSetEntryNode) normalizedNode);
+        } else if(schemaNode instanceof ListSchemaNode){    //8
+            return serializerFactory
+                .getMapEntryNodeSerializer()
+                .serialize((ListSchemaNode) schemaNode, (MapEntryNode) normalizedNode);
+        }
+
+
+
+        throw new UnsupportedOperationException(schemaNode.getClass().toString());
+    }
+
+    private static NormalizedNode parse(Document doc, DataSchemaNode schemaNode){
+        if(schemaNode instanceof ContainerSchemaNode){
+            return parserFactory
+                .getContainerNodeParser()
+                .parse(Collections.singletonList(doc.getDocumentElement()),
+                    (ContainerSchemaNode) schemaNode);
+
+        } else if(schemaNode instanceof ChoiceNode){
+            return parserFactory
+                .getChoiceNodeParser()
+                .parse(Collections.singletonList(doc.getDocumentElement()),
+                    (ChoiceNode) schemaNode);
+        } else if(schemaNode instanceof LeafNode){
+            return parserFactory
+                .getLeafNodeParser()
+                .parse(Collections.singletonList(doc.getDocumentElement()),
+                    (LeafSchemaNode) schemaNode);
+        } else if(schemaNode instanceof ListSchemaNode){
+            return parserFactory
+                .getMapNodeParser()
+                .parse(Collections.singletonList(doc.getDocumentElement()),
+                    (ListSchemaNode) schemaNode);
+        } else if(schemaNode instanceof LeafListSchemaNode){
+            return parserFactory
+                .getLeafSetNodeParser()
+                .parse(Collections.singletonList(doc.getDocumentElement()),
+                    (LeafListSchemaNode) schemaNode);
+        } else if(schemaNode instanceof AugmentationSchema){
+            return parserFactory
+                .getAugmentationNodeParser()
+                .parse(Collections.singletonList(doc.getDocumentElement()),
+                    (AugmentationSchema) schemaNode);
+        } else if(schemaNode instanceof ListSchemaNode){
+            return parserFactory
+                .getMapEntryNodeParser()
+                .parse(Collections.singletonList(doc.getDocumentElement()),
+                    (ListSchemaNode) schemaNode);
+
+        }
+
+        throw new UnsupportedOperationException(schemaNode.getClass().toString());
+    }
+
+
+    /**
+     * Helps in generation of NormalizedNodeXml message for the supplied NormalizedNode
+     *
+     * @param sc             --SchemaContext
+     * @param normalizedNode -- Normalized Node to be encoded
+     * @return SimpleNormalizedNodeMessage.NormalizedNodeXml
+     */
+    public static SimpleNormalizedNodeMessage.NormalizedNodeXml encode(
+        SchemaContext sc, NormalizedNode<?, ?> normalizedNode) {
+
+        Preconditions.checkArgument(sc != null, "Schema context found null");
+
+        Preconditions.checkArgument(normalizedNode != null,
+            "normalized node found null");
+
+        DataSchemaNode schemaNode = getSchemaNode(sc,
+            normalizedNode.getIdentifier()
+                .getNodeType()
+        );
+
+        Preconditions.checkState(schemaNode != null,
+            "Couldn't find schema node for " + normalizedNode.getIdentifier());
+
+        Iterable<Element> els = serialize(schemaNode, normalizedNode);
+
+        String xmlString = toString(els.iterator().next());
+        SimpleNormalizedNodeMessage.NormalizedNodeXml.Builder builder =
+            SimpleNormalizedNodeMessage.NormalizedNodeXml.newBuilder();
+        builder.setXmlString(xmlString);
+        builder
+            .setNodeIdentifier(normalizedNode.getIdentifier()
+                .getNodeType().toString());
+        return builder.build();
+
+    }
+
+    /**
+     * Utilizes the SimpleNormalizedNodeMessage.NormalizedNodeXml to convert into NormalizedNode
+     *
+     * @param sc                -- schema context
+     * @param normalizedNodeXml -- containing the normalized Node XML
+     * @return NormalizedNode return
+     * @throws Exception
+     */
+
+    public static NormalizedNode decode(SchemaContext sc,
+        SimpleNormalizedNodeMessage.NormalizedNodeXml normalizedNodeXml)
+        throws Exception {
+
+        Preconditions
+            .checkArgument(sc != null, "schema context seems to be null");
+
+        Preconditions.checkArgument(normalizedNodeXml != null,
+            "SimpleNormalizedNodeMessage.NormalizedNodeXml found to be null");
+        QName qname = QName.create(normalizedNodeXml.getNodeIdentifier());
+
+        // here we will try to get back the NormalizedNode
+        DataSchemaNode schemaNode = getSchemaNode(sc, qname);
+
+        // now we need to read the XML
+        Document doc =
+            factory.newDocumentBuilder().parse(
+                new ByteArrayInputStream(
+                    normalizedNodeXml.getXmlString().getBytes(
+                        "utf-8"))
+            );
+
+        doc.getDocumentElement().normalize();
+
+
+        return parse(doc, schemaNode);
+    }
+
+
+
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/util/InstanceIdentifierUtils.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/util/InstanceIdentifierUtils.java
new file mode 100644 (file)
index 0000000..5b459e7
--- /dev/null
@@ -0,0 +1,277 @@
+package org.opendaylight.controller.cluster.datastore.util;
+
+import org.opendaylight.controller.cluster.datastore.node.utils.NodeIdentifierFactory;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * This class contains utility methods for converting an MD-SAL
+ * YangInstanceIdentifier to and from other representations.
+ * <p>
+ * The representations convered for now are,
+ *
+ * <ul>
+ *     <li>String</li>
+ *     <li>Protocol Buffer</li>
+ * </ul>
+ */
+public class InstanceIdentifierUtils {
+
+    protected static final Logger logger = LoggerFactory
+        .getLogger(InstanceIdentifierUtils.class);
+
+    @Deprecated
+    public static YangInstanceIdentifier from(String path) {
+        String[] ids = path.split("/");
+
+        List<YangInstanceIdentifier.PathArgument> pathArguments =
+            new ArrayList<>();
+        for (String nodeId : ids) {
+            if (!"".equals(nodeId)) {
+                pathArguments
+                    .add(NodeIdentifierFactory.getArgument(nodeId));
+            }
+        }
+        final YangInstanceIdentifier instanceIdentifier =
+            YangInstanceIdentifier.create(pathArguments);
+        return instanceIdentifier;
+    }
+
+
+    /**
+     * Convert an MD-SAL YangInstanceIdentifier into a protocol buffer version of it
+     *
+     * @param path an MD-SAL YangInstanceIdentifier
+     * @return a protocol buffer version of the MD-SAL YangInstanceIdentifier
+     */
+    public static NormalizedNodeMessages.InstanceIdentifier toSerializable(YangInstanceIdentifier path){
+        NormalizedNodeMessages.InstanceIdentifier.Builder builder =
+            NormalizedNodeMessages.InstanceIdentifier.newBuilder();
+
+        try {
+
+            for (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument pathArgument : path
+                .getPathArguments()) {
+
+                String nodeType = "";
+                if(!(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier)){
+                    nodeType = pathArgument.getNodeType().toString();
+                }
+
+                NormalizedNodeMessages.PathArgument serializablePathArgument =
+                    NormalizedNodeMessages.PathArgument.newBuilder()
+                        .setValue(pathArgument.toString())
+                        .setType(pathArgument.getClass().getSimpleName())
+                        .setNodeType(NormalizedNodeMessages.QName.newBuilder()
+                            .setValue(nodeType))
+                        .addAllAttributes(getPathArgumentAttributes(
+                            pathArgument))
+                        .build();
+
+                builder.addArguments(serializablePathArgument);
+            }
+
+        } catch(Exception e){
+            logger.error("An exception occurred", e);
+        }
+        return builder.build();
+    }
+
+
+    /**
+     * Convert a protocol buffer version of the MD-SAL YangInstanceIdentifier into
+     * the MD-SAL version of the YangInstanceIdentifier
+     *
+     * @param path a protocol buffer version of the MD-SAL YangInstanceIdentifier
+     * @return  an MD-SAL YangInstanceIdentifier
+     */
+    public static YangInstanceIdentifier fromSerializable(NormalizedNodeMessages.InstanceIdentifier path){
+
+        List<YangInstanceIdentifier.PathArgument> pathArguments =
+            new ArrayList<>();
+
+        for(NormalizedNodeMessages.PathArgument pathArgument : path.getArgumentsList()){
+
+            pathArguments
+                .add(parsePathArgument(pathArgument));
+
+        }
+
+        final YangInstanceIdentifier instanceIdentifier = YangInstanceIdentifier.create(pathArguments);
+
+        return instanceIdentifier;
+    }
+
+    /**
+     * Take the various attributes of a PathArgument and package them up as
+     * protocol buffer attributes.
+     * <p>
+     *
+     * PathArguments have 4 subtypes and each of the various subtypes have
+     * different attributes
+     * <ul>
+     *     <li>
+     *         NodeIdentifier is the most basic PathArgument. It is used for
+     *         ContainerNode, LeafNode etc and has no attributes
+     *     </li>
+     *     <li>
+     *         NodeWithValue has only a single attribute. It is used for
+     *         LeafListEntryNodes and the attribute it contains is the value
+     *         of the entry
+     *     </li>
+     *     <li>
+     *         NodeIdentifierWithPredicates has a map of attributes.
+     *         It is used to represent a ListItemNode. Each entry
+     *         in the map of attributes represents the key and value of the
+     *         keys in that entry.
+     *     </li>
+     *     <li>
+     *         AugmentationIdentifier has a list of unnamed attributes. Each
+     *         attribute represents the possible children that can go within
+     *         an augmentation entry.
+     *     </li>
+     * </ul>
+     * @param pathArgument
+     * @return
+     */
+    private static Iterable<? extends NormalizedNodeMessages.Attribute> getPathArgumentAttributes(
+        YangInstanceIdentifier.PathArgument pathArgument) {
+        List<NormalizedNodeMessages.Attribute> attributes = new ArrayList<>();
+
+
+
+        if (pathArgument instanceof YangInstanceIdentifier.NodeWithValue) {
+            YangInstanceIdentifier.NodeWithValue identifier
+                = (YangInstanceIdentifier.NodeWithValue) pathArgument;
+
+            NormalizedNodeMessages.Attribute attribute =
+                NormalizedNodeMessages.Attribute.newBuilder()
+                    .setName("name")
+                    .setValue(identifier.getValue().toString())
+                    .setType(identifier.getValue().getClass().getSimpleName())
+                    .build();
+
+            attributes.add(attribute);
+        } else if (pathArgument instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) {
+            YangInstanceIdentifier.NodeIdentifierWithPredicates identifier
+                = (YangInstanceIdentifier.NodeIdentifierWithPredicates) pathArgument;
+
+            for (QName key : identifier.getKeyValues().keySet()) {
+                Object value = identifier.getKeyValues().get(key);
+                NormalizedNodeMessages.Attribute attribute =
+                    NormalizedNodeMessages.Attribute.newBuilder()
+                        .setName(key.toString())
+                        .setValue(value.toString())
+                        .setType(value.getClass().getSimpleName())
+                        .build();
+
+                attributes.add(attribute);
+
+            }
+
+        } else if(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier) {
+            YangInstanceIdentifier.AugmentationIdentifier identifier
+                = (YangInstanceIdentifier.AugmentationIdentifier) pathArgument;
+
+            for (QName key : identifier.getPossibleChildNames()) {
+                Object value = key;
+                NormalizedNodeMessages.Attribute attribute =
+                    NormalizedNodeMessages.Attribute.newBuilder()
+                        .setName(key.toString())
+                        .setValue(value.toString())
+                        .setType(value.getClass().getSimpleName())
+                        .build();
+
+                attributes.add(attribute);
+
+            }
+        }
+
+        return attributes;
+    }
+
+
+    /**
+     * Parse a protocol buffer PathArgument and return an MD-SAL PathArgument
+     *
+     * @param pathArgument protocol buffer PathArgument
+     * @return MD-SAL PathArgument
+     */
+    private static YangInstanceIdentifier.PathArgument parsePathArgument(NormalizedNodeMessages.PathArgument pathArgument) {
+        if (YangInstanceIdentifier.NodeWithValue.class.getSimpleName().equals(pathArgument.getType())) {
+
+            YangInstanceIdentifier.NodeWithValue nodeWithValue =
+                new YangInstanceIdentifier.NodeWithValue(
+                    QName.create(pathArgument.getNodeType().getValue()),
+                    parseAttribute(pathArgument.getAttributes(0)));
+
+            return nodeWithValue;
+
+        } else if(YangInstanceIdentifier.NodeIdentifierWithPredicates.class.getSimpleName().equals(pathArgument.getType())){
+
+            YangInstanceIdentifier.NodeIdentifierWithPredicates
+                nodeIdentifierWithPredicates =
+                new YangInstanceIdentifier.NodeIdentifierWithPredicates(
+                    QName.create(pathArgument.getNodeType().getValue()), toAttributesMap(pathArgument.getAttributesList()));
+
+            return nodeIdentifierWithPredicates;
+
+        } else if(YangInstanceIdentifier.AugmentationIdentifier.class.getSimpleName().equals(pathArgument.getType())){
+
+            Set<QName> qNameSet = new HashSet<>();
+
+            for(NormalizedNodeMessages.Attribute attribute : pathArgument.getAttributesList()){
+                qNameSet.add(QName.create(attribute.getValue()));
+            }
+
+            return new YangInstanceIdentifier.AugmentationIdentifier(qNameSet);
+        }
+
+        return NodeIdentifierFactory.getArgument(pathArgument.getValue());
+    }
+
+    private static Map<QName, Object> toAttributesMap(
+        List<NormalizedNodeMessages.Attribute> attributesList) {
+
+        Map<QName, Object> map = new HashMap<>();
+
+        for(NormalizedNodeMessages.Attribute attribute : attributesList){
+            String name = attribute.getName();
+            Object value = parseAttribute(attribute);
+
+            map.put(QName.create(name), value);
+        }
+
+        return map;
+    }
+
+    /**
+     * FIXME: This method only covers a subset of values that may go in an InstanceIdentifier
+     *
+     * @param attribute
+     * @return
+     */
+    private static Object parseAttribute(NormalizedNodeMessages.Attribute attribute){
+        if(Short.class.getSimpleName().equals(attribute.getType())) {
+            return Short.parseShort(attribute.getValue());
+        } else if(Long.class.getSimpleName().equals(attribute.getType())){
+            return Long.parseLong(attribute.getValue());
+        } else if(Boolean.class.getSimpleName().equals(attribute.getType())){
+            return Boolean.parseBoolean(attribute.getValue());
+        } else if(Integer.class.getSimpleName().equals(attribute.getType())){
+            return Integer.parseInt(attribute.getValue());
+        }
+
+        return attribute.getValue();
+    }
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/mdsal/CompositeModificationPayload.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/mdsal/CompositeModificationPayload.java
new file mode 100644 (file)
index 0000000..87b246b
--- /dev/null
@@ -0,0 +1,60 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: CompositeModificationPayload.proto
+
+package org.opendaylight.controller.mdsal;
+
+public final class CompositeModificationPayload {
+  private CompositeModificationPayload() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registry.add(org.opendaylight.controller.mdsal.CompositeModificationPayload.modification);
+  }
+  public static final int MODIFICATION_FIELD_NUMBER = 2;
+  /**
+   * <code>extend .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload { ... }</code>
+   */
+  public static final
+    com.google.protobuf.GeneratedMessage.GeneratedExtension<
+      org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload,
+      org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification> modification = com.google.protobuf.GeneratedMessage
+          .newFileScopedGeneratedExtension(
+        org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification.class,
+        org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification.getDefaultInstance());
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\"CompositeModificationPayload.proto\022!or" +
+      "g.opendaylight.controller.mdsal\032\033AppendE" +
+      "ntriesMessages.proto\032\014Common.proto\032\020Pers" +
+      "istent.proto:\242\001\n\014modification\022R.org.open" +
+      "daylight.controller.cluster.raft.AppendE" +
+      "ntries.ReplicatedLogEntry.Payload\030\002 \001(\0132" +
+      "8.org.opendaylight.controller.mdsal.Comp" +
+      "ositeModification"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          modification.internalInit(descriptor.getExtensions().get(0));
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.getDescriptor(),
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.getDescriptor(),
+          org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.getDescriptor(),
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/cohort3pc/ThreePhaseCommitCohortMessages.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/cohort3pc/ThreePhaseCommitCohortMessages.java
new file mode 100644 (file)
index 0000000..ac0701a
--- /dev/null
@@ -0,0 +1,2700 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: Cohort.proto
+
+package org.opendaylight.controller.protobuff.messages.cohort3pc;
+
+public final class ThreePhaseCommitCohortMessages {
+  private ThreePhaseCommitCohortMessages() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface CanCommitTransactionOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.CanCommitTransaction}
+   */
+  public static final class CanCommitTransaction extends
+      com.google.protobuf.GeneratedMessage
+      implements CanCommitTransactionOrBuilder {
+    // Use CanCommitTransaction.newBuilder() to construct.
+    private CanCommitTransaction(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private CanCommitTransaction(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final CanCommitTransaction defaultInstance;
+    public static CanCommitTransaction getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public CanCommitTransaction getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private CanCommitTransaction(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CanCommitTransaction_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CanCommitTransaction_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<CanCommitTransaction> PARSER =
+        new com.google.protobuf.AbstractParser<CanCommitTransaction>() {
+      public CanCommitTransaction parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new CanCommitTransaction(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CanCommitTransaction> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.CanCommitTransaction}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CanCommitTransaction_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CanCommitTransaction_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CanCommitTransaction_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction build() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction buildPartial() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction result = new org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction other) {
+        if (other == org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransaction) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CanCommitTransaction)
+    }
+
+    static {
+      defaultInstance = new CanCommitTransaction(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CanCommitTransaction)
+  }
+
+  public interface CanCommitTransactionReplyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required bool canCommit = 1;
+    /**
+     * <code>required bool canCommit = 1;</code>
+     */
+    boolean hasCanCommit();
+    /**
+     * <code>required bool canCommit = 1;</code>
+     */
+    boolean getCanCommit();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.CanCommitTransactionReply}
+   */
+  public static final class CanCommitTransactionReply extends
+      com.google.protobuf.GeneratedMessage
+      implements CanCommitTransactionReplyOrBuilder {
+    // Use CanCommitTransactionReply.newBuilder() to construct.
+    private CanCommitTransactionReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private CanCommitTransactionReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final CanCommitTransactionReply defaultInstance;
+    public static CanCommitTransactionReply getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public CanCommitTransactionReply getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private CanCommitTransactionReply(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              bitField0_ |= 0x00000001;
+              canCommit_ = input.readBool();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CanCommitTransactionReply_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CanCommitTransactionReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<CanCommitTransactionReply> PARSER =
+        new com.google.protobuf.AbstractParser<CanCommitTransactionReply>() {
+      public CanCommitTransactionReply parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new CanCommitTransactionReply(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CanCommitTransactionReply> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required bool canCommit = 1;
+    public static final int CANCOMMIT_FIELD_NUMBER = 1;
+    private boolean canCommit_;
+    /**
+     * <code>required bool canCommit = 1;</code>
+     */
+    public boolean hasCanCommit() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required bool canCommit = 1;</code>
+     */
+    public boolean getCanCommit() {
+      return canCommit_;
+    }
+
+    private void initFields() {
+      canCommit_ = false;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasCanCommit()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBool(1, canCommit_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(1, canCommit_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.CanCommitTransactionReply}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReplyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CanCommitTransactionReply_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CanCommitTransactionReply_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        canCommit_ = false;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CanCommitTransactionReply_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply build() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply result = new org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.canCommit_ = canCommit_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply.getDefaultInstance()) return this;
+        if (other.hasCanCommit()) {
+          setCanCommit(other.getCanCommit());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasCanCommit()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CanCommitTransactionReply) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required bool canCommit = 1;
+      private boolean canCommit_ ;
+      /**
+       * <code>required bool canCommit = 1;</code>
+       */
+      public boolean hasCanCommit() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required bool canCommit = 1;</code>
+       */
+      public boolean getCanCommit() {
+        return canCommit_;
+      }
+      /**
+       * <code>required bool canCommit = 1;</code>
+       */
+      public Builder setCanCommit(boolean value) {
+        bitField0_ |= 0x00000001;
+        canCommit_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required bool canCommit = 1;</code>
+       */
+      public Builder clearCanCommit() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        canCommit_ = false;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CanCommitTransactionReply)
+    }
+
+    static {
+      defaultInstance = new CanCommitTransactionReply(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CanCommitTransactionReply)
+  }
+
+  public interface AbortTransactionOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.AbortTransaction}
+   */
+  public static final class AbortTransaction extends
+      com.google.protobuf.GeneratedMessage
+      implements AbortTransactionOrBuilder {
+    // Use AbortTransaction.newBuilder() to construct.
+    private AbortTransaction(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private AbortTransaction(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final AbortTransaction defaultInstance;
+    public static AbortTransaction getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public AbortTransaction getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private AbortTransaction(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_AbortTransaction_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_AbortTransaction_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<AbortTransaction> PARSER =
+        new com.google.protobuf.AbstractParser<AbortTransaction>() {
+      public AbortTransaction parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new AbortTransaction(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<AbortTransaction> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.AbortTransaction}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_AbortTransaction_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_AbortTransaction_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_AbortTransaction_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction build() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction buildPartial() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction result = new org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction other) {
+        if (other == org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransaction) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.AbortTransaction)
+    }
+
+    static {
+      defaultInstance = new AbortTransaction(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.AbortTransaction)
+  }
+
+  public interface AbortTransactionReplyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.AbortTransactionReply}
+   */
+  public static final class AbortTransactionReply extends
+      com.google.protobuf.GeneratedMessage
+      implements AbortTransactionReplyOrBuilder {
+    // Use AbortTransactionReply.newBuilder() to construct.
+    private AbortTransactionReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private AbortTransactionReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final AbortTransactionReply defaultInstance;
+    public static AbortTransactionReply getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public AbortTransactionReply getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private AbortTransactionReply(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_AbortTransactionReply_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_AbortTransactionReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<AbortTransactionReply> PARSER =
+        new com.google.protobuf.AbstractParser<AbortTransactionReply>() {
+      public AbortTransactionReply parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new AbortTransactionReply(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<AbortTransactionReply> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.AbortTransactionReply}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReplyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_AbortTransactionReply_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_AbortTransactionReply_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_AbortTransactionReply_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply build() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply result = new org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.AbortTransactionReply) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.AbortTransactionReply)
+    }
+
+    static {
+      defaultInstance = new AbortTransactionReply(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.AbortTransactionReply)
+  }
+
+  public interface CommitTransactionOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.CommitTransaction}
+   */
+  public static final class CommitTransaction extends
+      com.google.protobuf.GeneratedMessage
+      implements CommitTransactionOrBuilder {
+    // Use CommitTransaction.newBuilder() to construct.
+    private CommitTransaction(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private CommitTransaction(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final CommitTransaction defaultInstance;
+    public static CommitTransaction getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public CommitTransaction getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private CommitTransaction(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CommitTransaction_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CommitTransaction_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<CommitTransaction> PARSER =
+        new com.google.protobuf.AbstractParser<CommitTransaction>() {
+      public CommitTransaction parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new CommitTransaction(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CommitTransaction> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.CommitTransaction}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CommitTransaction_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CommitTransaction_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CommitTransaction_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction build() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction buildPartial() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction result = new org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction other) {
+        if (other == org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransaction) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CommitTransaction)
+    }
+
+    static {
+      defaultInstance = new CommitTransaction(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CommitTransaction)
+  }
+
+  public interface CommitTransactionReplyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.CommitTransactionReply}
+   */
+  public static final class CommitTransactionReply extends
+      com.google.protobuf.GeneratedMessage
+      implements CommitTransactionReplyOrBuilder {
+    // Use CommitTransactionReply.newBuilder() to construct.
+    private CommitTransactionReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private CommitTransactionReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final CommitTransactionReply defaultInstance;
+    public static CommitTransactionReply getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public CommitTransactionReply getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private CommitTransactionReply(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CommitTransactionReply_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CommitTransactionReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<CommitTransactionReply> PARSER =
+        new com.google.protobuf.AbstractParser<CommitTransactionReply>() {
+      public CommitTransactionReply parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new CommitTransactionReply(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CommitTransactionReply> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.CommitTransactionReply}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReplyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CommitTransactionReply_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CommitTransactionReply_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_CommitTransactionReply_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply build() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply result = new org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.CommitTransactionReply) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CommitTransactionReply)
+    }
+
+    static {
+      defaultInstance = new CommitTransactionReply(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CommitTransactionReply)
+  }
+
+  public interface PreCommitTransactionOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.PreCommitTransaction}
+   */
+  public static final class PreCommitTransaction extends
+      com.google.protobuf.GeneratedMessage
+      implements PreCommitTransactionOrBuilder {
+    // Use PreCommitTransaction.newBuilder() to construct.
+    private PreCommitTransaction(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private PreCommitTransaction(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final PreCommitTransaction defaultInstance;
+    public static PreCommitTransaction getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public PreCommitTransaction getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private PreCommitTransaction(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_PreCommitTransaction_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_PreCommitTransaction_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<PreCommitTransaction> PARSER =
+        new com.google.protobuf.AbstractParser<PreCommitTransaction>() {
+      public PreCommitTransaction parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new PreCommitTransaction(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<PreCommitTransaction> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.PreCommitTransaction}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_PreCommitTransaction_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_PreCommitTransaction_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_PreCommitTransaction_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction build() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction buildPartial() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction result = new org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction other) {
+        if (other == org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransaction) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.PreCommitTransaction)
+    }
+
+    static {
+      defaultInstance = new PreCommitTransaction(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.PreCommitTransaction)
+  }
+
+  public interface PreCommitTransactionReplyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.PreCommitTransactionReply}
+   */
+  public static final class PreCommitTransactionReply extends
+      com.google.protobuf.GeneratedMessage
+      implements PreCommitTransactionReplyOrBuilder {
+    // Use PreCommitTransactionReply.newBuilder() to construct.
+    private PreCommitTransactionReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private PreCommitTransactionReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final PreCommitTransactionReply defaultInstance;
+    public static PreCommitTransactionReply getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public PreCommitTransactionReply getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private PreCommitTransactionReply(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_PreCommitTransactionReply_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_PreCommitTransactionReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<PreCommitTransactionReply> PARSER =
+        new com.google.protobuf.AbstractParser<PreCommitTransactionReply>() {
+      public PreCommitTransactionReply parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new PreCommitTransactionReply(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<PreCommitTransactionReply> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.PreCommitTransactionReply}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReplyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_PreCommitTransactionReply_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_PreCommitTransactionReply_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply.class, org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.internal_static_org_opendaylight_controller_mdsal_PreCommitTransactionReply_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply build() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply result = new org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.cohort3pc.ThreePhaseCommitCohortMessages.PreCommitTransactionReply) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.PreCommitTransactionReply)
+    }
+
+    static {
+      defaultInstance = new PreCommitTransactionReply(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.PreCommitTransactionReply)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_CanCommitTransaction_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_CanCommitTransaction_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_CanCommitTransactionReply_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_CanCommitTransactionReply_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_AbortTransaction_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_AbortTransaction_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_AbortTransactionReply_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_AbortTransactionReply_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_CommitTransaction_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_CommitTransaction_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_CommitTransactionReply_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_CommitTransactionReply_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_PreCommitTransaction_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_PreCommitTransaction_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_PreCommitTransactionReply_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_PreCommitTransactionReply_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\014Cohort.proto\022!org.opendaylight.control" +
+      "ler.mdsal\"\026\n\024CanCommitTransaction\".\n\031Can" +
+      "CommitTransactionReply\022\021\n\tcanCommit\030\001 \002(" +
+      "\010\"\022\n\020AbortTransaction\"\027\n\025AbortTransactio" +
+      "nReply\"\023\n\021CommitTransaction\"\030\n\026CommitTra" +
+      "nsactionReply\"\026\n\024PreCommitTransaction\"\033\n" +
+      "\031PreCommitTransactionReplyBZ\n8org.openda" +
+      "ylight.controller.protobuff.messages.coh" +
+      "ort3pcB\036ThreePhaseCommitCohortMessages"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_org_opendaylight_controller_mdsal_CanCommitTransaction_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_org_opendaylight_controller_mdsal_CanCommitTransaction_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_CanCommitTransaction_descriptor,
+              new java.lang.String[] { });
+          internal_static_org_opendaylight_controller_mdsal_CanCommitTransactionReply_descriptor =
+            getDescriptor().getMessageTypes().get(1);
+          internal_static_org_opendaylight_controller_mdsal_CanCommitTransactionReply_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_CanCommitTransactionReply_descriptor,
+              new java.lang.String[] { "CanCommit", });
+          internal_static_org_opendaylight_controller_mdsal_AbortTransaction_descriptor =
+            getDescriptor().getMessageTypes().get(2);
+          internal_static_org_opendaylight_controller_mdsal_AbortTransaction_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_AbortTransaction_descriptor,
+              new java.lang.String[] { });
+          internal_static_org_opendaylight_controller_mdsal_AbortTransactionReply_descriptor =
+            getDescriptor().getMessageTypes().get(3);
+          internal_static_org_opendaylight_controller_mdsal_AbortTransactionReply_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_AbortTransactionReply_descriptor,
+              new java.lang.String[] { });
+          internal_static_org_opendaylight_controller_mdsal_CommitTransaction_descriptor =
+            getDescriptor().getMessageTypes().get(4);
+          internal_static_org_opendaylight_controller_mdsal_CommitTransaction_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_CommitTransaction_descriptor,
+              new java.lang.String[] { });
+          internal_static_org_opendaylight_controller_mdsal_CommitTransactionReply_descriptor =
+            getDescriptor().getMessageTypes().get(5);
+          internal_static_org_opendaylight_controller_mdsal_CommitTransactionReply_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_CommitTransactionReply_descriptor,
+              new java.lang.String[] { });
+          internal_static_org_opendaylight_controller_mdsal_PreCommitTransaction_descriptor =
+            getDescriptor().getMessageTypes().get(6);
+          internal_static_org_opendaylight_controller_mdsal_PreCommitTransaction_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_PreCommitTransaction_descriptor,
+              new java.lang.String[] { });
+          internal_static_org_opendaylight_controller_mdsal_PreCommitTransactionReply_descriptor =
+            getDescriptor().getMessageTypes().get(7);
+          internal_static_org_opendaylight_controller_mdsal_PreCommitTransactionReply_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_PreCommitTransactionReply_descriptor,
+              new java.lang.String[] { });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/common/NormalizedNodeMessages.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/common/NormalizedNodeMessages.java
new file mode 100644 (file)
index 0000000..81e5b46
--- /dev/null
@@ -0,0 +1,7541 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: Common.proto
+
+package org.opendaylight.controller.protobuff.messages.common;
+
+public final class NormalizedNodeMessages {
+  private NormalizedNodeMessages() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface AttributeOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string name = 1;
+    /**
+     * <code>required string name = 1;</code>
+     */
+    boolean hasName();
+    /**
+     * <code>required string name = 1;</code>
+     */
+    java.lang.String getName();
+    /**
+     * <code>required string name = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getNameBytes();
+
+    // optional string value = 2;
+    /**
+     * <code>optional string value = 2;</code>
+     */
+    boolean hasValue();
+    /**
+     * <code>optional string value = 2;</code>
+     */
+    java.lang.String getValue();
+    /**
+     * <code>optional string value = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getValueBytes();
+
+    // optional string type = 3;
+    /**
+     * <code>optional string type = 3;</code>
+     */
+    boolean hasType();
+    /**
+     * <code>optional string type = 3;</code>
+     */
+    java.lang.String getType();
+    /**
+     * <code>optional string type = 3;</code>
+     */
+    com.google.protobuf.ByteString
+        getTypeBytes();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.Attribute}
+   */
+  public static final class Attribute extends
+      com.google.protobuf.GeneratedMessage
+      implements AttributeOrBuilder {
+    // Use Attribute.newBuilder() to construct.
+    private Attribute(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Attribute(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final Attribute defaultInstance;
+    public static Attribute getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Attribute getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Attribute(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              name_ = input.readBytes();
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              value_ = input.readBytes();
+              break;
+            }
+            case 26: {
+              bitField0_ |= 0x00000004;
+              type_ = input.readBytes();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Attribute_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Attribute_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<Attribute> PARSER =
+        new com.google.protobuf.AbstractParser<Attribute>() {
+      public Attribute parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Attribute(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Attribute> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string name = 1;
+    public static final int NAME_FIELD_NUMBER = 1;
+    private java.lang.Object name_;
+    /**
+     * <code>required string name = 1;</code>
+     */
+    public boolean hasName() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string name = 1;</code>
+     */
+    public java.lang.String getName() {
+      java.lang.Object ref = name_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          name_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string name = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      java.lang.Object ref = name_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional string value = 2;
+    public static final int VALUE_FIELD_NUMBER = 2;
+    private java.lang.Object value_;
+    /**
+     * <code>optional string value = 2;</code>
+     */
+    public boolean hasValue() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional string value = 2;</code>
+     */
+    public java.lang.String getValue() {
+      java.lang.Object ref = value_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          value_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string value = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getValueBytes() {
+      java.lang.Object ref = value_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        value_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional string type = 3;
+    public static final int TYPE_FIELD_NUMBER = 3;
+    private java.lang.Object type_;
+    /**
+     * <code>optional string type = 3;</code>
+     */
+    public boolean hasType() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>optional string type = 3;</code>
+     */
+    public java.lang.String getType() {
+      java.lang.Object ref = type_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          type_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string type = 3;</code>
+     */
+    public com.google.protobuf.ByteString
+        getTypeBytes() {
+      java.lang.Object ref = type_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        type_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    private void initFields() {
+      name_ = "";
+      value_ = "";
+      type_ = "";
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasName()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getNameBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, getValueBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeBytes(3, getTypeBytes());
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getNameBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, getValueBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(3, getTypeBytes());
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.Attribute}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Attribute_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Attribute_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        name_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        value_ = "";
+        bitField0_ = (bitField0_ & ~0x00000002);
+        type_ = "";
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Attribute_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute build() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute buildPartial() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute result = new org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.name_ = name_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.value_ = value_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.type_ = type_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute other) {
+        if (other == org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.getDefaultInstance()) return this;
+        if (other.hasName()) {
+          bitField0_ |= 0x00000001;
+          name_ = other.name_;
+          onChanged();
+        }
+        if (other.hasValue()) {
+          bitField0_ |= 0x00000002;
+          value_ = other.value_;
+          onChanged();
+        }
+        if (other.hasType()) {
+          bitField0_ |= 0x00000004;
+          type_ = other.type_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasName()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string name = 1;
+      private java.lang.Object name_ = "";
+      /**
+       * <code>required string name = 1;</code>
+       */
+      public boolean hasName() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string name = 1;</code>
+       */
+      public java.lang.String getName() {
+        java.lang.Object ref = name_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          name_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string name = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getNameBytes() {
+        java.lang.Object ref = name_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          name_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string name = 1;</code>
+       */
+      public Builder setName(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        name_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string name = 1;</code>
+       */
+      public Builder clearName() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        name_ = getDefaultInstance().getName();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string name = 1;</code>
+       */
+      public Builder setNameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        name_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional string value = 2;
+      private java.lang.Object value_ = "";
+      /**
+       * <code>optional string value = 2;</code>
+       */
+      public boolean hasValue() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional string value = 2;</code>
+       */
+      public java.lang.String getValue() {
+        java.lang.Object ref = value_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          value_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string value = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getValueBytes() {
+        java.lang.Object ref = value_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          value_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string value = 2;</code>
+       */
+      public Builder setValue(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string value = 2;</code>
+       */
+      public Builder clearValue() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        value_ = getDefaultInstance().getValue();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string value = 2;</code>
+       */
+      public Builder setValueBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional string type = 3;
+      private java.lang.Object type_ = "";
+      /**
+       * <code>optional string type = 3;</code>
+       */
+      public boolean hasType() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>optional string type = 3;</code>
+       */
+      public java.lang.String getType() {
+        java.lang.Object ref = type_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          type_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string type = 3;</code>
+       */
+      public com.google.protobuf.ByteString
+          getTypeBytes() {
+        java.lang.Object ref = type_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          type_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string type = 3;</code>
+       */
+      public Builder setType(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+        type_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string type = 3;</code>
+       */
+      public Builder clearType() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        type_ = getDefaultInstance().getType();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string type = 3;</code>
+       */
+      public Builder setTypeBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+        type_ = value;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.Attribute)
+    }
+
+    static {
+      defaultInstance = new Attribute(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.Attribute)
+  }
+
+  public interface QNameOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string value = 1;
+    /**
+     * <code>required string value = 1;</code>
+     */
+    boolean hasValue();
+    /**
+     * <code>required string value = 1;</code>
+     */
+    java.lang.String getValue();
+    /**
+     * <code>required string value = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getValueBytes();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.QName}
+   */
+  public static final class QName extends
+      com.google.protobuf.GeneratedMessage
+      implements QNameOrBuilder {
+    // Use QName.newBuilder() to construct.
+    private QName(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private QName(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final QName defaultInstance;
+    public static QName getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public QName getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private QName(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              value_ = input.readBytes();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_QName_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_QName_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<QName> PARSER =
+        new com.google.protobuf.AbstractParser<QName>() {
+      public QName parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new QName(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<QName> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string value = 1;
+    public static final int VALUE_FIELD_NUMBER = 1;
+    private java.lang.Object value_;
+    /**
+     * <code>required string value = 1;</code>
+     */
+    public boolean hasValue() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string value = 1;</code>
+     */
+    public java.lang.String getValue() {
+      java.lang.Object ref = value_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          value_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string value = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getValueBytes() {
+      java.lang.Object ref = value_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        value_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    private void initFields() {
+      value_ = "";
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasValue()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getValueBytes());
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getValueBytes());
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.QName}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QNameOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_QName_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_QName_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        value_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_QName_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName build() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName buildPartial() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName result = new org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.value_ = value_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName other) {
+        if (other == org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.getDefaultInstance()) return this;
+        if (other.hasValue()) {
+          bitField0_ |= 0x00000001;
+          value_ = other.value_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasValue()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string value = 1;
+      private java.lang.Object value_ = "";
+      /**
+       * <code>required string value = 1;</code>
+       */
+      public boolean hasValue() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string value = 1;</code>
+       */
+      public java.lang.String getValue() {
+        java.lang.Object ref = value_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          value_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string value = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getValueBytes() {
+        java.lang.Object ref = value_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          value_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string value = 1;</code>
+       */
+      public Builder setValue(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string value = 1;</code>
+       */
+      public Builder clearValue() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        value_ = getDefaultInstance().getValue();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string value = 1;</code>
+       */
+      public Builder setValueBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.QName)
+    }
+
+    static {
+      defaultInstance = new QName(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.QName)
+  }
+
+  public interface PathArgumentOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string value = 1;
+    /**
+     * <code>required string value = 1;</code>
+     */
+    boolean hasValue();
+    /**
+     * <code>required string value = 1;</code>
+     */
+    java.lang.String getValue();
+    /**
+     * <code>required string value = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getValueBytes();
+
+    // optional string type = 2;
+    /**
+     * <code>optional string type = 2;</code>
+     *
+     * <pre>
+     *NodeIdentifier, NodeWithValue, NodeIdentifierWithPredicates
+     * </pre>
+     */
+    boolean hasType();
+    /**
+     * <code>optional string type = 2;</code>
+     *
+     * <pre>
+     *NodeIdentifier, NodeWithValue, NodeIdentifierWithPredicates
+     * </pre>
+     */
+    java.lang.String getType();
+    /**
+     * <code>optional string type = 2;</code>
+     *
+     * <pre>
+     *NodeIdentifier, NodeWithValue, NodeIdentifierWithPredicates
+     * </pre>
+     */
+    com.google.protobuf.ByteString
+        getTypeBytes();
+
+    // optional .org.opendaylight.controller.mdsal.QName nodeType = 3;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+     */
+    boolean hasNodeType();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName getNodeType();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QNameOrBuilder getNodeTypeOrBuilder();
+
+    // repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+     */
+    java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute> 
+        getAttributesList();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute getAttributes(int index);
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+     */
+    int getAttributesCount();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+     */
+    java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder> 
+        getAttributesOrBuilderList();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder getAttributesOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.PathArgument}
+   */
+  public static final class PathArgument extends
+      com.google.protobuf.GeneratedMessage
+      implements PathArgumentOrBuilder {
+    // Use PathArgument.newBuilder() to construct.
+    private PathArgument(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private PathArgument(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final PathArgument defaultInstance;
+    public static PathArgument getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public PathArgument getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private PathArgument(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              value_ = input.readBytes();
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              type_ = input.readBytes();
+              break;
+            }
+            case 26: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+                subBuilder = nodeType_.toBuilder();
+              }
+              nodeType_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(nodeType_);
+                nodeType_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000004;
+              break;
+            }
+            case 34: {
+              if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+                attributes_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute>();
+                mutable_bitField0_ |= 0x00000008;
+              }
+              attributes_.add(input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+          attributes_ = java.util.Collections.unmodifiableList(attributes_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_PathArgument_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_PathArgument_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<PathArgument> PARSER =
+        new com.google.protobuf.AbstractParser<PathArgument>() {
+      public PathArgument parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new PathArgument(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<PathArgument> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string value = 1;
+    public static final int VALUE_FIELD_NUMBER = 1;
+    private java.lang.Object value_;
+    /**
+     * <code>required string value = 1;</code>
+     */
+    public boolean hasValue() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string value = 1;</code>
+     */
+    public java.lang.String getValue() {
+      java.lang.Object ref = value_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          value_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string value = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getValueBytes() {
+      java.lang.Object ref = value_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        value_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional string type = 2;
+    public static final int TYPE_FIELD_NUMBER = 2;
+    private java.lang.Object type_;
+    /**
+     * <code>optional string type = 2;</code>
+     *
+     * <pre>
+     *NodeIdentifier, NodeWithValue, NodeIdentifierWithPredicates
+     * </pre>
+     */
+    public boolean hasType() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional string type = 2;</code>
+     *
+     * <pre>
+     *NodeIdentifier, NodeWithValue, NodeIdentifierWithPredicates
+     * </pre>
+     */
+    public java.lang.String getType() {
+      java.lang.Object ref = type_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          type_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string type = 2;</code>
+     *
+     * <pre>
+     *NodeIdentifier, NodeWithValue, NodeIdentifierWithPredicates
+     * </pre>
+     */
+    public com.google.protobuf.ByteString
+        getTypeBytes() {
+      java.lang.Object ref = type_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        type_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional .org.opendaylight.controller.mdsal.QName nodeType = 3;
+    public static final int NODETYPE_FIELD_NUMBER = 3;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName nodeType_;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+     */
+    public boolean hasNodeType() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName getNodeType() {
+      return nodeType_;
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QNameOrBuilder getNodeTypeOrBuilder() {
+      return nodeType_;
+    }
+
+    // repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;
+    public static final int ATTRIBUTES_FIELD_NUMBER = 4;
+    private java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute> attributes_;
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+     */
+    public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute> getAttributesList() {
+      return attributes_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+     */
+    public java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder> 
+        getAttributesOrBuilderList() {
+      return attributes_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+     */
+    public int getAttributesCount() {
+      return attributes_.size();
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute getAttributes(int index) {
+      return attributes_.get(index);
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder getAttributesOrBuilder(
+        int index) {
+      return attributes_.get(index);
+    }
+
+    private void initFields() {
+      value_ = "";
+      type_ = "";
+      nodeType_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.getDefaultInstance();
+      attributes_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasValue()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (hasNodeType()) {
+        if (!getNodeType().isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      for (int i = 0; i < getAttributesCount(); i++) {
+        if (!getAttributes(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getValueBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, getTypeBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeMessage(3, nodeType_);
+      }
+      for (int i = 0; i < attributes_.size(); i++) {
+        output.writeMessage(4, attributes_.get(i));
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getValueBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, getTypeBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, nodeType_);
+      }
+      for (int i = 0; i < attributes_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(4, attributes_.get(i));
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.PathArgument}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgumentOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_PathArgument_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_PathArgument_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getNodeTypeFieldBuilder();
+          getAttributesFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        value_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        type_ = "";
+        bitField0_ = (bitField0_ & ~0x00000002);
+        if (nodeTypeBuilder_ == null) {
+          nodeType_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.getDefaultInstance();
+        } else {
+          nodeTypeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000004);
+        if (attributesBuilder_ == null) {
+          attributes_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000008);
+        } else {
+          attributesBuilder_.clear();
+        }
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_PathArgument_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument build() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument buildPartial() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument result = new org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.value_ = value_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.type_ = type_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        if (nodeTypeBuilder_ == null) {
+          result.nodeType_ = nodeType_;
+        } else {
+          result.nodeType_ = nodeTypeBuilder_.build();
+        }
+        if (attributesBuilder_ == null) {
+          if (((bitField0_ & 0x00000008) == 0x00000008)) {
+            attributes_ = java.util.Collections.unmodifiableList(attributes_);
+            bitField0_ = (bitField0_ & ~0x00000008);
+          }
+          result.attributes_ = attributes_;
+        } else {
+          result.attributes_ = attributesBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument other) {
+        if (other == org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.getDefaultInstance()) return this;
+        if (other.hasValue()) {
+          bitField0_ |= 0x00000001;
+          value_ = other.value_;
+          onChanged();
+        }
+        if (other.hasType()) {
+          bitField0_ |= 0x00000002;
+          type_ = other.type_;
+          onChanged();
+        }
+        if (other.hasNodeType()) {
+          mergeNodeType(other.getNodeType());
+        }
+        if (attributesBuilder_ == null) {
+          if (!other.attributes_.isEmpty()) {
+            if (attributes_.isEmpty()) {
+              attributes_ = other.attributes_;
+              bitField0_ = (bitField0_ & ~0x00000008);
+            } else {
+              ensureAttributesIsMutable();
+              attributes_.addAll(other.attributes_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.attributes_.isEmpty()) {
+            if (attributesBuilder_.isEmpty()) {
+              attributesBuilder_.dispose();
+              attributesBuilder_ = null;
+              attributes_ = other.attributes_;
+              bitField0_ = (bitField0_ & ~0x00000008);
+              attributesBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getAttributesFieldBuilder() : null;
+            } else {
+              attributesBuilder_.addAllMessages(other.attributes_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasValue()) {
+          
+          return false;
+        }
+        if (hasNodeType()) {
+          if (!getNodeType().isInitialized()) {
+            
+            return false;
+          }
+        }
+        for (int i = 0; i < getAttributesCount(); i++) {
+          if (!getAttributes(i).isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string value = 1;
+      private java.lang.Object value_ = "";
+      /**
+       * <code>required string value = 1;</code>
+       */
+      public boolean hasValue() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string value = 1;</code>
+       */
+      public java.lang.String getValue() {
+        java.lang.Object ref = value_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          value_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string value = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getValueBytes() {
+        java.lang.Object ref = value_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          value_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string value = 1;</code>
+       */
+      public Builder setValue(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string value = 1;</code>
+       */
+      public Builder clearValue() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        value_ = getDefaultInstance().getValue();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string value = 1;</code>
+       */
+      public Builder setValueBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional string type = 2;
+      private java.lang.Object type_ = "";
+      /**
+       * <code>optional string type = 2;</code>
+       *
+       * <pre>
+       *NodeIdentifier, NodeWithValue, NodeIdentifierWithPredicates
+       * </pre>
+       */
+      public boolean hasType() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional string type = 2;</code>
+       *
+       * <pre>
+       *NodeIdentifier, NodeWithValue, NodeIdentifierWithPredicates
+       * </pre>
+       */
+      public java.lang.String getType() {
+        java.lang.Object ref = type_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          type_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string type = 2;</code>
+       *
+       * <pre>
+       *NodeIdentifier, NodeWithValue, NodeIdentifierWithPredicates
+       * </pre>
+       */
+      public com.google.protobuf.ByteString
+          getTypeBytes() {
+        java.lang.Object ref = type_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          type_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string type = 2;</code>
+       *
+       * <pre>
+       *NodeIdentifier, NodeWithValue, NodeIdentifierWithPredicates
+       * </pre>
+       */
+      public Builder setType(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        type_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string type = 2;</code>
+       *
+       * <pre>
+       *NodeIdentifier, NodeWithValue, NodeIdentifierWithPredicates
+       * </pre>
+       */
+      public Builder clearType() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        type_ = getDefaultInstance().getType();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string type = 2;</code>
+       *
+       * <pre>
+       *NodeIdentifier, NodeWithValue, NodeIdentifierWithPredicates
+       * </pre>
+       */
+      public Builder setTypeBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        type_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional .org.opendaylight.controller.mdsal.QName nodeType = 3;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName nodeType_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QNameOrBuilder> nodeTypeBuilder_;
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+       */
+      public boolean hasNodeType() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName getNodeType() {
+        if (nodeTypeBuilder_ == null) {
+          return nodeType_;
+        } else {
+          return nodeTypeBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+       */
+      public Builder setNodeType(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName value) {
+        if (nodeTypeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          nodeType_ = value;
+          onChanged();
+        } else {
+          nodeTypeBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+       */
+      public Builder setNodeType(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.Builder builderForValue) {
+        if (nodeTypeBuilder_ == null) {
+          nodeType_ = builderForValue.build();
+          onChanged();
+        } else {
+          nodeTypeBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+       */
+      public Builder mergeNodeType(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName value) {
+        if (nodeTypeBuilder_ == null) {
+          if (((bitField0_ & 0x00000004) == 0x00000004) &&
+              nodeType_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.getDefaultInstance()) {
+            nodeType_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.newBuilder(nodeType_).mergeFrom(value).buildPartial();
+          } else {
+            nodeType_ = value;
+          }
+          onChanged();
+        } else {
+          nodeTypeBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+       */
+      public Builder clearNodeType() {
+        if (nodeTypeBuilder_ == null) {
+          nodeType_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.getDefaultInstance();
+          onChanged();
+        } else {
+          nodeTypeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.Builder getNodeTypeBuilder() {
+        bitField0_ |= 0x00000004;
+        onChanged();
+        return getNodeTypeFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QNameOrBuilder getNodeTypeOrBuilder() {
+        if (nodeTypeBuilder_ != null) {
+          return nodeTypeBuilder_.getMessageOrBuilder();
+        } else {
+          return nodeType_;
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.QName nodeType = 3;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QNameOrBuilder> 
+          getNodeTypeFieldBuilder() {
+        if (nodeTypeBuilder_ == null) {
+          nodeTypeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QName.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.QNameOrBuilder>(
+                  nodeType_,
+                  getParentForChildren(),
+                  isClean());
+          nodeType_ = null;
+        }
+        return nodeTypeBuilder_;
+      }
+
+      // repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;
+      private java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute> attributes_ =
+        java.util.Collections.emptyList();
+      private void ensureAttributesIsMutable() {
+        if (!((bitField0_ & 0x00000008) == 0x00000008)) {
+          attributes_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute>(attributes_);
+          bitField0_ |= 0x00000008;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder> attributesBuilder_;
+
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute> getAttributesList() {
+        if (attributesBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(attributes_);
+        } else {
+          return attributesBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public int getAttributesCount() {
+        if (attributesBuilder_ == null) {
+          return attributes_.size();
+        } else {
+          return attributesBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute getAttributes(int index) {
+        if (attributesBuilder_ == null) {
+          return attributes_.get(index);
+        } else {
+          return attributesBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public Builder setAttributes(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute value) {
+        if (attributesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureAttributesIsMutable();
+          attributes_.set(index, value);
+          onChanged();
+        } else {
+          attributesBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public Builder setAttributes(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder builderForValue) {
+        if (attributesBuilder_ == null) {
+          ensureAttributesIsMutable();
+          attributes_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          attributesBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public Builder addAttributes(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute value) {
+        if (attributesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureAttributesIsMutable();
+          attributes_.add(value);
+          onChanged();
+        } else {
+          attributesBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public Builder addAttributes(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute value) {
+        if (attributesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureAttributesIsMutable();
+          attributes_.add(index, value);
+          onChanged();
+        } else {
+          attributesBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public Builder addAttributes(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder builderForValue) {
+        if (attributesBuilder_ == null) {
+          ensureAttributesIsMutable();
+          attributes_.add(builderForValue.build());
+          onChanged();
+        } else {
+          attributesBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public Builder addAttributes(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder builderForValue) {
+        if (attributesBuilder_ == null) {
+          ensureAttributesIsMutable();
+          attributes_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          attributesBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public Builder addAllAttributes(
+          java.lang.Iterable<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute> values) {
+        if (attributesBuilder_ == null) {
+          ensureAttributesIsMutable();
+          super.addAll(values, attributes_);
+          onChanged();
+        } else {
+          attributesBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public Builder clearAttributes() {
+        if (attributesBuilder_ == null) {
+          attributes_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000008);
+          onChanged();
+        } else {
+          attributesBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public Builder removeAttributes(int index) {
+        if (attributesBuilder_ == null) {
+          ensureAttributesIsMutable();
+          attributes_.remove(index);
+          onChanged();
+        } else {
+          attributesBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder getAttributesBuilder(
+          int index) {
+        return getAttributesFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder getAttributesOrBuilder(
+          int index) {
+        if (attributesBuilder_ == null) {
+          return attributes_.get(index);  } else {
+          return attributesBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder> 
+           getAttributesOrBuilderList() {
+        if (attributesBuilder_ != null) {
+          return attributesBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(attributes_);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder addAttributesBuilder() {
+        return getAttributesFieldBuilder().addBuilder(
+            org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder addAttributesBuilder(
+          int index) {
+        return getAttributesFieldBuilder().addBuilder(
+            index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 4;</code>
+       */
+      public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder> 
+           getAttributesBuilderList() {
+        return getAttributesFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder> 
+          getAttributesFieldBuilder() {
+        if (attributesBuilder_ == null) {
+          attributesBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder>(
+                  attributes_,
+                  ((bitField0_ & 0x00000008) == 0x00000008),
+                  getParentForChildren(),
+                  isClean());
+          attributes_ = null;
+        }
+        return attributesBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.PathArgument)
+    }
+
+    static {
+      defaultInstance = new PathArgument(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.PathArgument)
+  }
+
+  public interface InstanceIdentifierOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+     */
+    java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument> 
+        getArgumentsList();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument getArguments(int index);
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+     */
+    int getArgumentsCount();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+     */
+    java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgumentOrBuilder> 
+        getArgumentsOrBuilderList();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgumentOrBuilder getArgumentsOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.InstanceIdentifier}
+   */
+  public static final class InstanceIdentifier extends
+      com.google.protobuf.GeneratedMessage
+      implements InstanceIdentifierOrBuilder {
+    // Use InstanceIdentifier.newBuilder() to construct.
+    private InstanceIdentifier(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private InstanceIdentifier(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final InstanceIdentifier defaultInstance;
+    public static InstanceIdentifier getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public InstanceIdentifier getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private InstanceIdentifier(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                arguments_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              arguments_.add(input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          arguments_ = java.util.Collections.unmodifiableList(arguments_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_InstanceIdentifier_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_InstanceIdentifier_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<InstanceIdentifier> PARSER =
+        new com.google.protobuf.AbstractParser<InstanceIdentifier>() {
+      public InstanceIdentifier parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new InstanceIdentifier(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<InstanceIdentifier> getParserForType() {
+      return PARSER;
+    }
+
+    // repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;
+    public static final int ARGUMENTS_FIELD_NUMBER = 1;
+    private java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument> arguments_;
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+     */
+    public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument> getArgumentsList() {
+      return arguments_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+     */
+    public java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgumentOrBuilder> 
+        getArgumentsOrBuilderList() {
+      return arguments_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+     */
+    public int getArgumentsCount() {
+      return arguments_.size();
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument getArguments(int index) {
+      return arguments_.get(index);
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgumentOrBuilder getArgumentsOrBuilder(
+        int index) {
+      return arguments_.get(index);
+    }
+
+    private void initFields() {
+      arguments_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      for (int i = 0; i < getArgumentsCount(); i++) {
+        if (!getArguments(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < arguments_.size(); i++) {
+        output.writeMessage(1, arguments_.get(i));
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < arguments_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, arguments_.get(i));
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.InstanceIdentifier}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_InstanceIdentifier_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_InstanceIdentifier_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getArgumentsFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (argumentsBuilder_ == null) {
+          arguments_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          argumentsBuilder_.clear();
+        }
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_InstanceIdentifier_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier build() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier buildPartial() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier result = new org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier(this);
+        int from_bitField0_ = bitField0_;
+        if (argumentsBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+            arguments_ = java.util.Collections.unmodifiableList(arguments_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.arguments_ = arguments_;
+        } else {
+          result.arguments_ = argumentsBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier other) {
+        if (other == org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance()) return this;
+        if (argumentsBuilder_ == null) {
+          if (!other.arguments_.isEmpty()) {
+            if (arguments_.isEmpty()) {
+              arguments_ = other.arguments_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureArgumentsIsMutable();
+              arguments_.addAll(other.arguments_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.arguments_.isEmpty()) {
+            if (argumentsBuilder_.isEmpty()) {
+              argumentsBuilder_.dispose();
+              argumentsBuilder_ = null;
+              arguments_ = other.arguments_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              argumentsBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getArgumentsFieldBuilder() : null;
+            } else {
+              argumentsBuilder_.addAllMessages(other.arguments_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        for (int i = 0; i < getArgumentsCount(); i++) {
+          if (!getArguments(i).isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;
+      private java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument> arguments_ =
+        java.util.Collections.emptyList();
+      private void ensureArgumentsIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          arguments_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument>(arguments_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgumentOrBuilder> argumentsBuilder_;
+
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument> getArgumentsList() {
+        if (argumentsBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(arguments_);
+        } else {
+          return argumentsBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public int getArgumentsCount() {
+        if (argumentsBuilder_ == null) {
+          return arguments_.size();
+        } else {
+          return argumentsBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument getArguments(int index) {
+        if (argumentsBuilder_ == null) {
+          return arguments_.get(index);
+        } else {
+          return argumentsBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public Builder setArguments(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument value) {
+        if (argumentsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureArgumentsIsMutable();
+          arguments_.set(index, value);
+          onChanged();
+        } else {
+          argumentsBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public Builder setArguments(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.Builder builderForValue) {
+        if (argumentsBuilder_ == null) {
+          ensureArgumentsIsMutable();
+          arguments_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          argumentsBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public Builder addArguments(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument value) {
+        if (argumentsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureArgumentsIsMutable();
+          arguments_.add(value);
+          onChanged();
+        } else {
+          argumentsBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public Builder addArguments(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument value) {
+        if (argumentsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureArgumentsIsMutable();
+          arguments_.add(index, value);
+          onChanged();
+        } else {
+          argumentsBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public Builder addArguments(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.Builder builderForValue) {
+        if (argumentsBuilder_ == null) {
+          ensureArgumentsIsMutable();
+          arguments_.add(builderForValue.build());
+          onChanged();
+        } else {
+          argumentsBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public Builder addArguments(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.Builder builderForValue) {
+        if (argumentsBuilder_ == null) {
+          ensureArgumentsIsMutable();
+          arguments_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          argumentsBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public Builder addAllArguments(
+          java.lang.Iterable<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument> values) {
+        if (argumentsBuilder_ == null) {
+          ensureArgumentsIsMutable();
+          super.addAll(values, arguments_);
+          onChanged();
+        } else {
+          argumentsBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public Builder clearArguments() {
+        if (argumentsBuilder_ == null) {
+          arguments_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          argumentsBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public Builder removeArguments(int index) {
+        if (argumentsBuilder_ == null) {
+          ensureArgumentsIsMutable();
+          arguments_.remove(index);
+          onChanged();
+        } else {
+          argumentsBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.Builder getArgumentsBuilder(
+          int index) {
+        return getArgumentsFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgumentOrBuilder getArgumentsOrBuilder(
+          int index) {
+        if (argumentsBuilder_ == null) {
+          return arguments_.get(index);  } else {
+          return argumentsBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgumentOrBuilder> 
+           getArgumentsOrBuilderList() {
+        if (argumentsBuilder_ != null) {
+          return argumentsBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(arguments_);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.Builder addArgumentsBuilder() {
+        return getArgumentsFieldBuilder().addBuilder(
+            org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.Builder addArgumentsBuilder(
+          int index) {
+        return getArgumentsFieldBuilder().addBuilder(
+            index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.PathArgument arguments = 1;</code>
+       */
+      public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.Builder> 
+           getArgumentsBuilderList() {
+        return getArgumentsFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgumentOrBuilder> 
+          getArgumentsFieldBuilder() {
+        if (argumentsBuilder_ == null) {
+          argumentsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgument.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.PathArgumentOrBuilder>(
+                  arguments_,
+                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  getParentForChildren(),
+                  isClean());
+          arguments_ = null;
+        }
+        return argumentsBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.InstanceIdentifier)
+    }
+
+    static {
+      defaultInstance = new InstanceIdentifier(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.InstanceIdentifier)
+  }
+
+  public interface NodeOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // optional string path = 1;
+    /**
+     * <code>optional string path = 1;</code>
+     */
+    boolean hasPath();
+    /**
+     * <code>optional string path = 1;</code>
+     */
+    java.lang.String getPath();
+    /**
+     * <code>optional string path = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getPathBytes();
+
+    // optional string type = 2;
+    /**
+     * <code>optional string type = 2;</code>
+     */
+    boolean hasType();
+    /**
+     * <code>optional string type = 2;</code>
+     */
+    java.lang.String getType();
+    /**
+     * <code>optional string type = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getTypeBytes();
+
+    // repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+     */
+    java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute> 
+        getAttributesList();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute getAttributes(int index);
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+     */
+    int getAttributesCount();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+     */
+    java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder> 
+        getAttributesOrBuilderList();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder getAttributesOrBuilder(
+        int index);
+
+    // repeated .org.opendaylight.controller.mdsal.Node child = 4;
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+     */
+    java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node> 
+        getChildList();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getChild(int index);
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+     */
+    int getChildCount();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+     */
+    java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> 
+        getChildOrBuilderList();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getChildOrBuilder(
+        int index);
+
+    // optional string value = 5;
+    /**
+     * <code>optional string value = 5;</code>
+     */
+    boolean hasValue();
+    /**
+     * <code>optional string value = 5;</code>
+     */
+    java.lang.String getValue();
+    /**
+     * <code>optional string value = 5;</code>
+     */
+    com.google.protobuf.ByteString
+        getValueBytes();
+
+    // optional string valueType = 6;
+    /**
+     * <code>optional string valueType = 6;</code>
+     */
+    boolean hasValueType();
+    /**
+     * <code>optional string valueType = 6;</code>
+     */
+    java.lang.String getValueType();
+    /**
+     * <code>optional string valueType = 6;</code>
+     */
+    com.google.protobuf.ByteString
+        getValueTypeBytes();
+
+    // repeated string bitsValue = 7;
+    /**
+     * <code>repeated string bitsValue = 7;</code>
+     */
+    java.util.List<java.lang.String>
+    getBitsValueList();
+    /**
+     * <code>repeated string bitsValue = 7;</code>
+     */
+    int getBitsValueCount();
+    /**
+     * <code>repeated string bitsValue = 7;</code>
+     */
+    java.lang.String getBitsValue(int index);
+    /**
+     * <code>repeated string bitsValue = 7;</code>
+     */
+    com.google.protobuf.ByteString
+        getBitsValueBytes(int index);
+
+    // optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+     */
+    boolean hasInstanceIdentifierValue();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierValue();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierValueOrBuilder();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.Node}
+   */
+  public static final class Node extends
+      com.google.protobuf.GeneratedMessage
+      implements NodeOrBuilder {
+    // Use Node.newBuilder() to construct.
+    private Node(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Node(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final Node defaultInstance;
+    public static Node getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Node getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Node(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              path_ = input.readBytes();
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              type_ = input.readBytes();
+              break;
+            }
+            case 26: {
+              if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+                attributes_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute>();
+                mutable_bitField0_ |= 0x00000004;
+              }
+              attributes_.add(input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.PARSER, extensionRegistry));
+              break;
+            }
+            case 34: {
+              if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+                child_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node>();
+                mutable_bitField0_ |= 0x00000008;
+              }
+              child_.add(input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.PARSER, extensionRegistry));
+              break;
+            }
+            case 42: {
+              bitField0_ |= 0x00000004;
+              value_ = input.readBytes();
+              break;
+            }
+            case 50: {
+              bitField0_ |= 0x00000008;
+              valueType_ = input.readBytes();
+              break;
+            }
+            case 58: {
+              if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
+                bitsValue_ = new com.google.protobuf.LazyStringArrayList();
+                mutable_bitField0_ |= 0x00000040;
+              }
+              bitsValue_.add(input.readBytes());
+              break;
+            }
+            case 66: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000010) == 0x00000010)) {
+                subBuilder = instanceIdentifierValue_.toBuilder();
+              }
+              instanceIdentifierValue_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(instanceIdentifierValue_);
+                instanceIdentifierValue_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000010;
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+          attributes_ = java.util.Collections.unmodifiableList(attributes_);
+        }
+        if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+          child_ = java.util.Collections.unmodifiableList(child_);
+        }
+        if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
+          bitsValue_ = new com.google.protobuf.UnmodifiableLazyStringList(bitsValue_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Node_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Node_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<Node> PARSER =
+        new com.google.protobuf.AbstractParser<Node>() {
+      public Node parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Node(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Node> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // optional string path = 1;
+    public static final int PATH_FIELD_NUMBER = 1;
+    private java.lang.Object path_;
+    /**
+     * <code>optional string path = 1;</code>
+     */
+    public boolean hasPath() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional string path = 1;</code>
+     */
+    public java.lang.String getPath() {
+      java.lang.Object ref = path_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          path_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string path = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getPathBytes() {
+      java.lang.Object ref = path_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        path_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional string type = 2;
+    public static final int TYPE_FIELD_NUMBER = 2;
+    private java.lang.Object type_;
+    /**
+     * <code>optional string type = 2;</code>
+     */
+    public boolean hasType() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional string type = 2;</code>
+     */
+    public java.lang.String getType() {
+      java.lang.Object ref = type_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          type_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string type = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getTypeBytes() {
+      java.lang.Object ref = type_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        type_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;
+    public static final int ATTRIBUTES_FIELD_NUMBER = 3;
+    private java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute> attributes_;
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+     */
+    public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute> getAttributesList() {
+      return attributes_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+     */
+    public java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder> 
+        getAttributesOrBuilderList() {
+      return attributes_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+     */
+    public int getAttributesCount() {
+      return attributes_.size();
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute getAttributes(int index) {
+      return attributes_.get(index);
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder getAttributesOrBuilder(
+        int index) {
+      return attributes_.get(index);
+    }
+
+    // repeated .org.opendaylight.controller.mdsal.Node child = 4;
+    public static final int CHILD_FIELD_NUMBER = 4;
+    private java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node> child_;
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+     */
+    public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node> getChildList() {
+      return child_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+     */
+    public java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> 
+        getChildOrBuilderList() {
+      return child_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+     */
+    public int getChildCount() {
+      return child_.size();
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getChild(int index) {
+      return child_.get(index);
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getChildOrBuilder(
+        int index) {
+      return child_.get(index);
+    }
+
+    // optional string value = 5;
+    public static final int VALUE_FIELD_NUMBER = 5;
+    private java.lang.Object value_;
+    /**
+     * <code>optional string value = 5;</code>
+     */
+    public boolean hasValue() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>optional string value = 5;</code>
+     */
+    public java.lang.String getValue() {
+      java.lang.Object ref = value_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          value_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string value = 5;</code>
+     */
+    public com.google.protobuf.ByteString
+        getValueBytes() {
+      java.lang.Object ref = value_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        value_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional string valueType = 6;
+    public static final int VALUETYPE_FIELD_NUMBER = 6;
+    private java.lang.Object valueType_;
+    /**
+     * <code>optional string valueType = 6;</code>
+     */
+    public boolean hasValueType() {
+      return ((bitField0_ & 0x00000008) == 0x00000008);
+    }
+    /**
+     * <code>optional string valueType = 6;</code>
+     */
+    public java.lang.String getValueType() {
+      java.lang.Object ref = valueType_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          valueType_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string valueType = 6;</code>
+     */
+    public com.google.protobuf.ByteString
+        getValueTypeBytes() {
+      java.lang.Object ref = valueType_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        valueType_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // repeated string bitsValue = 7;
+    public static final int BITSVALUE_FIELD_NUMBER = 7;
+    private com.google.protobuf.LazyStringList bitsValue_;
+    /**
+     * <code>repeated string bitsValue = 7;</code>
+     */
+    public java.util.List<java.lang.String>
+        getBitsValueList() {
+      return bitsValue_;
+    }
+    /**
+     * <code>repeated string bitsValue = 7;</code>
+     */
+    public int getBitsValueCount() {
+      return bitsValue_.size();
+    }
+    /**
+     * <code>repeated string bitsValue = 7;</code>
+     */
+    public java.lang.String getBitsValue(int index) {
+      return bitsValue_.get(index);
+    }
+    /**
+     * <code>repeated string bitsValue = 7;</code>
+     */
+    public com.google.protobuf.ByteString
+        getBitsValueBytes(int index) {
+      return bitsValue_.getByteString(index);
+    }
+
+    // optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;
+    public static final int INSTANCEIDENTIFIERVALUE_FIELD_NUMBER = 8;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier instanceIdentifierValue_;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+     */
+    public boolean hasInstanceIdentifierValue() {
+      return ((bitField0_ & 0x00000010) == 0x00000010);
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierValue() {
+      return instanceIdentifierValue_;
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierValueOrBuilder() {
+      return instanceIdentifierValue_;
+    }
+
+    private void initFields() {
+      path_ = "";
+      type_ = "";
+      attributes_ = java.util.Collections.emptyList();
+      child_ = java.util.Collections.emptyList();
+      value_ = "";
+      valueType_ = "";
+      bitsValue_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+      instanceIdentifierValue_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      for (int i = 0; i < getAttributesCount(); i++) {
+        if (!getAttributes(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      for (int i = 0; i < getChildCount(); i++) {
+        if (!getChild(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      if (hasInstanceIdentifierValue()) {
+        if (!getInstanceIdentifierValue().isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getPathBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, getTypeBytes());
+      }
+      for (int i = 0; i < attributes_.size(); i++) {
+        output.writeMessage(3, attributes_.get(i));
+      }
+      for (int i = 0; i < child_.size(); i++) {
+        output.writeMessage(4, child_.get(i));
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeBytes(5, getValueBytes());
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        output.writeBytes(6, getValueTypeBytes());
+      }
+      for (int i = 0; i < bitsValue_.size(); i++) {
+        output.writeBytes(7, bitsValue_.getByteString(i));
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        output.writeMessage(8, instanceIdentifierValue_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getPathBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, getTypeBytes());
+      }
+      for (int i = 0; i < attributes_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, attributes_.get(i));
+      }
+      for (int i = 0; i < child_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(4, child_.get(i));
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(5, getValueBytes());
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(6, getValueTypeBytes());
+      }
+      {
+        int dataSize = 0;
+        for (int i = 0; i < bitsValue_.size(); i++) {
+          dataSize += com.google.protobuf.CodedOutputStream
+            .computeBytesSizeNoTag(bitsValue_.getByteString(i));
+        }
+        size += dataSize;
+        size += 1 * getBitsValueList().size();
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(8, instanceIdentifierValue_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.Node}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Node_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Node_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getAttributesFieldBuilder();
+          getChildFieldBuilder();
+          getInstanceIdentifierValueFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        path_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        type_ = "";
+        bitField0_ = (bitField0_ & ~0x00000002);
+        if (attributesBuilder_ == null) {
+          attributes_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000004);
+        } else {
+          attributesBuilder_.clear();
+        }
+        if (childBuilder_ == null) {
+          child_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000008);
+        } else {
+          childBuilder_.clear();
+        }
+        value_ = "";
+        bitField0_ = (bitField0_ & ~0x00000010);
+        valueType_ = "";
+        bitField0_ = (bitField0_ & ~0x00000020);
+        bitsValue_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000040);
+        if (instanceIdentifierValueBuilder_ == null) {
+          instanceIdentifierValue_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+        } else {
+          instanceIdentifierValueBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000080);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Node_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node build() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node buildPartial() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node result = new org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.path_ = path_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.type_ = type_;
+        if (attributesBuilder_ == null) {
+          if (((bitField0_ & 0x00000004) == 0x00000004)) {
+            attributes_ = java.util.Collections.unmodifiableList(attributes_);
+            bitField0_ = (bitField0_ & ~0x00000004);
+          }
+          result.attributes_ = attributes_;
+        } else {
+          result.attributes_ = attributesBuilder_.build();
+        }
+        if (childBuilder_ == null) {
+          if (((bitField0_ & 0x00000008) == 0x00000008)) {
+            child_ = java.util.Collections.unmodifiableList(child_);
+            bitField0_ = (bitField0_ & ~0x00000008);
+          }
+          result.child_ = child_;
+        } else {
+          result.child_ = childBuilder_.build();
+        }
+        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.value_ = value_;
+        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+          to_bitField0_ |= 0x00000008;
+        }
+        result.valueType_ = valueType_;
+        if (((bitField0_ & 0x00000040) == 0x00000040)) {
+          bitsValue_ = new com.google.protobuf.UnmodifiableLazyStringList(
+              bitsValue_);
+          bitField0_ = (bitField0_ & ~0x00000040);
+        }
+        result.bitsValue_ = bitsValue_;
+        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
+          to_bitField0_ |= 0x00000010;
+        }
+        if (instanceIdentifierValueBuilder_ == null) {
+          result.instanceIdentifierValue_ = instanceIdentifierValue_;
+        } else {
+          result.instanceIdentifierValue_ = instanceIdentifierValueBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node other) {
+        if (other == org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance()) return this;
+        if (other.hasPath()) {
+          bitField0_ |= 0x00000001;
+          path_ = other.path_;
+          onChanged();
+        }
+        if (other.hasType()) {
+          bitField0_ |= 0x00000002;
+          type_ = other.type_;
+          onChanged();
+        }
+        if (attributesBuilder_ == null) {
+          if (!other.attributes_.isEmpty()) {
+            if (attributes_.isEmpty()) {
+              attributes_ = other.attributes_;
+              bitField0_ = (bitField0_ & ~0x00000004);
+            } else {
+              ensureAttributesIsMutable();
+              attributes_.addAll(other.attributes_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.attributes_.isEmpty()) {
+            if (attributesBuilder_.isEmpty()) {
+              attributesBuilder_.dispose();
+              attributesBuilder_ = null;
+              attributes_ = other.attributes_;
+              bitField0_ = (bitField0_ & ~0x00000004);
+              attributesBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getAttributesFieldBuilder() : null;
+            } else {
+              attributesBuilder_.addAllMessages(other.attributes_);
+            }
+          }
+        }
+        if (childBuilder_ == null) {
+          if (!other.child_.isEmpty()) {
+            if (child_.isEmpty()) {
+              child_ = other.child_;
+              bitField0_ = (bitField0_ & ~0x00000008);
+            } else {
+              ensureChildIsMutable();
+              child_.addAll(other.child_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.child_.isEmpty()) {
+            if (childBuilder_.isEmpty()) {
+              childBuilder_.dispose();
+              childBuilder_ = null;
+              child_ = other.child_;
+              bitField0_ = (bitField0_ & ~0x00000008);
+              childBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getChildFieldBuilder() : null;
+            } else {
+              childBuilder_.addAllMessages(other.child_);
+            }
+          }
+        }
+        if (other.hasValue()) {
+          bitField0_ |= 0x00000010;
+          value_ = other.value_;
+          onChanged();
+        }
+        if (other.hasValueType()) {
+          bitField0_ |= 0x00000020;
+          valueType_ = other.valueType_;
+          onChanged();
+        }
+        if (!other.bitsValue_.isEmpty()) {
+          if (bitsValue_.isEmpty()) {
+            bitsValue_ = other.bitsValue_;
+            bitField0_ = (bitField0_ & ~0x00000040);
+          } else {
+            ensureBitsValueIsMutable();
+            bitsValue_.addAll(other.bitsValue_);
+          }
+          onChanged();
+        }
+        if (other.hasInstanceIdentifierValue()) {
+          mergeInstanceIdentifierValue(other.getInstanceIdentifierValue());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        for (int i = 0; i < getAttributesCount(); i++) {
+          if (!getAttributes(i).isInitialized()) {
+            
+            return false;
+          }
+        }
+        for (int i = 0; i < getChildCount(); i++) {
+          if (!getChild(i).isInitialized()) {
+            
+            return false;
+          }
+        }
+        if (hasInstanceIdentifierValue()) {
+          if (!getInstanceIdentifierValue().isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // optional string path = 1;
+      private java.lang.Object path_ = "";
+      /**
+       * <code>optional string path = 1;</code>
+       */
+      public boolean hasPath() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional string path = 1;</code>
+       */
+      public java.lang.String getPath() {
+        java.lang.Object ref = path_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          path_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string path = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getPathBytes() {
+        java.lang.Object ref = path_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          path_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string path = 1;</code>
+       */
+      public Builder setPath(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        path_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string path = 1;</code>
+       */
+      public Builder clearPath() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        path_ = getDefaultInstance().getPath();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string path = 1;</code>
+       */
+      public Builder setPathBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        path_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional string type = 2;
+      private java.lang.Object type_ = "";
+      /**
+       * <code>optional string type = 2;</code>
+       */
+      public boolean hasType() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional string type = 2;</code>
+       */
+      public java.lang.String getType() {
+        java.lang.Object ref = type_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          type_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string type = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getTypeBytes() {
+        java.lang.Object ref = type_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          type_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string type = 2;</code>
+       */
+      public Builder setType(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        type_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string type = 2;</code>
+       */
+      public Builder clearType() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        type_ = getDefaultInstance().getType();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string type = 2;</code>
+       */
+      public Builder setTypeBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        type_ = value;
+        onChanged();
+        return this;
+      }
+
+      // repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;
+      private java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute> attributes_ =
+        java.util.Collections.emptyList();
+      private void ensureAttributesIsMutable() {
+        if (!((bitField0_ & 0x00000004) == 0x00000004)) {
+          attributes_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute>(attributes_);
+          bitField0_ |= 0x00000004;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder> attributesBuilder_;
+
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute> getAttributesList() {
+        if (attributesBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(attributes_);
+        } else {
+          return attributesBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public int getAttributesCount() {
+        if (attributesBuilder_ == null) {
+          return attributes_.size();
+        } else {
+          return attributesBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute getAttributes(int index) {
+        if (attributesBuilder_ == null) {
+          return attributes_.get(index);
+        } else {
+          return attributesBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public Builder setAttributes(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute value) {
+        if (attributesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureAttributesIsMutable();
+          attributes_.set(index, value);
+          onChanged();
+        } else {
+          attributesBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public Builder setAttributes(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder builderForValue) {
+        if (attributesBuilder_ == null) {
+          ensureAttributesIsMutable();
+          attributes_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          attributesBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public Builder addAttributes(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute value) {
+        if (attributesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureAttributesIsMutable();
+          attributes_.add(value);
+          onChanged();
+        } else {
+          attributesBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public Builder addAttributes(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute value) {
+        if (attributesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureAttributesIsMutable();
+          attributes_.add(index, value);
+          onChanged();
+        } else {
+          attributesBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public Builder addAttributes(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder builderForValue) {
+        if (attributesBuilder_ == null) {
+          ensureAttributesIsMutable();
+          attributes_.add(builderForValue.build());
+          onChanged();
+        } else {
+          attributesBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public Builder addAttributes(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder builderForValue) {
+        if (attributesBuilder_ == null) {
+          ensureAttributesIsMutable();
+          attributes_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          attributesBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public Builder addAllAttributes(
+          java.lang.Iterable<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute> values) {
+        if (attributesBuilder_ == null) {
+          ensureAttributesIsMutable();
+          super.addAll(values, attributes_);
+          onChanged();
+        } else {
+          attributesBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public Builder clearAttributes() {
+        if (attributesBuilder_ == null) {
+          attributes_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000004);
+          onChanged();
+        } else {
+          attributesBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public Builder removeAttributes(int index) {
+        if (attributesBuilder_ == null) {
+          ensureAttributesIsMutable();
+          attributes_.remove(index);
+          onChanged();
+        } else {
+          attributesBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder getAttributesBuilder(
+          int index) {
+        return getAttributesFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder getAttributesOrBuilder(
+          int index) {
+        if (attributesBuilder_ == null) {
+          return attributes_.get(index);  } else {
+          return attributesBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder> 
+           getAttributesOrBuilderList() {
+        if (attributesBuilder_ != null) {
+          return attributesBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(attributes_);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder addAttributesBuilder() {
+        return getAttributesFieldBuilder().addBuilder(
+            org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder addAttributesBuilder(
+          int index) {
+        return getAttributesFieldBuilder().addBuilder(
+            index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Attribute attributes = 3;</code>
+       */
+      public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder> 
+           getAttributesBuilderList() {
+        return getAttributesFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder> 
+          getAttributesFieldBuilder() {
+        if (attributesBuilder_ == null) {
+          attributesBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Attribute.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.AttributeOrBuilder>(
+                  attributes_,
+                  ((bitField0_ & 0x00000004) == 0x00000004),
+                  getParentForChildren(),
+                  isClean());
+          attributes_ = null;
+        }
+        return attributesBuilder_;
+      }
+
+      // repeated .org.opendaylight.controller.mdsal.Node child = 4;
+      private java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node> child_ =
+        java.util.Collections.emptyList();
+      private void ensureChildIsMutable() {
+        if (!((bitField0_ & 0x00000008) == 0x00000008)) {
+          child_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node>(child_);
+          bitField0_ |= 0x00000008;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> childBuilder_;
+
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node> getChildList() {
+        if (childBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(child_);
+        } else {
+          return childBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public int getChildCount() {
+        if (childBuilder_ == null) {
+          return child_.size();
+        } else {
+          return childBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getChild(int index) {
+        if (childBuilder_ == null) {
+          return child_.get(index);
+        } else {
+          return childBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public Builder setChild(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (childBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureChildIsMutable();
+          child_.set(index, value);
+          onChanged();
+        } else {
+          childBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public Builder setChild(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder builderForValue) {
+        if (childBuilder_ == null) {
+          ensureChildIsMutable();
+          child_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          childBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public Builder addChild(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (childBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureChildIsMutable();
+          child_.add(value);
+          onChanged();
+        } else {
+          childBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public Builder addChild(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (childBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureChildIsMutable();
+          child_.add(index, value);
+          onChanged();
+        } else {
+          childBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public Builder addChild(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder builderForValue) {
+        if (childBuilder_ == null) {
+          ensureChildIsMutable();
+          child_.add(builderForValue.build());
+          onChanged();
+        } else {
+          childBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public Builder addChild(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder builderForValue) {
+        if (childBuilder_ == null) {
+          ensureChildIsMutable();
+          child_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          childBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public Builder addAllChild(
+          java.lang.Iterable<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node> values) {
+        if (childBuilder_ == null) {
+          ensureChildIsMutable();
+          super.addAll(values, child_);
+          onChanged();
+        } else {
+          childBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public Builder clearChild() {
+        if (childBuilder_ == null) {
+          child_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000008);
+          onChanged();
+        } else {
+          childBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public Builder removeChild(int index) {
+        if (childBuilder_ == null) {
+          ensureChildIsMutable();
+          child_.remove(index);
+          onChanged();
+        } else {
+          childBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder getChildBuilder(
+          int index) {
+        return getChildFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getChildOrBuilder(
+          int index) {
+        if (childBuilder_ == null) {
+          return child_.get(index);  } else {
+          return childBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> 
+           getChildOrBuilderList() {
+        if (childBuilder_ != null) {
+          return childBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(child_);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder addChildBuilder() {
+        return getChildFieldBuilder().addBuilder(
+            org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder addChildBuilder(
+          int index) {
+        return getChildFieldBuilder().addBuilder(
+            index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Node child = 4;</code>
+       */
+      public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder> 
+           getChildBuilderList() {
+        return getChildFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> 
+          getChildFieldBuilder() {
+        if (childBuilder_ == null) {
+          childBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder>(
+                  child_,
+                  ((bitField0_ & 0x00000008) == 0x00000008),
+                  getParentForChildren(),
+                  isClean());
+          child_ = null;
+        }
+        return childBuilder_;
+      }
+
+      // optional string value = 5;
+      private java.lang.Object value_ = "";
+      /**
+       * <code>optional string value = 5;</code>
+       */
+      public boolean hasValue() {
+        return ((bitField0_ & 0x00000010) == 0x00000010);
+      }
+      /**
+       * <code>optional string value = 5;</code>
+       */
+      public java.lang.String getValue() {
+        java.lang.Object ref = value_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          value_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string value = 5;</code>
+       */
+      public com.google.protobuf.ByteString
+          getValueBytes() {
+        java.lang.Object ref = value_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          value_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string value = 5;</code>
+       */
+      public Builder setValue(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000010;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string value = 5;</code>
+       */
+      public Builder clearValue() {
+        bitField0_ = (bitField0_ & ~0x00000010);
+        value_ = getDefaultInstance().getValue();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string value = 5;</code>
+       */
+      public Builder setValueBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000010;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional string valueType = 6;
+      private java.lang.Object valueType_ = "";
+      /**
+       * <code>optional string valueType = 6;</code>
+       */
+      public boolean hasValueType() {
+        return ((bitField0_ & 0x00000020) == 0x00000020);
+      }
+      /**
+       * <code>optional string valueType = 6;</code>
+       */
+      public java.lang.String getValueType() {
+        java.lang.Object ref = valueType_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          valueType_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string valueType = 6;</code>
+       */
+      public com.google.protobuf.ByteString
+          getValueTypeBytes() {
+        java.lang.Object ref = valueType_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          valueType_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string valueType = 6;</code>
+       */
+      public Builder setValueType(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000020;
+        valueType_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string valueType = 6;</code>
+       */
+      public Builder clearValueType() {
+        bitField0_ = (bitField0_ & ~0x00000020);
+        valueType_ = getDefaultInstance().getValueType();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string valueType = 6;</code>
+       */
+      public Builder setValueTypeBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000020;
+        valueType_ = value;
+        onChanged();
+        return this;
+      }
+
+      // repeated string bitsValue = 7;
+      private com.google.protobuf.LazyStringList bitsValue_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+      private void ensureBitsValueIsMutable() {
+        if (!((bitField0_ & 0x00000040) == 0x00000040)) {
+          bitsValue_ = new com.google.protobuf.LazyStringArrayList(bitsValue_);
+          bitField0_ |= 0x00000040;
+         }
+      }
+      /**
+       * <code>repeated string bitsValue = 7;</code>
+       */
+      public java.util.List<java.lang.String>
+          getBitsValueList() {
+        return java.util.Collections.unmodifiableList(bitsValue_);
+      }
+      /**
+       * <code>repeated string bitsValue = 7;</code>
+       */
+      public int getBitsValueCount() {
+        return bitsValue_.size();
+      }
+      /**
+       * <code>repeated string bitsValue = 7;</code>
+       */
+      public java.lang.String getBitsValue(int index) {
+        return bitsValue_.get(index);
+      }
+      /**
+       * <code>repeated string bitsValue = 7;</code>
+       */
+      public com.google.protobuf.ByteString
+          getBitsValueBytes(int index) {
+        return bitsValue_.getByteString(index);
+      }
+      /**
+       * <code>repeated string bitsValue = 7;</code>
+       */
+      public Builder setBitsValue(
+          int index, java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureBitsValueIsMutable();
+        bitsValue_.set(index, value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string bitsValue = 7;</code>
+       */
+      public Builder addBitsValue(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureBitsValueIsMutable();
+        bitsValue_.add(value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string bitsValue = 7;</code>
+       */
+      public Builder addAllBitsValue(
+          java.lang.Iterable<java.lang.String> values) {
+        ensureBitsValueIsMutable();
+        super.addAll(values, bitsValue_);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string bitsValue = 7;</code>
+       */
+      public Builder clearBitsValue() {
+        bitsValue_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000040);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string bitsValue = 7;</code>
+       */
+      public Builder addBitsValueBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureBitsValueIsMutable();
+        bitsValue_.add(value);
+        onChanged();
+        return this;
+      }
+
+      // optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier instanceIdentifierValue_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> instanceIdentifierValueBuilder_;
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+       */
+      public boolean hasInstanceIdentifierValue() {
+        return ((bitField0_ & 0x00000080) == 0x00000080);
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierValue() {
+        if (instanceIdentifierValueBuilder_ == null) {
+          return instanceIdentifierValue_;
+        } else {
+          return instanceIdentifierValueBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+       */
+      public Builder setInstanceIdentifierValue(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (instanceIdentifierValueBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          instanceIdentifierValue_ = value;
+          onChanged();
+        } else {
+          instanceIdentifierValueBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000080;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+       */
+      public Builder setInstanceIdentifierValue(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder builderForValue) {
+        if (instanceIdentifierValueBuilder_ == null) {
+          instanceIdentifierValue_ = builderForValue.build();
+          onChanged();
+        } else {
+          instanceIdentifierValueBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000080;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+       */
+      public Builder mergeInstanceIdentifierValue(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (instanceIdentifierValueBuilder_ == null) {
+          if (((bitField0_ & 0x00000080) == 0x00000080) &&
+              instanceIdentifierValue_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance()) {
+            instanceIdentifierValue_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.newBuilder(instanceIdentifierValue_).mergeFrom(value).buildPartial();
+          } else {
+            instanceIdentifierValue_ = value;
+          }
+          onChanged();
+        } else {
+          instanceIdentifierValueBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000080;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+       */
+      public Builder clearInstanceIdentifierValue() {
+        if (instanceIdentifierValueBuilder_ == null) {
+          instanceIdentifierValue_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+          onChanged();
+        } else {
+          instanceIdentifierValueBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000080);
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder getInstanceIdentifierValueBuilder() {
+        bitField0_ |= 0x00000080;
+        onChanged();
+        return getInstanceIdentifierValueFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierValueOrBuilder() {
+        if (instanceIdentifierValueBuilder_ != null) {
+          return instanceIdentifierValueBuilder_.getMessageOrBuilder();
+        } else {
+          return instanceIdentifierValue_;
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierValue = 8;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> 
+          getInstanceIdentifierValueFieldBuilder() {
+        if (instanceIdentifierValueBuilder_ == null) {
+          instanceIdentifierValueBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder>(
+                  instanceIdentifierValue_,
+                  getParentForChildren(),
+                  isClean());
+          instanceIdentifierValue_ = null;
+        }
+        return instanceIdentifierValueBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.Node)
+    }
+
+    static {
+      defaultInstance = new Node(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.Node)
+  }
+
+  public interface ContainerOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string parentPath = 1;
+    /**
+     * <code>required string parentPath = 1;</code>
+     */
+    boolean hasParentPath();
+    /**
+     * <code>required string parentPath = 1;</code>
+     */
+    java.lang.String getParentPath();
+    /**
+     * <code>required string parentPath = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getParentPathBytes();
+
+    // optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    boolean hasNormalizedNode();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.Container}
+   */
+  public static final class Container extends
+      com.google.protobuf.GeneratedMessage
+      implements ContainerOrBuilder {
+    // Use Container.newBuilder() to construct.
+    private Container(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Container(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final Container defaultInstance;
+    public static Container getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Container getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Container(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              parentPath_ = input.readBytes();
+              break;
+            }
+            case 18: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+                subBuilder = normalizedNode_.toBuilder();
+              }
+              normalizedNode_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(normalizedNode_);
+                normalizedNode_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000002;
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Container_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Container_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<Container> PARSER =
+        new com.google.protobuf.AbstractParser<Container>() {
+      public Container parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Container(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Container> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string parentPath = 1;
+    public static final int PARENTPATH_FIELD_NUMBER = 1;
+    private java.lang.Object parentPath_;
+    /**
+     * <code>required string parentPath = 1;</code>
+     */
+    public boolean hasParentPath() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string parentPath = 1;</code>
+     */
+    public java.lang.String getParentPath() {
+      java.lang.Object ref = parentPath_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          parentPath_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string parentPath = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getParentPathBytes() {
+      java.lang.Object ref = parentPath_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        parentPath_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;
+    public static final int NORMALIZEDNODE_FIELD_NUMBER = 2;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node normalizedNode_;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    public boolean hasNormalizedNode() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode() {
+      return normalizedNode_;
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder() {
+      return normalizedNode_;
+    }
+
+    private void initFields() {
+      parentPath_ = "";
+      normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasParentPath()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (hasNormalizedNode()) {
+        if (!getNormalizedNode().isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getParentPathBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeMessage(2, normalizedNode_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getParentPathBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, normalizedNode_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.Container}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.ContainerOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Container_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Container_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getNormalizedNodeFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        parentPath_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+        } else {
+          normalizedNodeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_Container_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container build() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container buildPartial() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container result = new org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.parentPath_ = parentPath_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        if (normalizedNodeBuilder_ == null) {
+          result.normalizedNode_ = normalizedNode_;
+        } else {
+          result.normalizedNode_ = normalizedNodeBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container other) {
+        if (other == org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container.getDefaultInstance()) return this;
+        if (other.hasParentPath()) {
+          bitField0_ |= 0x00000001;
+          parentPath_ = other.parentPath_;
+          onChanged();
+        }
+        if (other.hasNormalizedNode()) {
+          mergeNormalizedNode(other.getNormalizedNode());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasParentPath()) {
+          
+          return false;
+        }
+        if (hasNormalizedNode()) {
+          if (!getNormalizedNode().isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string parentPath = 1;
+      private java.lang.Object parentPath_ = "";
+      /**
+       * <code>required string parentPath = 1;</code>
+       */
+      public boolean hasParentPath() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string parentPath = 1;</code>
+       */
+      public java.lang.String getParentPath() {
+        java.lang.Object ref = parentPath_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          parentPath_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string parentPath = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getParentPathBytes() {
+        java.lang.Object ref = parentPath_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          parentPath_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string parentPath = 1;</code>
+       */
+      public Builder setParentPath(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        parentPath_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string parentPath = 1;</code>
+       */
+      public Builder clearParentPath() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        parentPath_ = getDefaultInstance().getParentPath();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string parentPath = 1;</code>
+       */
+      public Builder setParentPathBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        parentPath_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> normalizedNodeBuilder_;
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public boolean hasNormalizedNode() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode() {
+        if (normalizedNodeBuilder_ == null) {
+          return normalizedNode_;
+        } else {
+          return normalizedNodeBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder setNormalizedNode(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (normalizedNodeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          normalizedNode_ = value;
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder setNormalizedNode(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder builderForValue) {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = builderForValue.build();
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder mergeNormalizedNode(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (normalizedNodeBuilder_ == null) {
+          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+              normalizedNode_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance()) {
+            normalizedNode_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.newBuilder(normalizedNode_).mergeFrom(value).buildPartial();
+          } else {
+            normalizedNode_ = value;
+          }
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder clearNormalizedNode() {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder getNormalizedNodeBuilder() {
+        bitField0_ |= 0x00000002;
+        onChanged();
+        return getNormalizedNodeFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder() {
+        if (normalizedNodeBuilder_ != null) {
+          return normalizedNodeBuilder_.getMessageOrBuilder();
+        } else {
+          return normalizedNode_;
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> 
+          getNormalizedNodeFieldBuilder() {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNodeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder>(
+                  normalizedNode_,
+                  getParentForChildren(),
+                  isClean());
+          normalizedNode_ = null;
+        }
+        return normalizedNodeBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.Container)
+    }
+
+    static {
+      defaultInstance = new Container(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.Container)
+  }
+
+  public interface NodeMapEntryOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+     */
+    boolean hasInstanceIdentifierPath();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPath();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathOrBuilder();
+
+    // optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    boolean hasNormalizedNode();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.NodeMapEntry}
+   */
+  public static final class NodeMapEntry extends
+      com.google.protobuf.GeneratedMessage
+      implements NodeMapEntryOrBuilder {
+    // Use NodeMapEntry.newBuilder() to construct.
+    private NodeMapEntry(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private NodeMapEntry(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final NodeMapEntry defaultInstance;
+    public static NodeMapEntry getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public NodeMapEntry getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private NodeMapEntry(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+                subBuilder = instanceIdentifierPath_.toBuilder();
+              }
+              instanceIdentifierPath_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(instanceIdentifierPath_);
+                instanceIdentifierPath_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000001;
+              break;
+            }
+            case 18: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+                subBuilder = normalizedNode_.toBuilder();
+              }
+              normalizedNode_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(normalizedNode_);
+                normalizedNode_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000002;
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_NodeMapEntry_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_NodeMapEntry_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<NodeMapEntry> PARSER =
+        new com.google.protobuf.AbstractParser<NodeMapEntry>() {
+      public NodeMapEntry parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new NodeMapEntry(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<NodeMapEntry> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;
+    public static final int INSTANCEIDENTIFIERPATH_FIELD_NUMBER = 1;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier instanceIdentifierPath_;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+     */
+    public boolean hasInstanceIdentifierPath() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPath() {
+      return instanceIdentifierPath_;
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathOrBuilder() {
+      return instanceIdentifierPath_;
+    }
+
+    // optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;
+    public static final int NORMALIZEDNODE_FIELD_NUMBER = 2;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node normalizedNode_;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    public boolean hasNormalizedNode() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode() {
+      return normalizedNode_;
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder() {
+      return normalizedNode_;
+    }
+
+    private void initFields() {
+      instanceIdentifierPath_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+      normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasInstanceIdentifierPath()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!getInstanceIdentifierPath().isInitialized()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (hasNormalizedNode()) {
+        if (!getNormalizedNode().isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeMessage(1, instanceIdentifierPath_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeMessage(2, normalizedNode_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, instanceIdentifierPath_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, normalizedNode_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.NodeMapEntry}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntryOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_NodeMapEntry_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_NodeMapEntry_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getInstanceIdentifierPathFieldBuilder();
+          getNormalizedNodeFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (instanceIdentifierPathBuilder_ == null) {
+          instanceIdentifierPath_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+        } else {
+          instanceIdentifierPathBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+        } else {
+          normalizedNodeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_NodeMapEntry_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry build() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry buildPartial() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry result = new org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        if (instanceIdentifierPathBuilder_ == null) {
+          result.instanceIdentifierPath_ = instanceIdentifierPath_;
+        } else {
+          result.instanceIdentifierPath_ = instanceIdentifierPathBuilder_.build();
+        }
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        if (normalizedNodeBuilder_ == null) {
+          result.normalizedNode_ = normalizedNode_;
+        } else {
+          result.normalizedNode_ = normalizedNodeBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry other) {
+        if (other == org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.getDefaultInstance()) return this;
+        if (other.hasInstanceIdentifierPath()) {
+          mergeInstanceIdentifierPath(other.getInstanceIdentifierPath());
+        }
+        if (other.hasNormalizedNode()) {
+          mergeNormalizedNode(other.getNormalizedNode());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasInstanceIdentifierPath()) {
+          
+          return false;
+        }
+        if (!getInstanceIdentifierPath().isInitialized()) {
+          
+          return false;
+        }
+        if (hasNormalizedNode()) {
+          if (!getNormalizedNode().isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier instanceIdentifierPath_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> instanceIdentifierPathBuilder_;
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public boolean hasInstanceIdentifierPath() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPath() {
+        if (instanceIdentifierPathBuilder_ == null) {
+          return instanceIdentifierPath_;
+        } else {
+          return instanceIdentifierPathBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public Builder setInstanceIdentifierPath(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (instanceIdentifierPathBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          instanceIdentifierPath_ = value;
+          onChanged();
+        } else {
+          instanceIdentifierPathBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public Builder setInstanceIdentifierPath(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder builderForValue) {
+        if (instanceIdentifierPathBuilder_ == null) {
+          instanceIdentifierPath_ = builderForValue.build();
+          onChanged();
+        } else {
+          instanceIdentifierPathBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public Builder mergeInstanceIdentifierPath(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (instanceIdentifierPathBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+              instanceIdentifierPath_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance()) {
+            instanceIdentifierPath_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.newBuilder(instanceIdentifierPath_).mergeFrom(value).buildPartial();
+          } else {
+            instanceIdentifierPath_ = value;
+          }
+          onChanged();
+        } else {
+          instanceIdentifierPathBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public Builder clearInstanceIdentifierPath() {
+        if (instanceIdentifierPathBuilder_ == null) {
+          instanceIdentifierPath_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+          onChanged();
+        } else {
+          instanceIdentifierPathBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder getInstanceIdentifierPathBuilder() {
+        bitField0_ |= 0x00000001;
+        onChanged();
+        return getInstanceIdentifierPathFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathOrBuilder() {
+        if (instanceIdentifierPathBuilder_ != null) {
+          return instanceIdentifierPathBuilder_.getMessageOrBuilder();
+        } else {
+          return instanceIdentifierPath_;
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> 
+          getInstanceIdentifierPathFieldBuilder() {
+        if (instanceIdentifierPathBuilder_ == null) {
+          instanceIdentifierPathBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder>(
+                  instanceIdentifierPath_,
+                  getParentForChildren(),
+                  isClean());
+          instanceIdentifierPath_ = null;
+        }
+        return instanceIdentifierPathBuilder_;
+      }
+
+      // optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> normalizedNodeBuilder_;
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public boolean hasNormalizedNode() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode() {
+        if (normalizedNodeBuilder_ == null) {
+          return normalizedNode_;
+        } else {
+          return normalizedNodeBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder setNormalizedNode(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (normalizedNodeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          normalizedNode_ = value;
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder setNormalizedNode(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder builderForValue) {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = builderForValue.build();
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder mergeNormalizedNode(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (normalizedNodeBuilder_ == null) {
+          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+              normalizedNode_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance()) {
+            normalizedNode_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.newBuilder(normalizedNode_).mergeFrom(value).buildPartial();
+          } else {
+            normalizedNode_ = value;
+          }
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder clearNormalizedNode() {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder getNormalizedNodeBuilder() {
+        bitField0_ |= 0x00000002;
+        onChanged();
+        return getNormalizedNodeFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder() {
+        if (normalizedNodeBuilder_ != null) {
+          return normalizedNodeBuilder_.getMessageOrBuilder();
+        } else {
+          return normalizedNode_;
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> 
+          getNormalizedNodeFieldBuilder() {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNodeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder>(
+                  normalizedNode_,
+                  getParentForChildren(),
+                  isClean());
+          normalizedNode_ = null;
+        }
+        return normalizedNodeBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.NodeMapEntry)
+    }
+
+    static {
+      defaultInstance = new NodeMapEntry(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.NodeMapEntry)
+  }
+
+  public interface NodeMapOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+     */
+    java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry> 
+        getMapEntriesList();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry getMapEntries(int index);
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+     */
+    int getMapEntriesCount();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+     */
+    java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntryOrBuilder> 
+        getMapEntriesOrBuilderList();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntryOrBuilder getMapEntriesOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.NodeMap}
+   */
+  public static final class NodeMap extends
+      com.google.protobuf.GeneratedMessage
+      implements NodeMapOrBuilder {
+    // Use NodeMap.newBuilder() to construct.
+    private NodeMap(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private NodeMap(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final NodeMap defaultInstance;
+    public static NodeMap getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public NodeMap getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private NodeMap(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                mapEntries_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              mapEntries_.add(input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          mapEntries_ = java.util.Collections.unmodifiableList(mapEntries_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_NodeMap_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_NodeMap_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<NodeMap> PARSER =
+        new com.google.protobuf.AbstractParser<NodeMap>() {
+      public NodeMap parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new NodeMap(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<NodeMap> getParserForType() {
+      return PARSER;
+    }
+
+    // repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;
+    public static final int MAPENTRIES_FIELD_NUMBER = 1;
+    private java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry> mapEntries_;
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+     */
+    public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry> getMapEntriesList() {
+      return mapEntries_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+     */
+    public java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntryOrBuilder> 
+        getMapEntriesOrBuilderList() {
+      return mapEntries_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+     */
+    public int getMapEntriesCount() {
+      return mapEntries_.size();
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry getMapEntries(int index) {
+      return mapEntries_.get(index);
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntryOrBuilder getMapEntriesOrBuilder(
+        int index) {
+      return mapEntries_.get(index);
+    }
+
+    private void initFields() {
+      mapEntries_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      for (int i = 0; i < getMapEntriesCount(); i++) {
+        if (!getMapEntries(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < mapEntries_.size(); i++) {
+        output.writeMessage(1, mapEntries_.get(i));
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < mapEntries_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, mapEntries_.get(i));
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.NodeMap}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_NodeMap_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_NodeMap_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.class, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getMapEntriesFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (mapEntriesBuilder_ == null) {
+          mapEntries_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          mapEntriesBuilder_.clear();
+        }
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.internal_static_org_opendaylight_controller_mdsal_NodeMap_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap build() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap buildPartial() {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap result = new org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap(this);
+        int from_bitField0_ = bitField0_;
+        if (mapEntriesBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+            mapEntries_ = java.util.Collections.unmodifiableList(mapEntries_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.mapEntries_ = mapEntries_;
+        } else {
+          result.mapEntries_ = mapEntriesBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap other) {
+        if (other == org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance()) return this;
+        if (mapEntriesBuilder_ == null) {
+          if (!other.mapEntries_.isEmpty()) {
+            if (mapEntries_.isEmpty()) {
+              mapEntries_ = other.mapEntries_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureMapEntriesIsMutable();
+              mapEntries_.addAll(other.mapEntries_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.mapEntries_.isEmpty()) {
+            if (mapEntriesBuilder_.isEmpty()) {
+              mapEntriesBuilder_.dispose();
+              mapEntriesBuilder_ = null;
+              mapEntries_ = other.mapEntries_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              mapEntriesBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getMapEntriesFieldBuilder() : null;
+            } else {
+              mapEntriesBuilder_.addAllMessages(other.mapEntries_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        for (int i = 0; i < getMapEntriesCount(); i++) {
+          if (!getMapEntries(i).isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;
+      private java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry> mapEntries_ =
+        java.util.Collections.emptyList();
+      private void ensureMapEntriesIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          mapEntries_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry>(mapEntries_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntryOrBuilder> mapEntriesBuilder_;
+
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry> getMapEntriesList() {
+        if (mapEntriesBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(mapEntries_);
+        } else {
+          return mapEntriesBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public int getMapEntriesCount() {
+        if (mapEntriesBuilder_ == null) {
+          return mapEntries_.size();
+        } else {
+          return mapEntriesBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry getMapEntries(int index) {
+        if (mapEntriesBuilder_ == null) {
+          return mapEntries_.get(index);
+        } else {
+          return mapEntriesBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public Builder setMapEntries(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry value) {
+        if (mapEntriesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureMapEntriesIsMutable();
+          mapEntries_.set(index, value);
+          onChanged();
+        } else {
+          mapEntriesBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public Builder setMapEntries(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.Builder builderForValue) {
+        if (mapEntriesBuilder_ == null) {
+          ensureMapEntriesIsMutable();
+          mapEntries_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          mapEntriesBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public Builder addMapEntries(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry value) {
+        if (mapEntriesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureMapEntriesIsMutable();
+          mapEntries_.add(value);
+          onChanged();
+        } else {
+          mapEntriesBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public Builder addMapEntries(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry value) {
+        if (mapEntriesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureMapEntriesIsMutable();
+          mapEntries_.add(index, value);
+          onChanged();
+        } else {
+          mapEntriesBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public Builder addMapEntries(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.Builder builderForValue) {
+        if (mapEntriesBuilder_ == null) {
+          ensureMapEntriesIsMutable();
+          mapEntries_.add(builderForValue.build());
+          onChanged();
+        } else {
+          mapEntriesBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public Builder addMapEntries(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.Builder builderForValue) {
+        if (mapEntriesBuilder_ == null) {
+          ensureMapEntriesIsMutable();
+          mapEntries_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          mapEntriesBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public Builder addAllMapEntries(
+          java.lang.Iterable<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry> values) {
+        if (mapEntriesBuilder_ == null) {
+          ensureMapEntriesIsMutable();
+          super.addAll(values, mapEntries_);
+          onChanged();
+        } else {
+          mapEntriesBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public Builder clearMapEntries() {
+        if (mapEntriesBuilder_ == null) {
+          mapEntries_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          mapEntriesBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public Builder removeMapEntries(int index) {
+        if (mapEntriesBuilder_ == null) {
+          ensureMapEntriesIsMutable();
+          mapEntries_.remove(index);
+          onChanged();
+        } else {
+          mapEntriesBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.Builder getMapEntriesBuilder(
+          int index) {
+        return getMapEntriesFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntryOrBuilder getMapEntriesOrBuilder(
+          int index) {
+        if (mapEntriesBuilder_ == null) {
+          return mapEntries_.get(index);  } else {
+          return mapEntriesBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntryOrBuilder> 
+           getMapEntriesOrBuilderList() {
+        if (mapEntriesBuilder_ != null) {
+          return mapEntriesBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(mapEntries_);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.Builder addMapEntriesBuilder() {
+        return getMapEntriesFieldBuilder().addBuilder(
+            org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.Builder addMapEntriesBuilder(
+          int index) {
+        return getMapEntriesFieldBuilder().addBuilder(
+            index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.NodeMapEntry mapEntries = 1;</code>
+       */
+      public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.Builder> 
+           getMapEntriesBuilderList() {
+        return getMapEntriesFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntryOrBuilder> 
+          getMapEntriesFieldBuilder() {
+        if (mapEntriesBuilder_ == null) {
+          mapEntriesBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntry.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapEntryOrBuilder>(
+                  mapEntries_,
+                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  getParentForChildren(),
+                  isClean());
+          mapEntries_ = null;
+        }
+        return mapEntriesBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.NodeMap)
+    }
+
+    static {
+      defaultInstance = new NodeMap(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.NodeMap)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_Attribute_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_Attribute_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_QName_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_QName_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_PathArgument_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_PathArgument_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_InstanceIdentifier_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_InstanceIdentifier_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_Node_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_Node_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_Container_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_Container_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_NodeMapEntry_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_NodeMapEntry_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_NodeMap_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_NodeMap_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\014Common.proto\022!org.opendaylight.control" +
+      "ler.mdsal\"6\n\tAttribute\022\014\n\004name\030\001 \002(\t\022\r\n\005" +
+      "value\030\002 \001(\t\022\014\n\004type\030\003 \001(\t\"\026\n\005QName\022\r\n\005va" +
+      "lue\030\001 \002(\t\"\251\001\n\014PathArgument\022\r\n\005value\030\001 \002(" +
+      "\t\022\014\n\004type\030\002 \001(\t\022:\n\010nodeType\030\003 \001(\0132(.org." +
+      "opendaylight.controller.mdsal.QName\022@\n\na" +
+      "ttributes\030\004 \003(\0132,.org.opendaylight.contr" +
+      "oller.mdsal.Attribute\"X\n\022InstanceIdentif" +
+      "ier\022B\n\targuments\030\001 \003(\0132/.org.opendayligh" +
+      "t.controller.mdsal.PathArgument\"\251\002\n\004Node",
+      "\022\014\n\004path\030\001 \001(\t\022\014\n\004type\030\002 \001(\t\022@\n\nattribut" +
+      "es\030\003 \003(\0132,.org.opendaylight.controller.m" +
+      "dsal.Attribute\0226\n\005child\030\004 \003(\0132\'.org.open" +
+      "daylight.controller.mdsal.Node\022\r\n\005value\030" +
+      "\005 \001(\t\022\021\n\tvalueType\030\006 \001(\t\022\021\n\tbitsValue\030\007 " +
+      "\003(\t\022V\n\027instanceIdentifierValue\030\010 \001(\01325.o" +
+      "rg.opendaylight.controller.mdsal.Instanc" +
+      "eIdentifier\"`\n\tContainer\022\022\n\nparentPath\030\001" +
+      " \002(\t\022?\n\016normalizedNode\030\002 \001(\0132\'.org.opend" +
+      "aylight.controller.mdsal.Node\"\246\001\n\014NodeMa",
+      "pEntry\022U\n\026instanceIdentifierPath\030\001 \002(\01325" +
+      ".org.opendaylight.controller.mdsal.Insta" +
+      "nceIdentifier\022?\n\016normalizedNode\030\002 \001(\0132\'." +
+      "org.opendaylight.controller.mdsal.Node\"N" +
+      "\n\007NodeMap\022C\n\nmapEntries\030\001 \003(\0132/.org.open" +
+      "daylight.controller.mdsal.NodeMapEntryBO" +
+      "\n5org.opendaylight.controller.protobuff." +
+      "messages.commonB\026NormalizedNodeMessages"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_org_opendaylight_controller_mdsal_Attribute_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_org_opendaylight_controller_mdsal_Attribute_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_Attribute_descriptor,
+              new java.lang.String[] { "Name", "Value", "Type", });
+          internal_static_org_opendaylight_controller_mdsal_QName_descriptor =
+            getDescriptor().getMessageTypes().get(1);
+          internal_static_org_opendaylight_controller_mdsal_QName_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_QName_descriptor,
+              new java.lang.String[] { "Value", });
+          internal_static_org_opendaylight_controller_mdsal_PathArgument_descriptor =
+            getDescriptor().getMessageTypes().get(2);
+          internal_static_org_opendaylight_controller_mdsal_PathArgument_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_PathArgument_descriptor,
+              new java.lang.String[] { "Value", "Type", "NodeType", "Attributes", });
+          internal_static_org_opendaylight_controller_mdsal_InstanceIdentifier_descriptor =
+            getDescriptor().getMessageTypes().get(3);
+          internal_static_org_opendaylight_controller_mdsal_InstanceIdentifier_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_InstanceIdentifier_descriptor,
+              new java.lang.String[] { "Arguments", });
+          internal_static_org_opendaylight_controller_mdsal_Node_descriptor =
+            getDescriptor().getMessageTypes().get(4);
+          internal_static_org_opendaylight_controller_mdsal_Node_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_Node_descriptor,
+              new java.lang.String[] { "Path", "Type", "Attributes", "Child", "Value", "ValueType", "BitsValue", "InstanceIdentifierValue", });
+          internal_static_org_opendaylight_controller_mdsal_Container_descriptor =
+            getDescriptor().getMessageTypes().get(5);
+          internal_static_org_opendaylight_controller_mdsal_Container_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_Container_descriptor,
+              new java.lang.String[] { "ParentPath", "NormalizedNode", });
+          internal_static_org_opendaylight_controller_mdsal_NodeMapEntry_descriptor =
+            getDescriptor().getMessageTypes().get(6);
+          internal_static_org_opendaylight_controller_mdsal_NodeMapEntry_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_NodeMapEntry_descriptor,
+              new java.lang.String[] { "InstanceIdentifierPath", "NormalizedNode", });
+          internal_static_org_opendaylight_controller_mdsal_NodeMap_descriptor =
+            getDescriptor().getMessageTypes().get(7);
+          internal_static_org_opendaylight_controller_mdsal_NodeMap_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_NodeMap_descriptor,
+              new java.lang.String[] { "MapEntries", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/common/SimpleNormalizedNodeMessage.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/common/SimpleNormalizedNodeMessage.java
new file mode 100644 (file)
index 0000000..29e5457
--- /dev/null
@@ -0,0 +1,696 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: SimpleNormalizedNode.proto
+
+package org.opendaylight.controller.protobuff.messages.common;
+
+public final class SimpleNormalizedNodeMessage {
+  private SimpleNormalizedNodeMessage() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface NormalizedNodeXmlOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string nodeIdentifier = 1;
+    /**
+     * <code>required string nodeIdentifier = 1;</code>
+     */
+    boolean hasNodeIdentifier();
+    /**
+     * <code>required string nodeIdentifier = 1;</code>
+     */
+    java.lang.String getNodeIdentifier();
+    /**
+     * <code>required string nodeIdentifier = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getNodeIdentifierBytes();
+
+    // required string xmlString = 2;
+    /**
+     * <code>required string xmlString = 2;</code>
+     */
+    boolean hasXmlString();
+    /**
+     * <code>required string xmlString = 2;</code>
+     */
+    java.lang.String getXmlString();
+    /**
+     * <code>required string xmlString = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getXmlStringBytes();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.NormalizedNodeXml}
+   */
+  public static final class NormalizedNodeXml extends
+      com.google.protobuf.GeneratedMessage
+      implements NormalizedNodeXmlOrBuilder {
+    // Use NormalizedNodeXml.newBuilder() to construct.
+    private NormalizedNodeXml(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private NormalizedNodeXml(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final NormalizedNodeXml defaultInstance;
+    public static NormalizedNodeXml getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public NormalizedNodeXml getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private NormalizedNodeXml(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              nodeIdentifier_ = input.readBytes();
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              xmlString_ = input.readBytes();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.internal_static_org_opendaylight_controller_mdsal_NormalizedNodeXml_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.internal_static_org_opendaylight_controller_mdsal_NormalizedNodeXml_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml.class, org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<NormalizedNodeXml> PARSER =
+        new com.google.protobuf.AbstractParser<NormalizedNodeXml>() {
+      public NormalizedNodeXml parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new NormalizedNodeXml(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<NormalizedNodeXml> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string nodeIdentifier = 1;
+    public static final int NODEIDENTIFIER_FIELD_NUMBER = 1;
+    private java.lang.Object nodeIdentifier_;
+    /**
+     * <code>required string nodeIdentifier = 1;</code>
+     */
+    public boolean hasNodeIdentifier() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string nodeIdentifier = 1;</code>
+     */
+    public java.lang.String getNodeIdentifier() {
+      java.lang.Object ref = nodeIdentifier_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          nodeIdentifier_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string nodeIdentifier = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getNodeIdentifierBytes() {
+      java.lang.Object ref = nodeIdentifier_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        nodeIdentifier_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required string xmlString = 2;
+    public static final int XMLSTRING_FIELD_NUMBER = 2;
+    private java.lang.Object xmlString_;
+    /**
+     * <code>required string xmlString = 2;</code>
+     */
+    public boolean hasXmlString() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required string xmlString = 2;</code>
+     */
+    public java.lang.String getXmlString() {
+      java.lang.Object ref = xmlString_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          xmlString_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string xmlString = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getXmlStringBytes() {
+      java.lang.Object ref = xmlString_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        xmlString_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    private void initFields() {
+      nodeIdentifier_ = "";
+      xmlString_ = "";
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasNodeIdentifier()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasXmlString()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getNodeIdentifierBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, getXmlStringBytes());
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getNodeIdentifierBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, getXmlStringBytes());
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.NormalizedNodeXml}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXmlOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.internal_static_org_opendaylight_controller_mdsal_NormalizedNodeXml_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.internal_static_org_opendaylight_controller_mdsal_NormalizedNodeXml_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml.class, org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        nodeIdentifier_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        xmlString_ = "";
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.internal_static_org_opendaylight_controller_mdsal_NormalizedNodeXml_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml build() {
+        org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml buildPartial() {
+        org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml result = new org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.nodeIdentifier_ = nodeIdentifier_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.xmlString_ = xmlString_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml other) {
+        if (other == org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml.getDefaultInstance()) return this;
+        if (other.hasNodeIdentifier()) {
+          bitField0_ |= 0x00000001;
+          nodeIdentifier_ = other.nodeIdentifier_;
+          onChanged();
+        }
+        if (other.hasXmlString()) {
+          bitField0_ |= 0x00000002;
+          xmlString_ = other.xmlString_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasNodeIdentifier()) {
+          
+          return false;
+        }
+        if (!hasXmlString()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage.NormalizedNodeXml) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string nodeIdentifier = 1;
+      private java.lang.Object nodeIdentifier_ = "";
+      /**
+       * <code>required string nodeIdentifier = 1;</code>
+       */
+      public boolean hasNodeIdentifier() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string nodeIdentifier = 1;</code>
+       */
+      public java.lang.String getNodeIdentifier() {
+        java.lang.Object ref = nodeIdentifier_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          nodeIdentifier_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string nodeIdentifier = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getNodeIdentifierBytes() {
+        java.lang.Object ref = nodeIdentifier_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          nodeIdentifier_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string nodeIdentifier = 1;</code>
+       */
+      public Builder setNodeIdentifier(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        nodeIdentifier_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string nodeIdentifier = 1;</code>
+       */
+      public Builder clearNodeIdentifier() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        nodeIdentifier_ = getDefaultInstance().getNodeIdentifier();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string nodeIdentifier = 1;</code>
+       */
+      public Builder setNodeIdentifierBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        nodeIdentifier_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required string xmlString = 2;
+      private java.lang.Object xmlString_ = "";
+      /**
+       * <code>required string xmlString = 2;</code>
+       */
+      public boolean hasXmlString() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required string xmlString = 2;</code>
+       */
+      public java.lang.String getXmlString() {
+        java.lang.Object ref = xmlString_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          xmlString_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string xmlString = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getXmlStringBytes() {
+        java.lang.Object ref = xmlString_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          xmlString_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string xmlString = 2;</code>
+       */
+      public Builder setXmlString(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        xmlString_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string xmlString = 2;</code>
+       */
+      public Builder clearXmlString() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        xmlString_ = getDefaultInstance().getXmlString();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string xmlString = 2;</code>
+       */
+      public Builder setXmlStringBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        xmlString_ = value;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.NormalizedNodeXml)
+    }
+
+    static {
+      defaultInstance = new NormalizedNodeXml(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.NormalizedNodeXml)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_NormalizedNodeXml_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_NormalizedNodeXml_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\032SimpleNormalizedNode.proto\022!org.openda" +
+      "ylight.controller.mdsal\">\n\021NormalizedNod" +
+      "eXml\022\026\n\016nodeIdentifier\030\001 \002(\t\022\021\n\txmlStrin" +
+      "g\030\002 \002(\tBT\n5org.opendaylight.controller.p" +
+      "rotobuff.messages.commonB\033SimpleNormaliz" +
+      "edNodeMessage"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_org_opendaylight_controller_mdsal_NormalizedNodeXml_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_org_opendaylight_controller_mdsal_NormalizedNodeXml_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_NormalizedNodeXml_descriptor,
+              new java.lang.String[] { "NodeIdentifier", "XmlString", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/datachange/notification/DataChangeListenerMessages.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/datachange/notification/DataChangeListenerMessages.java
new file mode 100644 (file)
index 0000000..2018834
--- /dev/null
@@ -0,0 +1,2093 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: DataChangeListener.proto
+
+package org.opendaylight.controller.protobuff.messages.datachange.notification;
+
+public final class DataChangeListenerMessages {
+  private DataChangeListenerMessages() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface DataChangedOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+     */
+    boolean hasOriginalSubTree();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getOriginalSubTree();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getOriginalSubTreeOrBuilder();
+
+    // optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+     */
+    boolean hasUpdatedSubTree();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getUpdatedSubTree();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getUpdatedSubTreeOrBuilder();
+
+    // optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+     */
+    boolean hasOriginalData();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap getOriginalData();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder getOriginalDataOrBuilder();
+
+    // optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+     */
+    boolean hasUpdatedData();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap getUpdatedData();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder getUpdatedDataOrBuilder();
+
+    // optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+     */
+    boolean hasCreatedData();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap getCreatedData();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder getCreatedDataOrBuilder();
+
+    // repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+     */
+    java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier> 
+        getRemovedPathsList();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getRemovedPaths(int index);
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+     */
+    int getRemovedPathsCount();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+     */
+    java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> 
+        getRemovedPathsOrBuilderList();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getRemovedPathsOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.DataChanged}
+   */
+  public static final class DataChanged extends
+      com.google.protobuf.GeneratedMessage
+      implements DataChangedOrBuilder {
+    // Use DataChanged.newBuilder() to construct.
+    private DataChanged(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private DataChanged(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final DataChanged defaultInstance;
+    public static DataChanged getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public DataChanged getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private DataChanged(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+                subBuilder = originalSubTree_.toBuilder();
+              }
+              originalSubTree_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(originalSubTree_);
+                originalSubTree_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000001;
+              break;
+            }
+            case 18: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+                subBuilder = updatedSubTree_.toBuilder();
+              }
+              updatedSubTree_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(updatedSubTree_);
+                updatedSubTree_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000002;
+              break;
+            }
+            case 26: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+                subBuilder = originalData_.toBuilder();
+              }
+              originalData_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(originalData_);
+                originalData_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000004;
+              break;
+            }
+            case 34: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000008) == 0x00000008)) {
+                subBuilder = updatedData_.toBuilder();
+              }
+              updatedData_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(updatedData_);
+                updatedData_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000008;
+              break;
+            }
+            case 42: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000010) == 0x00000010)) {
+                subBuilder = createdData_.toBuilder();
+              }
+              createdData_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(createdData_);
+                createdData_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000010;
+              break;
+            }
+            case 50: {
+              if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+                removedPaths_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier>();
+                mutable_bitField0_ |= 0x00000020;
+              }
+              removedPaths_.add(input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+          removedPaths_ = java.util.Collections.unmodifiableList(removedPaths_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.internal_static_org_opendaylight_controller_mdsal_DataChanged_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.internal_static_org_opendaylight_controller_mdsal_DataChanged_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged.class, org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<DataChanged> PARSER =
+        new com.google.protobuf.AbstractParser<DataChanged>() {
+      public DataChanged parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new DataChanged(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<DataChanged> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;
+    public static final int ORIGINALSUBTREE_FIELD_NUMBER = 1;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node originalSubTree_;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+     */
+    public boolean hasOriginalSubTree() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getOriginalSubTree() {
+      return originalSubTree_;
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getOriginalSubTreeOrBuilder() {
+      return originalSubTree_;
+    }
+
+    // optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;
+    public static final int UPDATEDSUBTREE_FIELD_NUMBER = 2;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node updatedSubTree_;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+     */
+    public boolean hasUpdatedSubTree() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getUpdatedSubTree() {
+      return updatedSubTree_;
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getUpdatedSubTreeOrBuilder() {
+      return updatedSubTree_;
+    }
+
+    // optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;
+    public static final int ORIGINALDATA_FIELD_NUMBER = 3;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap originalData_;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+     */
+    public boolean hasOriginalData() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap getOriginalData() {
+      return originalData_;
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder getOriginalDataOrBuilder() {
+      return originalData_;
+    }
+
+    // optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;
+    public static final int UPDATEDDATA_FIELD_NUMBER = 4;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap updatedData_;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+     */
+    public boolean hasUpdatedData() {
+      return ((bitField0_ & 0x00000008) == 0x00000008);
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap getUpdatedData() {
+      return updatedData_;
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder getUpdatedDataOrBuilder() {
+      return updatedData_;
+    }
+
+    // optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;
+    public static final int CREATEDDATA_FIELD_NUMBER = 5;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap createdData_;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+     */
+    public boolean hasCreatedData() {
+      return ((bitField0_ & 0x00000010) == 0x00000010);
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap getCreatedData() {
+      return createdData_;
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder getCreatedDataOrBuilder() {
+      return createdData_;
+    }
+
+    // repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;
+    public static final int REMOVEDPATHS_FIELD_NUMBER = 6;
+    private java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier> removedPaths_;
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+     */
+    public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier> getRemovedPathsList() {
+      return removedPaths_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+     */
+    public java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> 
+        getRemovedPathsOrBuilderList() {
+      return removedPaths_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+     */
+    public int getRemovedPathsCount() {
+      return removedPaths_.size();
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getRemovedPaths(int index) {
+      return removedPaths_.get(index);
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getRemovedPathsOrBuilder(
+        int index) {
+      return removedPaths_.get(index);
+    }
+
+    private void initFields() {
+      originalSubTree_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+      updatedSubTree_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+      originalData_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance();
+      updatedData_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance();
+      createdData_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance();
+      removedPaths_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (hasOriginalSubTree()) {
+        if (!getOriginalSubTree().isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      if (hasUpdatedSubTree()) {
+        if (!getUpdatedSubTree().isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      if (hasOriginalData()) {
+        if (!getOriginalData().isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      if (hasUpdatedData()) {
+        if (!getUpdatedData().isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      if (hasCreatedData()) {
+        if (!getCreatedData().isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      for (int i = 0; i < getRemovedPathsCount(); i++) {
+        if (!getRemovedPaths(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeMessage(1, originalSubTree_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeMessage(2, updatedSubTree_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeMessage(3, originalData_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        output.writeMessage(4, updatedData_);
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        output.writeMessage(5, createdData_);
+      }
+      for (int i = 0; i < removedPaths_.size(); i++) {
+        output.writeMessage(6, removedPaths_.get(i));
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, originalSubTree_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, updatedSubTree_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, originalData_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(4, updatedData_);
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(5, createdData_);
+      }
+      for (int i = 0; i < removedPaths_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(6, removedPaths_.get(i));
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.DataChanged}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.internal_static_org_opendaylight_controller_mdsal_DataChanged_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.internal_static_org_opendaylight_controller_mdsal_DataChanged_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged.class, org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getOriginalSubTreeFieldBuilder();
+          getUpdatedSubTreeFieldBuilder();
+          getOriginalDataFieldBuilder();
+          getUpdatedDataFieldBuilder();
+          getCreatedDataFieldBuilder();
+          getRemovedPathsFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (originalSubTreeBuilder_ == null) {
+          originalSubTree_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+        } else {
+          originalSubTreeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        if (updatedSubTreeBuilder_ == null) {
+          updatedSubTree_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+        } else {
+          updatedSubTreeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000002);
+        if (originalDataBuilder_ == null) {
+          originalData_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance();
+        } else {
+          originalDataBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000004);
+        if (updatedDataBuilder_ == null) {
+          updatedData_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance();
+        } else {
+          updatedDataBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000008);
+        if (createdDataBuilder_ == null) {
+          createdData_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance();
+        } else {
+          createdDataBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000010);
+        if (removedPathsBuilder_ == null) {
+          removedPaths_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000020);
+        } else {
+          removedPathsBuilder_.clear();
+        }
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.internal_static_org_opendaylight_controller_mdsal_DataChanged_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged build() {
+        org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged buildPartial() {
+        org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged result = new org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        if (originalSubTreeBuilder_ == null) {
+          result.originalSubTree_ = originalSubTree_;
+        } else {
+          result.originalSubTree_ = originalSubTreeBuilder_.build();
+        }
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        if (updatedSubTreeBuilder_ == null) {
+          result.updatedSubTree_ = updatedSubTree_;
+        } else {
+          result.updatedSubTree_ = updatedSubTreeBuilder_.build();
+        }
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        if (originalDataBuilder_ == null) {
+          result.originalData_ = originalData_;
+        } else {
+          result.originalData_ = originalDataBuilder_.build();
+        }
+        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+          to_bitField0_ |= 0x00000008;
+        }
+        if (updatedDataBuilder_ == null) {
+          result.updatedData_ = updatedData_;
+        } else {
+          result.updatedData_ = updatedDataBuilder_.build();
+        }
+        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+          to_bitField0_ |= 0x00000010;
+        }
+        if (createdDataBuilder_ == null) {
+          result.createdData_ = createdData_;
+        } else {
+          result.createdData_ = createdDataBuilder_.build();
+        }
+        if (removedPathsBuilder_ == null) {
+          if (((bitField0_ & 0x00000020) == 0x00000020)) {
+            removedPaths_ = java.util.Collections.unmodifiableList(removedPaths_);
+            bitField0_ = (bitField0_ & ~0x00000020);
+          }
+          result.removedPaths_ = removedPaths_;
+        } else {
+          result.removedPaths_ = removedPathsBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged other) {
+        if (other == org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged.getDefaultInstance()) return this;
+        if (other.hasOriginalSubTree()) {
+          mergeOriginalSubTree(other.getOriginalSubTree());
+        }
+        if (other.hasUpdatedSubTree()) {
+          mergeUpdatedSubTree(other.getUpdatedSubTree());
+        }
+        if (other.hasOriginalData()) {
+          mergeOriginalData(other.getOriginalData());
+        }
+        if (other.hasUpdatedData()) {
+          mergeUpdatedData(other.getUpdatedData());
+        }
+        if (other.hasCreatedData()) {
+          mergeCreatedData(other.getCreatedData());
+        }
+        if (removedPathsBuilder_ == null) {
+          if (!other.removedPaths_.isEmpty()) {
+            if (removedPaths_.isEmpty()) {
+              removedPaths_ = other.removedPaths_;
+              bitField0_ = (bitField0_ & ~0x00000020);
+            } else {
+              ensureRemovedPathsIsMutable();
+              removedPaths_.addAll(other.removedPaths_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.removedPaths_.isEmpty()) {
+            if (removedPathsBuilder_.isEmpty()) {
+              removedPathsBuilder_.dispose();
+              removedPathsBuilder_ = null;
+              removedPaths_ = other.removedPaths_;
+              bitField0_ = (bitField0_ & ~0x00000020);
+              removedPathsBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getRemovedPathsFieldBuilder() : null;
+            } else {
+              removedPathsBuilder_.addAllMessages(other.removedPaths_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (hasOriginalSubTree()) {
+          if (!getOriginalSubTree().isInitialized()) {
+            
+            return false;
+          }
+        }
+        if (hasUpdatedSubTree()) {
+          if (!getUpdatedSubTree().isInitialized()) {
+            
+            return false;
+          }
+        }
+        if (hasOriginalData()) {
+          if (!getOriginalData().isInitialized()) {
+            
+            return false;
+          }
+        }
+        if (hasUpdatedData()) {
+          if (!getUpdatedData().isInitialized()) {
+            
+            return false;
+          }
+        }
+        if (hasCreatedData()) {
+          if (!getCreatedData().isInitialized()) {
+            
+            return false;
+          }
+        }
+        for (int i = 0; i < getRemovedPathsCount(); i++) {
+          if (!getRemovedPaths(i).isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChanged) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node originalSubTree_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> originalSubTreeBuilder_;
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+       */
+      public boolean hasOriginalSubTree() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getOriginalSubTree() {
+        if (originalSubTreeBuilder_ == null) {
+          return originalSubTree_;
+        } else {
+          return originalSubTreeBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+       */
+      public Builder setOriginalSubTree(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (originalSubTreeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          originalSubTree_ = value;
+          onChanged();
+        } else {
+          originalSubTreeBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+       */
+      public Builder setOriginalSubTree(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder builderForValue) {
+        if (originalSubTreeBuilder_ == null) {
+          originalSubTree_ = builderForValue.build();
+          onChanged();
+        } else {
+          originalSubTreeBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+       */
+      public Builder mergeOriginalSubTree(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (originalSubTreeBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+              originalSubTree_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance()) {
+            originalSubTree_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.newBuilder(originalSubTree_).mergeFrom(value).buildPartial();
+          } else {
+            originalSubTree_ = value;
+          }
+          onChanged();
+        } else {
+          originalSubTreeBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+       */
+      public Builder clearOriginalSubTree() {
+        if (originalSubTreeBuilder_ == null) {
+          originalSubTree_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+          onChanged();
+        } else {
+          originalSubTreeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder getOriginalSubTreeBuilder() {
+        bitField0_ |= 0x00000001;
+        onChanged();
+        return getOriginalSubTreeFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getOriginalSubTreeOrBuilder() {
+        if (originalSubTreeBuilder_ != null) {
+          return originalSubTreeBuilder_.getMessageOrBuilder();
+        } else {
+          return originalSubTree_;
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node originalSubTree = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> 
+          getOriginalSubTreeFieldBuilder() {
+        if (originalSubTreeBuilder_ == null) {
+          originalSubTreeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder>(
+                  originalSubTree_,
+                  getParentForChildren(),
+                  isClean());
+          originalSubTree_ = null;
+        }
+        return originalSubTreeBuilder_;
+      }
+
+      // optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node updatedSubTree_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> updatedSubTreeBuilder_;
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+       */
+      public boolean hasUpdatedSubTree() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getUpdatedSubTree() {
+        if (updatedSubTreeBuilder_ == null) {
+          return updatedSubTree_;
+        } else {
+          return updatedSubTreeBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+       */
+      public Builder setUpdatedSubTree(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (updatedSubTreeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          updatedSubTree_ = value;
+          onChanged();
+        } else {
+          updatedSubTreeBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+       */
+      public Builder setUpdatedSubTree(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder builderForValue) {
+        if (updatedSubTreeBuilder_ == null) {
+          updatedSubTree_ = builderForValue.build();
+          onChanged();
+        } else {
+          updatedSubTreeBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+       */
+      public Builder mergeUpdatedSubTree(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (updatedSubTreeBuilder_ == null) {
+          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+              updatedSubTree_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance()) {
+            updatedSubTree_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.newBuilder(updatedSubTree_).mergeFrom(value).buildPartial();
+          } else {
+            updatedSubTree_ = value;
+          }
+          onChanged();
+        } else {
+          updatedSubTreeBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+       */
+      public Builder clearUpdatedSubTree() {
+        if (updatedSubTreeBuilder_ == null) {
+          updatedSubTree_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+          onChanged();
+        } else {
+          updatedSubTreeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder getUpdatedSubTreeBuilder() {
+        bitField0_ |= 0x00000002;
+        onChanged();
+        return getUpdatedSubTreeFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getUpdatedSubTreeOrBuilder() {
+        if (updatedSubTreeBuilder_ != null) {
+          return updatedSubTreeBuilder_.getMessageOrBuilder();
+        } else {
+          return updatedSubTree_;
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node updatedSubTree = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> 
+          getUpdatedSubTreeFieldBuilder() {
+        if (updatedSubTreeBuilder_ == null) {
+          updatedSubTreeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder>(
+                  updatedSubTree_,
+                  getParentForChildren(),
+                  isClean());
+          updatedSubTree_ = null;
+        }
+        return updatedSubTreeBuilder_;
+      }
+
+      // optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap originalData_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder> originalDataBuilder_;
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+       */
+      public boolean hasOriginalData() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap getOriginalData() {
+        if (originalDataBuilder_ == null) {
+          return originalData_;
+        } else {
+          return originalDataBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+       */
+      public Builder setOriginalData(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap value) {
+        if (originalDataBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          originalData_ = value;
+          onChanged();
+        } else {
+          originalDataBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+       */
+      public Builder setOriginalData(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder builderForValue) {
+        if (originalDataBuilder_ == null) {
+          originalData_ = builderForValue.build();
+          onChanged();
+        } else {
+          originalDataBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+       */
+      public Builder mergeOriginalData(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap value) {
+        if (originalDataBuilder_ == null) {
+          if (((bitField0_ & 0x00000004) == 0x00000004) &&
+              originalData_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance()) {
+            originalData_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.newBuilder(originalData_).mergeFrom(value).buildPartial();
+          } else {
+            originalData_ = value;
+          }
+          onChanged();
+        } else {
+          originalDataBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+       */
+      public Builder clearOriginalData() {
+        if (originalDataBuilder_ == null) {
+          originalData_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance();
+          onChanged();
+        } else {
+          originalDataBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder getOriginalDataBuilder() {
+        bitField0_ |= 0x00000004;
+        onChanged();
+        return getOriginalDataFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder getOriginalDataOrBuilder() {
+        if (originalDataBuilder_ != null) {
+          return originalDataBuilder_.getMessageOrBuilder();
+        } else {
+          return originalData_;
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap originalData = 3;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder> 
+          getOriginalDataFieldBuilder() {
+        if (originalDataBuilder_ == null) {
+          originalDataBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder>(
+                  originalData_,
+                  getParentForChildren(),
+                  isClean());
+          originalData_ = null;
+        }
+        return originalDataBuilder_;
+      }
+
+      // optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap updatedData_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder> updatedDataBuilder_;
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+       */
+      public boolean hasUpdatedData() {
+        return ((bitField0_ & 0x00000008) == 0x00000008);
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap getUpdatedData() {
+        if (updatedDataBuilder_ == null) {
+          return updatedData_;
+        } else {
+          return updatedDataBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+       */
+      public Builder setUpdatedData(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap value) {
+        if (updatedDataBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          updatedData_ = value;
+          onChanged();
+        } else {
+          updatedDataBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000008;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+       */
+      public Builder setUpdatedData(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder builderForValue) {
+        if (updatedDataBuilder_ == null) {
+          updatedData_ = builderForValue.build();
+          onChanged();
+        } else {
+          updatedDataBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000008;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+       */
+      public Builder mergeUpdatedData(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap value) {
+        if (updatedDataBuilder_ == null) {
+          if (((bitField0_ & 0x00000008) == 0x00000008) &&
+              updatedData_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance()) {
+            updatedData_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.newBuilder(updatedData_).mergeFrom(value).buildPartial();
+          } else {
+            updatedData_ = value;
+          }
+          onChanged();
+        } else {
+          updatedDataBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000008;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+       */
+      public Builder clearUpdatedData() {
+        if (updatedDataBuilder_ == null) {
+          updatedData_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance();
+          onChanged();
+        } else {
+          updatedDataBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000008);
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder getUpdatedDataBuilder() {
+        bitField0_ |= 0x00000008;
+        onChanged();
+        return getUpdatedDataFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder getUpdatedDataOrBuilder() {
+        if (updatedDataBuilder_ != null) {
+          return updatedDataBuilder_.getMessageOrBuilder();
+        } else {
+          return updatedData_;
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap updatedData = 4;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder> 
+          getUpdatedDataFieldBuilder() {
+        if (updatedDataBuilder_ == null) {
+          updatedDataBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder>(
+                  updatedData_,
+                  getParentForChildren(),
+                  isClean());
+          updatedData_ = null;
+        }
+        return updatedDataBuilder_;
+      }
+
+      // optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap createdData_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder> createdDataBuilder_;
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+       */
+      public boolean hasCreatedData() {
+        return ((bitField0_ & 0x00000010) == 0x00000010);
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap getCreatedData() {
+        if (createdDataBuilder_ == null) {
+          return createdData_;
+        } else {
+          return createdDataBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+       */
+      public Builder setCreatedData(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap value) {
+        if (createdDataBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          createdData_ = value;
+          onChanged();
+        } else {
+          createdDataBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000010;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+       */
+      public Builder setCreatedData(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder builderForValue) {
+        if (createdDataBuilder_ == null) {
+          createdData_ = builderForValue.build();
+          onChanged();
+        } else {
+          createdDataBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000010;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+       */
+      public Builder mergeCreatedData(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap value) {
+        if (createdDataBuilder_ == null) {
+          if (((bitField0_ & 0x00000010) == 0x00000010) &&
+              createdData_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance()) {
+            createdData_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.newBuilder(createdData_).mergeFrom(value).buildPartial();
+          } else {
+            createdData_ = value;
+          }
+          onChanged();
+        } else {
+          createdDataBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000010;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+       */
+      public Builder clearCreatedData() {
+        if (createdDataBuilder_ == null) {
+          createdData_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.getDefaultInstance();
+          onChanged();
+        } else {
+          createdDataBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000010);
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder getCreatedDataBuilder() {
+        bitField0_ |= 0x00000010;
+        onChanged();
+        return getCreatedDataFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder getCreatedDataOrBuilder() {
+        if (createdDataBuilder_ != null) {
+          return createdDataBuilder_.getMessageOrBuilder();
+        } else {
+          return createdData_;
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.NodeMap createdData = 5;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder> 
+          getCreatedDataFieldBuilder() {
+        if (createdDataBuilder_ == null) {
+          createdDataBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMap.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeMapOrBuilder>(
+                  createdData_,
+                  getParentForChildren(),
+                  isClean());
+          createdData_ = null;
+        }
+        return createdDataBuilder_;
+      }
+
+      // repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;
+      private java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier> removedPaths_ =
+        java.util.Collections.emptyList();
+      private void ensureRemovedPathsIsMutable() {
+        if (!((bitField0_ & 0x00000020) == 0x00000020)) {
+          removedPaths_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier>(removedPaths_);
+          bitField0_ |= 0x00000020;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> removedPathsBuilder_;
+
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier> getRemovedPathsList() {
+        if (removedPathsBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(removedPaths_);
+        } else {
+          return removedPathsBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public int getRemovedPathsCount() {
+        if (removedPathsBuilder_ == null) {
+          return removedPaths_.size();
+        } else {
+          return removedPathsBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getRemovedPaths(int index) {
+        if (removedPathsBuilder_ == null) {
+          return removedPaths_.get(index);
+        } else {
+          return removedPathsBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public Builder setRemovedPaths(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (removedPathsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureRemovedPathsIsMutable();
+          removedPaths_.set(index, value);
+          onChanged();
+        } else {
+          removedPathsBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public Builder setRemovedPaths(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder builderForValue) {
+        if (removedPathsBuilder_ == null) {
+          ensureRemovedPathsIsMutable();
+          removedPaths_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          removedPathsBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public Builder addRemovedPaths(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (removedPathsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureRemovedPathsIsMutable();
+          removedPaths_.add(value);
+          onChanged();
+        } else {
+          removedPathsBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public Builder addRemovedPaths(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (removedPathsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureRemovedPathsIsMutable();
+          removedPaths_.add(index, value);
+          onChanged();
+        } else {
+          removedPathsBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public Builder addRemovedPaths(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder builderForValue) {
+        if (removedPathsBuilder_ == null) {
+          ensureRemovedPathsIsMutable();
+          removedPaths_.add(builderForValue.build());
+          onChanged();
+        } else {
+          removedPathsBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public Builder addRemovedPaths(
+          int index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder builderForValue) {
+        if (removedPathsBuilder_ == null) {
+          ensureRemovedPathsIsMutable();
+          removedPaths_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          removedPathsBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public Builder addAllRemovedPaths(
+          java.lang.Iterable<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier> values) {
+        if (removedPathsBuilder_ == null) {
+          ensureRemovedPathsIsMutable();
+          super.addAll(values, removedPaths_);
+          onChanged();
+        } else {
+          removedPathsBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public Builder clearRemovedPaths() {
+        if (removedPathsBuilder_ == null) {
+          removedPaths_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000020);
+          onChanged();
+        } else {
+          removedPathsBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public Builder removeRemovedPaths(int index) {
+        if (removedPathsBuilder_ == null) {
+          ensureRemovedPathsIsMutable();
+          removedPaths_.remove(index);
+          onChanged();
+        } else {
+          removedPathsBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder getRemovedPathsBuilder(
+          int index) {
+        return getRemovedPathsFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getRemovedPathsOrBuilder(
+          int index) {
+        if (removedPathsBuilder_ == null) {
+          return removedPaths_.get(index);  } else {
+          return removedPathsBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public java.util.List<? extends org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> 
+           getRemovedPathsOrBuilderList() {
+        if (removedPathsBuilder_ != null) {
+          return removedPathsBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(removedPaths_);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder addRemovedPathsBuilder() {
+        return getRemovedPathsFieldBuilder().addBuilder(
+            org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder addRemovedPathsBuilder(
+          int index) {
+        return getRemovedPathsFieldBuilder().addBuilder(
+            index, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.InstanceIdentifier removedPaths = 6;</code>
+       */
+      public java.util.List<org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder> 
+           getRemovedPathsBuilderList() {
+        return getRemovedPathsFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> 
+          getRemovedPathsFieldBuilder() {
+        if (removedPathsBuilder_ == null) {
+          removedPathsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder>(
+                  removedPaths_,
+                  ((bitField0_ & 0x00000020) == 0x00000020),
+                  getParentForChildren(),
+                  isClean());
+          removedPaths_ = null;
+        }
+        return removedPathsBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.DataChanged)
+    }
+
+    static {
+      defaultInstance = new DataChanged(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.DataChanged)
+  }
+
+  public interface DataChangedReplyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.DataChangedReply}
+   */
+  public static final class DataChangedReply extends
+      com.google.protobuf.GeneratedMessage
+      implements DataChangedReplyOrBuilder {
+    // Use DataChangedReply.newBuilder() to construct.
+    private DataChangedReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private DataChangedReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final DataChangedReply defaultInstance;
+    public static DataChangedReply getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public DataChangedReply getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private DataChangedReply(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.internal_static_org_opendaylight_controller_mdsal_DataChangedReply_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.internal_static_org_opendaylight_controller_mdsal_DataChangedReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply.class, org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<DataChangedReply> PARSER =
+        new com.google.protobuf.AbstractParser<DataChangedReply>() {
+      public DataChangedReply parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new DataChangedReply(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<DataChangedReply> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.DataChangedReply}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReplyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.internal_static_org_opendaylight_controller_mdsal_DataChangedReply_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.internal_static_org_opendaylight_controller_mdsal_DataChangedReply_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply.class, org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.internal_static_org_opendaylight_controller_mdsal_DataChangedReply_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply build() {
+        org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply result = new org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages.DataChangedReply) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.DataChangedReply)
+    }
+
+    static {
+      defaultInstance = new DataChangedReply(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.DataChangedReply)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_DataChanged_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_DataChanged_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_DataChangedReply_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_DataChangedReply_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\030DataChangeListener.proto\022!org.opendayl" +
+      "ight.controller.mdsal\032\014Common.proto\"\241\003\n\013" +
+      "DataChanged\022@\n\017originalSubTree\030\001 \001(\0132\'.o" +
+      "rg.opendaylight.controller.mdsal.Node\022?\n" +
+      "\016updatedSubTree\030\002 \001(\0132\'.org.opendaylight" +
+      ".controller.mdsal.Node\022@\n\014originalData\030\003" +
+      " \001(\0132*.org.opendaylight.controller.mdsal" +
+      ".NodeMap\022?\n\013updatedData\030\004 \001(\0132*.org.open" +
+      "daylight.controller.mdsal.NodeMap\022?\n\013cre" +
+      "atedData\030\005 \001(\0132*.org.opendaylight.contro",
+      "ller.mdsal.NodeMap\022K\n\014removedPaths\030\006 \003(\013" +
+      "25.org.opendaylight.controller.mdsal.Ins" +
+      "tanceIdentifier\"\022\n\020DataChangedReplyBd\nFo" +
+      "rg.opendaylight.controller.protobuff.mes" +
+      "sages.datachange.notificationB\032DataChang" +
+      "eListenerMessages"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_org_opendaylight_controller_mdsal_DataChanged_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_org_opendaylight_controller_mdsal_DataChanged_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_DataChanged_descriptor,
+              new java.lang.String[] { "OriginalSubTree", "UpdatedSubTree", "OriginalData", "UpdatedData", "CreatedData", "RemovedPaths", });
+          internal_static_org_opendaylight_controller_mdsal_DataChangedReply_descriptor =
+            getDescriptor().getMessageTypes().get(1);
+          internal_static_org_opendaylight_controller_mdsal_DataChangedReply_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_DataChangedReply_descriptor,
+              new java.lang.String[] { });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.getDescriptor(),
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/persistent/PersistentMessages.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/persistent/PersistentMessages.java
new file mode 100644 (file)
index 0000000..eaa9001
--- /dev/null
@@ -0,0 +1,1648 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: Persistent.proto
+
+package org.opendaylight.controller.protobuff.messages.persistent;
+
+public final class PersistentMessages {
+  private PersistentMessages() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface ModificationOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string type = 1;
+    /**
+     * <code>required string type = 1;</code>
+     */
+    boolean hasType();
+    /**
+     * <code>required string type = 1;</code>
+     */
+    java.lang.String getType();
+    /**
+     * <code>required string type = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getTypeBytes();
+
+    // required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+     */
+    boolean hasPath();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getPath();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getPathOrBuilder();
+
+    // optional .org.opendaylight.controller.mdsal.Node data = 3;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+     */
+    boolean hasData();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getData();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getDataOrBuilder();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.Modification}
+   */
+  public static final class Modification extends
+      com.google.protobuf.GeneratedMessage
+      implements ModificationOrBuilder {
+    // Use Modification.newBuilder() to construct.
+    private Modification(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Modification(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final Modification defaultInstance;
+    public static Modification getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Modification getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Modification(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              type_ = input.readBytes();
+              break;
+            }
+            case 18: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+                subBuilder = path_.toBuilder();
+              }
+              path_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(path_);
+                path_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000002;
+              break;
+            }
+            case 26: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+                subBuilder = data_.toBuilder();
+              }
+              data_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(data_);
+                data_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000004;
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.internal_static_org_opendaylight_controller_mdsal_Modification_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.internal_static_org_opendaylight_controller_mdsal_Modification_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.class, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<Modification> PARSER =
+        new com.google.protobuf.AbstractParser<Modification>() {
+      public Modification parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Modification(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Modification> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string type = 1;
+    public static final int TYPE_FIELD_NUMBER = 1;
+    private java.lang.Object type_;
+    /**
+     * <code>required string type = 1;</code>
+     */
+    public boolean hasType() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string type = 1;</code>
+     */
+    public java.lang.String getType() {
+      java.lang.Object ref = type_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          type_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string type = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getTypeBytes() {
+      java.lang.Object ref = type_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        type_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;
+    public static final int PATH_FIELD_NUMBER = 2;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier path_;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+     */
+    public boolean hasPath() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getPath() {
+      return path_;
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getPathOrBuilder() {
+      return path_;
+    }
+
+    // optional .org.opendaylight.controller.mdsal.Node data = 3;
+    public static final int DATA_FIELD_NUMBER = 3;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node data_;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+     */
+    public boolean hasData() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getData() {
+      return data_;
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getDataOrBuilder() {
+      return data_;
+    }
+
+    private void initFields() {
+      type_ = "";
+      path_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+      data_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasType()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasPath()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!getPath().isInitialized()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (hasData()) {
+        if (!getData().isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getTypeBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeMessage(2, path_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeMessage(3, data_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getTypeBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, path_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, data_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.Modification}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.ModificationOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.internal_static_org_opendaylight_controller_mdsal_Modification_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.internal_static_org_opendaylight_controller_mdsal_Modification_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.class, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getPathFieldBuilder();
+          getDataFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        type_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        if (pathBuilder_ == null) {
+          path_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+        } else {
+          pathBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000002);
+        if (dataBuilder_ == null) {
+          data_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+        } else {
+          dataBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.internal_static_org_opendaylight_controller_mdsal_Modification_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification build() {
+        org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification buildPartial() {
+        org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification result = new org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.type_ = type_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        if (pathBuilder_ == null) {
+          result.path_ = path_;
+        } else {
+          result.path_ = pathBuilder_.build();
+        }
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        if (dataBuilder_ == null) {
+          result.data_ = data_;
+        } else {
+          result.data_ = dataBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification other) {
+        if (other == org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.getDefaultInstance()) return this;
+        if (other.hasType()) {
+          bitField0_ |= 0x00000001;
+          type_ = other.type_;
+          onChanged();
+        }
+        if (other.hasPath()) {
+          mergePath(other.getPath());
+        }
+        if (other.hasData()) {
+          mergeData(other.getData());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasType()) {
+          
+          return false;
+        }
+        if (!hasPath()) {
+          
+          return false;
+        }
+        if (!getPath().isInitialized()) {
+          
+          return false;
+        }
+        if (hasData()) {
+          if (!getData().isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string type = 1;
+      private java.lang.Object type_ = "";
+      /**
+       * <code>required string type = 1;</code>
+       */
+      public boolean hasType() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string type = 1;</code>
+       */
+      public java.lang.String getType() {
+        java.lang.Object ref = type_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          type_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string type = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getTypeBytes() {
+        java.lang.Object ref = type_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          type_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string type = 1;</code>
+       */
+      public Builder setType(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        type_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string type = 1;</code>
+       */
+      public Builder clearType() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        type_ = getDefaultInstance().getType();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string type = 1;</code>
+       */
+      public Builder setTypeBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        type_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier path_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> pathBuilder_;
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+       */
+      public boolean hasPath() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getPath() {
+        if (pathBuilder_ == null) {
+          return path_;
+        } else {
+          return pathBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+       */
+      public Builder setPath(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (pathBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          path_ = value;
+          onChanged();
+        } else {
+          pathBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+       */
+      public Builder setPath(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder builderForValue) {
+        if (pathBuilder_ == null) {
+          path_ = builderForValue.build();
+          onChanged();
+        } else {
+          pathBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+       */
+      public Builder mergePath(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (pathBuilder_ == null) {
+          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+              path_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance()) {
+            path_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.newBuilder(path_).mergeFrom(value).buildPartial();
+          } else {
+            path_ = value;
+          }
+          onChanged();
+        } else {
+          pathBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+       */
+      public Builder clearPath() {
+        if (pathBuilder_ == null) {
+          path_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+          onChanged();
+        } else {
+          pathBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder getPathBuilder() {
+        bitField0_ |= 0x00000002;
+        onChanged();
+        return getPathFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getPathOrBuilder() {
+        if (pathBuilder_ != null) {
+          return pathBuilder_.getMessageOrBuilder();
+        } else {
+          return path_;
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier path = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> 
+          getPathFieldBuilder() {
+        if (pathBuilder_ == null) {
+          pathBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder>(
+                  path_,
+                  getParentForChildren(),
+                  isClean());
+          path_ = null;
+        }
+        return pathBuilder_;
+      }
+
+      // optional .org.opendaylight.controller.mdsal.Node data = 3;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node data_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> dataBuilder_;
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+       */
+      public boolean hasData() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getData() {
+        if (dataBuilder_ == null) {
+          return data_;
+        } else {
+          return dataBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+       */
+      public Builder setData(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (dataBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          data_ = value;
+          onChanged();
+        } else {
+          dataBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+       */
+      public Builder setData(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder builderForValue) {
+        if (dataBuilder_ == null) {
+          data_ = builderForValue.build();
+          onChanged();
+        } else {
+          dataBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+       */
+      public Builder mergeData(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (dataBuilder_ == null) {
+          if (((bitField0_ & 0x00000004) == 0x00000004) &&
+              data_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance()) {
+            data_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.newBuilder(data_).mergeFrom(value).buildPartial();
+          } else {
+            data_ = value;
+          }
+          onChanged();
+        } else {
+          dataBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+       */
+      public Builder clearData() {
+        if (dataBuilder_ == null) {
+          data_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+          onChanged();
+        } else {
+          dataBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder getDataBuilder() {
+        bitField0_ |= 0x00000004;
+        onChanged();
+        return getDataFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getDataOrBuilder() {
+        if (dataBuilder_ != null) {
+          return dataBuilder_.getMessageOrBuilder();
+        } else {
+          return data_;
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node data = 3;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> 
+          getDataFieldBuilder() {
+        if (dataBuilder_ == null) {
+          dataBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder>(
+                  data_,
+                  getParentForChildren(),
+                  isClean());
+          data_ = null;
+        }
+        return dataBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.Modification)
+    }
+
+    static {
+      defaultInstance = new Modification(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.Modification)
+  }
+
+  public interface CompositeModificationOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // repeated .org.opendaylight.controller.mdsal.Modification modification = 1;
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+     */
+    java.util.List<org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification> 
+        getModificationList();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification getModification(int index);
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+     */
+    int getModificationCount();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+     */
+    java.util.List<? extends org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.ModificationOrBuilder> 
+        getModificationOrBuilderList();
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.ModificationOrBuilder getModificationOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.CompositeModification}
+   */
+  public static final class CompositeModification extends
+      com.google.protobuf.GeneratedMessage
+      implements CompositeModificationOrBuilder {
+    // Use CompositeModification.newBuilder() to construct.
+    private CompositeModification(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private CompositeModification(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final CompositeModification defaultInstance;
+    public static CompositeModification getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public CompositeModification getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private CompositeModification(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                modification_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              modification_.add(input.readMessage(org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          modification_ = java.util.Collections.unmodifiableList(modification_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.internal_static_org_opendaylight_controller_mdsal_CompositeModification_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.internal_static_org_opendaylight_controller_mdsal_CompositeModification_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification.class, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<CompositeModification> PARSER =
+        new com.google.protobuf.AbstractParser<CompositeModification>() {
+      public CompositeModification parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new CompositeModification(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CompositeModification> getParserForType() {
+      return PARSER;
+    }
+
+    // repeated .org.opendaylight.controller.mdsal.Modification modification = 1;
+    public static final int MODIFICATION_FIELD_NUMBER = 1;
+    private java.util.List<org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification> modification_;
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+     */
+    public java.util.List<org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification> getModificationList() {
+      return modification_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+     */
+    public java.util.List<? extends org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.ModificationOrBuilder> 
+        getModificationOrBuilderList() {
+      return modification_;
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+     */
+    public int getModificationCount() {
+      return modification_.size();
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification getModification(int index) {
+      return modification_.get(index);
+    }
+    /**
+     * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.ModificationOrBuilder getModificationOrBuilder(
+        int index) {
+      return modification_.get(index);
+    }
+
+    private void initFields() {
+      modification_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      for (int i = 0; i < getModificationCount(); i++) {
+        if (!getModification(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < modification_.size(); i++) {
+        output.writeMessage(1, modification_.get(i));
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < modification_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, modification_.get(i));
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.CompositeModification}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModificationOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.internal_static_org_opendaylight_controller_mdsal_CompositeModification_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.internal_static_org_opendaylight_controller_mdsal_CompositeModification_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification.class, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getModificationFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (modificationBuilder_ == null) {
+          modification_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          modificationBuilder_.clear();
+        }
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.internal_static_org_opendaylight_controller_mdsal_CompositeModification_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification build() {
+        org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification buildPartial() {
+        org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification result = new org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification(this);
+        int from_bitField0_ = bitField0_;
+        if (modificationBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+            modification_ = java.util.Collections.unmodifiableList(modification_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.modification_ = modification_;
+        } else {
+          result.modification_ = modificationBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification other) {
+        if (other == org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification.getDefaultInstance()) return this;
+        if (modificationBuilder_ == null) {
+          if (!other.modification_.isEmpty()) {
+            if (modification_.isEmpty()) {
+              modification_ = other.modification_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureModificationIsMutable();
+              modification_.addAll(other.modification_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.modification_.isEmpty()) {
+            if (modificationBuilder_.isEmpty()) {
+              modificationBuilder_.dispose();
+              modificationBuilder_ = null;
+              modification_ = other.modification_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              modificationBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getModificationFieldBuilder() : null;
+            } else {
+              modificationBuilder_.addAllMessages(other.modification_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        for (int i = 0; i < getModificationCount(); i++) {
+          if (!getModification(i).isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.CompositeModification) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // repeated .org.opendaylight.controller.mdsal.Modification modification = 1;
+      private java.util.List<org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification> modification_ =
+        java.util.Collections.emptyList();
+      private void ensureModificationIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          modification_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification>(modification_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.Builder, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.ModificationOrBuilder> modificationBuilder_;
+
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public java.util.List<org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification> getModificationList() {
+        if (modificationBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(modification_);
+        } else {
+          return modificationBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public int getModificationCount() {
+        if (modificationBuilder_ == null) {
+          return modification_.size();
+        } else {
+          return modificationBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification getModification(int index) {
+        if (modificationBuilder_ == null) {
+          return modification_.get(index);
+        } else {
+          return modificationBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public Builder setModification(
+          int index, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification value) {
+        if (modificationBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureModificationIsMutable();
+          modification_.set(index, value);
+          onChanged();
+        } else {
+          modificationBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public Builder setModification(
+          int index, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.Builder builderForValue) {
+        if (modificationBuilder_ == null) {
+          ensureModificationIsMutable();
+          modification_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          modificationBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public Builder addModification(org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification value) {
+        if (modificationBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureModificationIsMutable();
+          modification_.add(value);
+          onChanged();
+        } else {
+          modificationBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public Builder addModification(
+          int index, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification value) {
+        if (modificationBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureModificationIsMutable();
+          modification_.add(index, value);
+          onChanged();
+        } else {
+          modificationBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public Builder addModification(
+          org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.Builder builderForValue) {
+        if (modificationBuilder_ == null) {
+          ensureModificationIsMutable();
+          modification_.add(builderForValue.build());
+          onChanged();
+        } else {
+          modificationBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public Builder addModification(
+          int index, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.Builder builderForValue) {
+        if (modificationBuilder_ == null) {
+          ensureModificationIsMutable();
+          modification_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          modificationBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public Builder addAllModification(
+          java.lang.Iterable<? extends org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification> values) {
+        if (modificationBuilder_ == null) {
+          ensureModificationIsMutable();
+          super.addAll(values, modification_);
+          onChanged();
+        } else {
+          modificationBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public Builder clearModification() {
+        if (modificationBuilder_ == null) {
+          modification_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          modificationBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public Builder removeModification(int index) {
+        if (modificationBuilder_ == null) {
+          ensureModificationIsMutable();
+          modification_.remove(index);
+          onChanged();
+        } else {
+          modificationBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.Builder getModificationBuilder(
+          int index) {
+        return getModificationFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.ModificationOrBuilder getModificationOrBuilder(
+          int index) {
+        if (modificationBuilder_ == null) {
+          return modification_.get(index);  } else {
+          return modificationBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public java.util.List<? extends org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.ModificationOrBuilder> 
+           getModificationOrBuilderList() {
+        if (modificationBuilder_ != null) {
+          return modificationBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(modification_);
+        }
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.Builder addModificationBuilder() {
+        return getModificationFieldBuilder().addBuilder(
+            org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.Builder addModificationBuilder(
+          int index) {
+        return getModificationFieldBuilder().addBuilder(
+            index, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.opendaylight.controller.mdsal.Modification modification = 1;</code>
+       */
+      public java.util.List<org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.Builder> 
+           getModificationBuilderList() {
+        return getModificationFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.Builder, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.ModificationOrBuilder> 
+          getModificationFieldBuilder() {
+        if (modificationBuilder_ == null) {
+          modificationBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.Modification.Builder, org.opendaylight.controller.protobuff.messages.persistent.PersistentMessages.ModificationOrBuilder>(
+                  modification_,
+                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  getParentForChildren(),
+                  isClean());
+          modification_ = null;
+        }
+        return modificationBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CompositeModification)
+    }
+
+    static {
+      defaultInstance = new CompositeModification(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CompositeModification)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_Modification_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_Modification_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_CompositeModification_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_CompositeModification_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\020Persistent.proto\022!org.opendaylight.con" +
+      "troller.mdsal\032\014Common.proto\032\033AppendEntri" +
+      "esMessages.proto\"\230\001\n\014Modification\022\014\n\004typ" +
+      "e\030\001 \002(\t\022C\n\004path\030\002 \002(\01325.org.opendaylight" +
+      ".controller.mdsal.InstanceIdentifier\0225\n\004" +
+      "data\030\003 \001(\0132\'.org.opendaylight.controller" +
+      ".mdsal.Node\"^\n\025CompositeModification\022E\n\014" +
+      "modification\030\001 \003(\0132/.org.opendaylight.co" +
+      "ntroller.mdsal.ModificationBO\n9org.opend" +
+      "aylight.controller.protobuff.messages.pe",
+      "rsistentB\022PersistentMessages"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_org_opendaylight_controller_mdsal_Modification_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_org_opendaylight_controller_mdsal_Modification_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_Modification_descriptor,
+              new java.lang.String[] { "Type", "Path", "Data", });
+          internal_static_org_opendaylight_controller_mdsal_CompositeModification_descriptor =
+            getDescriptor().getMessageTypes().get(1);
+          internal_static_org_opendaylight_controller_mdsal_CompositeModification_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_CompositeModification_descriptor,
+              new java.lang.String[] { "Modification", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.getDescriptor(),
+          org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.getDescriptor(),
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/registration/ListenerRegistrationMessages.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/registration/ListenerRegistrationMessages.java
new file mode 100644 (file)
index 0000000..e06dd0d
--- /dev/null
@@ -0,0 +1,1997 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: ListenerRegistration.proto
+
+package org.opendaylight.controller.protobuff.messages.registration;
+
+public final class ListenerRegistrationMessages {
+  private ListenerRegistrationMessages() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface CloseDataChangeListenerRegistrationOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.CloseDataChangeListenerRegistration}
+   *
+   * <pre>
+   ** used when a listener needs to be unregistered
+   * </pre>
+   */
+  public static final class CloseDataChangeListenerRegistration extends
+      com.google.protobuf.GeneratedMessage
+      implements CloseDataChangeListenerRegistrationOrBuilder {
+    // Use CloseDataChangeListenerRegistration.newBuilder() to construct.
+    private CloseDataChangeListenerRegistration(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private CloseDataChangeListenerRegistration(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final CloseDataChangeListenerRegistration defaultInstance;
+    public static CloseDataChangeListenerRegistration getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public CloseDataChangeListenerRegistration getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private CloseDataChangeListenerRegistration(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistration_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistration_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration.class, org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<CloseDataChangeListenerRegistration> PARSER =
+        new com.google.protobuf.AbstractParser<CloseDataChangeListenerRegistration>() {
+      public CloseDataChangeListenerRegistration parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new CloseDataChangeListenerRegistration(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CloseDataChangeListenerRegistration> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.CloseDataChangeListenerRegistration}
+     *
+     * <pre>
+     ** used when a listener needs to be unregistered
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistration_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistration_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration.class, org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistration_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration build() {
+        org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration buildPartial() {
+        org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration result = new org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration other) {
+        if (other == org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistration) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CloseDataChangeListenerRegistration)
+    }
+
+    static {
+      defaultInstance = new CloseDataChangeListenerRegistration(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CloseDataChangeListenerRegistration)
+  }
+
+  public interface CloseDataChangeListenerRegistrationReplyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.CloseDataChangeListenerRegistrationReply}
+   *
+   * <pre>
+   ** reply to the CloseDataChangeListenerRegistration request
+   * </pre>
+   */
+  public static final class CloseDataChangeListenerRegistrationReply extends
+      com.google.protobuf.GeneratedMessage
+      implements CloseDataChangeListenerRegistrationReplyOrBuilder {
+    // Use CloseDataChangeListenerRegistrationReply.newBuilder() to construct.
+    private CloseDataChangeListenerRegistrationReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private CloseDataChangeListenerRegistrationReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final CloseDataChangeListenerRegistrationReply defaultInstance;
+    public static CloseDataChangeListenerRegistrationReply getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public CloseDataChangeListenerRegistrationReply getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private CloseDataChangeListenerRegistrationReply(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistrationReply_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistrationReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply.class, org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<CloseDataChangeListenerRegistrationReply> PARSER =
+        new com.google.protobuf.AbstractParser<CloseDataChangeListenerRegistrationReply>() {
+      public CloseDataChangeListenerRegistrationReply parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new CloseDataChangeListenerRegistrationReply(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CloseDataChangeListenerRegistrationReply> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.CloseDataChangeListenerRegistrationReply}
+     *
+     * <pre>
+     ** reply to the CloseDataChangeListenerRegistration request
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReplyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistrationReply_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistrationReply_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply.class, org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistrationReply_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply build() {
+        org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply result = new org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.CloseDataChangeListenerRegistrationReply) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CloseDataChangeListenerRegistrationReply)
+    }
+
+    static {
+      defaultInstance = new CloseDataChangeListenerRegistrationReply(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CloseDataChangeListenerRegistrationReply)
+  }
+
+  public interface RegisterChangeListenerOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+     */
+    boolean hasInstanceIdentifierPath();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPath();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathOrBuilder();
+
+    // required string dataChangeListenerActorPath = 2;
+    /**
+     * <code>required string dataChangeListenerActorPath = 2;</code>
+     */
+    boolean hasDataChangeListenerActorPath();
+    /**
+     * <code>required string dataChangeListenerActorPath = 2;</code>
+     */
+    java.lang.String getDataChangeListenerActorPath();
+    /**
+     * <code>required string dataChangeListenerActorPath = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getDataChangeListenerActorPathBytes();
+
+    // required int32 dataChangeScope = 3;
+    /**
+     * <code>required int32 dataChangeScope = 3;</code>
+     */
+    boolean hasDataChangeScope();
+    /**
+     * <code>required int32 dataChangeScope = 3;</code>
+     */
+    int getDataChangeScope();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.RegisterChangeListener}
+   */
+  public static final class RegisterChangeListener extends
+      com.google.protobuf.GeneratedMessage
+      implements RegisterChangeListenerOrBuilder {
+    // Use RegisterChangeListener.newBuilder() to construct.
+    private RegisterChangeListener(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private RegisterChangeListener(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final RegisterChangeListener defaultInstance;
+    public static RegisterChangeListener getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public RegisterChangeListener getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private RegisterChangeListener(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+                subBuilder = instanceIdentifierPath_.toBuilder();
+              }
+              instanceIdentifierPath_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(instanceIdentifierPath_);
+                instanceIdentifierPath_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000001;
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              dataChangeListenerActorPath_ = input.readBytes();
+              break;
+            }
+            case 24: {
+              bitField0_ |= 0x00000004;
+              dataChangeScope_ = input.readInt32();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_RegisterChangeListener_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_RegisterChangeListener_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener.class, org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<RegisterChangeListener> PARSER =
+        new com.google.protobuf.AbstractParser<RegisterChangeListener>() {
+      public RegisterChangeListener parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new RegisterChangeListener(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<RegisterChangeListener> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;
+    public static final int INSTANCEIDENTIFIERPATH_FIELD_NUMBER = 1;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier instanceIdentifierPath_;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+     */
+    public boolean hasInstanceIdentifierPath() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPath() {
+      return instanceIdentifierPath_;
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathOrBuilder() {
+      return instanceIdentifierPath_;
+    }
+
+    // required string dataChangeListenerActorPath = 2;
+    public static final int DATACHANGELISTENERACTORPATH_FIELD_NUMBER = 2;
+    private java.lang.Object dataChangeListenerActorPath_;
+    /**
+     * <code>required string dataChangeListenerActorPath = 2;</code>
+     */
+    public boolean hasDataChangeListenerActorPath() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required string dataChangeListenerActorPath = 2;</code>
+     */
+    public java.lang.String getDataChangeListenerActorPath() {
+      java.lang.Object ref = dataChangeListenerActorPath_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          dataChangeListenerActorPath_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string dataChangeListenerActorPath = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getDataChangeListenerActorPathBytes() {
+      java.lang.Object ref = dataChangeListenerActorPath_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        dataChangeListenerActorPath_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required int32 dataChangeScope = 3;
+    public static final int DATACHANGESCOPE_FIELD_NUMBER = 3;
+    private int dataChangeScope_;
+    /**
+     * <code>required int32 dataChangeScope = 3;</code>
+     */
+    public boolean hasDataChangeScope() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>required int32 dataChangeScope = 3;</code>
+     */
+    public int getDataChangeScope() {
+      return dataChangeScope_;
+    }
+
+    private void initFields() {
+      instanceIdentifierPath_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+      dataChangeListenerActorPath_ = "";
+      dataChangeScope_ = 0;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasInstanceIdentifierPath()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasDataChangeListenerActorPath()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasDataChangeScope()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!getInstanceIdentifierPath().isInitialized()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeMessage(1, instanceIdentifierPath_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, getDataChangeListenerActorPathBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeInt32(3, dataChangeScope_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, instanceIdentifierPath_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, getDataChangeListenerActorPathBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(3, dataChangeScope_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.RegisterChangeListener}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_RegisterChangeListener_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_RegisterChangeListener_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener.class, org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getInstanceIdentifierPathFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (instanceIdentifierPathBuilder_ == null) {
+          instanceIdentifierPath_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+        } else {
+          instanceIdentifierPathBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        dataChangeListenerActorPath_ = "";
+        bitField0_ = (bitField0_ & ~0x00000002);
+        dataChangeScope_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_RegisterChangeListener_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener build() {
+        org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener buildPartial() {
+        org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener result = new org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        if (instanceIdentifierPathBuilder_ == null) {
+          result.instanceIdentifierPath_ = instanceIdentifierPath_;
+        } else {
+          result.instanceIdentifierPath_ = instanceIdentifierPathBuilder_.build();
+        }
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.dataChangeListenerActorPath_ = dataChangeListenerActorPath_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.dataChangeScope_ = dataChangeScope_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener other) {
+        if (other == org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener.getDefaultInstance()) return this;
+        if (other.hasInstanceIdentifierPath()) {
+          mergeInstanceIdentifierPath(other.getInstanceIdentifierPath());
+        }
+        if (other.hasDataChangeListenerActorPath()) {
+          bitField0_ |= 0x00000002;
+          dataChangeListenerActorPath_ = other.dataChangeListenerActorPath_;
+          onChanged();
+        }
+        if (other.hasDataChangeScope()) {
+          setDataChangeScope(other.getDataChangeScope());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasInstanceIdentifierPath()) {
+          
+          return false;
+        }
+        if (!hasDataChangeListenerActorPath()) {
+          
+          return false;
+        }
+        if (!hasDataChangeScope()) {
+          
+          return false;
+        }
+        if (!getInstanceIdentifierPath().isInitialized()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListener) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier instanceIdentifierPath_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> instanceIdentifierPathBuilder_;
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public boolean hasInstanceIdentifierPath() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPath() {
+        if (instanceIdentifierPathBuilder_ == null) {
+          return instanceIdentifierPath_;
+        } else {
+          return instanceIdentifierPathBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public Builder setInstanceIdentifierPath(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (instanceIdentifierPathBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          instanceIdentifierPath_ = value;
+          onChanged();
+        } else {
+          instanceIdentifierPathBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public Builder setInstanceIdentifierPath(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder builderForValue) {
+        if (instanceIdentifierPathBuilder_ == null) {
+          instanceIdentifierPath_ = builderForValue.build();
+          onChanged();
+        } else {
+          instanceIdentifierPathBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public Builder mergeInstanceIdentifierPath(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (instanceIdentifierPathBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+              instanceIdentifierPath_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance()) {
+            instanceIdentifierPath_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.newBuilder(instanceIdentifierPath_).mergeFrom(value).buildPartial();
+          } else {
+            instanceIdentifierPath_ = value;
+          }
+          onChanged();
+        } else {
+          instanceIdentifierPathBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public Builder clearInstanceIdentifierPath() {
+        if (instanceIdentifierPathBuilder_ == null) {
+          instanceIdentifierPath_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+          onChanged();
+        } else {
+          instanceIdentifierPathBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder getInstanceIdentifierPathBuilder() {
+        bitField0_ |= 0x00000001;
+        onChanged();
+        return getInstanceIdentifierPathFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathOrBuilder() {
+        if (instanceIdentifierPathBuilder_ != null) {
+          return instanceIdentifierPathBuilder_.getMessageOrBuilder();
+        } else {
+          return instanceIdentifierPath_;
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPath = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> 
+          getInstanceIdentifierPathFieldBuilder() {
+        if (instanceIdentifierPathBuilder_ == null) {
+          instanceIdentifierPathBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder>(
+                  instanceIdentifierPath_,
+                  getParentForChildren(),
+                  isClean());
+          instanceIdentifierPath_ = null;
+        }
+        return instanceIdentifierPathBuilder_;
+      }
+
+      // required string dataChangeListenerActorPath = 2;
+      private java.lang.Object dataChangeListenerActorPath_ = "";
+      /**
+       * <code>required string dataChangeListenerActorPath = 2;</code>
+       */
+      public boolean hasDataChangeListenerActorPath() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required string dataChangeListenerActorPath = 2;</code>
+       */
+      public java.lang.String getDataChangeListenerActorPath() {
+        java.lang.Object ref = dataChangeListenerActorPath_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          dataChangeListenerActorPath_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string dataChangeListenerActorPath = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getDataChangeListenerActorPathBytes() {
+        java.lang.Object ref = dataChangeListenerActorPath_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          dataChangeListenerActorPath_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string dataChangeListenerActorPath = 2;</code>
+       */
+      public Builder setDataChangeListenerActorPath(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        dataChangeListenerActorPath_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string dataChangeListenerActorPath = 2;</code>
+       */
+      public Builder clearDataChangeListenerActorPath() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        dataChangeListenerActorPath_ = getDefaultInstance().getDataChangeListenerActorPath();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string dataChangeListenerActorPath = 2;</code>
+       */
+      public Builder setDataChangeListenerActorPathBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        dataChangeListenerActorPath_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required int32 dataChangeScope = 3;
+      private int dataChangeScope_ ;
+      /**
+       * <code>required int32 dataChangeScope = 3;</code>
+       */
+      public boolean hasDataChangeScope() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>required int32 dataChangeScope = 3;</code>
+       */
+      public int getDataChangeScope() {
+        return dataChangeScope_;
+      }
+      /**
+       * <code>required int32 dataChangeScope = 3;</code>
+       */
+      public Builder setDataChangeScope(int value) {
+        bitField0_ |= 0x00000004;
+        dataChangeScope_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 dataChangeScope = 3;</code>
+       */
+      public Builder clearDataChangeScope() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        dataChangeScope_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.RegisterChangeListener)
+    }
+
+    static {
+      defaultInstance = new RegisterChangeListener(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.RegisterChangeListener)
+  }
+
+  public interface RegisterChangeListenerReplyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string listenerRegistrationPath = 1;
+    /**
+     * <code>required string listenerRegistrationPath = 1;</code>
+     */
+    boolean hasListenerRegistrationPath();
+    /**
+     * <code>required string listenerRegistrationPath = 1;</code>
+     */
+    java.lang.String getListenerRegistrationPath();
+    /**
+     * <code>required string listenerRegistrationPath = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getListenerRegistrationPathBytes();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.RegisterChangeListenerReply}
+   *
+   * <pre>
+   **
+   * This is the reply for the RegisterChangeListener message
+   * It contains the listenerRegistration actor path
+   * that can be used to unregister the listener
+   * </pre>
+   */
+  public static final class RegisterChangeListenerReply extends
+      com.google.protobuf.GeneratedMessage
+      implements RegisterChangeListenerReplyOrBuilder {
+    // Use RegisterChangeListenerReply.newBuilder() to construct.
+    private RegisterChangeListenerReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private RegisterChangeListenerReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final RegisterChangeListenerReply defaultInstance;
+    public static RegisterChangeListenerReply getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public RegisterChangeListenerReply getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private RegisterChangeListenerReply(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              listenerRegistrationPath_ = input.readBytes();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_RegisterChangeListenerReply_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_RegisterChangeListenerReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply.class, org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<RegisterChangeListenerReply> PARSER =
+        new com.google.protobuf.AbstractParser<RegisterChangeListenerReply>() {
+      public RegisterChangeListenerReply parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new RegisterChangeListenerReply(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<RegisterChangeListenerReply> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string listenerRegistrationPath = 1;
+    public static final int LISTENERREGISTRATIONPATH_FIELD_NUMBER = 1;
+    private java.lang.Object listenerRegistrationPath_;
+    /**
+     * <code>required string listenerRegistrationPath = 1;</code>
+     */
+    public boolean hasListenerRegistrationPath() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string listenerRegistrationPath = 1;</code>
+     */
+    public java.lang.String getListenerRegistrationPath() {
+      java.lang.Object ref = listenerRegistrationPath_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          listenerRegistrationPath_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string listenerRegistrationPath = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getListenerRegistrationPathBytes() {
+      java.lang.Object ref = listenerRegistrationPath_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        listenerRegistrationPath_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    private void initFields() {
+      listenerRegistrationPath_ = "";
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasListenerRegistrationPath()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getListenerRegistrationPathBytes());
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getListenerRegistrationPathBytes());
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.RegisterChangeListenerReply}
+     *
+     * <pre>
+     **
+     * This is the reply for the RegisterChangeListener message
+     * It contains the listenerRegistration actor path
+     * that can be used to unregister the listener
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReplyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_RegisterChangeListenerReply_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_RegisterChangeListenerReply_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply.class, org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        listenerRegistrationPath_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.internal_static_org_opendaylight_controller_mdsal_RegisterChangeListenerReply_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply build() {
+        org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply result = new org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.listenerRegistrationPath_ = listenerRegistrationPath_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply.getDefaultInstance()) return this;
+        if (other.hasListenerRegistrationPath()) {
+          bitField0_ |= 0x00000001;
+          listenerRegistrationPath_ = other.listenerRegistrationPath_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasListenerRegistrationPath()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.registration.ListenerRegistrationMessages.RegisterChangeListenerReply) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string listenerRegistrationPath = 1;
+      private java.lang.Object listenerRegistrationPath_ = "";
+      /**
+       * <code>required string listenerRegistrationPath = 1;</code>
+       */
+      public boolean hasListenerRegistrationPath() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string listenerRegistrationPath = 1;</code>
+       */
+      public java.lang.String getListenerRegistrationPath() {
+        java.lang.Object ref = listenerRegistrationPath_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          listenerRegistrationPath_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string listenerRegistrationPath = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getListenerRegistrationPathBytes() {
+        java.lang.Object ref = listenerRegistrationPath_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          listenerRegistrationPath_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string listenerRegistrationPath = 1;</code>
+       */
+      public Builder setListenerRegistrationPath(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        listenerRegistrationPath_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string listenerRegistrationPath = 1;</code>
+       */
+      public Builder clearListenerRegistrationPath() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        listenerRegistrationPath_ = getDefaultInstance().getListenerRegistrationPath();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string listenerRegistrationPath = 1;</code>
+       */
+      public Builder setListenerRegistrationPathBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        listenerRegistrationPath_ = value;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.RegisterChangeListenerReply)
+    }
+
+    static {
+      defaultInstance = new RegisterChangeListenerReply(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.RegisterChangeListenerReply)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistration_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistration_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistrationReply_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistrationReply_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_RegisterChangeListener_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_RegisterChangeListener_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_RegisterChangeListenerReply_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_RegisterChangeListenerReply_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\032ListenerRegistration.proto\022!org.openda" +
+      "ylight.controller.mdsal\032\014Common.proto\"%\n" +
+      "#CloseDataChangeListenerRegistration\"*\n(" +
+      "CloseDataChangeListenerRegistrationReply" +
+      "\"\255\001\n\026RegisterChangeListener\022U\n\026instanceI" +
+      "dentifierPath\030\001 \002(\01325.org.opendaylight.c" +
+      "ontroller.mdsal.InstanceIdentifier\022#\n\033da" +
+      "taChangeListenerActorPath\030\002 \002(\t\022\027\n\017dataC" +
+      "hangeScope\030\003 \002(\005\"?\n\033RegisterChangeListen" +
+      "erReply\022 \n\030listenerRegistrationPath\030\001 \002(",
+      "\tB[\n;org.opendaylight.controller.protobu" +
+      "ff.messages.registrationB\034ListenerRegist" +
+      "rationMessages"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistration_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistration_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistration_descriptor,
+              new java.lang.String[] { });
+          internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistrationReply_descriptor =
+            getDescriptor().getMessageTypes().get(1);
+          internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistrationReply_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_CloseDataChangeListenerRegistrationReply_descriptor,
+              new java.lang.String[] { });
+          internal_static_org_opendaylight_controller_mdsal_RegisterChangeListener_descriptor =
+            getDescriptor().getMessageTypes().get(2);
+          internal_static_org_opendaylight_controller_mdsal_RegisterChangeListener_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_RegisterChangeListener_descriptor,
+              new java.lang.String[] { "InstanceIdentifierPath", "DataChangeListenerActorPath", "DataChangeScope", });
+          internal_static_org_opendaylight_controller_mdsal_RegisterChangeListenerReply_descriptor =
+            getDescriptor().getMessageTypes().get(3);
+          internal_static_org_opendaylight_controller_mdsal_RegisterChangeListenerReply_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_RegisterChangeListenerReply_descriptor,
+              new java.lang.String[] { "ListenerRegistrationPath", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.getDescriptor(),
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
@@ -1,7 +1,7 @@
 // Generated by the protocol buffer compiler.  DO NOT EDIT!
 // source: ShardManager.proto
 
-package org.opendaylight.controller.cluster.datastore.shard;
+package org.opendaylight.controller.protobuff.messages.shard;
 
 public final class ShardManagerMessages {
   private ShardManagerMessages() {}
@@ -96,14 +96,14 @@ public final class ShardManagerMessages {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_FindPrimary_descriptor;
+      return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_FindPrimary_descriptor;
     }
 
     protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_FindPrimary_fieldAccessorTable
+      return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_FindPrimary_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary.class, org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary.Builder.class);
+              org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary.class, org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary.Builder.class);
     }
 
     public static com.google.protobuf.Parser<FindPrimary> PARSER =
@@ -139,7 +139,7 @@ public final class ShardManagerMessages {
       if (ref instanceof java.lang.String) {
         return (java.lang.String) ref;
       } else {
-        com.google.protobuf.ByteString bs =
+        com.google.protobuf.ByteString bs = 
             (com.google.protobuf.ByteString) ref;
         java.lang.String s = bs.toStringUtf8();
         if (bs.isValidUtf8()) {
@@ -155,7 +155,7 @@ public final class ShardManagerMessages {
         getShardNameBytes() {
       java.lang.Object ref = shardName_;
       if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b =
+        com.google.protobuf.ByteString b = 
             com.google.protobuf.ByteString.copyFromUtf8(
                 (java.lang.String) ref);
         shardName_ = b;
@@ -212,53 +212,53 @@ public final class ShardManagerMessages {
       return super.writeReplace();
     }
 
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary parseFrom(
         com.google.protobuf.ByteString data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary parseFrom(byte[] data)
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary parseFrom(java.io.InputStream input)
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return PARSER.parseFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return PARSER.parseFrom(input, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary parseDelimitedFrom(java.io.InputStream input)
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return PARSER.parseDelimitedFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary parseDelimitedFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return PARSER.parseDelimitedFrom(input, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return PARSER.parseFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -267,7 +267,7 @@ public final class ShardManagerMessages {
 
     public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary prototype) {
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary prototype) {
       return newBuilder().mergeFrom(prototype);
     }
     public Builder toBuilder() { return newBuilder(this); }
@@ -283,20 +283,20 @@ public final class ShardManagerMessages {
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimaryOrBuilder {
+       implements org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimaryOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_FindPrimary_descriptor;
+        return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_FindPrimary_descriptor;
       }
 
       protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_FindPrimary_fieldAccessorTable
+        return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_FindPrimary_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary.class, org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary.Builder.class);
+                org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary.class, org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary.Builder.class);
       }
 
-      // Construct using org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary.newBuilder()
+      // Construct using org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -327,23 +327,23 @@ public final class ShardManagerMessages {
 
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_FindPrimary_descriptor;
+        return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_FindPrimary_descriptor;
       }
 
-      public org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary.getDefaultInstance();
+      public org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary.getDefaultInstance();
       }
 
-      public org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary build() {
-        org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary result = buildPartial();
+      public org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary build() {
+        org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
         return result;
       }
 
-      public org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary buildPartial() {
-        org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary result = new org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary(this);
+      public org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary buildPartial() {
+        org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary result = new org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
         if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
@@ -356,16 +356,16 @@ public final class ShardManagerMessages {
       }
 
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary)other);
+        if (other instanceof org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary other) {
-        if (other == org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary.getDefaultInstance()) return this;
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary other) {
+        if (other == org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary.getDefaultInstance()) return this;
         if (other.hasShardName()) {
           bitField0_ |= 0x00000001;
           shardName_ = other.shardName_;
@@ -377,7 +377,7 @@ public final class ShardManagerMessages {
 
       public final boolean isInitialized() {
         if (!hasShardName()) {
-
+          
           return false;
         }
         return true;
@@ -387,11 +387,11 @@ public final class ShardManagerMessages {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary parsedMessage = null;
+        org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.FindPrimary) e.getUnfinishedMessage();
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.FindPrimary) e.getUnfinishedMessage();
           throw e;
         } finally {
           if (parsedMessage != null) {
@@ -431,7 +431,7 @@ public final class ShardManagerMessages {
           getShardNameBytes() {
         java.lang.Object ref = shardName_;
         if (ref instanceof String) {
-          com.google.protobuf.ByteString b =
+          com.google.protobuf.ByteString b = 
               com.google.protobuf.ByteString.copyFromUtf8(
                   (java.lang.String) ref);
           shardName_ = b;
@@ -489,6 +489,21 @@ public final class ShardManagerMessages {
 
   public interface PrimaryFoundOrBuilder
       extends com.google.protobuf.MessageOrBuilder {
+
+    // required string primaryPath = 1;
+    /**
+     * <code>required string primaryPath = 1;</code>
+     */
+    boolean hasPrimaryPath();
+    /**
+     * <code>required string primaryPath = 1;</code>
+     */
+    java.lang.String getPrimaryPath();
+    /**
+     * <code>required string primaryPath = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getPrimaryPathBytes();
   }
   /**
    * Protobuf type {@code org.opendaylight.controller.mdsal.PrimaryFound}
@@ -523,6 +538,7 @@ public final class ShardManagerMessages {
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       initFields();
+      int mutable_bitField0_ = 0;
       com.google.protobuf.UnknownFieldSet.Builder unknownFields =
           com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
@@ -540,6 +556,11 @@ public final class ShardManagerMessages {
               }
               break;
             }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              primaryPath_ = input.readBytes();
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -554,14 +575,14 @@ public final class ShardManagerMessages {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryFound_descriptor;
+      return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryFound_descriptor;
     }
 
     protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryFound_fieldAccessorTable
+      return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryFound_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound.class, org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound.Builder.class);
+              org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound.class, org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound.Builder.class);
     }
 
     public static com.google.protobuf.Parser<PrimaryFound> PARSER =
@@ -579,13 +600,62 @@ public final class ShardManagerMessages {
       return PARSER;
     }
 
+    private int bitField0_;
+    // required string primaryPath = 1;
+    public static final int PRIMARYPATH_FIELD_NUMBER = 1;
+    private java.lang.Object primaryPath_;
+    /**
+     * <code>required string primaryPath = 1;</code>
+     */
+    public boolean hasPrimaryPath() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string primaryPath = 1;</code>
+     */
+    public java.lang.String getPrimaryPath() {
+      java.lang.Object ref = primaryPath_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          primaryPath_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string primaryPath = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getPrimaryPathBytes() {
+      java.lang.Object ref = primaryPath_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        primaryPath_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
     private void initFields() {
+      primaryPath_ = "";
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
       if (isInitialized != -1) return isInitialized == 1;
 
+      if (!hasPrimaryPath()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -593,6 +663,9 @@ public final class ShardManagerMessages {
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
       getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getPrimaryPathBytes());
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -602,6 +675,10 @@ public final class ShardManagerMessages {
       if (size != -1) return size;
 
       size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getPrimaryPathBytes());
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -614,53 +691,53 @@ public final class ShardManagerMessages {
       return super.writeReplace();
     }
 
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound parseFrom(
         com.google.protobuf.ByteString data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound parseFrom(byte[] data)
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound parseFrom(java.io.InputStream input)
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return PARSER.parseFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return PARSER.parseFrom(input, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound parseDelimitedFrom(java.io.InputStream input)
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return PARSER.parseDelimitedFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound parseDelimitedFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return PARSER.parseDelimitedFrom(input, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return PARSER.parseFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -669,7 +746,7 @@ public final class ShardManagerMessages {
 
     public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound prototype) {
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound prototype) {
       return newBuilder().mergeFrom(prototype);
     }
     public Builder toBuilder() { return newBuilder(this); }
@@ -685,20 +762,20 @@ public final class ShardManagerMessages {
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFoundOrBuilder {
+       implements org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFoundOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryFound_descriptor;
+        return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryFound_descriptor;
       }
 
       protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryFound_fieldAccessorTable
+        return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryFound_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound.class, org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound.Builder.class);
+                org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound.class, org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound.Builder.class);
       }
 
-      // Construct using org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound.newBuilder()
+      // Construct using org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -718,6 +795,8 @@ public final class ShardManagerMessages {
 
       public Builder clear() {
         super.clear();
+        primaryPath_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
         return this;
       }
 
@@ -727,43 +806,59 @@ public final class ShardManagerMessages {
 
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryFound_descriptor;
+        return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryFound_descriptor;
       }
 
-      public org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound.getDefaultInstance();
+      public org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound.getDefaultInstance();
       }
 
-      public org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound build() {
-        org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound result = buildPartial();
+      public org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound build() {
+        org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
         return result;
       }
 
-      public org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound buildPartial() {
-        org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound result = new org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound(this);
+      public org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound buildPartial() {
+        org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound result = new org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.primaryPath_ = primaryPath_;
+        result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
       }
 
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound)other);
+        if (other instanceof org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound other) {
-        if (other == org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound.getDefaultInstance()) return this;
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound other) {
+        if (other == org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound.getDefaultInstance()) return this;
+        if (other.hasPrimaryPath()) {
+          bitField0_ |= 0x00000001;
+          primaryPath_ = other.primaryPath_;
+          onChanged();
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
 
       public final boolean isInitialized() {
+        if (!hasPrimaryPath()) {
+          
+          return false;
+        }
         return true;
       }
 
@@ -771,11 +866,11 @@ public final class ShardManagerMessages {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound parsedMessage = null;
+        org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryFound) e.getUnfinishedMessage();
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryFound) e.getUnfinishedMessage();
           throw e;
         } finally {
           if (parsedMessage != null) {
@@ -784,6 +879,81 @@ public final class ShardManagerMessages {
         }
         return this;
       }
+      private int bitField0_;
+
+      // required string primaryPath = 1;
+      private java.lang.Object primaryPath_ = "";
+      /**
+       * <code>required string primaryPath = 1;</code>
+       */
+      public boolean hasPrimaryPath() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string primaryPath = 1;</code>
+       */
+      public java.lang.String getPrimaryPath() {
+        java.lang.Object ref = primaryPath_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          primaryPath_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string primaryPath = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getPrimaryPathBytes() {
+        java.lang.Object ref = primaryPath_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          primaryPath_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string primaryPath = 1;</code>
+       */
+      public Builder setPrimaryPath(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        primaryPath_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string primaryPath = 1;</code>
+       */
+      public Builder clearPrimaryPath() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        primaryPath_ = getDefaultInstance().getPrimaryPath();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string primaryPath = 1;</code>
+       */
+      public Builder setPrimaryPathBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        primaryPath_ = value;
+        onChanged();
+        return this;
+      }
 
       // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.PrimaryFound)
     }
@@ -798,6 +968,21 @@ public final class ShardManagerMessages {
 
   public interface PrimaryNotFoundOrBuilder
       extends com.google.protobuf.MessageOrBuilder {
+
+    // required string shardName = 1;
+    /**
+     * <code>required string shardName = 1;</code>
+     */
+    boolean hasShardName();
+    /**
+     * <code>required string shardName = 1;</code>
+     */
+    java.lang.String getShardName();
+    /**
+     * <code>required string shardName = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getShardNameBytes();
   }
   /**
    * Protobuf type {@code org.opendaylight.controller.mdsal.PrimaryNotFound}
@@ -832,6 +1017,7 @@ public final class ShardManagerMessages {
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       initFields();
+      int mutable_bitField0_ = 0;
       com.google.protobuf.UnknownFieldSet.Builder unknownFields =
           com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
@@ -849,6 +1035,11 @@ public final class ShardManagerMessages {
               }
               break;
             }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              shardName_ = input.readBytes();
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -863,14 +1054,14 @@ public final class ShardManagerMessages {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryNotFound_descriptor;
+      return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryNotFound_descriptor;
     }
 
     protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryNotFound_fieldAccessorTable
+      return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryNotFound_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound.class, org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound.Builder.class);
+              org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound.class, org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound.Builder.class);
     }
 
     public static com.google.protobuf.Parser<PrimaryNotFound> PARSER =
@@ -888,13 +1079,62 @@ public final class ShardManagerMessages {
       return PARSER;
     }
 
+    private int bitField0_;
+    // required string shardName = 1;
+    public static final int SHARDNAME_FIELD_NUMBER = 1;
+    private java.lang.Object shardName_;
+    /**
+     * <code>required string shardName = 1;</code>
+     */
+    public boolean hasShardName() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string shardName = 1;</code>
+     */
+    public java.lang.String getShardName() {
+      java.lang.Object ref = shardName_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          shardName_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string shardName = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getShardNameBytes() {
+      java.lang.Object ref = shardName_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        shardName_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
     private void initFields() {
+      shardName_ = "";
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
       if (isInitialized != -1) return isInitialized == 1;
 
+      if (!hasShardName()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -902,6 +1142,9 @@ public final class ShardManagerMessages {
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
       getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getShardNameBytes());
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -911,6 +1154,10 @@ public final class ShardManagerMessages {
       if (size != -1) return size;
 
       size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getShardNameBytes());
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -923,53 +1170,53 @@ public final class ShardManagerMessages {
       return super.writeReplace();
     }
 
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound parseFrom(
         com.google.protobuf.ByteString data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound parseFrom(byte[] data)
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound parseFrom(java.io.InputStream input)
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return PARSER.parseFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return PARSER.parseFrom(input, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound parseDelimitedFrom(java.io.InputStream input)
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return PARSER.parseDelimitedFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound parseDelimitedFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return PARSER.parseDelimitedFrom(input, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return PARSER.parseFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -978,7 +1225,7 @@ public final class ShardManagerMessages {
 
     public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound prototype) {
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound prototype) {
       return newBuilder().mergeFrom(prototype);
     }
     public Builder toBuilder() { return newBuilder(this); }
@@ -994,20 +1241,20 @@ public final class ShardManagerMessages {
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFoundOrBuilder {
+       implements org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFoundOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryNotFound_descriptor;
+        return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryNotFound_descriptor;
       }
 
       protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryNotFound_fieldAccessorTable
+        return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryNotFound_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound.class, org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound.Builder.class);
+                org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound.class, org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound.Builder.class);
       }
 
-      // Construct using org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound.newBuilder()
+      // Construct using org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -1027,6 +1274,8 @@ public final class ShardManagerMessages {
 
       public Builder clear() {
         super.clear();
+        shardName_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
         return this;
       }
 
@@ -1036,43 +1285,59 @@ public final class ShardManagerMessages {
 
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryNotFound_descriptor;
+        return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.internal_static_org_opendaylight_controller_mdsal_PrimaryNotFound_descriptor;
       }
 
-      public org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound.getDefaultInstance();
+      public org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound.getDefaultInstance();
       }
 
-      public org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound build() {
-        org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound result = buildPartial();
+      public org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound build() {
+        org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
         return result;
       }
 
-      public org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound buildPartial() {
-        org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound result = new org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound(this);
+      public org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound buildPartial() {
+        org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound result = new org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.shardName_ = shardName_;
+        result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
       }
 
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound)other);
+        if (other instanceof org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound other) {
-        if (other == org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound.getDefaultInstance()) return this;
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound other) {
+        if (other == org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound.getDefaultInstance()) return this;
+        if (other.hasShardName()) {
+          bitField0_ |= 0x00000001;
+          shardName_ = other.shardName_;
+          onChanged();
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
 
       public final boolean isInitialized() {
+        if (!hasShardName()) {
+          
+          return false;
+        }
         return true;
       }
 
@@ -1080,11 +1345,11 @@ public final class ShardManagerMessages {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound parsedMessage = null;
+        org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages.PrimaryNotFound) e.getUnfinishedMessage();
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages.PrimaryNotFound) e.getUnfinishedMessage();
           throw e;
         } finally {
           if (parsedMessage != null) {
@@ -1093,6 +1358,81 @@ public final class ShardManagerMessages {
         }
         return this;
       }
+      private int bitField0_;
+
+      // required string shardName = 1;
+      private java.lang.Object shardName_ = "";
+      /**
+       * <code>required string shardName = 1;</code>
+       */
+      public boolean hasShardName() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string shardName = 1;</code>
+       */
+      public java.lang.String getShardName() {
+        java.lang.Object ref = shardName_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          shardName_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string shardName = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getShardNameBytes() {
+        java.lang.Object ref = shardName_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          shardName_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string shardName = 1;</code>
+       */
+      public Builder setShardName(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        shardName_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string shardName = 1;</code>
+       */
+      public Builder clearShardName() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        shardName_ = getDefaultInstance().getShardName();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string shardName = 1;</code>
+       */
+      public Builder setShardNameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        shardName_ = value;
+        onChanged();
+        return this;
+      }
 
       // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.PrimaryNotFound)
     }
@@ -1131,10 +1471,11 @@ public final class ShardManagerMessages {
     java.lang.String[] descriptorData = {
       "\n\022ShardManager.proto\022!org.opendaylight.c" +
       "ontroller.mdsal\" \n\013FindPrimary\022\021\n\tshardN" +
-      "ame\030\001 \002(\t\"\016\n\014PrimaryFound\"\021\n\017PrimaryNotF" +
-      "oundBK\n3org.opendaylight.controller.clus" +
-      "ter.datastore.shardB\024ShardManagerMessage" +
-      "s"
+      "ame\030\001 \002(\t\"#\n\014PrimaryFound\022\023\n\013primaryPath" +
+      "\030\001 \002(\t\"$\n\017PrimaryNotFound\022\021\n\tshardName\030\001" +
+      " \002(\tBL\n4org.opendaylight.controller.prot" +
+      "obuff.messages.shardB\024ShardManagerMessag" +
+      "es"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
       new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -1152,13 +1493,13 @@ public final class ShardManagerMessages {
           internal_static_org_opendaylight_controller_mdsal_PrimaryFound_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_opendaylight_controller_mdsal_PrimaryFound_descriptor,
-              new java.lang.String[] { });
+              new java.lang.String[] { "PrimaryPath", });
           internal_static_org_opendaylight_controller_mdsal_PrimaryNotFound_descriptor =
             getDescriptor().getMessageTypes().get(2);
           internal_static_org_opendaylight_controller_mdsal_PrimaryNotFound_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_opendaylight_controller_mdsal_PrimaryNotFound_descriptor,
-              new java.lang.String[] { });
+              new java.lang.String[] { "ShardName", });
           return null;
         }
       };
@@ -1,7 +1,7 @@
 // Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: ShardTransactionChainMessages.proto
+// source: ShardTransactionChain.proto
 
-package org.opendaylight.controller.cluster.datastore.transaction;
+package org.opendaylight.controller.protobuff.messages.transaction;
 
 public final class ShardTransactionChainMessages {
   private ShardTransactionChainMessages() {}
@@ -75,14 +75,14 @@ public final class ShardTransactionChainMessages {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChain_descriptor;
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChain_descriptor;
     }
 
     protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChain_fieldAccessorTable
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChain_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain.Builder.class);
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain.Builder.class);
     }
 
     public static com.google.protobuf.Parser<CloseTransactionChain> PARSER =
@@ -135,53 +135,53 @@ public final class ShardTransactionChainMessages {
       return super.writeReplace();
     }
 
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(
         com.google.protobuf.ByteString data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(byte[] data)
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(java.io.InputStream input)
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return PARSER.parseFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return PARSER.parseFrom(input, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain parseDelimitedFrom(java.io.InputStream input)
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return PARSER.parseDelimitedFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain parseDelimitedFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return PARSER.parseDelimitedFrom(input, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return PARSER.parseFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -190,7 +190,7 @@ public final class ShardTransactionChainMessages {
 
     public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain prototype) {
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain prototype) {
       return newBuilder().mergeFrom(prototype);
     }
     public Builder toBuilder() { return newBuilder(this); }
@@ -206,20 +206,20 @@ public final class ShardTransactionChainMessages {
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainOrBuilder {
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChain_descriptor;
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChain_descriptor;
       }
 
       protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChain_fieldAccessorTable
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChain_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain.Builder.class);
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain.Builder.class);
       }
 
-      // Construct using org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain.newBuilder()
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -248,38 +248,38 @@ public final class ShardTransactionChainMessages {
 
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChain_descriptor;
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChain_descriptor;
       }
 
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain.getDefaultInstance();
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain.getDefaultInstance();
       }
 
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain build() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain result = buildPartial();
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
         return result;
       }
 
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain buildPartial() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain result = new org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain(this);
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain(this);
         onBuilt();
         return result;
       }
 
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain)other);
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain other) {
-        if (other == org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain.getDefaultInstance()) return this;
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain.getDefaultInstance()) return this;
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -292,11 +292,11 @@ public final class ShardTransactionChainMessages {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain parsedMessage = null;
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChain) e.getUnfinishedMessage();
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChain) e.getUnfinishedMessage();
           throw e;
         } finally {
           if (parsedMessage != null) {
@@ -384,14 +384,14 @@ public final class ShardTransactionChainMessages {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChainReply_descriptor;
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChainReply_descriptor;
     }
 
     protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChainReply_fieldAccessorTable
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChainReply_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply.Builder.class);
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply.Builder.class);
     }
 
     public static com.google.protobuf.Parser<CloseTransactionChainReply> PARSER =
@@ -444,53 +444,53 @@ public final class ShardTransactionChainMessages {
       return super.writeReplace();
     }
 
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(
         com.google.protobuf.ByteString data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(byte[] data)
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(java.io.InputStream input)
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return PARSER.parseFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return PARSER.parseFrom(input, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseDelimitedFrom(java.io.InputStream input)
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return PARSER.parseDelimitedFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseDelimitedFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return PARSER.parseDelimitedFrom(input, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return PARSER.parseFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -499,7 +499,7 @@ public final class ShardTransactionChainMessages {
 
     public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply prototype) {
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply prototype) {
       return newBuilder().mergeFrom(prototype);
     }
     public Builder toBuilder() { return newBuilder(this); }
@@ -515,20 +515,20 @@ public final class ShardTransactionChainMessages {
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReplyOrBuilder {
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReplyOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChainReply_descriptor;
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChainReply_descriptor;
       }
 
       protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChainReply_fieldAccessorTable
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChainReply_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply.Builder.class);
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply.Builder.class);
       }
 
-      // Construct using org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply.newBuilder()
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -557,38 +557,38 @@ public final class ShardTransactionChainMessages {
 
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChainReply_descriptor;
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionChainReply_descriptor;
       }
 
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply.getDefaultInstance();
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply.getDefaultInstance();
       }
 
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply build() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply result = buildPartial();
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
         return result;
       }
 
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply buildPartial() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply result = new org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply(this);
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply(this);
         onBuilt();
         return result;
       }
 
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply)other);
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply other) {
-        if (other == org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply.getDefaultInstance()) return this;
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply.getDefaultInstance()) return this;
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -601,11 +601,11 @@ public final class ShardTransactionChainMessages {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parsedMessage = null;
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CloseTransactionChainReply) e.getUnfinishedMessage();
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CloseTransactionChainReply) e.getUnfinishedMessage();
           throw e;
         } finally {
           if (parsedMessage != null) {
@@ -693,14 +693,14 @@ public final class ShardTransactionChainMessages {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChain_descriptor;
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChain_descriptor;
     }
 
     protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChain_fieldAccessorTable
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChain_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain.Builder.class);
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain.Builder.class);
     }
 
     public static com.google.protobuf.Parser<CreateTransactionChain> PARSER =
@@ -753,53 +753,53 @@ public final class ShardTransactionChainMessages {
       return super.writeReplace();
     }
 
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(
         com.google.protobuf.ByteString data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(byte[] data)
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(java.io.InputStream input)
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return PARSER.parseFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return PARSER.parseFrom(input, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain parseDelimitedFrom(java.io.InputStream input)
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return PARSER.parseDelimitedFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain parseDelimitedFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return PARSER.parseDelimitedFrom(input, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return PARSER.parseFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -808,7 +808,7 @@ public final class ShardTransactionChainMessages {
 
     public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain prototype) {
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain prototype) {
       return newBuilder().mergeFrom(prototype);
     }
     public Builder toBuilder() { return newBuilder(this); }
@@ -824,20 +824,20 @@ public final class ShardTransactionChainMessages {
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainOrBuilder {
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChain_descriptor;
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChain_descriptor;
       }
 
       protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChain_fieldAccessorTable
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChain_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain.Builder.class);
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain.Builder.class);
       }
 
-      // Construct using org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain.newBuilder()
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -866,38 +866,38 @@ public final class ShardTransactionChainMessages {
 
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChain_descriptor;
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChain_descriptor;
       }
 
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain.getDefaultInstance();
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain.getDefaultInstance();
       }
 
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain build() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain result = buildPartial();
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
         return result;
       }
 
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain buildPartial() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain result = new org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain(this);
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain(this);
         onBuilt();
         return result;
       }
 
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain)other);
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain other) {
-        if (other == org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain.getDefaultInstance()) return this;
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain.getDefaultInstance()) return this;
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -910,11 +910,11 @@ public final class ShardTransactionChainMessages {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain parsedMessage = null;
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChain) e.getUnfinishedMessage();
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChain) e.getUnfinishedMessage();
           throw e;
         } finally {
           if (parsedMessage != null) {
@@ -1023,14 +1023,14 @@ public final class ShardTransactionChainMessages {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChainReply_descriptor;
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChainReply_descriptor;
     }
 
     protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChainReply_fieldAccessorTable
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChainReply_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply.Builder.class);
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply.Builder.class);
     }
 
     public static com.google.protobuf.Parser<CreateTransactionChainReply> PARSER =
@@ -1066,7 +1066,7 @@ public final class ShardTransactionChainMessages {
       if (ref instanceof java.lang.String) {
         return (java.lang.String) ref;
       } else {
-        com.google.protobuf.ByteString bs =
+        com.google.protobuf.ByteString bs = 
             (com.google.protobuf.ByteString) ref;
         java.lang.String s = bs.toStringUtf8();
         if (bs.isValidUtf8()) {
@@ -1082,7 +1082,7 @@ public final class ShardTransactionChainMessages {
         getTransactionChainPathBytes() {
       java.lang.Object ref = transactionChainPath_;
       if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b =
+        com.google.protobuf.ByteString b = 
             com.google.protobuf.ByteString.copyFromUtf8(
                 (java.lang.String) ref);
         transactionChainPath_ = b;
@@ -1139,53 +1139,53 @@ public final class ShardTransactionChainMessages {
       return super.writeReplace();
     }
 
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(
         com.google.protobuf.ByteString data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(byte[] data)
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(java.io.InputStream input)
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return PARSER.parseFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return PARSER.parseFrom(input, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseDelimitedFrom(java.io.InputStream input)
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return PARSER.parseDelimitedFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseDelimitedFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return PARSER.parseDelimitedFrom(input, extensionRegistry);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return PARSER.parseFrom(input);
     }
-    public static org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -1194,7 +1194,7 @@ public final class ShardTransactionChainMessages {
 
     public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply prototype) {
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply prototype) {
       return newBuilder().mergeFrom(prototype);
     }
     public Builder toBuilder() { return newBuilder(this); }
@@ -1210,20 +1210,20 @@ public final class ShardTransactionChainMessages {
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessage.Builder<Builder>
-       implements org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReplyOrBuilder {
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReplyOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChainReply_descriptor;
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChainReply_descriptor;
       }
 
       protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChainReply_fieldAccessorTable
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChainReply_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply.class, org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply.Builder.class);
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply.Builder.class);
       }
 
-      // Construct using org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply.newBuilder()
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -1254,23 +1254,23 @@ public final class ShardTransactionChainMessages {
 
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChainReply_descriptor;
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionChainReply_descriptor;
       }
 
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply getDefaultInstanceForType() {
-        return org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply.getDefaultInstance();
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply.getDefaultInstance();
       }
 
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply build() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply result = buildPartial();
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
         return result;
       }
 
-      public org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply buildPartial() {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply result = new org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply(this);
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
         if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
@@ -1283,16 +1283,16 @@ public final class ShardTransactionChainMessages {
       }
 
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply) {
-          return mergeFrom((org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply)other);
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply other) {
-        if (other == org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply.getDefaultInstance()) return this;
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply.getDefaultInstance()) return this;
         if (other.hasTransactionChainPath()) {
           bitField0_ |= 0x00000001;
           transactionChainPath_ = other.transactionChainPath_;
@@ -1303,7 +1303,8 @@ public final class ShardTransactionChainMessages {
       }
 
       public final boolean isInitialized() {
-        if (!hasTransactionChainPath()){
+        if (!hasTransactionChainPath()) {
+          
           return false;
         }
         return true;
@@ -1313,11 +1314,11 @@ public final class ShardTransactionChainMessages {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parsedMessage = null;
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.opendaylight.controller.cluster.datastore.transaction.ShardTransactionChainMessages.CreateTransactionChainReply) e.getUnfinishedMessage();
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionChainMessages.CreateTransactionChainReply) e.getUnfinishedMessage();
           throw e;
         } finally {
           if (parsedMessage != null) {
@@ -1357,7 +1358,7 @@ public final class ShardTransactionChainMessages {
           getTransactionChainPathBytes() {
         java.lang.Object ref = transactionChainPath_;
         if (ref instanceof String) {
-          com.google.protobuf.ByteString b =
+          com.google.protobuf.ByteString b = 
               com.google.protobuf.ByteString.copyFromUtf8(
                   (java.lang.String) ref);
           transactionChainPath_ = b;
@@ -1442,14 +1443,14 @@ public final class ShardTransactionChainMessages {
       descriptor;
   static {
     java.lang.String[] descriptorData = {
-      "\n#ShardTransactionChainMessages.proto\022!o" +
-      "rg.opendaylight.controller.mdsal\"\027\n\025Clos" +
-      "eTransactionChain\"\034\n\032CloseTransactionCha" +
-      "inReply\"\030\n\026CreateTransactionChain\";\n\033Cre" +
-      "ateTransactionChainReply\022\034\n\024transactionC" +
-      "hainPath\030\001 \002(\tBZ\n9org.opendaylight.contr" +
-      "oller.cluster.datastore.transactionB\035Sha" +
-      "rdTransactionChainMessages"
+      "\n\033ShardTransactionChain.proto\022!org.opend" +
+      "aylight.controller.mdsal\"\027\n\025CloseTransac" +
+      "tionChain\"\034\n\032CloseTransactionChainReply\"" +
+      "\030\n\026CreateTransactionChain\";\n\033CreateTrans" +
+      "actionChainReply\022\034\n\024transactionChainPath" +
+      "\030\001 \002(\tB[\n:org.opendaylight.controller.pr" +
+      "otobuff.messages.transactionB\035ShardTrans" +
+      "actionChainMessages"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
       new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/transaction/ShardTransactionMessages.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/protobuff/messages/transaction/ShardTransactionMessages.java
new file mode 100644 (file)
index 0000000..ee2c704
--- /dev/null
@@ -0,0 +1,6701 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: ShardTransaction.proto
+
+package org.opendaylight.controller.protobuff.messages.transaction;
+
+public final class ShardTransactionMessages {
+  private ShardTransactionMessages() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface CloseTransactionOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.CloseTransaction}
+   */
+  public static final class CloseTransaction extends
+      com.google.protobuf.GeneratedMessage
+      implements CloseTransactionOrBuilder {
+    // Use CloseTransaction.newBuilder() to construct.
+    private CloseTransaction(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private CloseTransaction(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final CloseTransaction defaultInstance;
+    public static CloseTransaction getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public CloseTransaction getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private CloseTransaction(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransaction_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransaction_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<CloseTransaction> PARSER =
+        new com.google.protobuf.AbstractParser<CloseTransaction>() {
+      public CloseTransaction parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new CloseTransaction(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CloseTransaction> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.CloseTransaction}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransaction_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransaction_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransaction_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransaction) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CloseTransaction)
+    }
+
+    static {
+      defaultInstance = new CloseTransaction(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CloseTransaction)
+  }
+
+  public interface CloseTransactionReplyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.CloseTransactionReply}
+   */
+  public static final class CloseTransactionReply extends
+      com.google.protobuf.GeneratedMessage
+      implements CloseTransactionReplyOrBuilder {
+    // Use CloseTransactionReply.newBuilder() to construct.
+    private CloseTransactionReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private CloseTransactionReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final CloseTransactionReply defaultInstance;
+    public static CloseTransactionReply getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public CloseTransactionReply getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private CloseTransactionReply(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<CloseTransactionReply> PARSER =
+        new com.google.protobuf.AbstractParser<CloseTransactionReply>() {
+      public CloseTransactionReply parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new CloseTransactionReply(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CloseTransactionReply> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.CloseTransactionReply}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReplyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CloseTransactionReply) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CloseTransactionReply)
+    }
+
+    static {
+      defaultInstance = new CloseTransactionReply(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CloseTransactionReply)
+  }
+
+  public interface CreateTransactionOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string transactionId = 1;
+    /**
+     * <code>required string transactionId = 1;</code>
+     */
+    boolean hasTransactionId();
+    /**
+     * <code>required string transactionId = 1;</code>
+     */
+    java.lang.String getTransactionId();
+    /**
+     * <code>required string transactionId = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getTransactionIdBytes();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.CreateTransaction}
+   */
+  public static final class CreateTransaction extends
+      com.google.protobuf.GeneratedMessage
+      implements CreateTransactionOrBuilder {
+    // Use CreateTransaction.newBuilder() to construct.
+    private CreateTransaction(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private CreateTransaction(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final CreateTransaction defaultInstance;
+    public static CreateTransaction getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public CreateTransaction getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private CreateTransaction(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              transactionId_ = input.readBytes();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransaction_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransaction_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<CreateTransaction> PARSER =
+        new com.google.protobuf.AbstractParser<CreateTransaction>() {
+      public CreateTransaction parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new CreateTransaction(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CreateTransaction> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string transactionId = 1;
+    public static final int TRANSACTIONID_FIELD_NUMBER = 1;
+    private java.lang.Object transactionId_;
+    /**
+     * <code>required string transactionId = 1;</code>
+     */
+    public boolean hasTransactionId() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string transactionId = 1;</code>
+     */
+    public java.lang.String getTransactionId() {
+      java.lang.Object ref = transactionId_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          transactionId_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string transactionId = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getTransactionIdBytes() {
+      java.lang.Object ref = transactionId_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        transactionId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    private void initFields() {
+      transactionId_ = "";
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasTransactionId()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getTransactionIdBytes());
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getTransactionIdBytes());
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.CreateTransaction}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransaction_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransaction_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        transactionId_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransaction_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.transactionId_ = transactionId_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction.getDefaultInstance()) return this;
+        if (other.hasTransactionId()) {
+          bitField0_ |= 0x00000001;
+          transactionId_ = other.transactionId_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasTransactionId()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransaction) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string transactionId = 1;
+      private java.lang.Object transactionId_ = "";
+      /**
+       * <code>required string transactionId = 1;</code>
+       */
+      public boolean hasTransactionId() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string transactionId = 1;</code>
+       */
+      public java.lang.String getTransactionId() {
+        java.lang.Object ref = transactionId_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          transactionId_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string transactionId = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getTransactionIdBytes() {
+        java.lang.Object ref = transactionId_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          transactionId_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string transactionId = 1;</code>
+       */
+      public Builder setTransactionId(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        transactionId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string transactionId = 1;</code>
+       */
+      public Builder clearTransactionId() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        transactionId_ = getDefaultInstance().getTransactionId();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string transactionId = 1;</code>
+       */
+      public Builder setTransactionIdBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        transactionId_ = value;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CreateTransaction)
+    }
+
+    static {
+      defaultInstance = new CreateTransaction(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CreateTransaction)
+  }
+
+  public interface CreateTransactionReplyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string transactionActorPath = 1;
+    /**
+     * <code>required string transactionActorPath = 1;</code>
+     */
+    boolean hasTransactionActorPath();
+    /**
+     * <code>required string transactionActorPath = 1;</code>
+     */
+    java.lang.String getTransactionActorPath();
+    /**
+     * <code>required string transactionActorPath = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getTransactionActorPathBytes();
+
+    // required string transactionId = 2;
+    /**
+     * <code>required string transactionId = 2;</code>
+     */
+    boolean hasTransactionId();
+    /**
+     * <code>required string transactionId = 2;</code>
+     */
+    java.lang.String getTransactionId();
+    /**
+     * <code>required string transactionId = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getTransactionIdBytes();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.CreateTransactionReply}
+   */
+  public static final class CreateTransactionReply extends
+      com.google.protobuf.GeneratedMessage
+      implements CreateTransactionReplyOrBuilder {
+    // Use CreateTransactionReply.newBuilder() to construct.
+    private CreateTransactionReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private CreateTransactionReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final CreateTransactionReply defaultInstance;
+    public static CreateTransactionReply getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public CreateTransactionReply getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private CreateTransactionReply(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              transactionActorPath_ = input.readBytes();
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              transactionId_ = input.readBytes();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<CreateTransactionReply> PARSER =
+        new com.google.protobuf.AbstractParser<CreateTransactionReply>() {
+      public CreateTransactionReply parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new CreateTransactionReply(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CreateTransactionReply> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string transactionActorPath = 1;
+    public static final int TRANSACTIONACTORPATH_FIELD_NUMBER = 1;
+    private java.lang.Object transactionActorPath_;
+    /**
+     * <code>required string transactionActorPath = 1;</code>
+     */
+    public boolean hasTransactionActorPath() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string transactionActorPath = 1;</code>
+     */
+    public java.lang.String getTransactionActorPath() {
+      java.lang.Object ref = transactionActorPath_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          transactionActorPath_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string transactionActorPath = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getTransactionActorPathBytes() {
+      java.lang.Object ref = transactionActorPath_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        transactionActorPath_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required string transactionId = 2;
+    public static final int TRANSACTIONID_FIELD_NUMBER = 2;
+    private java.lang.Object transactionId_;
+    /**
+     * <code>required string transactionId = 2;</code>
+     */
+    public boolean hasTransactionId() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required string transactionId = 2;</code>
+     */
+    public java.lang.String getTransactionId() {
+      java.lang.Object ref = transactionId_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          transactionId_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string transactionId = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getTransactionIdBytes() {
+      java.lang.Object ref = transactionId_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        transactionId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    private void initFields() {
+      transactionActorPath_ = "";
+      transactionId_ = "";
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasTransactionActorPath()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasTransactionId()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getTransactionActorPathBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, getTransactionIdBytes());
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getTransactionActorPathBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, getTransactionIdBytes());
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.CreateTransactionReply}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReplyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        transactionActorPath_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        transactionId_ = "";
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.transactionActorPath_ = transactionActorPath_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.transactionId_ = transactionId_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply.getDefaultInstance()) return this;
+        if (other.hasTransactionActorPath()) {
+          bitField0_ |= 0x00000001;
+          transactionActorPath_ = other.transactionActorPath_;
+          onChanged();
+        }
+        if (other.hasTransactionId()) {
+          bitField0_ |= 0x00000002;
+          transactionId_ = other.transactionId_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasTransactionActorPath()) {
+          
+          return false;
+        }
+        if (!hasTransactionId()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.CreateTransactionReply) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string transactionActorPath = 1;
+      private java.lang.Object transactionActorPath_ = "";
+      /**
+       * <code>required string transactionActorPath = 1;</code>
+       */
+      public boolean hasTransactionActorPath() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string transactionActorPath = 1;</code>
+       */
+      public java.lang.String getTransactionActorPath() {
+        java.lang.Object ref = transactionActorPath_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          transactionActorPath_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string transactionActorPath = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getTransactionActorPathBytes() {
+        java.lang.Object ref = transactionActorPath_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          transactionActorPath_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string transactionActorPath = 1;</code>
+       */
+      public Builder setTransactionActorPath(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        transactionActorPath_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string transactionActorPath = 1;</code>
+       */
+      public Builder clearTransactionActorPath() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        transactionActorPath_ = getDefaultInstance().getTransactionActorPath();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string transactionActorPath = 1;</code>
+       */
+      public Builder setTransactionActorPathBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        transactionActorPath_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required string transactionId = 2;
+      private java.lang.Object transactionId_ = "";
+      /**
+       * <code>required string transactionId = 2;</code>
+       */
+      public boolean hasTransactionId() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required string transactionId = 2;</code>
+       */
+      public java.lang.String getTransactionId() {
+        java.lang.Object ref = transactionId_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          transactionId_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string transactionId = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getTransactionIdBytes() {
+        java.lang.Object ref = transactionId_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          transactionId_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string transactionId = 2;</code>
+       */
+      public Builder setTransactionId(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        transactionId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string transactionId = 2;</code>
+       */
+      public Builder clearTransactionId() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        transactionId_ = getDefaultInstance().getTransactionId();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string transactionId = 2;</code>
+       */
+      public Builder setTransactionIdBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        transactionId_ = value;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.CreateTransactionReply)
+    }
+
+    static {
+      defaultInstance = new CreateTransactionReply(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.CreateTransactionReply)
+  }
+
+  public interface ReadyTransactionOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.ReadyTransaction}
+   */
+  public static final class ReadyTransaction extends
+      com.google.protobuf.GeneratedMessage
+      implements ReadyTransactionOrBuilder {
+    // Use ReadyTransaction.newBuilder() to construct.
+    private ReadyTransaction(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private ReadyTransaction(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final ReadyTransaction defaultInstance;
+    public static ReadyTransaction getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public ReadyTransaction getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private ReadyTransaction(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<ReadyTransaction> PARSER =
+        new com.google.protobuf.AbstractParser<ReadyTransaction>() {
+      public ReadyTransaction parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new ReadyTransaction(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<ReadyTransaction> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.ReadyTransaction}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransaction) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.ReadyTransaction)
+    }
+
+    static {
+      defaultInstance = new ReadyTransaction(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.ReadyTransaction)
+  }
+
+  public interface ReadyTransactionReplyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string actorPath = 1;
+    /**
+     * <code>required string actorPath = 1;</code>
+     */
+    boolean hasActorPath();
+    /**
+     * <code>required string actorPath = 1;</code>
+     */
+    java.lang.String getActorPath();
+    /**
+     * <code>required string actorPath = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getActorPathBytes();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.ReadyTransactionReply}
+   */
+  public static final class ReadyTransactionReply extends
+      com.google.protobuf.GeneratedMessage
+      implements ReadyTransactionReplyOrBuilder {
+    // Use ReadyTransactionReply.newBuilder() to construct.
+    private ReadyTransactionReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private ReadyTransactionReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final ReadyTransactionReply defaultInstance;
+    public static ReadyTransactionReply getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public ReadyTransactionReply getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private ReadyTransactionReply(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              actorPath_ = input.readBytes();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<ReadyTransactionReply> PARSER =
+        new com.google.protobuf.AbstractParser<ReadyTransactionReply>() {
+      public ReadyTransactionReply parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new ReadyTransactionReply(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<ReadyTransactionReply> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string actorPath = 1;
+    public static final int ACTORPATH_FIELD_NUMBER = 1;
+    private java.lang.Object actorPath_;
+    /**
+     * <code>required string actorPath = 1;</code>
+     */
+    public boolean hasActorPath() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string actorPath = 1;</code>
+     */
+    public java.lang.String getActorPath() {
+      java.lang.Object ref = actorPath_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          actorPath_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string actorPath = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getActorPathBytes() {
+      java.lang.Object ref = actorPath_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        actorPath_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    private void initFields() {
+      actorPath_ = "";
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasActorPath()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getActorPathBytes());
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getActorPathBytes());
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.ReadyTransactionReply}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReplyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        actorPath_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.actorPath_ = actorPath_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply.getDefaultInstance()) return this;
+        if (other.hasActorPath()) {
+          bitField0_ |= 0x00000001;
+          actorPath_ = other.actorPath_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasActorPath()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadyTransactionReply) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string actorPath = 1;
+      private java.lang.Object actorPath_ = "";
+      /**
+       * <code>required string actorPath = 1;</code>
+       */
+      public boolean hasActorPath() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string actorPath = 1;</code>
+       */
+      public java.lang.String getActorPath() {
+        java.lang.Object ref = actorPath_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          actorPath_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string actorPath = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getActorPathBytes() {
+        java.lang.Object ref = actorPath_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          actorPath_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string actorPath = 1;</code>
+       */
+      public Builder setActorPath(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        actorPath_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string actorPath = 1;</code>
+       */
+      public Builder clearActorPath() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        actorPath_ = getDefaultInstance().getActorPath();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string actorPath = 1;</code>
+       */
+      public Builder setActorPathBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        actorPath_ = value;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.ReadyTransactionReply)
+    }
+
+    static {
+      defaultInstance = new ReadyTransactionReply(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.ReadyTransactionReply)
+  }
+
+  public interface DeleteDataOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    boolean hasInstanceIdentifierPathArguments();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPathArguments();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathArgumentsOrBuilder();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.DeleteData}
+   */
+  public static final class DeleteData extends
+      com.google.protobuf.GeneratedMessage
+      implements DeleteDataOrBuilder {
+    // Use DeleteData.newBuilder() to construct.
+    private DeleteData(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private DeleteData(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final DeleteData defaultInstance;
+    public static DeleteData getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public DeleteData getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private DeleteData(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+                subBuilder = instanceIdentifierPathArguments_.toBuilder();
+              }
+              instanceIdentifierPathArguments_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(instanceIdentifierPathArguments_);
+                instanceIdentifierPathArguments_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000001;
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteData_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteData_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<DeleteData> PARSER =
+        new com.google.protobuf.AbstractParser<DeleteData>() {
+      public DeleteData parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new DeleteData(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<DeleteData> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;
+    public static final int INSTANCEIDENTIFIERPATHARGUMENTS_FIELD_NUMBER = 1;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier instanceIdentifierPathArguments_;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    public boolean hasInstanceIdentifierPathArguments() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPathArguments() {
+      return instanceIdentifierPathArguments_;
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathArgumentsOrBuilder() {
+      return instanceIdentifierPathArguments_;
+    }
+
+    private void initFields() {
+      instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasInstanceIdentifierPathArguments()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!getInstanceIdentifierPathArguments().isInitialized()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeMessage(1, instanceIdentifierPathArguments_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, instanceIdentifierPathArguments_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.DeleteData}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteData_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteData_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getInstanceIdentifierPathArgumentsFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteData_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          result.instanceIdentifierPathArguments_ = instanceIdentifierPathArguments_;
+        } else {
+          result.instanceIdentifierPathArguments_ = instanceIdentifierPathArgumentsBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData.getDefaultInstance()) return this;
+        if (other.hasInstanceIdentifierPathArguments()) {
+          mergeInstanceIdentifierPathArguments(other.getInstanceIdentifierPathArguments());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasInstanceIdentifierPathArguments()) {
+          
+          return false;
+        }
+        if (!getInstanceIdentifierPathArguments().isInitialized()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteData) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> instanceIdentifierPathArgumentsBuilder_;
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public boolean hasInstanceIdentifierPathArguments() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPathArguments() {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          return instanceIdentifierPathArguments_;
+        } else {
+          return instanceIdentifierPathArgumentsBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder setInstanceIdentifierPathArguments(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          instanceIdentifierPathArguments_ = value;
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder setInstanceIdentifierPathArguments(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder builderForValue) {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArguments_ = builderForValue.build();
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder mergeInstanceIdentifierPathArguments(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+              instanceIdentifierPathArguments_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance()) {
+            instanceIdentifierPathArguments_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.newBuilder(instanceIdentifierPathArguments_).mergeFrom(value).buildPartial();
+          } else {
+            instanceIdentifierPathArguments_ = value;
+          }
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder clearInstanceIdentifierPathArguments() {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder getInstanceIdentifierPathArgumentsBuilder() {
+        bitField0_ |= 0x00000001;
+        onChanged();
+        return getInstanceIdentifierPathArgumentsFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathArgumentsOrBuilder() {
+        if (instanceIdentifierPathArgumentsBuilder_ != null) {
+          return instanceIdentifierPathArgumentsBuilder_.getMessageOrBuilder();
+        } else {
+          return instanceIdentifierPathArguments_;
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> 
+          getInstanceIdentifierPathArgumentsFieldBuilder() {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArgumentsBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder>(
+                  instanceIdentifierPathArguments_,
+                  getParentForChildren(),
+                  isClean());
+          instanceIdentifierPathArguments_ = null;
+        }
+        return instanceIdentifierPathArgumentsBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.DeleteData)
+    }
+
+    static {
+      defaultInstance = new DeleteData(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.DeleteData)
+  }
+
+  public interface DeleteDataReplyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.DeleteDataReply}
+   */
+  public static final class DeleteDataReply extends
+      com.google.protobuf.GeneratedMessage
+      implements DeleteDataReplyOrBuilder {
+    // Use DeleteDataReply.newBuilder() to construct.
+    private DeleteDataReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private DeleteDataReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final DeleteDataReply defaultInstance;
+    public static DeleteDataReply getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public DeleteDataReply getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private DeleteDataReply(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<DeleteDataReply> PARSER =
+        new com.google.protobuf.AbstractParser<DeleteDataReply>() {
+      public DeleteDataReply parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new DeleteDataReply(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<DeleteDataReply> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.DeleteDataReply}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReplyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.DeleteDataReply) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.DeleteDataReply)
+    }
+
+    static {
+      defaultInstance = new DeleteDataReply(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.DeleteDataReply)
+  }
+
+  public interface ReadDataOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    boolean hasInstanceIdentifierPathArguments();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPathArguments();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathArgumentsOrBuilder();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.ReadData}
+   */
+  public static final class ReadData extends
+      com.google.protobuf.GeneratedMessage
+      implements ReadDataOrBuilder {
+    // Use ReadData.newBuilder() to construct.
+    private ReadData(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private ReadData(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final ReadData defaultInstance;
+    public static ReadData getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public ReadData getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private ReadData(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+                subBuilder = instanceIdentifierPathArguments_.toBuilder();
+              }
+              instanceIdentifierPathArguments_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(instanceIdentifierPathArguments_);
+                instanceIdentifierPathArguments_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000001;
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadData_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadData_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<ReadData> PARSER =
+        new com.google.protobuf.AbstractParser<ReadData>() {
+      public ReadData parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new ReadData(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<ReadData> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;
+    public static final int INSTANCEIDENTIFIERPATHARGUMENTS_FIELD_NUMBER = 1;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier instanceIdentifierPathArguments_;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    public boolean hasInstanceIdentifierPathArguments() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPathArguments() {
+      return instanceIdentifierPathArguments_;
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathArgumentsOrBuilder() {
+      return instanceIdentifierPathArguments_;
+    }
+
+    private void initFields() {
+      instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasInstanceIdentifierPathArguments()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!getInstanceIdentifierPathArguments().isInitialized()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeMessage(1, instanceIdentifierPathArguments_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, instanceIdentifierPathArguments_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.ReadData}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadData_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadData_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getInstanceIdentifierPathArgumentsFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadData_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          result.instanceIdentifierPathArguments_ = instanceIdentifierPathArguments_;
+        } else {
+          result.instanceIdentifierPathArguments_ = instanceIdentifierPathArgumentsBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData.getDefaultInstance()) return this;
+        if (other.hasInstanceIdentifierPathArguments()) {
+          mergeInstanceIdentifierPathArguments(other.getInstanceIdentifierPathArguments());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasInstanceIdentifierPathArguments()) {
+          
+          return false;
+        }
+        if (!getInstanceIdentifierPathArguments().isInitialized()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadData) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> instanceIdentifierPathArgumentsBuilder_;
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public boolean hasInstanceIdentifierPathArguments() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPathArguments() {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          return instanceIdentifierPathArguments_;
+        } else {
+          return instanceIdentifierPathArgumentsBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder setInstanceIdentifierPathArguments(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          instanceIdentifierPathArguments_ = value;
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder setInstanceIdentifierPathArguments(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder builderForValue) {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArguments_ = builderForValue.build();
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder mergeInstanceIdentifierPathArguments(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+              instanceIdentifierPathArguments_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance()) {
+            instanceIdentifierPathArguments_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.newBuilder(instanceIdentifierPathArguments_).mergeFrom(value).buildPartial();
+          } else {
+            instanceIdentifierPathArguments_ = value;
+          }
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder clearInstanceIdentifierPathArguments() {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder getInstanceIdentifierPathArgumentsBuilder() {
+        bitField0_ |= 0x00000001;
+        onChanged();
+        return getInstanceIdentifierPathArgumentsFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathArgumentsOrBuilder() {
+        if (instanceIdentifierPathArgumentsBuilder_ != null) {
+          return instanceIdentifierPathArgumentsBuilder_.getMessageOrBuilder();
+        } else {
+          return instanceIdentifierPathArguments_;
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> 
+          getInstanceIdentifierPathArgumentsFieldBuilder() {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArgumentsBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder>(
+                  instanceIdentifierPathArguments_,
+                  getParentForChildren(),
+                  isClean());
+          instanceIdentifierPathArguments_ = null;
+        }
+        return instanceIdentifierPathArgumentsBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.ReadData)
+    }
+
+    static {
+      defaultInstance = new ReadData(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.ReadData)
+  }
+
+  public interface ReadDataReplyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+     */
+    boolean hasNormalizedNode();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode();
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.ReadDataReply}
+   */
+  public static final class ReadDataReply extends
+      com.google.protobuf.GeneratedMessage
+      implements ReadDataReplyOrBuilder {
+    // Use ReadDataReply.newBuilder() to construct.
+    private ReadDataReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private ReadDataReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final ReadDataReply defaultInstance;
+    public static ReadDataReply getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public ReadDataReply getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private ReadDataReply(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+                subBuilder = normalizedNode_.toBuilder();
+              }
+              normalizedNode_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(normalizedNode_);
+                normalizedNode_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000001;
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadDataReply_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadDataReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<ReadDataReply> PARSER =
+        new com.google.protobuf.AbstractParser<ReadDataReply>() {
+      public ReadDataReply parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new ReadDataReply(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<ReadDataReply> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;
+    public static final int NORMALIZEDNODE_FIELD_NUMBER = 1;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node normalizedNode_;
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+     */
+    public boolean hasNormalizedNode() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode() {
+      return normalizedNode_;
+    }
+    /**
+     * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder() {
+      return normalizedNode_;
+    }
+
+    private void initFields() {
+      normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (hasNormalizedNode()) {
+        if (!getNormalizedNode().isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeMessage(1, normalizedNode_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, normalizedNode_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.ReadDataReply}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReplyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadDataReply_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadDataReply_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getNormalizedNodeFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+        } else {
+          normalizedNodeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_ReadDataReply_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        if (normalizedNodeBuilder_ == null) {
+          result.normalizedNode_ = normalizedNode_;
+        } else {
+          result.normalizedNode_ = normalizedNodeBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply.getDefaultInstance()) return this;
+        if (other.hasNormalizedNode()) {
+          mergeNormalizedNode(other.getNormalizedNode());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (hasNormalizedNode()) {
+          if (!getNormalizedNode().isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.ReadDataReply) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> normalizedNodeBuilder_;
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+       */
+      public boolean hasNormalizedNode() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode() {
+        if (normalizedNodeBuilder_ == null) {
+          return normalizedNode_;
+        } else {
+          return normalizedNodeBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+       */
+      public Builder setNormalizedNode(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (normalizedNodeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          normalizedNode_ = value;
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+       */
+      public Builder setNormalizedNode(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder builderForValue) {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = builderForValue.build();
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+       */
+      public Builder mergeNormalizedNode(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (normalizedNodeBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+              normalizedNode_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance()) {
+            normalizedNode_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.newBuilder(normalizedNode_).mergeFrom(value).buildPartial();
+          } else {
+            normalizedNode_ = value;
+          }
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+       */
+      public Builder clearNormalizedNode() {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder getNormalizedNodeBuilder() {
+        bitField0_ |= 0x00000001;
+        onChanged();
+        return getNormalizedNodeFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder() {
+        if (normalizedNodeBuilder_ != null) {
+          return normalizedNodeBuilder_.getMessageOrBuilder();
+        } else {
+          return normalizedNode_;
+        }
+      }
+      /**
+       * <code>optional .org.opendaylight.controller.mdsal.Node normalizedNode = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> 
+          getNormalizedNodeFieldBuilder() {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNodeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder>(
+                  normalizedNode_,
+                  getParentForChildren(),
+                  isClean());
+          normalizedNode_ = null;
+        }
+        return normalizedNodeBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.ReadDataReply)
+    }
+
+    static {
+      defaultInstance = new ReadDataReply(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.ReadDataReply)
+  }
+
+  public interface WriteDataOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    boolean hasInstanceIdentifierPathArguments();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPathArguments();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathArgumentsOrBuilder();
+
+    // required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    boolean hasNormalizedNode();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.WriteData}
+   */
+  public static final class WriteData extends
+      com.google.protobuf.GeneratedMessage
+      implements WriteDataOrBuilder {
+    // Use WriteData.newBuilder() to construct.
+    private WriteData(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private WriteData(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final WriteData defaultInstance;
+    public static WriteData getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public WriteData getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private WriteData(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+                subBuilder = instanceIdentifierPathArguments_.toBuilder();
+              }
+              instanceIdentifierPathArguments_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(instanceIdentifierPathArguments_);
+                instanceIdentifierPathArguments_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000001;
+              break;
+            }
+            case 18: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+                subBuilder = normalizedNode_.toBuilder();
+              }
+              normalizedNode_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(normalizedNode_);
+                normalizedNode_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000002;
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_WriteData_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_WriteData_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<WriteData> PARSER =
+        new com.google.protobuf.AbstractParser<WriteData>() {
+      public WriteData parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new WriteData(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<WriteData> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;
+    public static final int INSTANCEIDENTIFIERPATHARGUMENTS_FIELD_NUMBER = 1;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier instanceIdentifierPathArguments_;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    public boolean hasInstanceIdentifierPathArguments() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPathArguments() {
+      return instanceIdentifierPathArguments_;
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathArgumentsOrBuilder() {
+      return instanceIdentifierPathArguments_;
+    }
+
+    // required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;
+    public static final int NORMALIZEDNODE_FIELD_NUMBER = 2;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node normalizedNode_;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    public boolean hasNormalizedNode() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode() {
+      return normalizedNode_;
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder() {
+      return normalizedNode_;
+    }
+
+    private void initFields() {
+      instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+      normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasInstanceIdentifierPathArguments()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasNormalizedNode()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!getInstanceIdentifierPathArguments().isInitialized()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!getNormalizedNode().isInitialized()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeMessage(1, instanceIdentifierPathArguments_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeMessage(2, normalizedNode_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, instanceIdentifierPathArguments_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, normalizedNode_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.WriteData}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_WriteData_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_WriteData_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getInstanceIdentifierPathArgumentsFieldBuilder();
+          getNormalizedNodeFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+        } else {
+          normalizedNodeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_WriteData_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          result.instanceIdentifierPathArguments_ = instanceIdentifierPathArguments_;
+        } else {
+          result.instanceIdentifierPathArguments_ = instanceIdentifierPathArgumentsBuilder_.build();
+        }
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        if (normalizedNodeBuilder_ == null) {
+          result.normalizedNode_ = normalizedNode_;
+        } else {
+          result.normalizedNode_ = normalizedNodeBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData.getDefaultInstance()) return this;
+        if (other.hasInstanceIdentifierPathArguments()) {
+          mergeInstanceIdentifierPathArguments(other.getInstanceIdentifierPathArguments());
+        }
+        if (other.hasNormalizedNode()) {
+          mergeNormalizedNode(other.getNormalizedNode());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasInstanceIdentifierPathArguments()) {
+          
+          return false;
+        }
+        if (!hasNormalizedNode()) {
+          
+          return false;
+        }
+        if (!getInstanceIdentifierPathArguments().isInitialized()) {
+          
+          return false;
+        }
+        if (!getNormalizedNode().isInitialized()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteData) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> instanceIdentifierPathArgumentsBuilder_;
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public boolean hasInstanceIdentifierPathArguments() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPathArguments() {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          return instanceIdentifierPathArguments_;
+        } else {
+          return instanceIdentifierPathArgumentsBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder setInstanceIdentifierPathArguments(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          instanceIdentifierPathArguments_ = value;
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder setInstanceIdentifierPathArguments(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder builderForValue) {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArguments_ = builderForValue.build();
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder mergeInstanceIdentifierPathArguments(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+              instanceIdentifierPathArguments_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance()) {
+            instanceIdentifierPathArguments_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.newBuilder(instanceIdentifierPathArguments_).mergeFrom(value).buildPartial();
+          } else {
+            instanceIdentifierPathArguments_ = value;
+          }
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder clearInstanceIdentifierPathArguments() {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder getInstanceIdentifierPathArgumentsBuilder() {
+        bitField0_ |= 0x00000001;
+        onChanged();
+        return getInstanceIdentifierPathArgumentsFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathArgumentsOrBuilder() {
+        if (instanceIdentifierPathArgumentsBuilder_ != null) {
+          return instanceIdentifierPathArgumentsBuilder_.getMessageOrBuilder();
+        } else {
+          return instanceIdentifierPathArguments_;
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> 
+          getInstanceIdentifierPathArgumentsFieldBuilder() {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArgumentsBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder>(
+                  instanceIdentifierPathArguments_,
+                  getParentForChildren(),
+                  isClean());
+          instanceIdentifierPathArguments_ = null;
+        }
+        return instanceIdentifierPathArgumentsBuilder_;
+      }
+
+      // required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> normalizedNodeBuilder_;
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public boolean hasNormalizedNode() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode() {
+        if (normalizedNodeBuilder_ == null) {
+          return normalizedNode_;
+        } else {
+          return normalizedNodeBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder setNormalizedNode(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (normalizedNodeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          normalizedNode_ = value;
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder setNormalizedNode(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder builderForValue) {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = builderForValue.build();
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder mergeNormalizedNode(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (normalizedNodeBuilder_ == null) {
+          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+              normalizedNode_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance()) {
+            normalizedNode_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.newBuilder(normalizedNode_).mergeFrom(value).buildPartial();
+          } else {
+            normalizedNode_ = value;
+          }
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder clearNormalizedNode() {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder getNormalizedNodeBuilder() {
+        bitField0_ |= 0x00000002;
+        onChanged();
+        return getNormalizedNodeFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder() {
+        if (normalizedNodeBuilder_ != null) {
+          return normalizedNodeBuilder_.getMessageOrBuilder();
+        } else {
+          return normalizedNode_;
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> 
+          getNormalizedNodeFieldBuilder() {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNodeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder>(
+                  normalizedNode_,
+                  getParentForChildren(),
+                  isClean());
+          normalizedNode_ = null;
+        }
+        return normalizedNodeBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.WriteData)
+    }
+
+    static {
+      defaultInstance = new WriteData(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.WriteData)
+  }
+
+  public interface WriteDataReplyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.WriteDataReply}
+   */
+  public static final class WriteDataReply extends
+      com.google.protobuf.GeneratedMessage
+      implements WriteDataReplyOrBuilder {
+    // Use WriteDataReply.newBuilder() to construct.
+    private WriteDataReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private WriteDataReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final WriteDataReply defaultInstance;
+    public static WriteDataReply getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public WriteDataReply getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private WriteDataReply(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_WriteDataReply_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_WriteDataReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<WriteDataReply> PARSER =
+        new com.google.protobuf.AbstractParser<WriteDataReply>() {
+      public WriteDataReply parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new WriteDataReply(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<WriteDataReply> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.WriteDataReply}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReplyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_WriteDataReply_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_WriteDataReply_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_WriteDataReply_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.WriteDataReply) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.WriteDataReply)
+    }
+
+    static {
+      defaultInstance = new WriteDataReply(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.WriteDataReply)
+  }
+
+  public interface MergeDataOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    boolean hasInstanceIdentifierPathArguments();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPathArguments();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathArgumentsOrBuilder();
+
+    // required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    boolean hasNormalizedNode();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode();
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder();
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.MergeData}
+   */
+  public static final class MergeData extends
+      com.google.protobuf.GeneratedMessage
+      implements MergeDataOrBuilder {
+    // Use MergeData.newBuilder() to construct.
+    private MergeData(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private MergeData(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final MergeData defaultInstance;
+    public static MergeData getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public MergeData getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private MergeData(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+                subBuilder = instanceIdentifierPathArguments_.toBuilder();
+              }
+              instanceIdentifierPathArguments_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(instanceIdentifierPathArguments_);
+                instanceIdentifierPathArguments_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000001;
+              break;
+            }
+            case 18: {
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+                subBuilder = normalizedNode_.toBuilder();
+              }
+              normalizedNode_ = input.readMessage(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(normalizedNode_);
+                normalizedNode_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000002;
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_MergeData_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_MergeData_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<MergeData> PARSER =
+        new com.google.protobuf.AbstractParser<MergeData>() {
+      public MergeData parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new MergeData(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<MergeData> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;
+    public static final int INSTANCEIDENTIFIERPATHARGUMENTS_FIELD_NUMBER = 1;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier instanceIdentifierPathArguments_;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    public boolean hasInstanceIdentifierPathArguments() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPathArguments() {
+      return instanceIdentifierPathArguments_;
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathArgumentsOrBuilder() {
+      return instanceIdentifierPathArguments_;
+    }
+
+    // required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;
+    public static final int NORMALIZEDNODE_FIELD_NUMBER = 2;
+    private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node normalizedNode_;
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    public boolean hasNormalizedNode() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode() {
+      return normalizedNode_;
+    }
+    /**
+     * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+     */
+    public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder() {
+      return normalizedNode_;
+    }
+
+    private void initFields() {
+      instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+      normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasInstanceIdentifierPathArguments()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasNormalizedNode()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!getInstanceIdentifierPathArguments().isInitialized()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!getNormalizedNode().isInitialized()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeMessage(1, instanceIdentifierPathArguments_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeMessage(2, normalizedNode_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, instanceIdentifierPathArguments_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, normalizedNode_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.MergeData}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_MergeData_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_MergeData_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getInstanceIdentifierPathArgumentsFieldBuilder();
+          getNormalizedNodeFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+        } else {
+          normalizedNodeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_MergeData_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          result.instanceIdentifierPathArguments_ = instanceIdentifierPathArguments_;
+        } else {
+          result.instanceIdentifierPathArguments_ = instanceIdentifierPathArgumentsBuilder_.build();
+        }
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        if (normalizedNodeBuilder_ == null) {
+          result.normalizedNode_ = normalizedNode_;
+        } else {
+          result.normalizedNode_ = normalizedNodeBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData.getDefaultInstance()) return this;
+        if (other.hasInstanceIdentifierPathArguments()) {
+          mergeInstanceIdentifierPathArguments(other.getInstanceIdentifierPathArguments());
+        }
+        if (other.hasNormalizedNode()) {
+          mergeNormalizedNode(other.getNormalizedNode());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasInstanceIdentifierPathArguments()) {
+          
+          return false;
+        }
+        if (!hasNormalizedNode()) {
+          
+          return false;
+        }
+        if (!getInstanceIdentifierPathArguments().isInitialized()) {
+          
+          return false;
+        }
+        if (!getNormalizedNode().isInitialized()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeData) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> instanceIdentifierPathArgumentsBuilder_;
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public boolean hasInstanceIdentifierPathArguments() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier getInstanceIdentifierPathArguments() {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          return instanceIdentifierPathArguments_;
+        } else {
+          return instanceIdentifierPathArgumentsBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder setInstanceIdentifierPathArguments(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          instanceIdentifierPathArguments_ = value;
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder setInstanceIdentifierPathArguments(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder builderForValue) {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArguments_ = builderForValue.build();
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder mergeInstanceIdentifierPathArguments(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier value) {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+              instanceIdentifierPathArguments_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance()) {
+            instanceIdentifierPathArguments_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.newBuilder(instanceIdentifierPathArguments_).mergeFrom(value).buildPartial();
+          } else {
+            instanceIdentifierPathArguments_ = value;
+          }
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public Builder clearInstanceIdentifierPathArguments() {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArguments_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.getDefaultInstance();
+          onChanged();
+        } else {
+          instanceIdentifierPathArgumentsBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder getInstanceIdentifierPathArgumentsBuilder() {
+        bitField0_ |= 0x00000001;
+        onChanged();
+        return getInstanceIdentifierPathArgumentsFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder getInstanceIdentifierPathArgumentsOrBuilder() {
+        if (instanceIdentifierPathArgumentsBuilder_ != null) {
+          return instanceIdentifierPathArgumentsBuilder_.getMessageOrBuilder();
+        } else {
+          return instanceIdentifierPathArguments_;
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.InstanceIdentifier instanceIdentifierPathArguments = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder> 
+          getInstanceIdentifierPathArgumentsFieldBuilder() {
+        if (instanceIdentifierPathArgumentsBuilder_ == null) {
+          instanceIdentifierPathArgumentsBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifier.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.InstanceIdentifierOrBuilder>(
+                  instanceIdentifierPathArguments_,
+                  getParentForChildren(),
+                  isClean());
+          instanceIdentifierPathArguments_ = null;
+        }
+        return instanceIdentifierPathArgumentsBuilder_;
+      }
+
+      // required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;
+      private org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> normalizedNodeBuilder_;
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public boolean hasNormalizedNode() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node getNormalizedNode() {
+        if (normalizedNodeBuilder_ == null) {
+          return normalizedNode_;
+        } else {
+          return normalizedNodeBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder setNormalizedNode(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (normalizedNodeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          normalizedNode_ = value;
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder setNormalizedNode(
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder builderForValue) {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = builderForValue.build();
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder mergeNormalizedNode(org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node value) {
+        if (normalizedNodeBuilder_ == null) {
+          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+              normalizedNode_ != org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance()) {
+            normalizedNode_ =
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.newBuilder(normalizedNode_).mergeFrom(value).buildPartial();
+          } else {
+            normalizedNode_ = value;
+          }
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public Builder clearNormalizedNode() {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNode_ = org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.getDefaultInstance();
+          onChanged();
+        } else {
+          normalizedNodeBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder getNormalizedNodeBuilder() {
+        bitField0_ |= 0x00000002;
+        onChanged();
+        return getNormalizedNodeFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      public org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder getNormalizedNodeOrBuilder() {
+        if (normalizedNodeBuilder_ != null) {
+          return normalizedNodeBuilder_.getMessageOrBuilder();
+        } else {
+          return normalizedNode_;
+        }
+      }
+      /**
+       * <code>required .org.opendaylight.controller.mdsal.Node normalizedNode = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder> 
+          getNormalizedNodeFieldBuilder() {
+        if (normalizedNodeBuilder_ == null) {
+          normalizedNodeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node.Builder, org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.NodeOrBuilder>(
+                  normalizedNode_,
+                  getParentForChildren(),
+                  isClean());
+          normalizedNode_ = null;
+        }
+        return normalizedNodeBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.MergeData)
+    }
+
+    static {
+      defaultInstance = new MergeData(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.MergeData)
+  }
+
+  public interface MergeDataReplyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.opendaylight.controller.mdsal.MergeDataReply}
+   */
+  public static final class MergeDataReply extends
+      com.google.protobuf.GeneratedMessage
+      implements MergeDataReplyOrBuilder {
+    // Use MergeDataReply.newBuilder() to construct.
+    private MergeDataReply(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private MergeDataReply(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final MergeDataReply defaultInstance;
+    public static MergeDataReply getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public MergeDataReply getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private MergeDataReply(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_MergeDataReply_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_MergeDataReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<MergeDataReply> PARSER =
+        new com.google.protobuf.AbstractParser<MergeDataReply>() {
+      public MergeDataReply parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new MergeDataReply(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<MergeDataReply> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.opendaylight.controller.mdsal.MergeDataReply}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReplyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_MergeDataReply_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_MergeDataReply_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply.class, org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply.Builder.class);
+      }
+
+      // Construct using org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.internal_static_org_opendaylight_controller_mdsal_MergeDataReply_descriptor;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply getDefaultInstanceForType() {
+        return org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply.getDefaultInstance();
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply build() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply buildPartial() {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply result = new org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply) {
+          return mergeFrom((org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply other) {
+        if (other == org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages.MergeDataReply) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.mdsal.MergeDataReply)
+    }
+
+    static {
+      defaultInstance = new MergeDataReply(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.opendaylight.controller.mdsal.MergeDataReply)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_CloseTransaction_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_CloseTransaction_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_CreateTransaction_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_CreateTransaction_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_DeleteData_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_DeleteData_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_ReadData_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_ReadData_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_ReadDataReply_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_ReadDataReply_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_WriteData_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_WriteData_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_WriteDataReply_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_WriteDataReply_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_MergeData_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_MergeData_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_opendaylight_controller_mdsal_MergeDataReply_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_opendaylight_controller_mdsal_MergeDataReply_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\026ShardTransaction.proto\022!org.opendaylig" +
+      "ht.controller.mdsal\032\014Common.proto\"\022\n\020Clo" +
+      "seTransaction\"\027\n\025CloseTransactionReply\"*" +
+      "\n\021CreateTransaction\022\025\n\rtransactionId\030\001 \002" +
+      "(\t\"M\n\026CreateTransactionReply\022\034\n\024transact" +
+      "ionActorPath\030\001 \002(\t\022\025\n\rtransactionId\030\002 \002(" +
+      "\t\"\022\n\020ReadyTransaction\"*\n\025ReadyTransactio" +
+      "nReply\022\021\n\tactorPath\030\001 \002(\t\"l\n\nDeleteData\022" +
+      "^\n\037instanceIdentifierPathArguments\030\001 \002(\013" +
+      "25.org.opendaylight.controller.mdsal.Ins",
+      "tanceIdentifier\"\021\n\017DeleteDataReply\"j\n\010Re" +
+      "adData\022^\n\037instanceIdentifierPathArgument" +
+      "s\030\001 \002(\01325.org.opendaylight.controller.md" +
+      "sal.InstanceIdentifier\"P\n\rReadDataReply\022" +
+      "?\n\016normalizedNode\030\001 \001(\0132\'.org.opendaylig" +
+      "ht.controller.mdsal.Node\"\254\001\n\tWriteData\022^" +
+      "\n\037instanceIdentifierPathArguments\030\001 \002(\0132" +
+      "5.org.opendaylight.controller.mdsal.Inst" +
+      "anceIdentifier\022?\n\016normalizedNode\030\002 \002(\0132\'" +
+      ".org.opendaylight.controller.mdsal.Node\"",
+      "\020\n\016WriteDataReply\"\254\001\n\tMergeData\022^\n\037insta" +
+      "nceIdentifierPathArguments\030\001 \002(\01325.org.o" +
+      "pendaylight.controller.mdsal.InstanceIde" +
+      "ntifier\022?\n\016normalizedNode\030\002 \002(\0132\'.org.op" +
+      "endaylight.controller.mdsal.Node\"\020\n\016Merg" +
+      "eDataReplyBV\n:org.opendaylight.controlle" +
+      "r.protobuff.messages.transactionB\030ShardT" +
+      "ransactionMessages"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_org_opendaylight_controller_mdsal_CloseTransaction_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_org_opendaylight_controller_mdsal_CloseTransaction_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_CloseTransaction_descriptor,
+              new java.lang.String[] { });
+          internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_descriptor =
+            getDescriptor().getMessageTypes().get(1);
+          internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_CloseTransactionReply_descriptor,
+              new java.lang.String[] { });
+          internal_static_org_opendaylight_controller_mdsal_CreateTransaction_descriptor =
+            getDescriptor().getMessageTypes().get(2);
+          internal_static_org_opendaylight_controller_mdsal_CreateTransaction_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_CreateTransaction_descriptor,
+              new java.lang.String[] { "TransactionId", });
+          internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_descriptor =
+            getDescriptor().getMessageTypes().get(3);
+          internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_CreateTransactionReply_descriptor,
+              new java.lang.String[] { "TransactionActorPath", "TransactionId", });
+          internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_descriptor =
+            getDescriptor().getMessageTypes().get(4);
+          internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_ReadyTransaction_descriptor,
+              new java.lang.String[] { });
+          internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_descriptor =
+            getDescriptor().getMessageTypes().get(5);
+          internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_ReadyTransactionReply_descriptor,
+              new java.lang.String[] { "ActorPath", });
+          internal_static_org_opendaylight_controller_mdsal_DeleteData_descriptor =
+            getDescriptor().getMessageTypes().get(6);
+          internal_static_org_opendaylight_controller_mdsal_DeleteData_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_DeleteData_descriptor,
+              new java.lang.String[] { "InstanceIdentifierPathArguments", });
+          internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_descriptor =
+            getDescriptor().getMessageTypes().get(7);
+          internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_DeleteDataReply_descriptor,
+              new java.lang.String[] { });
+          internal_static_org_opendaylight_controller_mdsal_ReadData_descriptor =
+            getDescriptor().getMessageTypes().get(8);
+          internal_static_org_opendaylight_controller_mdsal_ReadData_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_ReadData_descriptor,
+              new java.lang.String[] { "InstanceIdentifierPathArguments", });
+          internal_static_org_opendaylight_controller_mdsal_ReadDataReply_descriptor =
+            getDescriptor().getMessageTypes().get(9);
+          internal_static_org_opendaylight_controller_mdsal_ReadDataReply_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_ReadDataReply_descriptor,
+              new java.lang.String[] { "NormalizedNode", });
+          internal_static_org_opendaylight_controller_mdsal_WriteData_descriptor =
+            getDescriptor().getMessageTypes().get(10);
+          internal_static_org_opendaylight_controller_mdsal_WriteData_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_WriteData_descriptor,
+              new java.lang.String[] { "InstanceIdentifierPathArguments", "NormalizedNode", });
+          internal_static_org_opendaylight_controller_mdsal_WriteDataReply_descriptor =
+            getDescriptor().getMessageTypes().get(11);
+          internal_static_org_opendaylight_controller_mdsal_WriteDataReply_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_WriteDataReply_descriptor,
+              new java.lang.String[] { });
+          internal_static_org_opendaylight_controller_mdsal_MergeData_descriptor =
+            getDescriptor().getMessageTypes().get(12);
+          internal_static_org_opendaylight_controller_mdsal_MergeData_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_MergeData_descriptor,
+              new java.lang.String[] { "InstanceIdentifierPathArguments", "NormalizedNode", });
+          internal_static_org_opendaylight_controller_mdsal_MergeDataReply_descriptor =
+            getDescriptor().getMessageTypes().get(13);
+          internal_static_org_opendaylight_controller_mdsal_MergeDataReply_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_opendaylight_controller_mdsal_MergeDataReply_descriptor,
+              new java.lang.String[] { });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.getDescriptor(),
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/Cohort.proto b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/Cohort.proto
new file mode 100644 (file)
index 0000000..dab6413
--- /dev/null
@@ -0,0 +1,37 @@
+package org.opendaylight.controller.mdsal;
+
+option java_package = "org.opendaylight.controller.protobuff.messages.cohort3pc";
+option java_outer_classname = "ThreePhaseCommitCohortMessages";
+
+
+message CanCommitTransaction{
+
+}
+
+message CanCommitTransactionReply{
+  required bool canCommit = 1;
+
+}
+
+message AbortTransaction{
+
+}
+
+message AbortTransactionReply {
+
+}
+
+message CommitTransaction{
+
+}
+
+message CommitTransactionReply{
+
+}
+
+message PreCommitTransaction{
+
+}
+message PreCommitTransactionReply{
+
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/Common.proto b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/Common.proto
new file mode 100644 (file)
index 0000000..59d78dd
--- /dev/null
@@ -0,0 +1,52 @@
+package org.opendaylight.controller.mdsal;
+
+option java_package = "org.opendaylight.controller.protobuff.messages.common";
+option java_outer_classname = "NormalizedNodeMessages";
+
+
+message Attribute{
+  required string name =1;
+  optional string value=2;
+  optional string type=3;
+}
+
+message QName {
+    required string value=1;
+}
+
+message PathArgument {
+  required string value=1;
+  optional string type=2; //NodeIdentifier, NodeWithValue, NodeIdentifierWithPredicates
+  optional QName nodeType=3;
+  repeated Attribute attributes=4;
+
+}
+
+message InstanceIdentifier {
+  repeated PathArgument arguments=1;
+}
+
+message Node{
+  optional string path = 1;
+  optional string type = 2;
+  repeated Attribute attributes = 3;
+  repeated Node child=4;
+  optional string value = 5;
+  optional string valueType = 6;
+  repeated string bitsValue = 7;
+  optional InstanceIdentifier instanceIdentifierValue = 8;
+}
+
+message Container{
+  required string parentPath =1 ;
+  optional Node normalizedNode=2;
+}
+
+message NodeMapEntry{
+  required InstanceIdentifier instanceIdentifierPath =1;
+  optional Node normalizedNode=2;
+}
+
+message NodeMap{
+repeated NodeMapEntry mapEntries=1;
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/CompositeModificationPayload.proto b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/CompositeModificationPayload.proto
new file mode 100644 (file)
index 0000000..b571cd2
--- /dev/null
@@ -0,0 +1,11 @@
+package org.opendaylight.controller.mdsal;
+
+import "AppendEntriesMessages.proto";
+import "Common.proto";
+import "Persistent.proto";
+
+extend org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload {
+    optional CompositeModification modification=2;
+}
+
+
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/DataChangeListener.proto b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/DataChangeListener.proto
new file mode 100644 (file)
index 0000000..e4ba800
--- /dev/null
@@ -0,0 +1,19 @@
+package org.opendaylight.controller.mdsal;
+
+import "Common.proto";
+
+option java_package = "org.opendaylight.controller.protobuff.messages.datachange.notification";
+option java_outer_classname = "DataChangeListenerMessages";
+
+message DataChanged {
+  optional Node originalSubTree = 1;
+  optional Node updatedSubTree = 2;
+  optional NodeMap originalData =3;
+  optional NodeMap updatedData =4;
+  optional NodeMap createdData =5;
+  repeated InstanceIdentifier removedPaths  =6;
+}
+
+message DataChangedReply{
+
+}
index ec8046f5574d84c65b315cd4e9096d4002ce7726..3342a1364abba61a87dae70190859d7908c4e1d0 100644 (file)
@@ -1,13 +1,40 @@
 package org.opendaylight.controller.mdsal;
 
-option java_package = "org.opendaylight.controller.cluster.datastore.registration";
+import "Common.proto";
+
+option java_package = "org.opendaylight.controller.protobuff.messages.registration";
 option java_outer_classname = "ListenerRegistrationMessages";
 
-message Close {
+/** used when a listener needs to be unregistered*/
+message CloseDataChangeListenerRegistration {
+
+}
+/** reply to the CloseDataChangeListenerRegistration request*/
+message CloseDataChangeListenerRegistrationReply{
 
 }
 
-message CloseReply{
+/**
+ * When registering a listener at particular level of tree
+ * identified by instanceIdentifierPath.
+ * dataChangeListenerActorPath is path to actor that will
+ * receive the change event
+ * scope is the data change scope like BASE,ONE and SUBTREE
+ * defined in AsyncDataBroker.DataChangeScope
+ */
+
+message RegisterChangeListener{
+required InstanceIdentifier instanceIdentifierPath=1;
+required string dataChangeListenerActorPath=2;
+required int32 dataChangeScope=3;
+}
+/**
+* This is the reply for the RegisterChangeListener message
+* It contains the listenerRegistration actor path
+* that can be used to unregister the listener
+*/
+message RegisterChangeListenerReply{
+required string listenerRegistrationPath=1;
 
 }
 
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/Persistent.proto b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/Persistent.proto
new file mode 100644 (file)
index 0000000..8e83449
--- /dev/null
@@ -0,0 +1,20 @@
+package org.opendaylight.controller.mdsal;
+
+import "Common.proto";
+import "AppendEntriesMessages.proto";
+
+option java_package = "org.opendaylight.controller.protobuff.messages.persistent";
+option java_outer_classname = "PersistentMessages";
+
+
+message Modification {
+    required string type=1;
+    required InstanceIdentifier path=2;
+    optional Node data=3;
+}
+
+
+message CompositeModification {
+    repeated Modification modification=1;
+}
+
index 31e8c58b13fcf95db1e34826be246f2a15d3992a..abd6fcc109447be6cdb9360f3ac2a12ddef2af7e 100644 (file)
@@ -1,6 +1,6 @@
 package org.opendaylight.controller.mdsal;
 
-option java_package = "org.opendaylight.controller.cluster.datastore.shard";
+option java_package = "org.opendaylight.controller.protobuff.messages.shard";
 option java_outer_classname = "ShardManagerMessages";
 
 message FindPrimary {
@@ -8,7 +8,9 @@ message FindPrimary {
 }
 
 message PrimaryFound {
+  required string primaryPath =1;
 }
 
 message PrimaryNotFound {
+  required string shardName =1;
 }
index 0b260c807175fffed3551983349af063da672bfe..9684b7d72f57679ad069f31320bf00f0e989380c 100644 (file)
@@ -1,6 +1,8 @@
 package org.opendaylight.controller.mdsal;
 
-option java_package = "org.opendaylight.controller.cluster.datastore.transaction";
+import "Common.proto";
+
+option java_package = "org.opendaylight.controller.protobuff.messages.transaction";
 option java_outer_classname = "ShardTransactionMessages";
 
 message CloseTransaction{
@@ -11,11 +13,12 @@ message CloseTransactionReply{
 }
 
 message CreateTransaction{
-
+  required string transactionId = 1;
 }
 
 message CreateTransactionReply{
-required string transactionPath = 1;
+required string transactionActorPath = 1;
+required string transactionId = 2;
 
 }
 
@@ -28,12 +31,36 @@ required string actorPath = 1;
 }
 
 message DeleteData {
-required string instanceIdentifierPath = 1;
+required InstanceIdentifier instanceIdentifierPathArguments = 1;
 }
 
 message DeleteDataReply{
 
 }
 message ReadData {
-required string intanceIdentifier=1;
-}
\ No newline at end of file
+required InstanceIdentifier instanceIdentifierPathArguments=1;
+}
+
+message ReadDataReply{
+  optional Node normalizedNode=1;
+}
+
+message WriteData {
+ required InstanceIdentifier instanceIdentifierPathArguments = 1;
+required Node normalizedNode =2;
+
+}
+
+message WriteDataReply{
+
+}
+
+message MergeData {
+ required InstanceIdentifier instanceIdentifierPathArguments = 1;
+required Node normalizedNode =2;
+
+}
+
+message MergeDataReply{
+
+}
index 73a9aa11c800c5383910644b815024321fada379..42f87cbda6dbd661b395efccd5ae9e729420759f 100644 (file)
@@ -1,6 +1,6 @@
 package org.opendaylight.controller.mdsal;
 
-option java_package = "org.opendaylight.controller.cluster.datastore.transaction";
+option java_package = "org.opendaylight.controller.protobuff.messages.transaction";
 option java_outer_classname = "ShardTransactionChainMessages";
 
 message CloseTransactionChain {
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/SimpleNormalizedNode.proto b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/resources/SimpleNormalizedNode.proto
new file mode 100644 (file)
index 0000000..e0b21d3
--- /dev/null
@@ -0,0 +1,10 @@
+package org.opendaylight.controller.mdsal;
+
+option java_package = "org.opendaylight.controller.protobuff.messages.common";
+option java_outer_classname = "SimpleNormalizedNodeMessage";
+
+message NormalizedNodeXml {
+  required string nodeIdentifier=1;
+  required string xmlString = 2;
+}
+
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/messages/ShardManagerMessagesTest.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/messages/ShardManagerMessagesTest.java
deleted file mode 100644 (file)
index f57cfc9..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.opendaylight.controller.cluster.datastore.messages;
-
-/**
- * This test case is present to ensure that if others have
- * used proper version of protocol buffer.
- *
- * If a different version of protocol buffer is used then it would
- * generate different java sources and would result in
- * breaking of this test case.
- *
- * @author: syedbahm
- * Date: 6/20/14
- *
- */
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.opendaylight.controller.cluster.datastore.shard.ShardManagerMessages;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-
-public class ShardManagerMessagesTest {
-
-  @Test
-  public void verifySerialization()throws Exception{
-   ShardManagerMessages.FindPrimary.Builder builder = ShardManagerMessages.FindPrimary.newBuilder();
-   builder.setShardName("Inventory");
-   File testFile = new File("./test");
-   FileOutputStream output = new FileOutputStream(testFile);
-   builder.build().writeTo(output);
-   output.close();
-
-   //Here we will read the same and check we got back what we had saved
-    ShardManagerMessages.FindPrimary findPrimary
-             =  ShardManagerMessages.FindPrimary.parseFrom(new FileInputStream(testFile));
-    Assert.assertEquals("Inventory", findPrimary.getShardName());
-
-    testFile.delete();
-
-  }
-}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/node/NormalizedNodeToNodeCodecTest.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/node/NormalizedNodeToNodeCodecTest.java
new file mode 100644 (file)
index 0000000..4ccbc97
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.node;
+
+import junit.framework.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.node.utils.NodeIdentifierFactory;
+import org.opendaylight.controller.cluster.datastore.node.utils.NormalizedNodeGetter;
+import org.opendaylight.controller.cluster.datastore.node.utils.NormalizedNodeNavigator;
+import org.opendaylight.controller.cluster.datastore.util.TestModel;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Container;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+
+public class NormalizedNodeToNodeCodecTest {
+
+
+
+    private SchemaContext schemaContext;
+
+    @Before
+    public void setUp(){
+        schemaContext = TestModel.createTestContext();
+        assertNotNull("Schema context must not be null.", schemaContext);
+    }
+
+    private YangInstanceIdentifier instanceIdentifierFromString(String s){
+
+        String[] ids = s.split("/");
+
+        List<YangInstanceIdentifier.PathArgument> pathArguments = new ArrayList<>();
+        for(String nodeId : ids){
+            if(!"".equals(nodeId)) {
+                pathArguments.add(NodeIdentifierFactory.getArgument(nodeId));
+            }
+        }
+        final YangInstanceIdentifier instanceIdentifier = YangInstanceIdentifier.create(pathArguments);
+        return instanceIdentifier;
+    }
+
+
+    @Test
+    public void testNormalizeNodeAttributesToProtoBuffNode(){
+        final NormalizedNode<?, ?> documentOne = TestModel.createTestContainer();
+        String id = "/(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)test" +
+            "/(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)outer-list" +
+            "/(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)outer-list[{(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)id=2}]" +
+            "/(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)id";
+
+        NormalizedNodeGetter normalizedNodeGetter = new NormalizedNodeGetter(id);
+        new NormalizedNodeNavigator(normalizedNodeGetter).navigate(
+            YangInstanceIdentifier.builder().build().toString(), documentOne);
+
+        // Validate the value of id can be retrieved from the normalized node
+        NormalizedNode output = normalizedNodeGetter.getOutput();
+        assertNotNull(output);
+
+
+      NormalizedNodeToNodeCodec codec = new NormalizedNodeToNodeCodec(schemaContext);
+      Container container = codec.encode(instanceIdentifierFromString(id),output);
+
+       assertNotNull(container);
+       assertEquals(id, container.getParentPath()+"/"+container.getNormalizedNode().getPath()) ;
+
+      // Decode the normalized node from the ProtocolBuffer form
+      //first get the node representation of normalized node
+      final Node node = container.getNormalizedNode();
+
+      NormalizedNode<?,?> normalizedNode = codec.decode(instanceIdentifierFromString(id),node);
+
+      assertEquals(normalizedNode.getValue().toString(),output.getValue().toString());
+    }
+
+    @Test
+    public void testThatANormalizedNodeToProtoBuffNodeEncodeDecode() throws Exception {
+        final NormalizedNode<?, ?> documentOne = TestModel.createTestContainer();
+
+        final NormalizedNodeToNodeCodec normalizedNodeToNodeCodec = new NormalizedNodeToNodeCodec(schemaContext);
+
+        Container container = normalizedNodeToNodeCodec.encode(YangInstanceIdentifier.builder().build(), documentOne);
+
+
+        final NormalizedNode<?, ?> decode = normalizedNodeToNodeCodec.decode(instanceIdentifierFromString("/(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)test"),container.getNormalizedNode());
+        assertNotNull(decode != null);
+
+        //let us ensure that the return decode normalized node encode returns same container
+        Container containerResult =  normalizedNodeToNodeCodec.encode(YangInstanceIdentifier.builder().build(), decode);
+
+        assertEquals(container.getParentPath(),containerResult.getParentPath());
+        assertEquals(container.getNormalizedNode().getChildCount(),container.getNormalizedNode().getChildCount());
+
+        Assert.assertEquals(containerResult.getNormalizedNode().getChildCount(),container.getNormalizedNode().getChildCount());
+
+        //check first level children are proper
+        List<Node>childrenResult = containerResult.getNormalizedNode().getChildList();
+        List<Node>childrenOriginal = container.getNormalizedNode().getChildList();
+
+        System.out.println("-------------------------------------------------");
+
+        System.out.println(childrenOriginal.toString());
+
+        System.out.println("-------------------------------------------------");
+
+        System.out.println(childrenResult.toString());
+
+       boolean bFound;
+        for(Node resultChild: childrenResult){
+           bFound = false;
+          for(Node originalChild:childrenOriginal){
+            if(originalChild.getPath().equals(resultChild.getPath())
+                && resultChild.getType().equals(resultChild.getType())){
+               bFound=true;
+               break;
+            }
+          }
+          Assert.assertTrue(bFound);
+        }
+
+    }
+
+    @Test
+    public void addAugmentations(){
+        String stringId = "/(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)test" +
+            "/(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)augmented-list" +
+            "/(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)augmented-list[{(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)id=1}]";
+
+        YangInstanceIdentifier identifier = instanceIdentifierFromString(stringId);
+
+        MapEntryNode uno = TestModel.createAugmentedListEntry(1, "Uno");
+
+        NormalizedNodeToNodeCodec codec =
+            new NormalizedNodeToNodeCodec(schemaContext);
+
+        Container encode = codec
+            .encode(identifier, uno);
+
+        System.out.println(encode.getNormalizedNode());
+
+        codec.decode(identifier, encode.getNormalizedNode());
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierFactoryTest.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/NodeIdentifierFactoryTest.java
new file mode 100644 (file)
index 0000000..4b0bde8
--- /dev/null
@@ -0,0 +1,20 @@
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public class NodeIdentifierFactoryTest {
+
+    @Test
+    public void validateAugmentationIdentifier(){
+        YangInstanceIdentifier.PathArgument argument = NodeIdentifierFactory
+            .getArgument(
+                "AugmentationIdentifier{childNames=[(urn:opendaylight:flow:table:statistics?revision=2013-12-15)flow-table-statistics]}");
+
+        Assert.assertTrue(argument instanceof YangInstanceIdentifier.AugmentationIdentifier);
+
+
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/util/InstanceIdentifierUtilsTest.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/util/InstanceIdentifierUtilsTest.java
new file mode 100644 (file)
index 0000000..bb246fb
--- /dev/null
@@ -0,0 +1,141 @@
+package org.opendaylight.controller.cluster.datastore.util;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+public class InstanceIdentifierUtilsTest {
+
+    private static QName TEST_QNAME = QName.create("(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)test");
+    private static QName NODE_WITH_VALUE_QNAME = QName.create("(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)value");
+    private static QName NODE_WITH_PREDICATES_QNAME = QName.create("(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)pred");
+    private static QName NAME_QNAME = QName.create("(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)name");
+
+    @Test
+    public void testSerializationOfNodeIdentifier(){
+        YangInstanceIdentifier.PathArgument p1 =
+            new YangInstanceIdentifier.NodeIdentifier(TEST_QNAME);
+
+        List<YangInstanceIdentifier.PathArgument> arguments = new ArrayList<>();
+
+        arguments.add(p1);
+
+        YangInstanceIdentifier expected = YangInstanceIdentifier.create(arguments);
+
+        NormalizedNodeMessages.InstanceIdentifier instanceIdentifier =
+            InstanceIdentifierUtils.toSerializable(expected);
+
+        YangInstanceIdentifier actual =
+            InstanceIdentifierUtils.fromSerializable(instanceIdentifier);
+
+
+        Assert.assertEquals(expected.getLastPathArgument(),
+            actual.getLastPathArgument());
+
+
+    }
+
+    @Test
+    public void testSerializationOfNodeWithValue(){
+
+        withValue((short) 1);
+        withValue((long) 2);
+        withValue(3);
+        withValue(true);
+
+    }
+
+    private void withValue(Object value){
+        YangInstanceIdentifier.PathArgument p1 =
+            new YangInstanceIdentifier.NodeIdentifier(TEST_QNAME);
+
+        YangInstanceIdentifier.PathArgument p2 =
+            new YangInstanceIdentifier.NodeWithValue(NODE_WITH_VALUE_QNAME, value);
+
+
+        List<YangInstanceIdentifier.PathArgument> arguments = new ArrayList<>();
+
+        arguments.add(p1);
+        arguments.add(p2);
+
+        YangInstanceIdentifier expected = YangInstanceIdentifier.create(arguments);
+
+        NormalizedNodeMessages.InstanceIdentifier instanceIdentifier =
+            InstanceIdentifierUtils.toSerializable(expected);
+
+        YangInstanceIdentifier actual =
+            InstanceIdentifierUtils.fromSerializable(instanceIdentifier);
+
+
+        Assert.assertEquals(expected.getLastPathArgument(),
+            actual.getLastPathArgument());
+    }
+
+
+    @Test
+    public void testSerializationOfNodeIdentifierWithPredicates(){
+
+        withPredicates((short) 1);
+        withPredicates((long) 2);
+        withPredicates(3);
+        withPredicates(true);
+
+    }
+
+    private void withPredicates(Object value){
+        YangInstanceIdentifier.PathArgument p1 =
+            new YangInstanceIdentifier.NodeIdentifier(TEST_QNAME);
+
+        YangInstanceIdentifier.PathArgument p2 =
+            new YangInstanceIdentifier.NodeIdentifierWithPredicates(NODE_WITH_PREDICATES_QNAME, NAME_QNAME, value);
+
+
+        List<YangInstanceIdentifier.PathArgument> arguments = new ArrayList<>();
+
+        arguments.add(p1);
+        arguments.add(p2);
+
+        YangInstanceIdentifier expected = YangInstanceIdentifier.create(arguments);
+
+        NormalizedNodeMessages.InstanceIdentifier instanceIdentifier =
+            InstanceIdentifierUtils.toSerializable(expected);
+
+        YangInstanceIdentifier actual =
+            InstanceIdentifierUtils.fromSerializable(instanceIdentifier);
+
+
+        Assert.assertEquals(expected.getLastPathArgument(),
+            actual.getLastPathArgument());
+    }
+
+    @Test
+    public void testAugmentationIdentifier(){
+        YangInstanceIdentifier.PathArgument p1 =
+            new YangInstanceIdentifier.AugmentationIdentifier(new HashSet(Arrays.asList(TEST_QNAME)));
+
+        List<YangInstanceIdentifier.PathArgument> arguments = new ArrayList<>();
+
+        arguments.add(p1);
+
+        YangInstanceIdentifier expected = YangInstanceIdentifier.create(arguments);
+
+        NormalizedNodeMessages.InstanceIdentifier instanceIdentifier =
+            InstanceIdentifierUtils.toSerializable(expected);
+
+        YangInstanceIdentifier actual =
+            InstanceIdentifierUtils.fromSerializable(instanceIdentifier);
+
+
+        Assert.assertEquals(expected.getLastPathArgument(),
+            actual.getLastPathArgument());
+
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/util/NormalizedNodeXmlConverterTest.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/util/NormalizedNodeXmlConverterTest.java
new file mode 100644 (file)
index 0000000..fb28704
--- /dev/null
@@ -0,0 +1,482 @@
+/*
+ * 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.cluster.datastore.util;
+
+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 org.custommonkey.xmlunit.Diff;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.Test;
+import org.opendaylight.controller.protobuff.messages.common.SimpleNormalizedNodeMessage;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.serializer.DomFromNormalizedNodeSerializerFactory;
+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.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+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.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.URI;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * Two of the testcases in the yangtools/yang-data-impl are leveraged (with  modification) to
+ * create the serialization of NormalizedNode using the ProtocolBuffer
+ *
+ * @syedbahm
+ *
+ */
+
+
+public class NormalizedNodeXmlConverterTest {
+    private static final Logger logger = LoggerFactory
+        .getLogger(NormalizedNodeXmlConverterTest.class);
+    public static final String NAMESPACE =
+        "urn:opendaylight:params:xml:ns:yang:controller:test";
+    private static Date revision;
+    private ContainerNode expectedNode;
+    private ContainerSchemaNode containerNode;
+    private String xmlPath;
+
+    static {
+        try {
+            revision = new SimpleDateFormat("yyyy-MM-dd").parse("2014-03-13");
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static DataSchemaNode getSchemaNode(final SchemaContext context,
+        final String moduleName, final String childNodeName) {
+        for (Module module : context.getModules()) {
+            if (module.getName().equals(moduleName)) {
+                DataSchemaNode found =
+                    findChildNode(module.getChildNodes(), childNodeName);
+                Preconditions.checkState(found != null, "Unable to find %s",
+                    childNodeName);
+                return found;
+            }
+        }
+        throw new IllegalStateException("Unable to find child node "
+            + childNodeName);
+    }
+
+    static DataSchemaNode findChildNode(final Collection<DataSchemaNode> children, final String name) {
+        List<DataNodeContainer> containers = Lists.newArrayList();
+
+        for (DataSchemaNode dataSchemaNode : children) {
+            if (dataSchemaNode.getQName().getLocalName().equals(name)) {
+                return dataSchemaNode;
+            }
+            if (dataSchemaNode instanceof DataNodeContainer) {
+                containers.add((DataNodeContainer) dataSchemaNode);
+            } else if (dataSchemaNode instanceof ChoiceNode) {
+                containers.addAll(((ChoiceNode) dataSchemaNode).getCases());
+            }
+        }
+
+        for (DataNodeContainer container : containers) {
+            DataSchemaNode retVal = findChildNode(container.getChildNodes(), name);
+            if (retVal != null) {
+                return retVal;
+            }
+        }
+
+        return null;
+    }
+
+    public static YangInstanceIdentifier.NodeIdentifier getNodeIdentifier(
+        final String localName) {
+        return new YangInstanceIdentifier.NodeIdentifier(QName.create(
+            URI.create(NAMESPACE), revision, localName));
+    }
+
+    public static YangInstanceIdentifier.AugmentationIdentifier getAugmentIdentifier(
+        final String... childNames) {
+        Set<QName> qn = Sets.newHashSet();
+
+        for (String childName : childNames) {
+            qn.add(getNodeIdentifier(childName).getNodeType());
+        }
+
+        return new YangInstanceIdentifier.AugmentationIdentifier(qn);
+    }
+
+
+    public static ContainerNode augmentChoiceExpectedNode() {
+
+        DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode> b =
+            Builders.containerBuilder();
+        b.withNodeIdentifier(getNodeIdentifier("container"));
+
+        b.withChild(Builders
+            .choiceBuilder()
+            .withNodeIdentifier(getNodeIdentifier("ch2"))
+            .withChild(
+                Builders.leafBuilder()
+                    .withNodeIdentifier(getNodeIdentifier("c2Leaf")).withValue("2")
+                    .build())
+            .withChild(
+                Builders
+                    .choiceBuilder()
+                    .withNodeIdentifier(getNodeIdentifier("c2DeepChoice"))
+                    .withChild(
+                        Builders
+                            .leafBuilder()
+                            .withNodeIdentifier(
+                                getNodeIdentifier("c2DeepChoiceCase1Leaf2"))
+                            .withValue("2").build()).build()).build());
+
+        b.withChild(Builders
+            .choiceBuilder()
+            .withNodeIdentifier(getNodeIdentifier("ch3"))
+            .withChild(
+                Builders.leafBuilder()
+                    .withNodeIdentifier(getNodeIdentifier("c3Leaf")).withValue("3")
+                    .build()).build());
+
+        b.withChild(Builders
+            .augmentationBuilder()
+            .withNodeIdentifier(getAugmentIdentifier("augLeaf"))
+            .withChild(
+                Builders.leafBuilder()
+                    .withNodeIdentifier(getNodeIdentifier("augLeaf"))
+                    .withValue("augment").build()).build());
+
+        b.withChild(Builders
+            .augmentationBuilder()
+            .withNodeIdentifier(getAugmentIdentifier("ch"))
+            .withChild(
+                Builders
+                    .choiceBuilder()
+                    .withNodeIdentifier(getNodeIdentifier("ch"))
+                    .withChild(
+                        Builders.leafBuilder()
+                            .withNodeIdentifier(getNodeIdentifier("c1Leaf"))
+                            .withValue("1").build())
+                    .withChild(
+                        Builders
+                            .augmentationBuilder()
+                            .withNodeIdentifier(
+                                getAugmentIdentifier("c1Leaf_AnotherAugment",
+                                    "deepChoice"))
+                            .withChild(
+                                Builders
+                                    .leafBuilder()
+                                    .withNodeIdentifier(
+                                        getNodeIdentifier("c1Leaf_AnotherAugment"))
+                                    .withValue("1").build())
+                            .withChild(
+                                Builders
+                                    .choiceBuilder()
+                                    .withNodeIdentifier(
+                                        getNodeIdentifier("deepChoice"))
+                                    .withChild(
+                                        Builders
+                                            .leafBuilder()
+                                            .withNodeIdentifier(
+                                                getNodeIdentifier("deepLeafc1"))
+                                            .withValue("1").build()).build())
+                            .build()).build()).build());
+
+        return b.build();
+    }
+
+
+
+    public void init(final String yangPath, final String xmlPath, final ContainerNode expectedNode)
+        throws Exception {
+        SchemaContext schema = parseTestSchema(yangPath);
+        this.xmlPath = xmlPath;
+        this.containerNode =
+            (ContainerSchemaNode) getSchemaNode(schema, "test", "container");
+        this.expectedNode = expectedNode;
+    }
+
+    SchemaContext parseTestSchema(final String yangPath) throws Exception {
+
+        YangParserImpl yangParserImpl = new YangParserImpl();
+        InputStream stream =
+            NormalizedNodeXmlConverterTest.class.getResourceAsStream(yangPath);
+        ArrayList<InputStream> al = new ArrayList<InputStream>();
+        al.add(stream);
+        Set<Module> modules = yangParserImpl.parseYangModelsFromStreams(al);
+        return yangParserImpl.resolveSchemaContext(modules);
+
+    }
+
+
+    @Test
+    public void testConversionWithAugmentChoice() throws Exception {
+        init("/augment_choice.yang", "/augment_choice.xml",
+            augmentChoiceExpectedNode());
+        Document doc = loadDocument(xmlPath);
+
+        ContainerNode built =
+            DomToNormalizedNodeParserFactory
+                .getInstance(DomUtils.defaultValueCodecProvider())
+                .getContainerNodeParser()
+                .parse(Collections.singletonList(doc.getDocumentElement()),
+                    containerNode);
+
+        if (expectedNode != null) {
+            junit.framework.Assert.assertEquals(expectedNode, built);
+        }
+
+        logger.info("{}", built);
+
+        Iterable<Element> els =
+            DomFromNormalizedNodeSerializerFactory
+                .getInstance(XmlDocumentUtils.getDocument(),
+                    DomUtils.defaultValueCodecProvider())
+                .getContainerNodeSerializer().serialize(containerNode, built);
+
+        Element el = els.iterator().next();
+
+        XMLUnit.setIgnoreWhitespace(true);
+        XMLUnit.setIgnoreComments(true);
+
+        System.out.println(toString(doc.getDocumentElement()));
+        System.out.println(toString(el));
+
+        new Diff(
+            XMLUnit.buildControlDocument(toString(doc.getDocumentElement())),
+            XMLUnit.buildTestDocument(toString(el))).similar();
+    }
+
+    private static ContainerNode listLeafListWithAttributes() {
+        DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode> b =
+            Builders.containerBuilder();
+        b.withNodeIdentifier(getNodeIdentifier("container"));
+
+        CollectionNodeBuilder<MapEntryNode, MapNode> listBuilder =
+            Builders.mapBuilder().withNodeIdentifier(getNodeIdentifier("list"));
+
+        Map<QName, Object> predicates = Maps.newHashMap();
+        predicates.put(getNodeIdentifier("uint32InList").getNodeType(), 3L);
+
+        DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> list1Builder =
+            Builders.mapEntryBuilder().withNodeIdentifier(
+                new YangInstanceIdentifier.NodeIdentifierWithPredicates(
+                    getNodeIdentifier("list").getNodeType(), predicates));
+        NormalizedNodeBuilder<YangInstanceIdentifier.NodeIdentifier, Object, LeafNode<Object>> uint32InListBuilder =
+            Builders.leafBuilder().withNodeIdentifier(
+                getNodeIdentifier("uint32InList"));
+
+        list1Builder.withChild(uint32InListBuilder.withValue(3L).build());
+
+        listBuilder.withChild(list1Builder.build());
+        b.withChild(listBuilder.build());
+
+        NormalizedNodeBuilder<YangInstanceIdentifier.NodeIdentifier, Object, LeafNode<Object>> booleanBuilder =
+            Builders.leafBuilder().withNodeIdentifier(getNodeIdentifier("boolean"));
+        booleanBuilder.withValue(false);
+        b.withChild(booleanBuilder.build());
+
+        ListNodeBuilder<Object, LeafSetEntryNode<Object>> leafListBuilder =
+            Builders.leafSetBuilder().withNodeIdentifier(
+                getNodeIdentifier("leafList"));
+
+        NormalizedNodeBuilder<YangInstanceIdentifier.NodeWithValue, Object, LeafSetEntryNode<Object>> leafList1Builder =
+            Builders.leafSetEntryBuilder().withNodeIdentifier(
+                new YangInstanceIdentifier.NodeWithValue(getNodeIdentifier("leafList")
+                    .getNodeType(), "a"));
+
+        leafList1Builder.withValue("a");
+
+        leafListBuilder.withChild(leafList1Builder.build());
+        b.withChild(leafListBuilder.build());
+
+        return b.build();
+    }
+
+
+    @Test
+    public void testConversionWithAttributes() throws Exception {
+        init("/test.yang", "/simple_xml_with_attributes.xml",
+            listLeafListWithAttributes());
+        Document doc = loadDocument(xmlPath);
+
+        ContainerNode built =
+            DomToNormalizedNodeParserFactory
+                .getInstance(DomUtils.defaultValueCodecProvider())
+                .getContainerNodeParser()
+                .parse(Collections.singletonList(doc.getDocumentElement()),
+                    containerNode);
+
+        if (expectedNode != null) {
+            junit.framework.Assert.assertEquals(expectedNode, built);
+        }
+
+        logger.info("{}", built);
+
+        Iterable<Element> els =
+            DomFromNormalizedNodeSerializerFactory
+                .getInstance(XmlDocumentUtils.getDocument(),
+                    DomUtils.defaultValueCodecProvider())
+                .getContainerNodeSerializer().serialize(containerNode, built);
+
+        Element el = els.iterator().next();
+
+        XMLUnit.setIgnoreWhitespace(true);
+        XMLUnit.setIgnoreComments(true);
+
+        System.out.println(toString(doc.getDocumentElement()));
+        System.out.println(toString(el));
+
+        new Diff(
+            XMLUnit.buildControlDocument(toString(doc.getDocumentElement())),
+            XMLUnit.buildTestDocument(toString(el))).similar();
+    }
+
+
+    private Document loadDocument(final String xmlPath) throws Exception {
+        InputStream resourceAsStream =
+            NormalizedNodeXmlConverterTest.class.getResourceAsStream(xmlPath);
+
+        Document currentConfigElement = readXmlToDocument(resourceAsStream);
+        Preconditions.checkNotNull(currentConfigElement);
+        return currentConfigElement;
+    }
+
+    private static final DocumentBuilderFactory BUILDERFACTORY;
+
+    static {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        factory.setCoalescing(true);
+        factory.setIgnoringElementContentWhitespace(true);
+        factory.setIgnoringComments(true);
+        BUILDERFACTORY = factory;
+    }
+
+    private Document readXmlToDocument(final InputStream xmlContent)
+        throws IOException, SAXException {
+        DocumentBuilder dBuilder;
+        try {
+            dBuilder = BUILDERFACTORY.newDocumentBuilder();
+        } catch (ParserConfigurationException e) {
+            throw new RuntimeException("Failed to parse XML document", e);
+        }
+        Document doc = dBuilder.parse(xmlContent);
+
+        doc.getDocumentElement().normalize();
+        return doc;
+    }
+
+    public static String toString(final Element xml) {
+        try {
+            Transformer transformer =
+                TransformerFactory.newInstance().newTransformer();
+            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+
+            StreamResult result = new StreamResult(new StringWriter());
+            DOMSource source = new DOMSource(xml);
+            transformer.transform(source, result);
+
+            return result.getWriter().toString();
+        } catch (IllegalArgumentException | TransformerFactoryConfigurationError
+            | TransformerException e) {
+            throw new RuntimeException("Unable to serialize xml element " + xml, e);
+        }
+    }
+
+    @Test
+    public void testConversionToNormalizedXml() throws Exception {
+        SimpleNormalizedNodeMessage.NormalizedNodeXml nnXml =
+            EncoderDecoderUtil.encode(parseTestSchema("/augment_choice.yang"),
+                augmentChoiceExpectedNode());
+        Document expectedDoc = loadDocument("/augment_choice.xml");
+        Document convertedDoc =
+            EncoderDecoderUtil.factory.newDocumentBuilder().parse(
+                new ByteArrayInputStream(nnXml.getXmlString().getBytes("utf-8")));
+        System.out.println(toString(convertedDoc.getDocumentElement()));
+        XMLUnit.setIgnoreWhitespace(true);
+        XMLUnit.setIgnoreComments(true);
+        new Diff(XMLUnit.buildControlDocument(toString(expectedDoc
+            .getDocumentElement())),
+            XMLUnit.buildTestDocument(toString(convertedDoc
+                .getDocumentElement()))).similar();
+        System.out.println(toString(expectedDoc.getDocumentElement()));
+
+    }
+
+
+    @Test
+    public void testConversionFromXmlToNormalizedNode() throws Exception {
+        SimpleNormalizedNodeMessage.NormalizedNodeXml nnXml =
+            EncoderDecoderUtil.encode(parseTestSchema("/test.yang"),
+                listLeafListWithAttributes());
+        Document expectedDoc = loadDocument("/simple_xml_with_attributes.xml");
+        Document convertedDoc =
+            EncoderDecoderUtil.factory.newDocumentBuilder().parse(
+                new ByteArrayInputStream(nnXml.getXmlString().getBytes("utf-8")));
+        System.out.println(toString(convertedDoc.getDocumentElement()));
+        XMLUnit.setIgnoreWhitespace(true);
+        XMLUnit.setIgnoreComments(true);
+        new Diff(XMLUnit.buildControlDocument(toString(expectedDoc
+            .getDocumentElement())),
+            XMLUnit.buildTestDocument(toString(convertedDoc
+                .getDocumentElement()))).similar();
+        System.out.println(toString(expectedDoc.getDocumentElement()));
+
+        // now we will try to convert xml back to normalize node.
+        ContainerNode cn =
+            (ContainerNode) EncoderDecoderUtil.decode(
+                parseTestSchema("/test.yang"), nnXml);
+        junit.framework.Assert.assertEquals(listLeafListWithAttributes(), cn);
+
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/util/TestModel.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/cluster/datastore/util/TestModel.java
new file mode 100644 (file)
index 0000000..bef4057
--- /dev/null
@@ -0,0 +1,486 @@
+package org.opendaylight.controller.cluster.datastore.util;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
+
+public class TestModel {
+
+    public static final QName TEST_QNAME = QName.create(
+        "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test",
+        "2014-03-13", "test");
+
+    public static final QName AUG_NAME_QNAME = QName.create(
+        "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:aug",
+        "2014-03-13", "name");
+
+    public static final QName AUG_CONT_QNAME = QName.create(
+        "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:aug",
+        "2014-03-13", "cont");
+
+
+    public static final QName DESC_QNAME = QName.create(TEST_QNAME, "desc");
+    public static final QName POINTER_QNAME =
+        QName.create(TEST_QNAME, "pointer");
+    public static final QName SOME_REF_QNAME =
+        QName.create(TEST_QNAME, "some-ref");
+    public static final QName MYIDENTITY_QNAME =
+        QName.create(TEST_QNAME, "myidentity");
+    public static final QName SWITCH_FEATURES_QNAME =
+        QName.create(TEST_QNAME, "switch-features");
+
+    public static final QName AUGMENTED_LIST_QNAME =
+        QName.create(TEST_QNAME, "augmented-list");
+
+    public static final QName OUTER_LIST_QNAME = QName.create(TEST_QNAME,
+        "outer-list");
+    public static final QName INNER_LIST_QNAME = QName.create(TEST_QNAME,
+        "inner-list");
+    public static final QName OUTER_CHOICE_QNAME = QName.create(TEST_QNAME,
+        "outer-choice");
+    public static final QName ID_QNAME = QName.create(TEST_QNAME, "id");
+    public static final QName NAME_QNAME = QName.create(TEST_QNAME, "name");
+    public static final QName VALUE_QNAME = QName.create(TEST_QNAME, "value");
+    private static final String DATASTORE_TEST_YANG =
+        "/odl-datastore-test.yang";
+    private static final String DATASTORE_AUG_YANG =
+        "/odl-datastore-augmentation.yang";
+    private static final String DATASTORE_TEST_NOTIFICATION_YANG =
+        "/odl-datastore-test-notification.yang";
+
+
+    public static final YangInstanceIdentifier TEST_PATH = YangInstanceIdentifier
+        .of(TEST_QNAME);
+    public static final YangInstanceIdentifier DESC_PATH = YangInstanceIdentifier
+        .builder(TEST_PATH).node(DESC_QNAME).build();
+    public static final YangInstanceIdentifier OUTER_LIST_PATH = YangInstanceIdentifier
+        .builder(TEST_PATH).node(OUTER_LIST_QNAME).build();
+    public static final QName TWO_QNAME = QName.create(TEST_QNAME, "two");
+    public static final QName THREE_QNAME = QName.create(TEST_QNAME, "three");
+
+    private static final Integer ONE_ID = 1;
+    private static final Integer TWO_ID = 2;
+    private static final String TWO_ONE_NAME = "one";
+    private static final String TWO_TWO_NAME = "two";
+    private static final String DESC = "Hello there";
+
+    // Family specific constants
+    public static final QName FAMILY_QNAME =
+        QName
+            .create(
+                "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:notification-test",
+                "2014-04-17", "family");
+    public static final QName CHILDREN_QNAME = QName.create(FAMILY_QNAME,
+        "children");
+    public static final QName GRAND_CHILDREN_QNAME = QName.create(FAMILY_QNAME,
+        "grand-children");
+    public static final QName CHILD_NUMBER_QNAME = QName.create(FAMILY_QNAME,
+        "child-number");
+    public static final QName CHILD_NAME_QNAME = QName.create(FAMILY_QNAME,
+        "child-name");
+    public static final QName GRAND_CHILD_NUMBER_QNAME = QName.create(
+        FAMILY_QNAME, "grand-child-number");
+    public static final QName GRAND_CHILD_NAME_QNAME =
+        QName.create(FAMILY_QNAME,
+            "grand-child-name");
+
+    public static final YangInstanceIdentifier FAMILY_PATH = YangInstanceIdentifier
+        .of(FAMILY_QNAME);
+    public static final YangInstanceIdentifier FAMILY_DESC_PATH = YangInstanceIdentifier
+        .builder(FAMILY_PATH).node(DESC_QNAME).build();
+    public static final YangInstanceIdentifier CHILDREN_PATH = YangInstanceIdentifier
+        .builder(FAMILY_PATH).node(CHILDREN_QNAME).build();
+
+    private static final Integer FIRST_CHILD_ID = 1;
+    private static final Integer SECOND_CHILD_ID = 2;
+
+    private static final String FIRST_CHILD_NAME = "first child";
+    private static final String SECOND_CHILD_NAME = "second child";
+
+    private static final Integer FIRST_GRAND_CHILD_ID = 1;
+    private static final Integer SECOND_GRAND_CHILD_ID = 2;
+
+    private static final String FIRST_GRAND_CHILD_NAME = "first grand child";
+    private static final String SECOND_GRAND_CHILD_NAME = "second grand child";
+
+    // first child
+    private static final YangInstanceIdentifier CHILDREN_1_PATH = YangInstanceIdentifier
+        .builder(CHILDREN_PATH)
+        .nodeWithKey(CHILDREN_QNAME, CHILD_NUMBER_QNAME, FIRST_CHILD_ID) //
+        .build();
+    private static final YangInstanceIdentifier CHILDREN_1_NAME_PATH =
+        YangInstanceIdentifier.builder(CHILDREN_PATH)
+            .nodeWithKey(CHILDREN_QNAME, CHILD_NAME_QNAME, FIRST_CHILD_NAME) //
+            .build();
+
+    private static final YangInstanceIdentifier CHILDREN_2_PATH = YangInstanceIdentifier
+        .builder(CHILDREN_PATH)
+        .nodeWithKey(CHILDREN_QNAME, CHILD_NUMBER_QNAME, SECOND_CHILD_ID) //
+        .build();
+    private static final YangInstanceIdentifier CHILDREN_2_NAME_PATH =
+        YangInstanceIdentifier.builder(CHILDREN_PATH)
+            .nodeWithKey(CHILDREN_QNAME, CHILD_NAME_QNAME, SECOND_CHILD_NAME) //
+            .build();
+
+
+    private static final YangInstanceIdentifier GRAND_CHILD_1_PATH =
+        YangInstanceIdentifier.builder(CHILDREN_1_PATH)
+            .node(GRAND_CHILDREN_QNAME)
+                //
+            .nodeWithKey(GRAND_CHILDREN_QNAME, GRAND_CHILD_NUMBER_QNAME,
+                FIRST_GRAND_CHILD_ID) //
+            .build();
+
+    private static final YangInstanceIdentifier GRAND_CHILD_1_NAME_PATH =
+        YangInstanceIdentifier.builder(CHILDREN_1_PATH)
+            .node(GRAND_CHILDREN_QNAME)
+                //
+            .nodeWithKey(GRAND_CHILDREN_QNAME, GRAND_CHILD_NAME_QNAME,
+                FIRST_GRAND_CHILD_NAME) //
+            .build();
+
+    private static final YangInstanceIdentifier GRAND_CHILD_2_PATH =
+        YangInstanceIdentifier.builder(CHILDREN_2_PATH)
+            .node(GRAND_CHILDREN_QNAME)
+                //
+            .nodeWithKey(GRAND_CHILDREN_QNAME, GRAND_CHILD_NUMBER_QNAME,
+                SECOND_GRAND_CHILD_ID) //
+            .build();
+
+    private static final YangInstanceIdentifier GRAND_CHILD_2_NAME_PATH =
+        YangInstanceIdentifier.builder(CHILDREN_2_PATH)
+            .node(GRAND_CHILDREN_QNAME)
+                //
+            .nodeWithKey(GRAND_CHILDREN_QNAME, GRAND_CHILD_NAME_QNAME,
+                SECOND_GRAND_CHILD_NAME) //
+            .build();
+
+    private static final YangInstanceIdentifier DESC_PATH_ID = YangInstanceIdentifier
+        .builder(DESC_PATH).build();
+    private static final YangInstanceIdentifier OUTER_LIST_1_PATH =
+        YangInstanceIdentifier.builder(OUTER_LIST_PATH)
+            .nodeWithKey(OUTER_LIST_QNAME, ID_QNAME, ONE_ID) //
+            .build();
+
+    private static final YangInstanceIdentifier OUTER_LIST_2_PATH =
+        YangInstanceIdentifier.builder(OUTER_LIST_PATH)
+            .nodeWithKey(OUTER_LIST_QNAME, ID_QNAME, TWO_ID) //
+            .build();
+
+    private static final YangInstanceIdentifier TWO_TWO_PATH = YangInstanceIdentifier
+        .builder(OUTER_LIST_2_PATH).node(INNER_LIST_QNAME) //
+        .nodeWithKey(INNER_LIST_QNAME, NAME_QNAME, TWO_TWO_NAME) //
+        .build();
+
+    private static final YangInstanceIdentifier TWO_TWO_VALUE_PATH =
+        YangInstanceIdentifier.builder(TWO_TWO_PATH).node(VALUE_QNAME) //
+            .build();
+
+    private static final MapEntryNode BAR_NODE = mapEntryBuilder(
+        OUTER_LIST_QNAME, ID_QNAME, TWO_ID) //
+        .withChild(mapNodeBuilder(INNER_LIST_QNAME) //
+            .withChild(mapEntry(INNER_LIST_QNAME, NAME_QNAME, TWO_ONE_NAME)) //
+            .withChild(mapEntry(INNER_LIST_QNAME, NAME_QNAME, TWO_TWO_NAME)) //
+            .build()) //
+        .build();
+
+    public static final InputStream getDatastoreTestInputStream() {
+        return getInputStream(DATASTORE_TEST_YANG);
+    }
+
+    public static final InputStream getDatastoreAugInputStream() {
+        return getInputStream(DATASTORE_AUG_YANG);
+    }
+
+    public static final InputStream getDatastoreTestNotificationInputStream() {
+        return getInputStream(DATASTORE_TEST_NOTIFICATION_YANG);
+    }
+
+    private static InputStream getInputStream(final String resourceName) {
+        return TestModel.class.getResourceAsStream(resourceName);
+    }
+
+    public static SchemaContext createTestContext() {
+        List<InputStream> inputStreams = new ArrayList<>();
+        inputStreams.add(getDatastoreTestInputStream());
+        inputStreams.add(getDatastoreAugInputStream());
+        inputStreams.add(getDatastoreTestNotificationInputStream());
+
+        YangParserImpl parser = new YangParserImpl();
+        Set<Module> modules = parser.parseYangModelsFromStreams(inputStreams);
+        return parser.resolveSchemaContext(modules);
+    }
+
+    /**
+     * Returns a test document
+     * <p/>
+     * <pre>
+     * test
+     *     outer-list
+     *          id 1
+     *     outer-list
+     *          id 2
+     *          inner-list
+     *                  name "one"
+     *          inner-list
+     *                  name "two"
+     *
+     * </pre>
+     *
+     * @return
+     */
+    public static NormalizedNode<?, ?> createDocumentOne(
+        SchemaContext schemaContext) {
+        return ImmutableContainerNodeBuilder
+            .create()
+            .withNodeIdentifier(
+                new YangInstanceIdentifier.NodeIdentifier(schemaContext.getQName()))
+            .withChild(createTestContainer()).build();
+
+    }
+
+    public static ContainerNode createTestContainer() {
+
+
+        // Create a list of shoes
+        // This is to test leaf list entry
+        final LeafSetEntryNode<Object> nike =
+            ImmutableLeafSetEntryNodeBuilder
+                .create()
+                .withNodeIdentifier(
+                    new YangInstanceIdentifier.NodeWithValue(
+                        QName.create(TEST_QNAME,
+                            "shoe"), "nike")
+                ).withValue("nike").build();
+
+        final LeafSetEntryNode<Object> puma =
+            ImmutableLeafSetEntryNodeBuilder
+                .create()
+                .withNodeIdentifier(
+                    new YangInstanceIdentifier.NodeWithValue(
+                        QName.create(TEST_QNAME,
+                            "shoe"), "puma")
+                ).withValue("puma").build();
+
+        final LeafSetNode<Object> shoes =
+            ImmutableLeafSetNodeBuilder
+                .create()
+                .withNodeIdentifier(
+                    new YangInstanceIdentifier.NodeIdentifier(
+                        QName.create(TEST_QNAME,
+                            "shoe"))
+                ).withChild(nike).withChild(puma).build();
+
+
+        // Test a leaf-list where each entry contains an identity
+        final LeafSetEntryNode<Object> cap1 =
+            ImmutableLeafSetEntryNodeBuilder
+                .create()
+                .withNodeIdentifier(
+                    new YangInstanceIdentifier.NodeWithValue(
+                        QName.create(TEST_QNAME,
+                            "capability"), DESC_QNAME)
+                ).withValue(DESC_QNAME).build();
+
+        final LeafSetNode<Object> capabilities =
+            ImmutableLeafSetNodeBuilder
+                .create()
+                .withNodeIdentifier(
+                    new YangInstanceIdentifier.NodeIdentifier(
+                        QName.create(TEST_QNAME,
+                            "capability"))
+                ).withChild(cap1).build();
+
+        ContainerNode switchFeatures = ImmutableContainerNodeBuilder
+            .create()
+            .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(
+                SWITCH_FEATURES_QNAME))
+            .withChild(capabilities)
+            .build();
+
+        // Create a leaf list with numbers
+        final LeafSetEntryNode<Object> five =
+            ImmutableLeafSetEntryNodeBuilder
+                .create()
+                .withNodeIdentifier(
+                    (new YangInstanceIdentifier.NodeWithValue(
+                        QName.create(TEST_QNAME,
+                            "number"), 5))
+                ).withValue(5).build();
+        final LeafSetEntryNode<Object> fifteen =
+            ImmutableLeafSetEntryNodeBuilder
+                .create()
+                .withNodeIdentifier(
+                    (new YangInstanceIdentifier.NodeWithValue(
+                        QName.create(TEST_QNAME,
+                            "number"), 15))
+                ).withValue(15).build();
+        final LeafSetNode<Object> numbers =
+            ImmutableLeafSetNodeBuilder
+                .create()
+                .withNodeIdentifier(
+                    new YangInstanceIdentifier.NodeIdentifier(
+                        QName.create(TEST_QNAME,
+                            "number"))
+                ).withChild(five).withChild(fifteen).build();
+
+
+        // Create augmentations
+        MapEntryNode mapEntry = createAugmentedListEntry(1, "First Test");
+
+
+        // Create the document
+        return ImmutableContainerNodeBuilder
+            .create()
+            .withNodeIdentifier(
+                new YangInstanceIdentifier.NodeIdentifier(TEST_QNAME))
+            .withChild(ImmutableNodes.leafNode(DESC_QNAME, DESC))
+            .withChild(ImmutableNodes.leafNode(POINTER_QNAME, "pointer"))
+            .withChild(ImmutableNodes.leafNode(SOME_REF_QNAME,
+                YangInstanceIdentifier.builder().build()))
+            .withChild(ImmutableNodes.leafNode(MYIDENTITY_QNAME, DESC_QNAME))
+
+                //.withChild(augmentationNode)
+            .withChild(shoes)
+            .withChild(numbers)
+            .withChild(switchFeatures)
+            .withChild(mapNodeBuilder(AUGMENTED_LIST_QNAME).withChild(mapEntry).build())
+            .withChild(
+                mapNodeBuilder(OUTER_LIST_QNAME)
+                    .withChild(mapEntry(OUTER_LIST_QNAME, ID_QNAME, ONE_ID))
+                    .withChild(BAR_NODE).build()
+            ).build();
+
+    }
+
+    public static MapEntryNode createAugmentedListEntry(int id, String name) {
+
+        Set<QName> childAugmentations = new HashSet<>();
+        childAugmentations.add(AUG_CONT_QNAME);
+
+        ContainerNode augCont = ImmutableContainerNodeBuilder
+            .create()
+            .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(AUG_CONT_QNAME))
+            .withChild(ImmutableNodes.leafNode(AUG_NAME_QNAME, name))
+            .build();
+
+
+        final YangInstanceIdentifier.AugmentationIdentifier augmentationIdentifier =
+            new YangInstanceIdentifier.AugmentationIdentifier(childAugmentations);
+
+        final AugmentationNode augmentationNode =
+            Builders.augmentationBuilder()
+                .withNodeIdentifier(augmentationIdentifier)
+                .withChild(augCont)
+                .build();
+
+        return ImmutableMapEntryNodeBuilder.create()
+            .withNodeIdentifier(
+                new YangInstanceIdentifier.NodeIdentifierWithPredicates(
+                    AUGMENTED_LIST_QNAME, ID_QNAME, id))
+            .withChild(ImmutableNodes.leafNode(ID_QNAME, id))
+            .withChild(augmentationNode).build();
+    }
+
+
+    public static ContainerNode createFamily() {
+        final DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode>
+            familyContainerBuilder =
+            ImmutableContainerNodeBuilder.create().withNodeIdentifier(
+                new YangInstanceIdentifier.NodeIdentifier(FAMILY_QNAME));
+
+        final CollectionNodeBuilder<MapEntryNode, MapNode> childrenBuilder =
+            mapNodeBuilder(CHILDREN_QNAME);
+
+        final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode>
+            firstChildBuilder =
+            mapEntryBuilder(CHILDREN_QNAME, CHILD_NUMBER_QNAME, FIRST_CHILD_ID);
+        final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode>
+            secondChildBuilder =
+            mapEntryBuilder(CHILDREN_QNAME, CHILD_NUMBER_QNAME,
+                SECOND_CHILD_ID);
+
+        final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode>
+            firstGrandChildBuilder =
+            mapEntryBuilder(GRAND_CHILDREN_QNAME, GRAND_CHILD_NUMBER_QNAME,
+                FIRST_GRAND_CHILD_ID);
+        final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode>
+            secondGrandChildBuilder =
+            mapEntryBuilder(GRAND_CHILDREN_QNAME, GRAND_CHILD_NUMBER_QNAME,
+                SECOND_GRAND_CHILD_ID);
+
+        firstGrandChildBuilder
+            .withChild(
+                ImmutableNodes.leafNode(GRAND_CHILD_NUMBER_QNAME,
+                    FIRST_GRAND_CHILD_ID)
+            ).withChild(
+            ImmutableNodes.leafNode(GRAND_CHILD_NAME_QNAME,
+                FIRST_GRAND_CHILD_NAME)
+        );
+
+        secondGrandChildBuilder.withChild(
+            ImmutableNodes
+                .leafNode(GRAND_CHILD_NUMBER_QNAME, SECOND_GRAND_CHILD_ID)
+        )
+            .withChild(
+                ImmutableNodes.leafNode(GRAND_CHILD_NAME_QNAME,
+                    SECOND_GRAND_CHILD_NAME)
+            );
+
+        firstChildBuilder
+            .withChild(
+                ImmutableNodes.leafNode(CHILD_NUMBER_QNAME, FIRST_CHILD_ID))
+            .withChild(
+                ImmutableNodes.leafNode(CHILD_NAME_QNAME, FIRST_CHILD_NAME))
+            .withChild(
+                mapNodeBuilder(GRAND_CHILDREN_QNAME).withChild(
+                    firstGrandChildBuilder.build()).build()
+            );
+
+
+        secondChildBuilder
+            .withChild(
+                ImmutableNodes.leafNode(CHILD_NUMBER_QNAME, SECOND_CHILD_ID))
+            .withChild(
+                ImmutableNodes.leafNode(CHILD_NAME_QNAME, SECOND_CHILD_NAME))
+            .withChild(
+                mapNodeBuilder(GRAND_CHILDREN_QNAME).withChild(
+                    firstGrandChildBuilder.build()).build()
+            );
+
+        childrenBuilder.withChild(firstChildBuilder.build());
+        childrenBuilder.withChild(secondChildBuilder.build());
+
+        return familyContainerBuilder.withChild(childrenBuilder.build())
+            .build();
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/protobuff/messages/ShardManagerMessagesTest.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/protobuff/messages/ShardManagerMessagesTest.java
new file mode 100644 (file)
index 0000000..b0758da
--- /dev/null
@@ -0,0 +1,42 @@
+package org.opendaylight.controller.protobuff.messages;
+
+/**
+ * This test case is present to ensure that if others have used proper version of protocol buffer.
+ *
+ * If a different version of protocol buffer is used then it would generate different java sources
+ * and would result in breaking of this test case.
+ *
+ * @author: syedbahm Date: 6/20/14
+ *
+ */
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.protobuff.messages.shard.ShardManagerMessages;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+public class ShardManagerMessagesTest {
+
+  @Test
+  public void verifySerialization() throws Exception {
+    ShardManagerMessages.FindPrimary.Builder builder =
+        ShardManagerMessages.FindPrimary.newBuilder();
+    builder.setShardName("Inventory");
+    File testFile = new File("./test");
+    FileOutputStream output = new FileOutputStream(testFile);
+    builder.build().writeTo(output);
+    output.close();
+
+    // Here we will read the same and check we got back what we had saved
+    ShardManagerMessages.FindPrimary findPrimary =
+        ShardManagerMessages.FindPrimary
+            .parseFrom(new FileInputStream(testFile));
+    Assert.assertEquals("Inventory", findPrimary.getShardName());
+
+    testFile.delete();
+
+  }
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/protobuff/messages/transaction/ShardTransactionMessagesTest.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/java/org/opendaylight/controller/protobuff/messages/transaction/ShardTransactionMessagesTest.java
new file mode 100644 (file)
index 0000000..2b1ee56
--- /dev/null
@@ -0,0 +1,10 @@
+package org.opendaylight.controller.protobuff.messages.transaction;
+
+/**
+ * @author: syedbahm
+ * Date: 7/7/14
+ */
+public class ShardTransactionMessagesTest {
+
+
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/application.conf b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/application.conf
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/augment_choice.xml b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/augment_choice.xml
new file mode 100644 (file)
index 0000000..c5a581c
--- /dev/null
@@ -0,0 +1,15 @@
+<container xmlns="urn:opendaylight:params:xml:ns:yang:controller:test">
+
+    <c2Leaf>2</c2Leaf>
+    <c2DeepChoiceCase1Leaf2>2</c2DeepChoiceCase1Leaf2>
+    <!--<c2DeepChoiceCase1Leaf1>2</c2DeepChoiceCase1Leaf1>-->
+
+    <c3Leaf>3</c3Leaf>
+
+    <augLeaf>augment</augLeaf>
+
+    <c1Leaf>1</c1Leaf>
+    <c1Leaf_AnotherAugment>1</c1Leaf_AnotherAugment>
+    <deepLeafc1>1</deepLeafc1>
+    <!--<deepLeafc2>1</deepLeafc2>-->
+</container>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/augment_choice.yang b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/augment_choice.yang
new file mode 100644 (file)
index 0000000..c2a57f6
--- /dev/null
@@ -0,0 +1,109 @@
+// vi: set smarttab et sw=4 tabstop=4:
+module test {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:test";
+    prefix "test";
+
+    organization "Cisco Systems, Inc.";
+
+    revision "2014-3-13" {
+        description
+            "Initial revision";
+    }
+
+
+    container container {
+        choice ch2{}
+        choice ch3{
+            case c3 {
+                leaf c3Leaf {
+                    type string;
+                }
+            }
+        }
+    }
+
+    augment "/container/" {
+        leaf augLeaf {
+            type string;
+        }
+    }
+
+    augment "/container/" {
+        choice ch{}
+    }
+
+    augment "/container/ch/" {
+        case c1 {
+            leaf c1Leaf {
+                type string;
+            }
+        }
+
+        leaf c12 {
+            type string;
+        }
+    }
+    augment "/container/ch/c1/" {
+        leaf c1Leaf_AnotherAugment {
+            type string;
+        }
+
+        choice deepChoice{}
+    }
+
+    augment "/container/ch3/" {
+        case c32 {
+            leaf c32Leaf {
+                type string;
+            }
+        }
+
+        leaf c34LeafS {
+            type string;
+        }
+    }
+
+
+    augment "/container/ch/c1/deepChoice/" {
+        case deepCase1 {
+            leaf deepLeafc1 {
+                type string;
+            }
+        }
+        case deepCase2 {
+            leaf deepLeafc2 {
+                type string;
+            }
+        }
+    }
+
+    augment "/container/ch2/" {
+        case c2 {
+            leaf c2Leaf {
+                type string;
+            }
+
+            choice c2DeepChoice {
+                case c2DeepChoiceCase1 {
+                    leaf c2DeepChoiceCase1Leaf1 {
+                        type string;
+                    }
+                }
+                case c2DeepChoiceCase2 {
+                    leaf c2DeepChoiceCase1Leaf2 {
+                        type string;
+                    }
+                }
+            }
+        }
+    }
+
+    augment "/container/ch2/" {
+        leaf c22Leaf {
+            type string;
+        }
+    }
+
+
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/odl-datastore-augmentation.yang b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/odl-datastore-augmentation.yang
new file mode 100644 (file)
index 0000000..c305572
--- /dev/null
@@ -0,0 +1,21 @@
+module odl-datastore-augmentation {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:aug";
+    prefix "store-aug";
+
+    import odl-datastore-test {prefix test;revision-date "2014-03-13";}
+
+    revision "2014-03-13" {
+        description "Initial revision.";
+    }
+
+
+    augment "/test:test/test:augmented-list" {
+        container cont {
+            leaf name {
+                type string;
+            }
+        }
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/odl-datastore-test-notification.yang b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/odl-datastore-test-notification.yang
new file mode 100644 (file)
index 0000000..25cc53a
--- /dev/null
@@ -0,0 +1,33 @@
+module odl-datastore-test-notification {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:notification-test";
+    prefix "notification-test-using-family-model";
+
+    revision "2014-04-17" {
+        description "Family structure created on ";
+    }
+
+    container family {
+        leaf desc {
+            type string;
+        }
+        list children {
+            key child-number;
+            leaf child-number {
+                type uint16;
+            }
+            leaf child-name {
+                type string;
+            }
+           list grand-children {
+                key grand-child-number;
+                leaf grand-child-number {
+                    type uint16;
+                }
+                leaf grand-child-name {
+                    type string;
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/odl-datastore-test.yang b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/odl-datastore-test.yang
new file mode 100644 (file)
index 0000000..e4eca7b
--- /dev/null
@@ -0,0 +1,91 @@
+module odl-datastore-test {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test";
+    prefix "store-test";
+
+    revision "2014-03-13" {
+        description "Initial revision.";
+    }
+
+    identity feature-capability {
+    }
+
+    container test {
+        leaf desc {
+            type string;
+        }
+        list outer-list {
+            key id;
+            leaf id {
+                type uint16;
+            }
+            choice outer-choice {
+                case one {
+                    leaf one {
+                        type string;
+                    }
+                }
+                case two-three {
+                    leaf two {
+                        type string;
+                    }
+                    leaf three {
+                        type string;
+                    }
+               }
+           }
+           list inner-list {
+                key name;
+                leaf name {
+                    type string;
+                }
+                leaf value {
+                    type string;
+                }
+            }
+        }
+
+        leaf-list shoe {
+            type string;
+        }
+
+        leaf-list number {
+            type uint8;
+        }
+
+        leaf pointer {
+            type leafref {
+                path "/network-topology/topology/node/termination-point/tp-id";
+            }
+        }
+
+        leaf some-ref {
+            type instance-identifier;
+        }
+
+        leaf myidentity {
+            type identityref {
+                base feature-capability;
+            }
+        }
+
+        container switch-features {
+            leaf-list capability {
+                type identityref {
+                    base feature-capability;
+                }
+
+            }
+        }
+
+        list augmented-list {
+            key id;
+
+            leaf id {
+                type uint8;
+            }
+        }
+
+
+    }
+}
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/simple_xml_with_attributes.xml b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/simple_xml_with_attributes.xml
new file mode 100644 (file)
index 0000000..0316d7a
--- /dev/null
@@ -0,0 +1,12 @@
+<container xmlns="urn:opendaylight:params:xml:ns:yang:controller:test" name="test" xmlns:foo="http://www.foo.com/"
+           foo:baz="baz">
+
+    <list list="on list entry">
+        <uint32InList name="test" foo:baz="baz">3</uint32InList>
+    </list>
+
+    <boolean xmlns:leaf="test:namespace:in:leaf" leaf:a="b">false</boolean>
+
+    <leafList foo:b="b">a</leafList>
+
+</container>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/test.yang b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/test/resources/test.yang
new file mode 100644 (file)
index 0000000..5f0e500
--- /dev/null
@@ -0,0 +1,225 @@
+// vi: set smarttab et sw=4 tabstop=4:
+module test {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:test";
+    prefix "test";
+
+    organization "Cisco Systems, Inc.";
+
+    revision "2014-3-13" {
+        description
+            "Initial revision";
+    }
+
+    grouping listGroup {
+        list list {
+            key "uint32InList";
+
+            leaf uint32InList {
+                type uint32;
+            }
+
+            container containerInList{
+                leaf uint32 {
+                    type uint32;
+                }
+                leaf uint16 {
+                    type uint16;
+                }
+            }
+        }
+     }
+
+     grouping innerContainerGrouping {
+        container innerContainer {
+            leaf uint16 {
+                type uint16;
+            }
+
+            container innerInnerContainer {
+
+                leaf uint16 {
+                    type uint16;
+                }
+
+                leaf uint32 {
+                    type uint32;
+                }
+            }
+        }
+     }
+
+    container container {
+        leaf uint32 {
+            type uint32;
+        }
+
+        leaf decimal64 {
+            type decimal64 {
+                fraction-digits 2;
+            }
+        }
+
+        leaf boolean {
+            type boolean;
+        }
+
+        leaf binary {
+            type binary;
+        }
+
+        leaf string {
+            type string;
+        }
+
+        uses listGroup {
+            augment "list/" {
+                leaf stringAugmentedToList{
+                    type string;
+                }
+
+                choice choiceInList {
+                    case caseInList1 {
+                        leaf stringAugmentedToListInCase1 {
+                            type string;
+                        }
+                    }
+                    case caseInList2 {
+                        leaf stringAugmentedToListInCase2 {
+                            type string;
+                        }
+                    }
+                }
+            }
+        }
+
+        list directList {
+            leaf stringInDirectList {
+                type string;
+            }
+        }
+
+        uses innerContainerGrouping;
+
+        choice choice{}
+        choice choice2{}
+
+        leaf-list leafList {
+            type string;
+        }
+
+        leaf identityRef {
+            type identityref {
+                base test-identity;
+            }
+        }
+
+        /* TODO test modification with empty type
+        leaf empty {
+             type empty;
+         }
+         */
+    }
+
+    augment "/container/" {
+        leaf augmentUint32 {
+            type uint32;
+        }
+    }
+
+    augment "/container/directList/" {
+        leaf augmentedString {
+            type uint32;
+        }
+    }
+
+    augment "/container/choice/" {
+        case test-identity-augment {
+            when "/container/identityRef = 'test-identity'";
+            leaf augmentString1 {
+                type string;
+            }
+
+            leaf augmentInt1 {
+                type uint32;
+            }
+        }
+        case test-identity-augment2 {
+            when "/container/identityRef = 'test-identity2'";
+            leaf augmentString2 {
+                type string;
+            }
+
+            leaf augmentInt2 {
+                type uint32;
+            }
+        }
+    }
+
+    augment "/container/choice/test-identity-augment/" {
+
+        choice augmentedChoiceInCase {
+
+            case augmentedCaseInAugmentedChoice {
+                leaf stringInAugmentedCaseInAugmentedChoice {
+                    type string;
+                }
+            }
+
+            case augmentedCaseInAugmentedChoice2 {
+                leaf stringInAugmentedCaseInAugmentedChoice2 {
+                    type string;
+                }
+            }
+        }
+    }
+
+    augment "/container/choice/test-identity-augment/augmentedChoiceInCase/" {
+        case augmentedCaseInAugmentedChoiceFromAugment {
+            leaf stringInAugmentedCaseInAugmentedChoiceFromAugment {
+                type string;
+            }
+        }
+    }
+
+    augment "/container/choice2/" {
+        case test-identity-augment {
+            when "/container/identityRef = 'test-identity'";
+            container augmentContainer {
+                leaf augmentStringInaugmentContainer {
+                    type string;
+                }
+            }
+        }
+        case test-identity-augment2 {
+            when "/container/identityRef = 'test-identity2'";
+            list augmentedList {
+                leaf augmentStringInaugmentList {
+                    type string;
+                }
+            }
+        }
+    }
+
+
+    augment "/container/choice2/test-identity-augment2/augmentedList/" {
+
+        container augmentedContainerInAugmentedListInAugmentedCase {
+            leaf-list leafInAugmentedContainerInAugmentedListInAugmentedCase {
+                type uint32;
+            }
+        }
+
+        list augmentedListInAugmentedListInAugmentedCase {
+            leaf-list leafInAugmentedListInAugmentedListInAugmentedCase {
+                    type uint32;
+                }
+        }
+    }
+
+    identity test-identity {}
+    identity test-identity2 {
+        base test-identity;
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/pom.xml b/opendaylight/md-sal/sal-remoterpc-connector/pom.xml
new file mode 100644 (file)
index 0000000..ce3bfe9
--- /dev/null
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>sal-parent</artifactId>
+    <version>1.1-SNAPSHOT</version>
+  </parent>
+  <artifactId>sal-remoterpc-connector</artifactId>
+  <packaging>bundle</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.typesafe.akka</groupId>
+      <artifactId>akka-actor_${scala.version}</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.typesafe.akka</groupId>
+      <artifactId>akka-cluster_${scala.version}</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.typesafe.akka</groupId>
+      <artifactId>akka-remote_${scala.version}</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.typesafe.akka</groupId>
+      <artifactId>akka-testkit_${scala.version}</artifactId>
+    </dependency>
+
+    <!-- SAL Dependencies -->
+
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-connector-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-common-util</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-core-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-util</artifactId>
+    </dependency>
+      <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>sal-core-spi</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>sal-common-impl</artifactId>
+      </dependency>
+    <!-- Yang tools-->
+
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-data-api</artifactId>
+
+    </dependency>
+      <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-model-api</artifactId>
+
+      </dependency>
+
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-data-impl</artifactId>
+
+    </dependency>
+
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-common</artifactId>
+
+    </dependency>
+
+
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.scala-lang</groupId>
+      <artifactId>scala-library</artifactId>
+    </dependency>
+
+    <!-- Test Dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <version>${slf4j.version}</version>
+      <scope>test</scope>
+    </dependency>
+      <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-parser-impl</artifactId>
+          <scope>test</scope>
+      </dependency>
+      <dependency>
+          <groupId>com.google.collections</groupId>
+          <artifactId>google-collections</artifactId>
+          <version>1.0</version>
+          <scope>test</scope>
+      </dependency>
+
+  </dependencies>
+
+  <build>
+    <plugins>
+
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+            <Export-package></Export-package>
+            <Private-Package></Private-Package>
+            <Import-Package>!org.jboss.*;!com.jcraft.*;*</Import-Package>
+            <Embed-Dependency>
+                !sal*;
+                !*config-api*;
+                !*testkit*;
+                *protobuf*;
+                akka*;
+                *scala*;
+                *config*;
+                *netty*;
+                *uncommons*;
+            </Embed-Dependency>
+            <Embed-Transitive>true</Embed-Transitive>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>yang-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>config</id>
+            <goals>
+              <goal>generate-sources</goal>
+            </goals>
+            <configuration>
+              <codeGenerators>
+                <generator>
+                  <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
+                  <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
+                  <additionalConfiguration>
+                    <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
+                  </additionalConfiguration>
+                </generator>
+                <generator>
+                  <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+                  <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+                </generator>
+              </codeGenerators>
+              <inspectDependencies>true</inspectDependencies>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+    <tag>HEAD</tag>
+    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Architecture:Clustering</url>
+  </scm>
+</project>
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/config/yang/config/remote_rpc_connector/RemoteRPCBrokerModule.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/config/yang/config/remote_rpc_connector/RemoteRPCBrokerModule.java
new file mode 100644 (file)
index 0000000..9824889
--- /dev/null
@@ -0,0 +1,25 @@
+package org.opendaylight.controller.config.yang.config.remote_rpc_connector;
+
+import org.opendaylight.controller.remote.rpc.RemoteRpcProviderFactory;
+import org.opendaylight.controller.sal.core.api.Broker;
+
+public class RemoteRPCBrokerModule extends org.opendaylight.controller.config.yang.config.remote_rpc_connector.AbstractRemoteRPCBrokerModule {
+  public RemoteRPCBrokerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+    super(identifier, dependencyResolver);
+  }
+
+  public RemoteRPCBrokerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.config.remote_rpc_connector.RemoteRPCBrokerModule oldModule, java.lang.AutoCloseable oldInstance) {
+    super(identifier, dependencyResolver, oldModule, oldInstance);
+  }
+
+  @Override
+  public void customValidation() {
+     // add custom validation form module attributes here.
+  }
+
+  @Override
+  public java.lang.AutoCloseable createInstance() {
+    Broker broker = getDomBrokerDependency();
+    return RemoteRpcProviderFactory.createInstance(broker);
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/config/yang/config/remote_rpc_connector/RemoteRPCBrokerModuleFactory.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/config/yang/config/remote_rpc_connector/RemoteRPCBrokerModuleFactory.java
new file mode 100644 (file)
index 0000000..330845b
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: remote-rpc-connector yang module local name: remote-rpc-connector
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Mon Jul 07 17:02:25 PDT 2014
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.config.remote_rpc_connector;
+
+
+public class RemoteRPCBrokerModuleFactory extends org.opendaylight.controller.config.yang.config.remote_rpc_connector.AbstractRemoteRPCBrokerModuleFactory {
+
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/AbstractUntypedActor.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/AbstractUntypedActor.java
new file mode 100644 (file)
index 0000000..66593ae
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc;
+
+import akka.actor.UntypedActor;
+import akka.event.Logging;
+import akka.event.LoggingAdapter;
+import org.opendaylight.controller.remote.rpc.messages.Monitor;
+
+public abstract class AbstractUntypedActor extends UntypedActor {
+    protected final LoggingAdapter LOG =
+        Logging.getLogger(getContext().system(), this);
+
+
+    public AbstractUntypedActor(){
+        LOG.debug("Actor created {}", getSelf());
+        getContext().
+            system().
+            actorSelection("user/termination-monitor").
+            tell(new Monitor(getSelf()), getSelf());
+    }
+
+    @Override public void onReceive(Object message) throws Exception {
+        LOG.debug("Received message {}", message);
+        handleReceive(message);
+        LOG.debug("Done handling message {}", message);
+    }
+
+    protected abstract void handleReceive(Object message) throws Exception;
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/ActorSystemFactory.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/ActorSystemFactory.java
new file mode 100644 (file)
index 0000000..4a6124a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc;
+
+import akka.actor.ActorSystem;
+import akka.actor.Props;
+import com.google.common.base.Function;
+import com.typesafe.config.ConfigFactory;
+
+import javax.annotation.Nullable;
+
+public class ActorSystemFactory {
+    private static final ActorSystem actorSystem = (new Function<Void, ActorSystem>(){
+
+        @Nullable @Override public ActorSystem apply(@Nullable Void aVoid) {
+                ActorSystem system =
+                    ActorSystem.create("opendaylight-rpc", ConfigFactory
+                        .load().getConfig("odl-cluster"));
+                system.actorOf(Props.create(TerminationMonitor.class), "termination-monitor");
+                return system;
+        }
+    }).apply(null);
+
+    public static final ActorSystem getInstance(){
+        return actorSystem;
+    }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RemoteRpcImplementation.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RemoteRpcImplementation.java
new file mode 100644 (file)
index 0000000..d384144
--- /dev/null
@@ -0,0 +1,86 @@
+package org.opendaylight.controller.remote.rpc;
+
+import akka.actor.ActorRef;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.remote.rpc.messages.ErrorResponse;
+import org.opendaylight.controller.remote.rpc.messages.InvokeRoutedRpc;
+import org.opendaylight.controller.remote.rpc.messages.InvokeRpc;
+import org.opendaylight.controller.remote.rpc.messages.RpcResponse;
+import org.opendaylight.controller.remote.rpc.utils.ActorUtil;
+import org.opendaylight.controller.remote.rpc.utils.XmlUtils;
+import org.opendaylight.controller.sal.core.api.RoutedRpcDefaultImplementation;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.Set;
+
+public class RemoteRpcImplementation implements RpcImplementation,
+    RoutedRpcDefaultImplementation {
+  private static final Logger LOG = LoggerFactory.getLogger(RemoteRpcImplementation.class);
+  private ActorRef rpcBroker;
+  private SchemaContext schemaContext;
+
+  public RemoteRpcImplementation(ActorRef rpcBroker, SchemaContext schemaContext) {
+    this.rpcBroker = rpcBroker;
+    this.schemaContext = schemaContext;
+  }
+
+  @Override
+  public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, YangInstanceIdentifier identifier, CompositeNode input) {
+    InvokeRoutedRpc rpcMsg = new InvokeRoutedRpc(rpc, identifier, input);
+
+    return executeMsg(rpcMsg);
+  }
+
+  @Override
+  public Set<QName> getSupportedRpcs() {
+    // TODO : check if we need to get this from routing registry
+    return Collections.emptySet();
+  }
+
+  @Override
+  public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
+    InvokeRpc rpcMsg = new InvokeRpc(rpc, input);
+    return executeMsg(rpcMsg);
+  }
+
+  private ListenableFuture<RpcResult<CompositeNode>> executeMsg(Object rpcMsg) {
+    ListenableFuture<RpcResult<CompositeNode>> listenableFuture = null;
+
+    try {
+      Object response = ActorUtil.executeLocalOperation(rpcBroker, rpcMsg, ActorUtil.ASK_DURATION, ActorUtil.AWAIT_DURATION);
+      if(response instanceof RpcResponse) {
+
+        RpcResponse rpcResponse = (RpcResponse) response;
+        CompositeNode result = XmlUtils.xmlToCompositeNode(rpcResponse.getResultCompositeNode());
+        listenableFuture = Futures.immediateFuture(RpcResultBuilder.success(result).build());
+
+      } else if(response instanceof ErrorResponse) {
+
+        ErrorResponse errorResponse = (ErrorResponse) response;
+        Exception e = errorResponse.getException();
+        final RpcResultBuilder<CompositeNode> failed = RpcResultBuilder.failed();
+        failed.withError(null, null, e.getMessage(), null, null, e.getCause());
+        listenableFuture = Futures.immediateFuture(failed.build());
+
+      }
+    } catch (Exception e) {
+      LOG.error("Error occurred while invoking RPC actor {}", e.toString());
+
+      final RpcResultBuilder<CompositeNode> failed = RpcResultBuilder.failed();
+      failed.withError(null, null, e.getMessage(), null, null, e.getCause());
+      listenableFuture = Futures.immediateFuture(failed.build());
+    }
+
+    return listenableFuture;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RemoteRpcProvider.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RemoteRpcProvider.java
new file mode 100644 (file)
index 0000000..3df572d
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc;
+
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import org.opendaylight.controller.remote.rpc.messages.UpdateSchemaContext;
+import org.opendaylight.controller.remote.rpc.registry.ClusterWrapper;
+import org.opendaylight.controller.remote.rpc.registry.ClusterWrapperImpl;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+
+/**
+ * This is the base class which initialize all the actors, listeners and
+ * default RPc implementation so remote invocation of rpcs.
+ */
+public class RemoteRpcProvider implements AutoCloseable, Provider, SchemaContextListener {
+
+  private static final Logger LOG = LoggerFactory.getLogger(RemoteRpcProvider.class);
+
+  private final ActorSystem actorSystem;
+  private final RpcProvisionRegistry rpcProvisionRegistry;
+  private Broker.ProviderSession brokerSession;
+  private SchemaContext schemaContext;
+  private ActorRef rpcManager;
+
+
+  public RemoteRpcProvider(ActorSystem actorSystem, RpcProvisionRegistry rpcProvisionRegistry) {
+    this.actorSystem = actorSystem;
+    this.rpcProvisionRegistry = rpcProvisionRegistry;
+  }
+
+  @Override
+  public void close() throws Exception {
+    this.actorSystem.shutdown();
+  }
+
+  @Override
+  public void onSessionInitiated(Broker.ProviderSession session) {
+    this.brokerSession = session;
+    start();
+  }
+
+  @Override
+  public Collection<ProviderFunctionality> getProviderFunctionality() {
+    return null;
+  }
+
+  private void start() {
+    LOG.info("Starting all rpc listeners and actors.");
+    // Create actor to handle and sync routing table in cluster
+    ClusterWrapper clusterWrapper = new ClusterWrapperImpl(actorSystem);
+    SchemaService schemaService = brokerSession.getService(SchemaService.class);
+    schemaContext = schemaService.getGlobalContext();
+
+    rpcManager = actorSystem.actorOf(RpcManager.props(clusterWrapper, schemaContext, brokerSession, rpcProvisionRegistry), "rpc");
+
+    LOG.debug("Rpc actors are created.");
+  }
+
+
+  @Override
+  public void onGlobalContextUpdated(SchemaContext schemaContext) {
+    this.schemaContext = schemaContext;
+    rpcManager.tell(new UpdateSchemaContext(schemaContext), null);
+
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RemoteRpcProviderFactory.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RemoteRpcProviderFactory.java
new file mode 100644 (file)
index 0000000..4c40ca1
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc;
+
+
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+
+public class RemoteRpcProviderFactory {
+    public static RemoteRpcProvider createInstance(final Broker broker){
+      RemoteRpcProvider rpcProvider =
+          new RemoteRpcProvider(ActorSystemFactory.getInstance(), (RpcProvisionRegistry) broker);
+      broker.registerProvider(rpcProvider);
+      return rpcProvider;
+    }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RouteIdentifierImpl.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RouteIdentifierImpl.java
new file mode 100644 (file)
index 0000000..85d2138
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.remote.rpc;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+
+import java.io.Serializable;
+
+public class RouteIdentifierImpl implements RpcRouter.RouteIdentifier<QName, QName, YangInstanceIdentifier>,Serializable {
+  private static final long serialVersionUID = 1L;
+
+  private final QName context;
+  private final QName type;
+  private final YangInstanceIdentifier route;
+
+  public RouteIdentifierImpl(final QName context, final QName type, final YangInstanceIdentifier route) {
+    Preconditions.checkNotNull(type, "Rpc type should not be null");
+    this.context = context;
+    this.type = type;
+    this.route = route;
+  }
+
+  @Override
+  public QName getContext() {
+    return this.context;
+  }
+
+  @Override
+  public QName getType() {
+    return this.type;
+  }
+
+  @Override
+  public YangInstanceIdentifier getRoute() {
+    return this.route;
+  }
+
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    RouteIdentifierImpl that = (RouteIdentifierImpl) o;
+
+    if (context == null){
+      if (that.getContext() != null)  return false;
+    }else
+      if (!context.equals(that.context)) return false;
+
+    if (route == null){
+      if (that.getRoute() != null) return false;
+    }else
+      if (!route.equals(that.route)) return false;
+
+    if (type == null){
+      if (that.getType() != null) return false;
+    }else
+      if (!type.equals(that.type)) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int prime = 31;
+    int result = 0;
+    result = prime * result + (context == null ? 0:context.hashCode());
+    result = prime * result + (type    == null ? 0:type.hashCode());
+    result = prime * result + (route   == null ? 0:route.hashCode());
+    return result;
+  }
+
+  @Override
+  public String toString() {
+    return "RouteIdentifierImpl{" +
+        "context=" + context +
+        ", type=" + type +
+        ", route=" + route +
+        '}';
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RoutedRpcListener.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RoutedRpcListener.java
new file mode 100644 (file)
index 0000000..a6eeac0
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc;
+
+
+import akka.actor.ActorRef;
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.remote.rpc.messages.AddRoutedRpc;
+import org.opendaylight.controller.remote.rpc.messages.RemoveRoutedRpc;
+import org.opendaylight.controller.remote.rpc.utils.ActorUtil;
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.opendaylight.controller.sal.core.api.RpcRoutingContext;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class RoutedRpcListener implements RouteChangeListener<RpcRoutingContext, YangInstanceIdentifier>{
+  private static final Logger LOG = LoggerFactory.getLogger(RoutedRpcListener.class);
+  private final ActorRef rpcRegistry;
+  private final String actorPath;
+
+  public RoutedRpcListener(ActorRef rpcRegistry, String actorPath) {
+    Preconditions.checkNotNull(rpcRegistry, "rpc registry actor should not be null");
+    Preconditions.checkNotNull(actorPath, "actor path of rpc broker on current node should not be null");
+
+    this.rpcRegistry = rpcRegistry;
+    this.actorPath = actorPath;
+  }
+
+  @Override
+  public void onRouteChange(RouteChange<RpcRoutingContext, YangInstanceIdentifier> routeChange) {
+    Map<RpcRoutingContext, Set<YangInstanceIdentifier>> announcements = routeChange.getAnnouncements();
+    announce(getRouteIdentifiers(announcements));
+
+    Map<RpcRoutingContext, Set<YangInstanceIdentifier>> removals = routeChange.getRemovals();
+    remove(getRouteIdentifiers(removals));
+  }
+
+  /**
+   *
+   * @param announcements
+   */
+  private void announce(Set<RpcRouter.RouteIdentifier<?, ?, ?>> announcements) {
+    LOG.debug("Announcing [{}]", announcements);
+    AddRoutedRpc addRpcMsg = new AddRoutedRpc(announcements, actorPath);
+    try {
+      ActorUtil.executeLocalOperation(rpcRegistry, addRpcMsg, ActorUtil.LOCAL_ASK_DURATION, ActorUtil.LOCAL_AWAIT_DURATION);
+    } catch (Exception e) {
+      // Just logging it because Akka API throws this exception
+      LOG.error(e.toString());
+    }
+  }
+
+  /**
+   *
+   * @param removals
+   */
+  private void remove(Set<RpcRouter.RouteIdentifier<?, ?, ?>> removals){
+    LOG.debug("Removing [{}]", removals);
+    RemoveRoutedRpc removeRpcMsg = new RemoveRoutedRpc(removals, actorPath);
+    try {
+      ActorUtil.executeLocalOperation(rpcRegistry, removeRpcMsg, ActorUtil.LOCAL_ASK_DURATION, ActorUtil.LOCAL_AWAIT_DURATION);
+    } catch (Exception e) {
+      // Just logging it because Akka API throws this exception
+      LOG.error(e.toString());
+    }
+  }
+
+  /**
+   *
+   * @param changes
+   * @return
+   */
+  private Set<RpcRouter.RouteIdentifier<?, ?, ?>> getRouteIdentifiers(Map<RpcRoutingContext, Set<YangInstanceIdentifier>> changes) {
+    RouteIdentifierImpl routeId = null;
+    Set<RpcRouter.RouteIdentifier<?, ?, ?>> routeIdSet = new HashSet<>();
+
+    for (RpcRoutingContext context : changes.keySet()){
+      for (YangInstanceIdentifier instanceId : changes.get(context)){
+        routeId = new RouteIdentifierImpl(null, context.getRpc(), instanceId);
+        routeIdSet.add(routeId);
+      }
+    }
+    return routeIdSet;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcBroker.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcBroker.java
new file mode 100644 (file)
index 0000000..26e8e96
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc;
+
+import akka.actor.ActorRef;
+import akka.actor.Props;
+import akka.japi.Creator;
+import org.opendaylight.controller.remote.rpc.messages.ErrorResponse;
+import org.opendaylight.controller.remote.rpc.messages.ExecuteRpc;
+import org.opendaylight.controller.remote.rpc.messages.GetRoutedRpc;
+import org.opendaylight.controller.remote.rpc.messages.GetRoutedRpcReply;
+import org.opendaylight.controller.remote.rpc.messages.GetRpc;
+import org.opendaylight.controller.remote.rpc.messages.GetRpcReply;
+import org.opendaylight.controller.remote.rpc.messages.InvokeRoutedRpc;
+import org.opendaylight.controller.remote.rpc.messages.InvokeRpc;
+import org.opendaylight.controller.remote.rpc.messages.RpcResponse;
+import org.opendaylight.controller.remote.rpc.utils.ActorUtil;
+import org.opendaylight.controller.remote.rpc.utils.XmlUtils;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.Future;
+
+/**
+ * Actor to initiate execution of remote RPC on other nodes of the cluster.
+ */
+
+public class RpcBroker extends AbstractUntypedActor {
+
+  private static final Logger LOG = LoggerFactory.getLogger(RpcBroker.class);
+  private final Broker.ProviderSession brokerSession;
+  private final ActorRef rpcRegistry;
+  private SchemaContext schemaContext;
+
+  private RpcBroker(Broker.ProviderSession brokerSession, ActorRef rpcRegistry, SchemaContext schemaContext){
+    this.brokerSession = brokerSession;
+    this.rpcRegistry = rpcRegistry;
+    this.schemaContext = schemaContext;
+  }
+
+  public static Props props(final Broker.ProviderSession brokerSession, final ActorRef rpcRegistry, final SchemaContext schemaContext){
+    return Props.create(new Creator<RpcBroker>(){
+
+      @Override
+      public RpcBroker create() throws Exception {
+        return new RpcBroker(brokerSession, rpcRegistry, schemaContext);
+      }
+    });
+  }
+  @Override
+  protected void handleReceive(Object message) throws Exception {
+    if(message instanceof InvokeRoutedRpc) {
+      invokeRemoteRoutedRpc((InvokeRoutedRpc) message);
+    } else if(message instanceof InvokeRpc) {
+      invokeRemoteRpc((InvokeRpc) message);
+    } else if(message instanceof ExecuteRpc) {
+      executeRpc((ExecuteRpc) message);
+    }
+  }
+
+  private void invokeRemoteRoutedRpc(InvokeRoutedRpc msg) {
+    // Look up the remote actor to execute rpc
+    LOG.debug("Looking up the remote actor for route {}", msg);
+    try {
+      RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, msg.getRpc(), msg.getIdentifier());
+      GetRoutedRpc routedRpcMsg = new GetRoutedRpc(routeId);
+      GetRoutedRpcReply rpcReply = (GetRoutedRpcReply) ActorUtil.executeLocalOperation(rpcRegistry, routedRpcMsg, ActorUtil.LOCAL_ASK_DURATION, ActorUtil.LOCAL_AWAIT_DURATION);
+
+      String remoteActorPath = rpcReply.getRoutePath();
+      if(remoteActorPath == null) {
+        LOG.debug("No remote actor found for rpc execution.");
+
+        getSender().tell(new ErrorResponse(
+          new IllegalStateException("No remote actor found for rpc execution.")), self());
+      } else {
+
+        ExecuteRpc executeMsg = new ExecuteRpc(XmlUtils.inputCompositeNodeToXml(msg.getInput(), schemaContext), msg.getRpc());
+
+        Object operationRes = ActorUtil.executeRemoteOperation(this.context().actorSelection(remoteActorPath),
+            executeMsg, ActorUtil.REMOTE_ASK_DURATION, ActorUtil.REMOTE_AWAIT_DURATION);
+
+        getSender().tell(operationRes, self());
+      }
+    } catch (Exception e) {
+        LOG.error(e.toString());
+        getSender().tell(new ErrorResponse(e), self());
+    }
+  }
+
+  private void invokeRemoteRpc(InvokeRpc msg) {
+    // Look up the remote actor to execute rpc
+    LOG.debug("Looking up the remote actor for route {}", msg);
+    try {
+      RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, msg.getRpc(), null);
+      GetRpc rpcMsg = new GetRpc(routeId);
+      GetRpcReply rpcReply = (GetRpcReply)ActorUtil.executeLocalOperation(rpcRegistry, rpcMsg, ActorUtil.LOCAL_ASK_DURATION, ActorUtil.LOCAL_AWAIT_DURATION);
+      String remoteActorPath = rpcReply.getRoutePath();
+
+      if(remoteActorPath == null) {
+        LOG.debug("No remote actor found for rpc {{}}.", msg.getRpc());
+
+        getSender().tell(new ErrorResponse(
+          new IllegalStateException("No remote actor found for rpc execution of : " + msg.getRpc())), self());
+      } else {
+
+        ExecuteRpc executeMsg = new ExecuteRpc(XmlUtils.inputCompositeNodeToXml(msg.getInput(), schemaContext), msg.getRpc());
+        Object operationRes = ActorUtil.executeRemoteOperation(this.context().actorSelection(remoteActorPath),
+            executeMsg, ActorUtil.REMOTE_ASK_DURATION, ActorUtil.REMOTE_AWAIT_DURATION);
+
+        getSender().tell(operationRes, self());
+      }
+    } catch (Exception e) {
+        LOG.error(e.toString());
+        getSender().tell(new ErrorResponse(e), self());
+    }
+  }
+
+  private void executeRpc(ExecuteRpc msg) {
+    LOG.debug("Executing rpc for rpc {}", msg.getRpc());
+    try {
+      Future<RpcResult<CompositeNode>> rpc = brokerSession.rpc(msg.getRpc(), XmlUtils.inputXmlToCompositeNode(msg.getRpc(), msg.getInputCompositeNode(), schemaContext));
+      RpcResult<CompositeNode> rpcResult = rpc != null ? rpc.get():null;
+      CompositeNode result = rpcResult != null ? rpcResult.getResult() : null;
+      getSender().tell(new RpcResponse(XmlUtils.outputCompositeNodeToXml(result, schemaContext)), self());
+    } catch (Exception e) {
+      LOG.error(e.toString());
+      getSender().tell(new ErrorResponse(e), self());
+    }
+  }
+
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcListener.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcListener.java
new file mode 100644 (file)
index 0000000..f614990
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc;
+
+
+import akka.actor.ActorRef;
+import org.opendaylight.controller.remote.rpc.messages.AddRpc;
+import org.opendaylight.controller.remote.rpc.messages.RemoveRpc;
+import org.opendaylight.controller.remote.rpc.utils.ActorUtil;
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RpcListener implements RpcRegistrationListener{
+
+  private static final Logger LOG = LoggerFactory.getLogger(RpcListener.class);
+  private final ActorRef rpcRegistry;
+  private final String actorPath;
+
+  public RpcListener(ActorRef rpcRegistry, String actorPath) {
+    this.rpcRegistry = rpcRegistry;
+    this.actorPath = actorPath;
+  }
+
+  @Override
+  public void onRpcImplementationAdded(QName rpc) {
+    LOG.debug("Adding registration for [{}]", rpc);
+    RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, rpc, null);
+    AddRpc addRpcMsg = new AddRpc(routeId, actorPath);
+    try {
+      ActorUtil.executeLocalOperation(rpcRegistry, addRpcMsg, ActorUtil.LOCAL_ASK_DURATION, ActorUtil.LOCAL_AWAIT_DURATION);
+      LOG.debug("Route added [{}-{}]", routeId, this.actorPath);
+    } catch (Exception e) {
+      // Just logging it because Akka API throws this exception
+      LOG.error(e.toString());
+    }
+
+  }
+
+  @Override
+  public void onRpcImplementationRemoved(QName rpc) {
+    LOG.debug("Removing registration for [{}]", rpc);
+    RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, rpc, null);
+    RemoveRpc removeRpcMsg = new RemoveRpc(routeId);
+    try {
+      ActorUtil.executeLocalOperation(rpcRegistry, removeRpcMsg, ActorUtil.LOCAL_ASK_DURATION, ActorUtil.LOCAL_AWAIT_DURATION);
+    } catch (Exception e) {
+      // Just logging it because Akka API throws this exception
+      LOG.error(e.toString());
+    }
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcManager.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcManager.java
new file mode 100644 (file)
index 0000000..4925a17
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc;
+
+
+import akka.actor.ActorRef;
+import akka.actor.OneForOneStrategy;
+import akka.actor.Props;
+import akka.actor.SupervisorStrategy;
+import akka.japi.Creator;
+import akka.japi.Function;
+import org.opendaylight.controller.remote.rpc.messages.UpdateSchemaContext;
+import org.opendaylight.controller.remote.rpc.registry.ClusterWrapper;
+import org.opendaylight.controller.remote.rpc.registry.RpcRegistry;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import scala.concurrent.duration.Duration;
+import java.util.Set;
+
+/**
+ * This class acts as a supervisor, creates all the actors, resumes them, if an exception is thrown.
+ *
+ * It also starts the rpc listeners
+ */
+
+public class RpcManager extends AbstractUntypedActor {
+
+  private static final Logger LOG = LoggerFactory.getLogger(RpcManager.class);
+
+  private SchemaContext schemaContext;
+  private final ClusterWrapper clusterWrapper;
+  private ActorRef rpcBroker;
+  private ActorRef rpcRegistry;
+  private final Broker.ProviderSession brokerSession;
+  private RpcListener rpcListener;
+  private RoutedRpcListener routeChangeListener;
+  private RemoteRpcImplementation rpcImplementation;
+  private final RpcProvisionRegistry rpcProvisionRegistry;
+
+  private RpcManager(ClusterWrapper clusterWrapper, SchemaContext schemaContext,
+                     Broker.ProviderSession brokerSession, RpcProvisionRegistry rpcProvisionRegistry) {
+    this.clusterWrapper = clusterWrapper;
+    this.schemaContext = schemaContext;
+    this.brokerSession = brokerSession;
+    this.rpcProvisionRegistry = rpcProvisionRegistry;
+
+    createRpcActors();
+    startListeners();
+  }
+
+
+  public static Props props(final ClusterWrapper clusterWrapper, final SchemaContext schemaContext,
+                            final Broker.ProviderSession brokerSession, final RpcProvisionRegistry rpcProvisionRegistry) {
+    return Props.create(new Creator<RpcManager>() {
+      @Override
+      public RpcManager create() throws Exception {
+        return new RpcManager(clusterWrapper, schemaContext, brokerSession, rpcProvisionRegistry);
+      }
+    });
+  }
+
+  private void createRpcActors() {
+    LOG.debug("Create rpc registry and broker actors");
+
+    rpcRegistry = getContext().actorOf(RpcRegistry.props(clusterWrapper), "rpc-registry");
+    rpcBroker = getContext().actorOf(RpcBroker.props(brokerSession, rpcRegistry, schemaContext), "rpc-broker");
+  }
+
+  private void startListeners() {
+    LOG.debug("Registers rpc listeners");
+
+    String rpcBrokerPath = clusterWrapper.getAddress().toString() + "/user/rpc/rpc-broker";
+    rpcListener = new RpcListener(rpcRegistry, rpcBrokerPath);
+    routeChangeListener = new RoutedRpcListener(rpcRegistry, rpcBrokerPath);
+    rpcImplementation = new RemoteRpcImplementation(rpcBroker, schemaContext);
+
+    brokerSession.addRpcRegistrationListener(rpcListener);
+    rpcProvisionRegistry.registerRouteChangeListener(routeChangeListener);
+    rpcProvisionRegistry.setRoutedRpcDefaultDelegate(rpcImplementation);
+    announceSupportedRpcs();
+  }
+
+  /**
+   * Add all the locally registered RPCs in the clustered routing table
+   */
+  private void announceSupportedRpcs(){
+    LOG.debug("Adding all supported rpcs to routing table");
+    Set<QName> currentlySupported = brokerSession.getSupportedRpcs();
+    for (QName rpc : currentlySupported) {
+      rpcListener.onRpcImplementationAdded(rpc);
+    }
+  }
+
+
+  @Override
+  protected void handleReceive(Object message) throws Exception {
+    if(message instanceof UpdateSchemaContext) {
+      updateSchemaContext((UpdateSchemaContext) message);
+    }
+
+  }
+
+  private void updateSchemaContext(UpdateSchemaContext message) {
+    this.schemaContext = message.getSchemaContext();
+  }
+
+  @Override
+  public SupervisorStrategy supervisorStrategy() {
+    return new OneForOneStrategy(10, Duration.create("1 minute"),
+        new Function<Throwable, SupervisorStrategy.Directive>() {
+          @Override
+          public SupervisorStrategy.Directive apply(Throwable t) {
+            return SupervisorStrategy.resume();
+          }
+        }
+    );
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/TerminationMonitor.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/TerminationMonitor.java
new file mode 100644 (file)
index 0000000..a90f1e1
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc;
+
+import akka.actor.Terminated;
+import akka.actor.UntypedActor;
+import akka.event.Logging;
+import akka.event.LoggingAdapter;
+import org.opendaylight.controller.remote.rpc.messages.Monitor;
+
+public class TerminationMonitor extends UntypedActor{
+    protected final LoggingAdapter LOG =
+        Logging.getLogger(getContext().system(), this);
+
+    public TerminationMonitor(){
+        LOG.info("Created TerminationMonitor");
+    }
+
+    @Override public void onReceive(Object message) throws Exception {
+        if(message instanceof Terminated){
+            Terminated terminated = (Terminated) message;
+            LOG.debug("Actor terminated : {}", terminated.actor());
+        }else if(message instanceof Monitor){
+          Monitor monitor = (Monitor) message;
+          getContext().watch(monitor.getActorRef());
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/AddRoutedRpc.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/AddRoutedRpc.java
new file mode 100644 (file)
index 0000000..fd1af2b
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc.messages;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+
+import java.io.Serializable;
+import java.util.Set;
+
+public class AddRoutedRpc implements Serializable {
+
+  private final Set<RpcRouter.RouteIdentifier<?, ?, ?>> announcements;
+  private final String actorPath;
+
+  public AddRoutedRpc(final Set<RpcRouter.RouteIdentifier<?, ?, ?>> announcements, final String actorPath) {
+    Preconditions.checkNotNull(announcements, "Route identifier should not be null");
+    Preconditions.checkNotNull(actorPath, "Actor path should not be null");
+
+    this.announcements = announcements;
+    this.actorPath = actorPath;
+  }
+
+  public Set<RpcRouter.RouteIdentifier<?, ?, ?>> getAnnouncements() {
+    return announcements;
+  }
+
+  public String getActorPath() {
+    return actorPath;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/AddRpc.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/AddRpc.java
new file mode 100644 (file)
index 0000000..7eaa8f0
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc.messages;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.remote.rpc.RouteIdentifierImpl;
+
+import java.io.Serializable;
+
+public class AddRpc implements Serializable {
+
+  private final RouteIdentifierImpl routeId;
+  private final String actorPath;
+
+  public AddRpc(final RouteIdentifierImpl routeId, final String actorPath) {
+    Preconditions.checkNotNull(routeId, "Route identifier should not be null");
+    Preconditions.checkNotNull(actorPath, "Actor path should not be null");
+
+    this.routeId = routeId;
+    this.actorPath = actorPath;
+  }
+
+  public RouteIdentifierImpl getRouteId() {
+    return routeId;
+  }
+
+  public String getActorPath() {
+    return actorPath;
+  }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/ErrorResponse.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/ErrorResponse.java
new file mode 100644 (file)
index 0000000..2c26243
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.remote.rpc.messages;
+
+import com.google.common.base.Preconditions;
+
+import java.io.Serializable;
+
+public class ErrorResponse implements Serializable {
+
+  private final Exception exception;
+
+  public ErrorResponse(final Exception e) {
+    Preconditions.checkNotNull(e, "Exception should be present for error message");
+    this.exception = e;
+  }
+
+  public Exception getException() {
+    return exception;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/ExecuteRpc.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/ExecuteRpc.java
new file mode 100644 (file)
index 0000000..522dd44
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.remote.rpc.messages;
+
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.common.QName;
+
+import java.io.Serializable;
+
+public class ExecuteRpc implements Serializable {
+
+  private final String inputCompositeNode;
+  private final QName rpc;
+
+  public ExecuteRpc(final String inputCompositeNode, final QName rpc) {
+    Preconditions.checkNotNull(inputCompositeNode, "Composite Node input string should be present");
+    Preconditions.checkNotNull(rpc, "rpc Qname should not be null");
+
+    this.inputCompositeNode = inputCompositeNode;
+    this.rpc = rpc;
+  }
+
+  public String getInputCompositeNode() {
+    return inputCompositeNode;
+  }
+
+  public QName getRpc() {
+    return rpc;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/GetRoutedRpc.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/GetRoutedRpc.java
new file mode 100644 (file)
index 0000000..e8d2262
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc.messages;
+
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.remote.rpc.RouteIdentifierImpl;
+
+import java.io.Serializable;
+
+public class GetRoutedRpc implements Serializable {
+
+  private final RouteIdentifierImpl routeId;
+
+  public GetRoutedRpc(final RouteIdentifierImpl routeId) {
+    Preconditions.checkNotNull(routeId, "route id should not be null");
+    this.routeId = routeId;
+  }
+
+  public RouteIdentifierImpl getRouteId() {
+    return routeId;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/GetRoutedRpcReply.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/GetRoutedRpcReply.java
new file mode 100644 (file)
index 0000000..d426662
--- /dev/null
@@ -0,0 +1,24 @@
+package org.opendaylight.controller.remote.rpc.messages;
+
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+import java.io.Serializable;
+
+public class GetRoutedRpcReply implements Serializable {
+
+  private final String routePath;
+
+  public GetRoutedRpcReply(final String routePath) {
+    this.routePath = routePath;
+  }
+
+  public String getRoutePath() {
+    return routePath;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/GetRpc.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/GetRpc.java
new file mode 100644 (file)
index 0000000..c1d4240
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.remote.rpc.messages;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.remote.rpc.RouteIdentifierImpl;
+
+import java.io.Serializable;
+
+public class GetRpc implements Serializable {
+
+  private final RouteIdentifierImpl routeId;
+
+  public GetRpc(final RouteIdentifierImpl routeId) {
+    Preconditions.checkNotNull(routeId, "Route Id should not be null");
+    this.routeId = routeId;
+  }
+
+  public RouteIdentifierImpl getRouteId() {
+    return routeId;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/GetRpcReply.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/GetRpcReply.java
new file mode 100644 (file)
index 0000000..aaf089d
--- /dev/null
@@ -0,0 +1,24 @@
+package org.opendaylight.controller.remote.rpc.messages;
+
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+import java.io.Serializable;
+
+public class GetRpcReply implements Serializable {
+
+  private final String routePath;
+
+  public GetRpcReply(final String routePath) {
+    this.routePath = routePath;
+  }
+
+  public String getRoutePath() {
+    return routePath;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/InvokeRoutedRpc.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/InvokeRoutedRpc.java
new file mode 100644 (file)
index 0000000..fd73144
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.remote.rpc.messages;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+import java.io.Serializable;
+
+public class InvokeRoutedRpc implements Serializable {
+
+  private final QName rpc;
+  private final YangInstanceIdentifier identifier;
+  private final CompositeNode input;
+
+  public InvokeRoutedRpc(final QName rpc, final YangInstanceIdentifier identifier, final CompositeNode input) {
+    Preconditions.checkNotNull(rpc, "rpc qname should not be null");
+    Preconditions.checkNotNull(identifier, "instance identifier of routed rpc should not be null");
+    Preconditions.checkNotNull(input, "rpc input should not be null");
+
+    this.rpc = rpc;
+    this.identifier = identifier;
+    this.input = input;
+  }
+
+  public QName getRpc() {
+    return rpc;
+  }
+
+  public YangInstanceIdentifier getIdentifier() {
+    return identifier;
+  }
+
+  public CompositeNode getInput() {
+    return input;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/InvokeRpc.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/InvokeRpc.java
new file mode 100644 (file)
index 0000000..94b7fe4
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.remote.rpc.messages;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+import java.io.Serializable;
+
+public class InvokeRpc implements Serializable {
+
+  private final QName rpc;
+  private final CompositeNode input;
+
+  public InvokeRpc(final QName rpc, final CompositeNode input) {
+    Preconditions.checkNotNull(rpc, "rpc qname should not be null");
+    Preconditions.checkNotNull(input, "rpc input should not be null");
+
+    this.rpc = rpc;
+    this.input = input;
+  }
+
+  public QName getRpc() {
+    return rpc;
+  }
+
+  public CompositeNode getInput() {
+    return input;
+  }
+}
@@ -5,20 +5,20 @@
  * 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.remote;
 
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
+package org.opendaylight.controller.remote.rpc.messages;
 
-public interface RemoteRpcRouter {
-
-
-
-
-
-
-    ListenerRegistration<RouteChangeListener> registerRouteChangeListener(RouteChangeListener listener);
+import akka.actor.ActorRef;
 
+public class Monitor {
+    private final ActorRef actorRef;
 
+    public Monitor(ActorRef actorRef){
 
+        this.actorRef = actorRef;
+    }
 
+    public ActorRef getActorRef() {
+        return actorRef;
+    }
 }
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/RemoveRoutedRpc.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/RemoveRoutedRpc.java
new file mode 100644 (file)
index 0000000..b560b8c
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc.messages;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+
+import java.io.Serializable;
+import java.util.Set;
+
+public class RemoveRoutedRpc implements Serializable {
+
+  private final Set<RpcRouter.RouteIdentifier<?, ?, ?>> announcements;
+  private final String actorPath;
+
+  public RemoveRoutedRpc(final Set<RpcRouter.RouteIdentifier<?, ?, ?>> announcements, final String actorPath) {
+    Preconditions.checkNotNull(announcements, "Route identifier should not be null");
+    Preconditions.checkNotNull(actorPath, "Actor path should not be null");
+
+    this.announcements = announcements;
+    this.actorPath = actorPath;
+  }
+
+  public Set<RpcRouter.RouteIdentifier<?, ?, ?>> getAnnouncements() {
+    return announcements;
+  }
+
+  public String getActorPath() {
+    return actorPath;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/RemoveRpc.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/RemoveRpc.java
new file mode 100644 (file)
index 0000000..289334f
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc.messages;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.remote.rpc.RouteIdentifierImpl;
+
+import java.io.Serializable;
+
+public class RemoveRpc implements Serializable {
+
+  private final RouteIdentifierImpl routeId;
+
+  public RemoveRpc(final RouteIdentifierImpl routeId) {
+    Preconditions.checkNotNull(routeId, "Route Id should not be null");
+
+    this.routeId = routeId;
+  }
+
+  public RouteIdentifierImpl getRouteId() {
+    return routeId;
+  }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/RoutingTableData.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/RoutingTableData.java
new file mode 100644 (file)
index 0000000..c57a258
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc.messages;
+
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+
+import java.io.Serializable;
+import java.util.LinkedHashSet;
+import java.util.Map;
+
+public class RoutingTableData implements Serializable {
+  private final Map<RpcRouter.RouteIdentifier<?, ?, ?>, String> rpcMap;
+  private final Map<RpcRouter.RouteIdentifier<?, ?, ?>, LinkedHashSet<String>> routedRpcMap;
+
+  public RoutingTableData(final Map<RpcRouter.RouteIdentifier<?, ?, ?>, String> rpcMap,
+                          final Map<RpcRouter.RouteIdentifier<?, ?, ?>, LinkedHashSet<String>> routedRpcMap) {
+    this.rpcMap = rpcMap;
+    this.routedRpcMap = routedRpcMap;
+  }
+
+  public Map<RpcRouter.RouteIdentifier<?, ?, ?>, String> getRpcMap() {
+    return rpcMap;
+  }
+
+  public Map<RpcRouter.RouteIdentifier<?, ?, ?>, LinkedHashSet<String>> getRoutedRpcMap() {
+    return routedRpcMap;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/RpcResponse.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/RpcResponse.java
new file mode 100644 (file)
index 0000000..17766f1
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.remote.rpc.messages;
+
+
+
+import java.io.Serializable;
+
+public class RpcResponse implements Serializable {
+  private final String resultCompositeNode;
+
+  public RpcResponse(final String resultCompositeNode) {
+    this.resultCompositeNode = resultCompositeNode;
+  }
+
+  public String getResultCompositeNode() {
+    return resultCompositeNode;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/UpdateSchemaContext.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/messages/UpdateSchemaContext.java
new file mode 100644 (file)
index 0000000..83fc772
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc.messages;
+
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class UpdateSchemaContext {
+
+  private final SchemaContext schemaContext;
+
+  public UpdateSchemaContext(final SchemaContext schemaContext) {
+    this.schemaContext = schemaContext;
+  }
+
+  public SchemaContext getSchemaContext() {
+    return schemaContext;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/ClusterWrapper.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/ClusterWrapper.java
new file mode 100644 (file)
index 0000000..4ddc2be
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc.registry;
+
+
+import akka.actor.Address;
+import akka.cluster.ClusterEvent;
+
+public interface ClusterWrapper {
+
+  ClusterEvent.CurrentClusterState getState();
+
+  Address getAddress();
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/ClusterWrapperImpl.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/ClusterWrapperImpl.java
new file mode 100644 (file)
index 0000000..89603a1
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc.registry;
+
+
+import akka.actor.ActorSystem;
+import akka.actor.Address;
+import akka.cluster.Cluster;
+import akka.cluster.ClusterEvent;
+
+
+public class ClusterWrapperImpl  implements ClusterWrapper{
+
+  private Cluster cluster;
+
+  public ClusterWrapperImpl(ActorSystem actorSystem) {
+    cluster = Cluster.get(actorSystem);
+  }
+
+  @Override
+  public ClusterEvent.CurrentClusterState getState() {
+    return cluster.state();
+  }
+
+  @Override
+  public Address getAddress() {
+    return cluster.selfAddress();
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RoutingTable.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RoutingTable.java
new file mode 100644 (file)
index 0000000..5e19653
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc.registry;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+public class RoutingTable<I, R> {
+
+  private final Logger LOG = LoggerFactory.getLogger(RoutingTable.class);
+
+  private ConcurrentMap<I,R> globalRpcMap = new ConcurrentHashMap<>();
+  private ConcurrentMap<I, LinkedHashSet<R>> routedRpcMap = new ConcurrentHashMap<>();
+
+  public ConcurrentMap<I, R> getGlobalRpcMap() {
+    return globalRpcMap;
+  }
+
+  public ConcurrentMap<I, LinkedHashSet<R>> getRoutedRpcMap() {
+    return routedRpcMap;
+  }
+
+  public R getGlobalRoute(final I routeId) {
+    Preconditions.checkNotNull(routeId, "getGlobalRoute: routeId cannot be null!");
+    return globalRpcMap.get(routeId);
+  }
+
+  public void addGlobalRoute(final I routeId, final R route) {
+    Preconditions.checkNotNull(routeId, "addGlobalRoute: routeId cannot be null!");
+    Preconditions.checkNotNull(route, "addGlobalRoute: route cannot be null!");
+    LOG.debug("addGlobalRoute: adding  a new route with id[{}] and value [{}]", routeId, route);
+    if(globalRpcMap.putIfAbsent(routeId, route) != null) {
+      LOG.debug("A route already exist for route id [{}] ", routeId);
+    }
+  }
+
+  public void removeGlobalRoute(final I routeId) {
+    Preconditions.checkNotNull(routeId, "removeGlobalRoute: routeId cannot be null!");
+    LOG.debug("removeGlobalRoute: removing  a new route with id [{}]", routeId);
+    globalRpcMap.remove(routeId);
+  }
+
+  public Set<R> getRoutedRpc(final I routeId) {
+    Preconditions.checkNotNull(routeId, "getRoutes: routeId cannot be null!");
+    Set<R> routes = routedRpcMap.get(routeId);
+
+    if (routes == null) {
+      return Collections.emptySet();
+    }
+
+    return ImmutableSet.copyOf(routes);
+  }
+
+  public R getLastAddedRoutedRpc(final I routeId) {
+
+    Set<R> routes = getRoutedRpc(routeId);
+
+    if (routes.isEmpty()) {
+      return null;
+    }
+
+    R route = null;
+    Iterator<R> iter = routes.iterator();
+    while (iter.hasNext()) {
+      route = iter.next();
+    }
+
+    return route;
+  }
+
+  public void addRoutedRpc(final I routeId, final R route)   {
+    Preconditions.checkNotNull(routeId, "addRoute: routeId cannot be null");
+    Preconditions.checkNotNull(route, "addRoute: route cannot be null");
+    LOG.debug("addRoute: adding a route with k/v [{}/{}]", routeId, route);
+    threadSafeAdd(routeId, route);
+  }
+
+  public void addRoutedRpcs(final Set<I> routeIds, final R route) {
+    Preconditions.checkNotNull(routeIds, "addRoutes: routeIds must not be null");
+    for (I routeId : routeIds){
+      addRoutedRpc(routeId, route);
+    }
+  }
+
+  public void removeRoute(final I routeId, final R route) {
+    Preconditions.checkNotNull(routeId, "removeRoute: routeId cannot be null!");
+    Preconditions.checkNotNull(route, "removeRoute: route cannot be null!");
+
+    LinkedHashSet<R> routes = routedRpcMap.get(routeId);
+    if (routes == null) {
+      return;
+    }
+    LOG.debug("removeRoute: removing  a new route with k/v [{}/{}]", routeId, route);
+    threadSafeRemove(routeId, route);
+  }
+
+  public void removeRoutes(final Set<I> routeIds, final R route) {
+    Preconditions.checkNotNull(routeIds, "removeRoutes: routeIds must not be null");
+    for (I routeId : routeIds){
+      removeRoute(routeId, route);
+    }
+  }
+
+  /**
+   * This method guarantees that no 2 thread over write each other's changes.
+   * Just so that we dont end up in infinite loop, it tries for 100 times then throw
+   */
+  private void threadSafeAdd(final I routeId, final R route) {
+
+    for (int i=0;i<100;i++){
+
+      LinkedHashSet<R> updatedRoutes = new LinkedHashSet<>();
+      updatedRoutes.add(route);
+      LinkedHashSet<R> oldRoutes = routedRpcMap.putIfAbsent(routeId, updatedRoutes);
+      if (oldRoutes == null) {
+        return;
+      }
+
+      updatedRoutes = new LinkedHashSet<>(oldRoutes);
+      updatedRoutes.add(route);
+
+      if (routedRpcMap.replace(routeId, oldRoutes, updatedRoutes)) {
+        return;
+      }
+    }
+    //the method did not already return means it failed to add route in 100 attempts
+    throw new IllegalStateException("Failed to add route [" + routeId + "]");
+  }
+
+  /**
+   * This method guarantees that no 2 thread over write each other's changes.
+   * Just so that we dont end up in infinite loop, it tries for 100 times then throw
+   */
+  private void threadSafeRemove(final I routeId, final R route) {
+    LinkedHashSet<R> updatedRoutes = null;
+    for (int i=0;i<100;i++){
+      LinkedHashSet<R> oldRoutes = routedRpcMap.get(routeId);
+
+      // if route to be deleted is the only entry in the set then remove routeId from the cache
+      if ((oldRoutes.size() == 1) && oldRoutes.contains(route)){
+        routedRpcMap.remove(routeId);
+        return;
+      }
+
+      // if there are multiple routes for this routeId, remove the route to be deleted only from the set.
+      updatedRoutes = new LinkedHashSet<>(oldRoutes);
+      updatedRoutes.remove(route);
+      if (routedRpcMap.replace(routeId, oldRoutes, updatedRoutes)) {
+        return;
+      }
+
+    }
+    //the method did not already return means it failed to remove route in 100 attempts
+    throw new IllegalStateException("Failed to remove route [" + routeId + "]");
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RpcRegistry.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RpcRegistry.java
new file mode 100644 (file)
index 0000000..7cb505a
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.remote.rpc.registry;
+
+import akka.actor.ActorSelection;
+import akka.actor.Address;
+import akka.actor.Props;
+import akka.cluster.ClusterEvent;
+import akka.cluster.Member;
+import akka.japi.Creator;
+import org.opendaylight.controller.remote.rpc.AbstractUntypedActor;
+import org.opendaylight.controller.remote.rpc.messages.AddRoutedRpc;
+import org.opendaylight.controller.remote.rpc.messages.AddRpc;
+import org.opendaylight.controller.remote.rpc.messages.GetRoutedRpc;
+import org.opendaylight.controller.remote.rpc.messages.GetRoutedRpcReply;
+import org.opendaylight.controller.remote.rpc.messages.GetRpc;
+import org.opendaylight.controller.remote.rpc.messages.GetRpcReply;
+import org.opendaylight.controller.remote.rpc.messages.RemoveRoutedRpc;
+import org.opendaylight.controller.remote.rpc.messages.RemoveRpc;
+import org.opendaylight.controller.remote.rpc.messages.RoutingTableData;
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import scala.collection.JavaConversions;
+
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This Actor maintains the routing table state and sync it with other nodes in the cluster.
+ *
+ * A scheduler runs after an interval of time, which pick a random member from the cluster
+ * and send the current state of routing table to the member.
+ *
+ * when a message of routing table data is received, it gets merged with the local routing table
+ * to keep the latest data.
+ */
+
+public class RpcRegistry extends AbstractUntypedActor {
+
+  private static final Logger LOG = LoggerFactory.getLogger(RpcRegistry.class);
+  private RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> routingTable;
+  private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
+  private final ClusterWrapper clusterWrapper;
+  private final ScheduledFuture<?> syncScheduler;
+
+  private RpcRegistry(ClusterWrapper clusterWrapper){
+    this.routingTable = new RoutingTable<>();
+    this.clusterWrapper = clusterWrapper;
+    this.syncScheduler = scheduler.scheduleAtFixedRate(new SendRoutingTable(), 10, 10, TimeUnit.SECONDS);
+  }
+
+  public static Props props(final ClusterWrapper clusterWrapper){
+    return Props.create(new Creator<RpcRegistry>(){
+
+      @Override
+      public RpcRegistry create() throws Exception {
+        return new RpcRegistry(clusterWrapper);
+      }
+    });
+  }
+
+  @Override
+  protected void handleReceive(Object message) throws Exception {
+    LOG.debug("Received message {}", message);
+    if(message instanceof RoutingTableData) {
+      syncRoutingTable((RoutingTableData) message);
+    } else if(message instanceof GetRoutedRpc) {
+      getRoutedRpc((GetRoutedRpc) message);
+    } else if(message instanceof GetRpc) {
+      getRpc((GetRpc) message);
+    } else if(message instanceof AddRpc) {
+      addRpc((AddRpc) message);
+    } else if(message instanceof RemoveRpc) {
+      removeRpc((RemoveRpc) message);
+    } else if(message instanceof AddRoutedRpc) {
+      addRoutedRpc((AddRoutedRpc) message);
+    } else if(message instanceof RemoveRoutedRpc) {
+      removeRoutedRpc((RemoveRoutedRpc) message);
+    }
+  }
+
+  private void getRoutedRpc(GetRoutedRpc rpcMsg){
+    LOG.debug("Get latest routed Rpc location from routing table {}", rpcMsg);
+    String remoteActorPath = routingTable.getLastAddedRoutedRpc(rpcMsg.getRouteId());
+    GetRoutedRpcReply routedRpcReply = new GetRoutedRpcReply(remoteActorPath);
+
+    getSender().tell(routedRpcReply, self());
+  }
+
+  private void getRpc(GetRpc rpcMsg) {
+    LOG.debug("Get global Rpc location from routing table {}", rpcMsg);
+    String remoteActorPath = routingTable.getGlobalRoute(rpcMsg.getRouteId());
+    GetRpcReply rpcReply = new GetRpcReply(remoteActorPath);
+
+    getSender().tell(rpcReply, self());
+  }
+
+  private void addRpc(AddRpc rpcMsg) {
+    LOG.debug("Add Rpc to routing table {}", rpcMsg);
+    routingTable.addGlobalRoute(rpcMsg.getRouteId(), rpcMsg.getActorPath());
+
+    getSender().tell("Success", self());
+  }
+
+  private void removeRpc(RemoveRpc rpcMsg) {
+    LOG.debug("Removing Rpc to routing table {}", rpcMsg);
+    routingTable.removeGlobalRoute(rpcMsg.getRouteId());
+
+    getSender().tell("Success", self());
+  }
+
+  private void addRoutedRpc(AddRoutedRpc rpcMsg) {
+    routingTable.addRoutedRpcs(rpcMsg.getAnnouncements(), rpcMsg.getActorPath());
+    getSender().tell("Success", self());
+  }
+
+  private void removeRoutedRpc(RemoveRoutedRpc rpcMsg) {
+    routingTable.removeRoutes(rpcMsg.getAnnouncements(), rpcMsg.getActorPath());
+    getSender().tell("Success", self());
+  }
+
+  private void syncRoutingTable(RoutingTableData routingTableData) {
+    LOG.debug("Syncing routing table {}", routingTableData);
+
+    Map<RpcRouter.RouteIdentifier<?, ?, ?>, String> newRpcMap = routingTableData.getRpcMap();
+    Set<RpcRouter.RouteIdentifier<?, ?, ?>> routeIds = newRpcMap.keySet();
+    for(RpcRouter.RouteIdentifier<?, ?, ?> routeId : routeIds) {
+      routingTable.addGlobalRoute(routeId, newRpcMap.get(routeId));
+    }
+
+    Map<RpcRouter.RouteIdentifier<?, ?, ?>, LinkedHashSet<String>> newRoutedRpcMap =
+        routingTableData.getRoutedRpcMap();
+    routeIds = newRoutedRpcMap.keySet();
+
+    for(RpcRouter.RouteIdentifier<?, ?, ?> routeId : routeIds) {
+      Set<String> routeAddresses = newRoutedRpcMap.get(routeId);
+      for(String routeAddress : routeAddresses) {
+        routingTable.addRoutedRpc(routeId, routeAddress);
+      }
+    }
+  }
+
+  private ActorSelection getRandomRegistryActor() {
+    ClusterEvent.CurrentClusterState clusterState = clusterWrapper.getState();
+    ActorSelection actor = null;
+    Set<Member> members = JavaConversions.asJavaSet(clusterState.members());
+    int memberSize = members.size();
+    // Don't select yourself
+    if(memberSize > 1) {
+      Address currentNodeAddress = clusterWrapper.getAddress();
+      int index = new Random().nextInt(memberSize);
+      int i = 0;
+      // keeping previous member, in case when random index member is same as current actor
+      // and current actor member is last in set
+      Member previousMember = null;
+      for(Member member : members){
+        if(i == index-1) {
+          previousMember = member;
+        }
+        if(i == index) {
+          if(!currentNodeAddress.equals(member.address())) {
+            actor = this.context().actorSelection(member.address() + "/user/rpc-registry");
+            break;
+          } else if(index < memberSize-1){ // pick the next element in the set
+            index++;
+          }
+        }
+        i++;
+      }
+      if(actor == null && previousMember != null) {
+        actor = this.context().actorSelection(previousMember.address() + "/user/rpc-registry");
+      }
+    }
+    return actor;
+  }
+
+  private class SendRoutingTable implements Runnable {
+
+    @Override
+    public void run() {
+      RoutingTableData routingTableData =
+          new RoutingTableData(routingTable.getGlobalRpcMap(), routingTable.getRoutedRpcMap());
+      LOG.debug("Sending routing table for sync {}", routingTableData);
+      ActorSelection actor = getRandomRegistryActor();
+      if(actor != null) {
+        actor.tell(routingTableData, self());
+      }
+    }
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/ActorUtil.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/ActorUtil.java
new file mode 100644 (file)
index 0000000..8f60eab
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+package org.opendaylight.controller.remote.rpc.utils;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSelection;
+import akka.util.Timeout;
+import scala.concurrent.Await;
+import scala.concurrent.Future;
+import scala.concurrent.duration.Duration;
+import scala.concurrent.duration.FiniteDuration;
+
+import java.util.concurrent.TimeUnit;
+
+import static akka.pattern.Patterns.ask;
+
+public class ActorUtil {
+  public static final FiniteDuration LOCAL_ASK_DURATION = Duration.create(2, TimeUnit.SECONDS);
+  public static final FiniteDuration REMOTE_ASK_DURATION = Duration.create(15, TimeUnit.SECONDS);
+  public static final FiniteDuration ASK_DURATION = Duration.create(17, TimeUnit.SECONDS);
+  public static final FiniteDuration LOCAL_AWAIT_DURATION = Duration.create(2, TimeUnit.SECONDS);
+  public static final FiniteDuration REMOTE_AWAIT_DURATION = Duration.create(15, TimeUnit.SECONDS);
+  public static final FiniteDuration AWAIT_DURATION = Duration.create(17, TimeUnit.SECONDS);
+
+  /**
+   * Executes an operation on a local actor and wait for it's response
+   * @param actor
+   * @param message
+   * @param askDuration
+   * @param awaitDuration
+   * @return The response of the operation
+   */
+  public static Object executeLocalOperation(ActorRef actor, Object message,
+                                      FiniteDuration askDuration, FiniteDuration awaitDuration) throws Exception{
+    Future<Object> future =
+        ask(actor, message, new Timeout(askDuration));
+
+      return Await.result(future, awaitDuration);
+  }
+
+  /**
+   * Execute an operation on a remote actor and wait for it's response
+   * @param actor
+   * @param message
+   * @param askDuration
+   * @param awaitDuration
+   * @return
+   */
+  public static Object executeRemoteOperation(ActorSelection actor, Object message,
+                                              FiniteDuration askDuration, FiniteDuration awaitDuration) throws Exception{
+    Future<Object> future =
+        ask(actor, message, new Timeout(askDuration));
+      return Await.result(future, awaitDuration);
+  }
+
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/InstanceIdentifierForXmlCodec.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/InstanceIdentifierForXmlCodec.java
new file mode 100644 (file)
index 0000000..92a7fba
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.remote.rpc.utils;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public final class InstanceIdentifierForXmlCodec {
+  private static final Pattern PREDICATE_PATTERN = Pattern.compile("\\[(.*?)\\]");
+  private static final Splitter SLASH_SPLITTER = Splitter.on('/');
+  private static final Splitter COLON_SPLITTER = Splitter.on(':');
+  private static final Splitter AT_SPLITTER = Splitter.on('@');
+  private static final Logger logger = LoggerFactory.getLogger(InstanceIdentifierForXmlCodec.class);
+
+  private InstanceIdentifierForXmlCodec() {
+    throw new UnsupportedOperationException("Utility class");
+  }
+
+  public static YangInstanceIdentifier deserialize(final Element element, final SchemaContext schemaContext) {
+    Preconditions.checkNotNull(element, "Value of element for deserialization can't be null");
+    Preconditions.checkNotNull(schemaContext,
+        "Schema context for deserialization of instance identifier type can't be null");
+
+    final String valueTrimmed = element.getTextContent().trim();
+    logger.debug("Instance identifier derserialize: splitting the text {} with Slash to find path arguments", valueTrimmed);
+    final Iterator<String> xPathParts = SLASH_SPLITTER.split(valueTrimmed).iterator();
+
+    // must be at least "/pr:node"
+    if (!xPathParts.hasNext() || !xPathParts.next().isEmpty() || !xPathParts.hasNext()) {
+      logger.debug("Instance identifier derserialize: No path argument found for element.");
+      return null;
+    }
+
+    List<PathArgument> result = new ArrayList<>();
+    while (xPathParts.hasNext()) {
+      String xPathPartTrimmed = xPathParts.next().trim();
+
+      PathArgument pathArgument = toPathArgument(xPathPartTrimmed, element, schemaContext);
+      if (pathArgument != null) {
+        result.add(pathArgument);
+      }
+    }
+    return YangInstanceIdentifier.create(result);
+  }
+
+  public static Element serialize(final YangInstanceIdentifier id, final Element element) {
+    Preconditions.checkNotNull(id, "Variable should contain instance of instance identifier and can't be null");
+    Preconditions.checkNotNull(element, "DOM element can't be null");
+
+    final RandomPrefix prefixes = new RandomPrefix();
+    final String str = XmlUtils.encodeIdentifier(prefixes, id);
+
+    for (Entry<URI, String> e: prefixes.getPrefixes()) {
+      element.setAttribute("xmlns:" + e.getValue(), e.getKey().toString());
+    }
+    element.setTextContent(str);
+    return element;
+  }
+
+  private static String getIdAndPrefixAsStr(final String pathPart) {
+    int predicateStartIndex = pathPart.indexOf('[');
+    return predicateStartIndex == -1 ? pathPart : pathPart.substring(0, predicateStartIndex);
+  }
+
+  private static PathArgument toPathArgument(final String xPathArgument, final Element element, final SchemaContext schemaContext) {
+    final QName mainQName = toIdentity(xPathArgument, element, schemaContext);
+
+    // predicates
+    final Matcher matcher = PREDICATE_PATTERN.matcher(xPathArgument);
+    final Map<QName, Object> predicates = new HashMap<>();
+    QName currentQName = mainQName;
+
+    while (matcher.find()) {
+      final String predicateStr = matcher.group(1).trim();
+      final int indexOfEqualityMark = predicateStr.indexOf('=');
+      if (indexOfEqualityMark != -1) {
+        final Object predicateValue = toPredicateValue(predicateStr.substring(indexOfEqualityMark + 1));
+        if (predicateValue == null) {
+          return null;
+        }
+
+        if (predicateStr.charAt(0) != '.') {
+          // target is not a leaf-list
+          currentQName = toIdentity(predicateStr.substring(0, indexOfEqualityMark), element, schemaContext);
+          if (currentQName == null) {
+            return null;
+          }
+        }
+        logger.debug("Instance identifier derserialize: finding predicates of node {}", predicateValue);
+        predicates.put(currentQName, predicateValue);
+      }
+    }
+
+    if (predicates.isEmpty()) {
+      return new YangInstanceIdentifier.NodeIdentifier(mainQName);
+    } else {
+      return new YangInstanceIdentifier.NodeIdentifierWithPredicates(mainQName, predicates);
+    }
+
+  }
+
+  public static QName toIdentity(final String xPathArgument, final Element element, final SchemaContext schemaContext) {
+    final String xPathPartTrimmed = getIdAndPrefixAsStr(xPathArgument).trim();
+    final Iterator<String> it = COLON_SPLITTER.split(xPathPartTrimmed).iterator();
+
+    // Empty string
+    if (!it.hasNext()) {
+      return null;
+    }
+
+    final String prefix = it.next().trim();
+    if (prefix.isEmpty()) {
+      return null;
+    }
+
+    // it is not "prefix:value"
+    if (!it.hasNext()) {
+      return null;
+    }
+
+    final String identifier = it.next().trim();
+    if (identifier.isEmpty()) {
+      return null;
+    }
+
+    URI namespace = null;
+    String namespaceStr = null;
+    try {
+      namespaceStr = element.getAttribute("xmlns:"+prefix);
+      namespace = new URI(namespaceStr);
+    } catch (URISyntaxException e) {
+      throw new IllegalArgumentException("It wasn't possible to convert " + namespaceStr + " to URI object.");
+    } catch (NullPointerException e) {
+      throw new IllegalArgumentException("I wasn't possible to get namespace for prefix " + prefix);
+    }
+
+    Module module = schemaContext.findModuleByNamespaceAndRevision(namespace, null);
+    return QName.create(module.getQNameModule(), identifier);
+  }
+
+  private static String trimIfEndIs(final String str, final char end) {
+    final int l = str.length() - 1;
+    if (str.charAt(l) != end) {
+      return null;
+    }
+
+    return str.substring(1, l);
+  }
+
+  private static Object toPredicateValue(final String predicatedValue) {
+    logger.debug("Instance identifier derserialize: converting the predicate vstring to object {}", predicatedValue);
+    final String predicatedValueTrimmed = predicatedValue.trim();
+    if (predicatedValue.isEmpty()) {
+      return null;
+    }
+    String updatedValue = null;
+    switch (predicatedValueTrimmed.charAt(0)) {
+      case '"':
+        updatedValue =  trimIfEndIs(predicatedValueTrimmed, '"');
+        break;
+      case '\'':
+        updatedValue =  trimIfEndIs(predicatedValueTrimmed, '\'');
+        break;
+      default:
+        updatedValue =  predicatedValueTrimmed;
+    }
+    Iterator<String> it = AT_SPLITTER.split(updatedValue).iterator();
+    // Empty string
+    if (!it.hasNext()) {
+      return null;
+    }
+
+    final String value = it.next().trim();
+    if (value.isEmpty()) {
+      return null;
+    }
+
+    if (!it.hasNext()) {
+      return value;
+    }
+
+    final String type = it.next().trim();
+    if (type.isEmpty()) {
+      return value;
+    }
+    Object predicateObject = null;
+    try {
+      logger.debug("Instance identifier derserialize: converting the predicate value {{}}to correct object type {{}}", value, type);
+      predicateObject = Class.forName(type).getConstructor(String.class).newInstance(value);
+    } catch (Exception e) {
+      logger.error("Could not convert to valid type of value", e);
+    }
+    return predicateObject;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/RandomPrefix.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/RandomPrefix.java
new file mode 100644 (file)
index 0000000..55cc819
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.remote.rpc.utils;
+
+import org.opendaylight.yangtools.yang.common.QName;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ * Picked from Yang tools because it was not public class
+ */
+
+final class RandomPrefix {
+    final Map<URI, String> prefixes = new HashMap<>();
+
+    Iterable<Entry<URI, String>> getPrefixes() {
+        return prefixes.entrySet();
+    }
+
+    String encodeQName(final QName qname) {
+        String prefix = prefixes.get(qname.getNamespace());
+        if (prefix == null) {
+            prefix = qname.getPrefix();
+            if (prefix == null || prefix.isEmpty() || prefixes.containsValue(prefix)) {
+                final ThreadLocalRandom random = ThreadLocalRandom.current();
+                do {
+                    final StringBuilder sb = new StringBuilder();
+                    for (int i = 0; i < 4; i++) {
+                        sb.append((char)('a' + random.nextInt(25)));
+                    }
+
+                    prefix = sb.toString();
+                } while (prefixes.containsValue(prefix));
+            }
+
+            prefixes.put(qname.getNamespace(), prefix);
+        }
+
+        return prefix + ':' + qname.getLocalName();
+    }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/XmlDocumentUtils.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/XmlDocumentUtils.java
new file mode 100644 (file)
index 0000000..127aa07
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * 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.remote.rpc.utils;
+
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider;
+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.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.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import javax.activation.UnsupportedDataTypeException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.dom.DOMResult;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkState;
+
+public class XmlDocumentUtils {
+  private static class ElementWithSchemaContext {
+    Element element;
+    SchemaContext schemaContext;
+
+    ElementWithSchemaContext(final Element element,final SchemaContext schemaContext) {
+      this.schemaContext = schemaContext;
+      this.element = element;
+    }
+
+    Element getElement() {
+      return element;
+    }
+
+    SchemaContext getSchemaContext() {
+      return schemaContext;
+    }
+  }
+
+  public static final QName OPERATION_ATTRIBUTE_QNAME = QName.create(URI.create("urn:ietf:params:xml:ns:netconf:base:1.0"), null, "operation");
+  private static final Logger logger = LoggerFactory.getLogger(XmlDocumentUtils.class);
+  private static final XMLOutputFactory FACTORY = XMLOutputFactory.newFactory();
+
+  /**
+   * Converts Data DOM structure to XML Document for specified XML Codec Provider and corresponding
+   * Data Node Container schema. The CompositeNode data parameter enters as root of Data DOM tree and will
+   * be transformed to root in XML Document. Each element of Data DOM tree is compared against specified Data
+   * Node Container Schema and transformed accordingly.
+   *
+   * @param data Data DOM root element
+   * @param schema Data Node Container Schema
+   * @param codecProvider XML Codec Provider
+   * @return new instance of XML Document
+   * @throws javax.activation.UnsupportedDataTypeException
+   */
+  public static Document toDocument(final CompositeNode data, final DataNodeContainer schema, final XmlCodecProvider codecProvider)
+      throws UnsupportedDataTypeException {
+    Preconditions.checkNotNull(data);
+    Preconditions.checkNotNull(schema);
+
+    if (!(schema instanceof ContainerSchemaNode || schema instanceof ListSchemaNode)) {
+      throw new UnsupportedDataTypeException("Schema can be ContainerSchemaNode or ListSchemaNode. Other types are not supported yet.");
+    }
+
+    final DOMResult result = new DOMResult(getDocument());
+    try {
+      final XMLStreamWriter writer = FACTORY.createXMLStreamWriter(result);
+      XmlStreamUtils.create(codecProvider).writeDocument(writer, data, (SchemaNode)schema);
+      writer.close();
+      return (Document)result.getNode();
+    } catch (XMLStreamException e) {
+      logger.error("Failed to serialize data {}", data, e);
+      return null;
+    }
+  }
+
+  public static Document getDocument() {
+    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+    Document doc = null;
+    try {
+      DocumentBuilder bob = dbf.newDocumentBuilder();
+      doc = bob.newDocument();
+    } catch (ParserConfigurationException e) {
+      throw new RuntimeException(e);
+    }
+    return doc;
+  }
+
+
+  public static QName qNameFromElement(final Element xmlElement) {
+    String namespace = xmlElement.getNamespaceURI();
+    String localName = xmlElement.getLocalName();
+    return QName.create(namespace != null ? URI.create(namespace) : null, null, localName);
+  }
+
+  private static Node<?> toNodeWithSchema(final Element xmlElement, final DataSchemaNode schema, final XmlCodecProvider codecProvider,final SchemaContext schemaCtx) {
+    checkQName(xmlElement, schema.getQName());
+    if (schema instanceof DataNodeContainer) {
+      return toCompositeNodeWithSchema(xmlElement, schema.getQName(), (DataNodeContainer) schema, schemaCtx);
+    } else if (schema instanceof LeafSchemaNode) {
+      return toSimpleNodeWithType(xmlElement, (LeafSchemaNode) schema, codecProvider,schemaCtx);
+    } else if (schema instanceof LeafListSchemaNode) {
+      return toSimpleNodeWithType(xmlElement, (LeafListSchemaNode) schema, codecProvider,schemaCtx);
+    }
+    return null;
+  }
+
+
+
+  private static Node<?> toSimpleNodeWithType(final Element xmlElement, final LeafSchemaNode schema,
+                                              final XmlCodecProvider codecProvider,final SchemaContext schemaCtx) {
+    TypeDefinitionAwareCodec<? extends Object, ? extends TypeDefinition<?>> codec = codecProvider.codecFor(schema.getType());
+    String text = xmlElement.getTextContent();
+    Object value = null;
+    if (codec != null) {
+      logger.debug("toSimpleNodeWithType: found codec, deserializing text {}", text);
+      value = codec.deserialize(text);
+    }
+
+    final TypeDefinition<?> baseType = XmlUtils.resolveBaseTypeFrom(schema.getType());
+    if (baseType instanceof org.opendaylight.yangtools.yang.model.util.InstanceIdentifier) {
+      logger.debug("toSimpleNodeWithType: base type of node is instance identifier, deserializing element", xmlElement);
+      value = InstanceIdentifierForXmlCodec.deserialize(xmlElement,schemaCtx);
+
+    } else if(baseType instanceof IdentityrefTypeDefinition){
+      logger.debug("toSimpleNodeWithType: base type of node is IdentityrefTypeDefinition, deserializing element", xmlElement);
+      value = InstanceIdentifierForXmlCodec.toIdentity(xmlElement.getTextContent(), xmlElement, schemaCtx);
+
+    }
+
+    if (value == null) {
+      logger.debug("toSimpleNodeWithType: no type found for element, returning just the text string value of element {}", xmlElement);
+      value = xmlElement.getTextContent();
+    }
+
+    Optional<ModifyAction> modifyAction = getModifyOperationFromAttributes(xmlElement);
+    return new SimpleNodeTOImpl<>(schema.getQName(), null, value, modifyAction.orNull());
+  }
+
+  private static Node<?> toSimpleNodeWithType(final Element xmlElement, final LeafListSchemaNode schema,
+                                              final XmlCodecProvider codecProvider,final SchemaContext schemaCtx) {
+    TypeDefinitionAwareCodec<? extends Object, ? extends TypeDefinition<?>> codec = codecProvider.codecFor(schema.getType());
+    String text = xmlElement.getTextContent();
+    Object value = null;
+    if (codec != null) {
+      logger.debug("toSimpleNodeWithType: found codec, deserializing text {}", text);
+      value = codec.deserialize(text);
+    }
+
+    if (schema.getType() instanceof org.opendaylight.yangtools.yang.model.util.InstanceIdentifier) {
+      logger.debug("toSimpleNodeWithType: base type of node is instance identifier, deserializing element", xmlElement);
+      value = InstanceIdentifierForXmlCodec.deserialize(xmlElement,schemaCtx);
+    }
+
+    if (value == null) {
+      logger.debug("toSimpleNodeWithType: no type found for element, returning just the text string value of element {}", xmlElement);
+      value = xmlElement.getTextContent();
+    }
+
+    Optional<ModifyAction> modifyAction = getModifyOperationFromAttributes(xmlElement);
+    return new SimpleNodeTOImpl<>(schema.getQName(), null, value, modifyAction.orNull());
+  }
+
+  private static Node<?> toCompositeNodeWithSchema(final Element xmlElement, final QName qName, final DataNodeContainer schema,
+                                                   final SchemaContext schemaCtx) {
+    List<Node<?>> values = toDomNodes(xmlElement, Optional.fromNullable(schema.getChildNodes()),schemaCtx);
+    Optional<ModifyAction> modifyAction = getModifyOperationFromAttributes(xmlElement);
+    return ImmutableCompositeNode.create(qName, values, modifyAction.orNull());
+  }
+
+  private static Optional<ModifyAction> getModifyOperationFromAttributes(final Element xmlElement) {
+    Attr attributeNodeNS = xmlElement.getAttributeNodeNS(OPERATION_ATTRIBUTE_QNAME.getNamespace().toString(), OPERATION_ATTRIBUTE_QNAME.getLocalName());
+    if(attributeNodeNS == null) {
+      return Optional.absent();
+    }
+
+    ModifyAction action = ModifyAction.fromXmlValue(attributeNodeNS.getValue());
+    Preconditions.checkArgument(action.isOnElementPermitted(), "Unexpected operation %s on %s", action, xmlElement);
+
+    return Optional.of(action);
+  }
+
+  private static void checkQName(final Element xmlElement, final QName qName) {
+    checkState(Objects.equal(xmlElement.getNamespaceURI(), qName.getNamespace().toString()));
+    checkState(qName.getLocalName().equals(xmlElement.getLocalName()));
+  }
+
+  public static final Optional<DataSchemaNode> findFirstSchema(final QName qname, final Collection<DataSchemaNode> dataSchemaNode) {
+    if (dataSchemaNode != null && !dataSchemaNode.isEmpty() && qname != null) {
+      for (DataSchemaNode dsn : dataSchemaNode) {
+        if (qname.isEqualWithoutRevision(dsn.getQName())) {
+          return Optional.<DataSchemaNode> of(dsn);
+        } else if (dsn instanceof ChoiceNode) {
+          for (ChoiceCaseNode choiceCase : ((ChoiceNode) dsn).getCases()) {
+            Optional<DataSchemaNode> foundDsn = findFirstSchema(qname, choiceCase.getChildNodes());
+            if (foundDsn != null && foundDsn.isPresent()) {
+              return foundDsn;
+            }
+          }
+        }
+      }
+    }
+    return Optional.absent();
+  }
+
+  private static Node<?> toDomNode(Element element) {
+    QName qname = qNameFromElement(element);
+
+    ImmutableList.Builder<Node<?>> values = ImmutableList.<Node<?>> builder();
+    NodeList nodes = element.getChildNodes();
+    boolean isSimpleObject = true;
+    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(toDomNode((Element) child));
+      }
+      if (isSimpleObject && child instanceof org.w3c.dom.Text) {
+        value = element.getTextContent();
+        if (!Strings.isNullOrEmpty(value)) {
+          isSimpleObject = true;
+        }
+      }
+    }
+    if (isSimpleObject) {
+      return new SimpleNodeTOImpl<>(qname, null, value);
+    }
+    return ImmutableCompositeNode.create(qname, values.build());
+  }
+
+  public static List<Node<?>> toDomNodes(final Element element, final Optional<Collection<DataSchemaNode>> context,SchemaContext schemaCtx) {
+    return forEachChild(element.getChildNodes(),schemaCtx, new Function<ElementWithSchemaContext, Optional<Node<?>>>() {
+
+      @Override
+      public Optional<Node<?>> apply(ElementWithSchemaContext input) {
+        if (context.isPresent()) {
+          QName partialQName = qNameFromElement(input.getElement());
+          Optional<DataSchemaNode> schemaNode = XmlDocumentUtils.findFirstSchema(partialQName, context.get());
+          if (schemaNode.isPresent()) {
+            return Optional.<Node<?>> fromNullable(//
+                toNodeWithSchema(input.getElement(), schemaNode.get(), XmlDocumentUtils.defaultValueCodecProvider(),input.getSchemaContext()));
+          }
+        }
+        return Optional.<Node<?>> fromNullable(toDomNode(input.getElement()));
+      }
+
+    });
+
+  }
+
+  private static final <T> List<T> forEachChild(final NodeList nodes, final SchemaContext schemaContext, final Function<ElementWithSchemaContext, Optional<T>> forBody) {
+    final int l = nodes.getLength();
+    if (l == 0) {
+      return ImmutableList.of();
+    }
+
+    final List<T> list = new ArrayList<>(l);
+    for (int i = 0; i < l; i++) {
+      org.w3c.dom.Node child = nodes.item(i);
+      if (child instanceof Element) {
+        Optional<T> result = forBody.apply(new ElementWithSchemaContext((Element) child,schemaContext));
+        if (result.isPresent()) {
+          list.add(result.get());
+        }
+      }
+    }
+    return ImmutableList.copyOf(list);
+  }
+
+  public static final XmlCodecProvider defaultValueCodecProvider() {
+    return XmlUtils.DEFAULT_XML_CODEC_PROVIDER;
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/XmlStreamUtils.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/XmlStreamUtils.java
new file mode 100644 (file)
index 0000000..e4576c4
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.remote.rpc.utils;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
+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.data.api.YangInstanceIdentifier;
+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.schema.SchemaUtils;
+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.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import java.net.URI;
+import java.util.Map.Entry;
+
+/**
+ * Utility class for bridging JAXP Stream and YANG Data APIs. Note that the definition of this class
+ * by no means final and subject to change as more functionality is centralized here.
+ */
+@Beta
+public class XmlStreamUtils {
+  private static final Logger LOG = LoggerFactory.getLogger(XmlStreamUtils.class);
+  private final XmlCodecProvider codecProvider;
+
+  protected XmlStreamUtils(final XmlCodecProvider codecProvider) {
+    this.codecProvider = Preconditions.checkNotNull(codecProvider);
+  }
+
+  /**
+   * Create a new instance encapsulating a particular codec provider.
+   *
+   * @param codecProvider XML codec provider
+   * @return A new instance
+   */
+  public static XmlStreamUtils create(final XmlCodecProvider codecProvider) {
+    return new XmlStreamUtils(codecProvider);
+  }
+
+  /**
+   * Check if a particular data element can be emitted as an empty element, bypassing value encoding. This
+   * functionality is optional, as valid XML stream is produced even if start/end element is produced unconditionally.
+   *
+   * @param data Data node
+   * @return True if the data node will result in empty element body.
+   */
+  public static boolean isEmptyElement(final Node<?> data) {
+    if (data == null) {
+      return true;
+    }
+
+    if (data instanceof CompositeNode) {
+      return ((CompositeNode) data).getValue().isEmpty();
+    }
+    if (data instanceof SimpleNode) {
+      return data.getValue() == null;
+    }
+
+    // Safe default
+    return false;
+  }
+
+  /**
+   * Write an InstanceIdentifier into the output stream. Calling corresponding {@link javax.xml.stream.XMLStreamWriter#writeStartElement(String)}
+   * and {@link javax.xml.stream.XMLStreamWriter#writeEndElement()} is the responsibility of the caller.
+   *
+   * @param writer XML Stream writer
+   * @param id InstanceIdentifier
+   * @throws javax.xml.stream.XMLStreamException
+   */
+  public static void write(final @Nonnull XMLStreamWriter writer, final @Nonnull YangInstanceIdentifier id) throws XMLStreamException {
+    Preconditions.checkNotNull(writer, "Writer may not be null");
+    Preconditions.checkNotNull(id, "Variable should contain instance of instance identifier and can't be null");
+    LOG.debug("Writing Instance identifier with Random prefix");
+    final RandomPrefix prefixes = new RandomPrefix();
+    final String str = XmlUtils.encodeIdentifier(prefixes, id);
+
+    for (Entry<URI, String> e: prefixes.getPrefixes()) {
+      writer.writeNamespace(e.getValue(), e.getKey().toString());
+    }
+    LOG.debug("Instance identifier with Random prefix is now {}", str);
+    writer.writeCharacters(str);
+  }
+
+  /**
+   * Write a full XML document corresponding to a CompositeNode into an XML stream writer.
+   *
+   * @param writer XML Stream writer
+   * @param data data node
+   * @param schema corresponding schema node, may be null
+   * @throws javax.xml.stream.XMLStreamException if an encoding problem occurs
+   */
+  public void writeDocument(final @Nonnull XMLStreamWriter writer, final @Nonnull CompositeNode data, final @Nullable SchemaNode schema) throws XMLStreamException {
+    // final Boolean repairing = (Boolean) writer.getProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES);
+    // Preconditions.checkArgument(repairing == true, "XML Stream Writer has to be repairing namespaces");
+
+    writer.writeStartDocument();
+    writeElement(writer, data, schema);
+    writer.writeEndDocument();
+    writer.flush();
+  }
+
+
+  /**
+   * Write an element into a XML stream writer. This includes the element start/end tags and
+   * the value of the element.
+   *
+   * @param writer XML Stream writer
+   * @param data data node
+   * @param schema Schema node
+   * @throws javax.xml.stream.XMLStreamException if an encoding problem occurs
+   */
+  public void writeElement(final XMLStreamWriter writer, final @Nonnull Node<?> data, final SchemaNode schema) throws XMLStreamException {
+    final QName qname = data.getNodeType();
+    final String pfx = qname.getPrefix() != null ? qname.getPrefix() : "";
+    final String ns = qname.getNamespace() != null ? qname.getNamespace().toString() : "";
+
+    if (isEmptyElement(data)) {
+      writer.writeEmptyElement(pfx, qname.getLocalName(), ns);
+      return;
+    }
+
+    writer.writeStartElement(pfx, qname.getLocalName(), ns);
+    if (data instanceof AttributesContainer && ((AttributesContainer) data).getAttributes() != null) {
+      for (Entry<QName, String> attribute : ((AttributesContainer) data).getAttributes().entrySet()) {
+        writer.writeAttribute(attribute.getKey().getNamespace().toString(), attribute.getKey().getLocalName(), attribute.getValue());
+      }
+    }
+
+    if (data instanceof SimpleNode<?>) {
+      LOG.debug("writeElement : node is of type SimpleNode");
+      // Simple node
+      if (schema instanceof LeafListSchemaNode) {
+        writeValue(writer, ((LeafListSchemaNode) schema).getType(), data.getValue());
+      } else if (schema instanceof LeafSchemaNode) {
+        writeValue(writer, ((LeafSchemaNode) schema).getType(), data.getValue());
+      } else {
+        Object value = data.getValue();
+        if (value != null) {
+          writer.writeCharacters(String.valueOf(value));
+        }
+      }
+    } else {
+      LOG.debug("writeElement : node is of type CompositeNode");
+      // CompositeNode
+      for (Node<?> child : ((CompositeNode) data).getValue()) {
+        DataSchemaNode childSchema = null;
+        if (schema instanceof DataNodeContainer) {
+          childSchema = SchemaUtils.findFirstSchema(child.getNodeType(), ((DataNodeContainer) schema).getChildNodes()).orNull();
+          if (childSchema == null) {
+            LOG.debug("Probably the data node \"{}\" does not conform to schema", child == null ? "" : child.getNodeType().getLocalName());
+          }
+        }
+
+        writeElement(writer, child, childSchema);
+      }
+    }
+
+    writer.writeEndElement();
+  }
+
+  /**
+   * Write a value into a XML stream writer. This method assumes the start and end of element is
+   * emitted by the caller.
+   *
+   * @param writer XML Stream writer
+   * @param type type definitions
+   * @param value object value
+   * @throws javax.xml.stream.XMLStreamException if an encoding problem occurs
+   */
+  public void writeValue(final @Nonnull XMLStreamWriter writer, final @Nonnull TypeDefinition<?> type, final Object value) throws XMLStreamException {
+    if (value == null) {
+      LOG.debug("Value of {}:{} is null, not encoding it", type.getQName().getNamespace(), type.getQName().getLocalName());
+      return;
+    }
+
+    final TypeDefinition<?> baseType = XmlUtils.resolveBaseTypeFrom(type);
+    if (baseType instanceof IdentityrefTypeDefinition) {
+      write(writer, (IdentityrefTypeDefinition) baseType, value);
+    } else if (baseType instanceof InstanceIdentifierTypeDefinition) {
+      write(writer, (InstanceIdentifierTypeDefinition) baseType, value);
+    } else {
+      final TypeDefinitionAwareCodec<Object, ?> codec = codecProvider.codecFor(baseType);
+      String text;
+      if (codec != null) {
+        try {
+          text = codec.serialize(value);
+        } catch (ClassCastException e) {
+          LOG.error("Provided node value {} did not have type {} required by mapping. Using stream instead.", value, baseType, e);
+          text = String.valueOf(value);
+        }
+      } else {
+        LOG.error("Failed to find codec for {}, falling back to using stream", baseType);
+        text = String.valueOf(value);
+      }
+      writer.writeCharacters(text);
+    }
+  }
+
+  private static void write(final @Nonnull XMLStreamWriter writer, final @Nonnull IdentityrefTypeDefinition type, final @Nonnull Object value) throws XMLStreamException {
+    if (value instanceof QName) {
+      final QName qname = (QName) value;
+      final String prefix;
+      if (qname.getPrefix() != null && !qname.getPrefix().isEmpty()) {
+        prefix = qname.getPrefix();
+      } else {
+        prefix = "x";
+      }
+
+      writer.writeNamespace(prefix, qname.getNamespace().toString());
+      writer.writeCharacters(prefix + ':' + qname.getLocalName());
+    } else {
+      LOG.debug("Value of {}:{} is not a QName but {}", type.getQName().getNamespace(), type.getQName().getLocalName(), value.getClass());
+      writer.writeCharacters(String.valueOf(value));
+    }
+  }
+
+  private static void write(final @Nonnull XMLStreamWriter writer, final @Nonnull InstanceIdentifierTypeDefinition type, final @Nonnull Object value) throws XMLStreamException {
+    if (value instanceof YangInstanceIdentifier) {
+      LOG.debug("Writing InstanceIdentifier object {}", value);
+      write(writer, (YangInstanceIdentifier)value);
+    } else {
+      LOG.debug("Value of {}:{} is not an InstanceIdentifier but {}", type.getQName().getNamespace(), type.getQName().getLocalName(), value.getClass());
+      writer.writeCharacters(String.valueOf(value));
+    }
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/XmlUtils.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/XmlUtils.java
new file mode 100644 (file)
index 0000000..e07401a
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.remote.rpc.utils;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+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.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
+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.util.CompositeNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import javax.activation.UnsupportedDataTypeException;
+import javax.annotation.Nonnull;
+import javax.xml.stream.XMLStreamException;
+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 java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Common XML-related utility methods, which are not specific to a particular
+ * JAXP API.
+ */
+public class XmlUtils {
+
+  public static final XmlCodecProvider DEFAULT_XML_CODEC_PROVIDER = new XmlCodecProvider() {
+    @Override
+    public TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> codecFor(final TypeDefinition<?> baseType) {
+      return TypeDefinitionAwareCodec.from(baseType);
+    }
+  };
+
+  private XmlUtils() {
+  }
+
+  private static final String BLANK = "";
+  private static final Logger LOG = LoggerFactory.getLogger(XmlUtils.class);
+
+  /**
+   * Converts the composite node to xml using rpc input schema node
+   * @param cNode
+   * @param schemaContext
+   * @return xml String
+   */
+  public static String inputCompositeNodeToXml(CompositeNode cNode, SchemaContext schemaContext){
+    LOG.debug("Converting input composite node to xml {}", cNode);
+    if (cNode == null) return BLANK;
+
+    if(schemaContext == null) return BLANK;
+
+    Document domTree = null;
+    try {
+      Set<RpcDefinition> rpcs =  schemaContext.getOperations();
+      for(RpcDefinition rpc : rpcs) {
+        if(rpc.getQName().equals(cNode.getNodeType())){
+          LOG.debug("Found the rpc definition from schema context matching with input composite node  {}", rpc.getQName());
+
+          CompositeNode inputContainer = cNode.getFirstCompositeByName(QName.create(cNode.getNodeType(), "input"));
+          domTree = XmlDocumentUtils.toDocument(inputContainer, rpc.getInput(), XmlDocumentUtils.defaultValueCodecProvider());
+
+          LOG.debug("input composite node to document conversion complete, document is   {}", domTree);
+          break;
+        }
+      }
+
+    } catch (UnsupportedDataTypeException e) {
+      LOG.error("Error during translation of CompositeNode to Document", e);
+    }
+    return domTransformer(domTree);
+  }
+
+  /**
+   * Converts the composite node to xml String using rpc output schema node
+   * @param cNode
+   * @param schemaContext
+   * @return xml string
+   */
+  public static String outputCompositeNodeToXml(CompositeNode cNode, SchemaContext schemaContext){
+    LOG.debug("Converting output composite node to xml {}", cNode);
+    if (cNode == null) return BLANK;
+
+    if(schemaContext == null) return BLANK;
+
+    Document domTree = null;
+    try {
+      Set<RpcDefinition> rpcs =  schemaContext.getOperations();
+      for(RpcDefinition rpc : rpcs) {
+        if(rpc.getQName().equals(cNode.getNodeType())){
+          LOG.debug("Found the rpc definition from schema context matching with output composite node  {}", rpc.getQName());
+
+          CompositeNode outputContainer = cNode.getFirstCompositeByName(QName.create(cNode.getNodeType(), "output"));
+          domTree = XmlDocumentUtils.toDocument(outputContainer, rpc.getOutput(), XmlDocumentUtils.defaultValueCodecProvider());
+
+          LOG.debug("output composite node to document conversion complete, document is   {}", domTree);
+          break;
+        }
+      }
+
+    } catch (UnsupportedDataTypeException e) {
+      LOG.error("Error during translation of CompositeNode to Document", e);
+    }
+    return domTransformer(domTree);
+  }
+
+  private static String domTransformer(Document domTree) {
+    StringWriter writer = new StringWriter();
+    try {
+      TransformerFactory tf = TransformerFactory.newInstance();
+      Transformer transformer = tf.newTransformer();
+      transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+      transformer.transform(new DOMSource(domTree), new StreamResult(writer));
+    } catch (TransformerException e) {
+
+      LOG.error("Error during translation of Document to OutputStream", e);
+    }
+    LOG.debug("Document to string conversion complete, xml string is  {} ",  writer.toString());
+
+    return writer.toString();
+  }
+
+  public static CompositeNode xmlToCompositeNode(String xml){
+    if (xml==null || xml.length()==0) return null;
+
+    Node<?> dataTree;
+    try {
+      dataTree = XmlTreeBuilder.buildDataTree(new ByteArrayInputStream(xml.getBytes()));
+    } catch (XMLStreamException e) {
+      LOG.error("Error during building data tree from XML", e);
+      return null;
+    }
+    if (dataTree == null) {
+      LOG.error("data tree is null");
+      return null;
+    }
+    if (dataTree instanceof SimpleNode) {
+      LOG.error("RPC XML was resolved as SimpleNode");
+      return null;
+    }
+    return (CompositeNode) dataTree;
+  }
+
+  /**
+   * Converts the xml to composite node using rpc input schema node
+   * @param rpc
+   * @param xml
+   * @param schemaContext
+   * @return CompositeNode object based on the input, if any of the input parameter is null, a null object is returned
+   */
+  public static CompositeNode inputXmlToCompositeNode(QName rpc, String xml,  SchemaContext schemaContext){
+    LOG.debug("Converting input xml to composite node {}", xml);
+    if (xml==null || xml.length()==0) return null;
+
+    if(rpc == null) return null;
+
+    if(schemaContext == null) return null;
+
+    CompositeNode compositeNode = null;
+    try {
+
+      Document doc = XmlUtil.readXmlToDocument(xml);
+      Set<RpcDefinition> rpcs =  schemaContext.getOperations();
+      for(RpcDefinition rpcDef : rpcs) {
+        if(rpcDef.getQName().equals(rpc)){
+          LOG.debug("found the rpc definition from schema context matching rpc  {}", rpc);
+
+          if(rpcDef.getInput() == null) {
+            LOG.warn("found rpc definition's input is null");
+            return null;
+          }
+
+          QName input = rpcDef.getInput().getQName();
+          NodeList nodeList = doc.getElementsByTagNameNS(input.getNamespace().toString(), "input");
+          if(nodeList == null || nodeList.getLength() < 1) {
+            LOG.warn("xml does not have input entry. {}", xml);
+            return null;
+          }
+          Element xmlData = (Element)nodeList.item(0);
+
+          List<Node<?>> dataNodes = XmlDocumentUtils.toDomNodes(xmlData,
+              Optional.of(rpcDef.getInput().getChildNodes()), schemaContext);
+
+          LOG.debug("Converted xml input to list of nodes  {}", dataNodes);
+
+          final CompositeNodeBuilder<ImmutableCompositeNode> it = ImmutableCompositeNode.builder();
+          it.setQName(input);
+          it.add(ImmutableCompositeNode.create(input, dataNodes));
+          compositeNode = it.toInstance();
+          break;
+        }
+      }
+    } catch (SAXException e) {
+      LOG.error("Error during building data tree from XML", e);
+    } catch (IOException e) {
+      LOG.error("Error during building data tree from XML", e);
+    }
+
+    LOG.debug("Xml to composite node conversion complete {} ", compositeNode);
+    return compositeNode;
+  }
+
+  public static TypeDefinition<?> resolveBaseTypeFrom(final @Nonnull TypeDefinition<?> type) {
+    TypeDefinition<?> superType = type;
+    while (superType.getBaseType() != null) {
+      superType = superType.getBaseType();
+    }
+    return superType;
+  }
+
+  /**
+   * This code is picked from yangtools and modified to add type of instance identifier
+   * output of instance identifier something like below for a flow ref composite node of type instance identifier,
+   * which has path arguments with predicates, whose value is of type java.lang.short
+   * <flow-ref xmlns:bgkj="urn:opendaylight:flow:inventory" xmlns:jdlk="urn:opendaylight:inventory">
+   *   /jdlk:nodes/jdlk:node[jdlk:id='openflow:205558455098190@java.lang.String']
+   *   /bgkj:table[bgkj:id='3@java.lang.Short']
+   *   /bgkj:flow[bgkj:id='156@java.lang.String']
+   * </flow-ref>
+   *
+   */
+
+  public static String encodeIdentifier(final RandomPrefix prefixes, final YangInstanceIdentifier id) {
+    StringBuilder textContent = new StringBuilder();
+    for (PathArgument pathArgument : id.getPathArguments()) {
+      textContent.append('/');
+      textContent.append(prefixes.encodeQName(pathArgument.getNodeType()));
+      if (pathArgument instanceof NodeIdentifierWithPredicates) {
+        Map<QName, Object> predicates = ((NodeIdentifierWithPredicates) pathArgument).getKeyValues();
+
+        for (QName keyValue : predicates.keySet()) {
+          Object value = predicates.get(keyValue);
+          String type = value.getClass().getName();
+          String predicateValue = String.valueOf(value);
+          textContent.append('[');
+          textContent.append(prefixes.encodeQName(keyValue));
+          textContent.append("='");
+          textContent.append(predicateValue);
+          textContent.append("@");
+          textContent.append(type);
+          textContent.append("']");
+        }
+      } else if (pathArgument instanceof NodeWithValue) {
+        textContent.append("[.='");
+        textContent.append(((NodeWithValue) pathArgument).getValue());
+        textContent.append("']");
+      }
+    }
+
+    return textContent.toString();
+  }
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/resources/application.conf b/opendaylight/md-sal/sal-remoterpc-connector/src/main/resources/application.conf
new file mode 100644 (file)
index 0000000..6088dd0
--- /dev/null
@@ -0,0 +1,21 @@
+odl-cluster{
+  akka {
+    actor {
+      provider = "akka.cluster.ClusterActorRefProvider"
+
+    }
+    remote {
+      log-remote-lifecycle-events = off
+      netty.tcp {
+        hostname = "192.168.141.141"
+        port = 2551
+      }
+    }
+
+    cluster {
+      seed-nodes = ["akka.tcp://opendaylight-rpc@192.168.141.141:2551"]
+
+      auto-down-unreachable-after = 10s
+    }
+  }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/yang/remote-rpc-connector.yang b/opendaylight/md-sal/sal-remoterpc-connector/src/main/yang/remote-rpc-connector.yang
new file mode 100644 (file)
index 0000000..08db5c0
--- /dev/null
@@ -0,0 +1,40 @@
+module remote-rpc-connector {
+       yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:config:remote-rpc-connector";
+    prefix "remote-rpc-connector";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import opendaylight-md-sal-dom {prefix dom;}
+    
+    description
+        "This module contains the base YANG definitions for
+                 the remote routed rpc";
+    revision "2014-07-07" {
+        description
+            "Initial revision";
+    }
+
+    // This is the definition of the service implementation as a module identity.
+    identity remote-rpc-connector {
+      base config:module-type;
+      // Specifies the prefix for generated java classes.
+      config:java-name-prefix RemoteRPCBroker;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case remote-rpc-connector {
+            when "/config:modules/config:module/config:type = 'remote-rpc-connector'";
+            
+            container dom-broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity dom:dom-broker-osgi-registry;
+                    }
+                }
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/RpcBrokerTest.java b/opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/RpcBrokerTest.java
new file mode 100644 (file)
index 0000000..392c1e6
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc;
+
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.testkit.JavaTestKit;
+import com.google.common.util.concurrent.Futures;
+import junit.framework.Assert;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.remote.rpc.messages.AddRoutedRpc;
+import org.opendaylight.controller.remote.rpc.messages.AddRpc;
+import org.opendaylight.controller.remote.rpc.messages.ErrorResponse;
+import org.opendaylight.controller.remote.rpc.messages.InvokeRoutedRpc;
+import org.opendaylight.controller.remote.rpc.messages.InvokeRpc;
+import org.opendaylight.controller.remote.rpc.messages.RpcResponse;
+import org.opendaylight.controller.remote.rpc.registry.ClusterWrapper;
+import org.opendaylight.controller.remote.rpc.registry.RpcRegistry;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
+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.Node;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class RpcBrokerTest {
+
+  static ActorSystem system;
+
+
+  @BeforeClass
+  public static void setup() {
+    system = ActorSystem.create();
+  }
+
+  @AfterClass
+  public static void teardown() {
+    JavaTestKit.shutdownActorSystem(system);
+    system = null;
+  }
+
+  @Test
+  public void testInvokeRpcError() throws URISyntaxException {
+    new JavaTestKit(system) {{
+      ActorRef rpcRegistry = system.actorOf(RpcRegistry.props(Mockito.mock(ClusterWrapper.class)));
+      Broker.ProviderSession brokerSession = Mockito.mock(Broker.ProviderSession.class);
+      SchemaContext schemaContext = mock(SchemaContext.class);
+      ActorRef rpcBroker = system.actorOf(RpcBroker.props(brokerSession, rpcRegistry, schemaContext));
+      QName rpc = new QName(new URI("noactor1"), "noactor1");
+      CompositeNode input = new ImmutableCompositeNode(QName.create("ns", "2013-12-09", "no child"), new ArrayList<Node<?>>(), ModifyAction.REPLACE);
+      InvokeRpc invokeMsg = new InvokeRpc(rpc, input);
+      rpcBroker.tell(invokeMsg, getRef());
+
+      Boolean getMsg = new ExpectMsg<Boolean>("ErrorResponse") {
+        protected Boolean match(Object in) {
+          if (in instanceof ErrorResponse) {
+            ErrorResponse reply = (ErrorResponse)in;
+            return reply.getException().getMessage().contains("No remote actor found for rpc execution of :");
+          } else {
+            throw noMatch();
+          }
+        }
+      }.get(); // this extracts the received message
+
+      Assert.assertTrue(getMsg);
+    }};
+  }
+
+  /**
+   * This test method invokes and executes the remote rpc
+   */
+
+  @Test
+  public void testInvokeRpc() throws URISyntaxException {
+    new JavaTestKit(system) {{
+      ActorRef rpcRegistry = system.actorOf(RpcRegistry.props(mock(ClusterWrapper.class)));
+      Broker.ProviderSession brokerSession = mock(Broker.ProviderSession.class);
+      SchemaContext schemaContext = mock(SchemaContext.class);
+      ActorRef rpcBroker = system.actorOf(RpcBroker.props(brokerSession, rpcRegistry, schemaContext));
+      ActorRef rpcBrokerRemote = system.actorOf(RpcBroker.props(brokerSession, rpcRegistry, schemaContext), "actor1");
+      // Add RPC in table
+      QName rpc = new QName(new URI("actor1"), "actor1");
+      RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, rpc, null);
+      final String route = rpcBrokerRemote.path().toString();
+      AddRpc rpcMsg = new AddRpc(routeId, route);
+      rpcRegistry.tell(rpcMsg, getRef());
+      expectMsgEquals(duration("2 second"), "Success");
+
+      // invoke rpc
+      CompositeNode input = new ImmutableCompositeNode(QName.create("ns", "2013-12-09", "child1"), new ArrayList<Node<?>>(), ModifyAction.REPLACE);
+      CompositeNode invokeRpcResult = mock(CompositeNode.class);
+      Collection<RpcError> errors = new ArrayList<>();
+      RpcResult<CompositeNode> result = Rpcs.getRpcResult(true, invokeRpcResult, errors);
+      Future<RpcResult<CompositeNode>> rpcResult = Futures.immediateFuture(result);
+      when(brokerSession.rpc(rpc, input)).thenReturn(rpcResult);
+      InvokeRpc invokeMsg = new InvokeRpc(rpc, input);
+      rpcBroker.tell(invokeMsg, getRef());
+
+      //verify response msg
+      Boolean getMsg = new ExpectMsg<Boolean>("RpcResponse") {
+        protected Boolean match(Object in) {
+          if (in instanceof RpcResponse) {
+            return true;
+          } else {
+            throw noMatch();
+          }
+        }
+      }.get(); // this extracts the received message
+
+      Assert.assertTrue(getMsg);
+    }};
+  }
+
+  @Test
+  public void testInvokeRoutedRpcError() throws URISyntaxException {
+    new JavaTestKit(system) {{
+      ActorRef rpcRegistry = system.actorOf(RpcRegistry.props(Mockito.mock(ClusterWrapper.class)));
+      Broker.ProviderSession brokerSession = Mockito.mock(Broker.ProviderSession.class);
+      SchemaContext schemaContext = mock(SchemaContext.class);
+      ActorRef rpcBroker = system.actorOf(RpcBroker.props(brokerSession, rpcRegistry, schemaContext));
+      QName rpc = new QName(new URI("actor1"), "actor1");
+      CompositeNode input = new ImmutableCompositeNode(QName.create("ns", "2013-12-09", "child1"), new ArrayList<Node<?>>(), ModifyAction.REPLACE);
+      InvokeRoutedRpc invokeMsg = new InvokeRoutedRpc(rpc, YangInstanceIdentifier.create(new YangInstanceIdentifier.NodeIdentifier(rpc)), input);
+      rpcBroker.tell(invokeMsg, getRef());
+
+      Boolean getMsg = new ExpectMsg<Boolean>("ErrorResponse") {
+        protected Boolean match(Object in) {
+          if (in instanceof ErrorResponse) {
+            ErrorResponse reply = (ErrorResponse)in;
+            return "No remote actor found for rpc execution.".equals(reply.getException().getMessage());
+          } else {
+            throw noMatch();
+          }
+        }
+      }.get(); // this extracts the received message
+
+      Assert.assertTrue(getMsg);
+    }};
+  }
+
+  /**
+   * This test method invokes and executes the remote routed rpc
+   */
+
+  @Test
+  public void testInvokeRoutedRpc() throws URISyntaxException {
+    new JavaTestKit(system) {{
+      ActorRef rpcRegistry = system.actorOf(RpcRegistry.props(mock(ClusterWrapper.class)));
+      Broker.ProviderSession brokerSession = mock(Broker.ProviderSession.class);
+      SchemaContext schemaContext = mock(SchemaContext.class);
+      ActorRef rpcBroker = system.actorOf(RpcBroker.props(brokerSession, rpcRegistry, schemaContext));
+      ActorRef rpcBrokerRemote = system.actorOf(RpcBroker.props(brokerSession, rpcRegistry, schemaContext), "actor2");
+      // Add Routed RPC in table
+      QName rpc = new QName(new URI("actor2"), "actor2");
+      YangInstanceIdentifier identifier = YangInstanceIdentifier.create(new YangInstanceIdentifier.NodeIdentifier(rpc));
+      RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, rpc, identifier);
+      final String route = rpcBrokerRemote.path().toString();
+      Set<RpcRouter.RouteIdentifier<?, ?, ?>> routeIds = new HashSet<>();
+      routeIds.add(routeId);
+
+      AddRoutedRpc rpcMsg = new AddRoutedRpc(routeIds, route);
+      rpcRegistry.tell(rpcMsg, getRef());
+      expectMsgEquals(duration("2 second"), "Success");
+
+      // invoke rpc
+      CompositeNode input = new ImmutableCompositeNode(QName.create("ns", "2013-12-09", "child1"), new ArrayList<Node<?>>(), ModifyAction.REPLACE);
+      CompositeNode invokeRpcResult = mock(CompositeNode.class);
+      Collection<RpcError> errors = new ArrayList<>();
+      RpcResult<CompositeNode> result = Rpcs.getRpcResult(true, invokeRpcResult, errors);
+      Future<RpcResult<CompositeNode>> rpcResult = Futures.immediateFuture(result);
+      when(brokerSession.rpc(rpc, input)).thenReturn(rpcResult);
+      InvokeRoutedRpc invokeMsg = new InvokeRoutedRpc(rpc, identifier, input);
+      rpcBroker.tell(invokeMsg, getRef());
+
+      //verify response msg
+      Boolean getMsg = new ExpectMsg<Boolean>("RpcResponse") {
+        protected Boolean match(Object in) {
+          if (in instanceof RpcResponse) {
+            return true;
+          } else {
+            throw noMatch();
+          }
+        }
+      }.get(); // this extracts the received message
+
+      Assert.assertTrue(getMsg);
+    }};
+  }
+
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/registry/RoutingTableTest.java b/opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/registry/RoutingTableTest.java
new file mode 100644 (file)
index 0000000..129a5a5
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc.registry;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.remote.rpc.RouteIdentifierImpl;
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.opendaylight.yangtools.yang.common.QName;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashSet;
+import java.util.Set;
+
+public class RoutingTableTest {
+
+  private RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> routingTable =
+      new RoutingTable<>();
+
+  @Test
+  public void addGlobalRouteNullRouteIdTest() {
+    try {
+      routingTable.addGlobalRoute(null, null);
+
+      Assert.fail("Null pointer exception was not thrown.");
+    } catch (Exception e) {
+      Assert.assertEquals(NullPointerException.class.getName(), e.getClass().getName());
+      Assert.assertEquals("addGlobalRoute: routeId cannot be null!", e.getMessage());
+    }
+  }
+
+  @Test
+  public void addGlobalRouteNullRouteTest() {
+    try {
+      QName type = new QName(new URI("actor1"), "actor1");
+      RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, type, null);
+      routingTable.addGlobalRoute(routeId, null);
+
+      Assert.fail("Null pointer exception was not thrown.");
+    } catch (Exception e) {
+      Assert.assertEquals(NullPointerException.class.getName(), e.getClass().getName());
+      Assert.assertEquals("addGlobalRoute: route cannot be null!", e.getMessage());
+    }
+  }
+
+  @Test
+  public void getGlobalRouteNullTest() {
+    try {
+      routingTable.getGlobalRoute(null);
+
+      Assert.fail("Null pointer exception was not thrown.");
+    } catch (Exception e) {
+      Assert.assertEquals(NullPointerException.class.getName(), e.getClass().getName());
+      Assert.assertEquals("getGlobalRoute: routeId cannot be null!", e.getMessage());
+    }
+  }
+
+  @Test
+  public void getGlobalRouteTest() throws URISyntaxException {
+    QName type = new QName(new URI("actor1"), "actor1");
+    RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, type, null);
+    String route = "actor1";
+
+    routingTable.addGlobalRoute(routeId, route);
+
+    String returnedRoute = routingTable.getGlobalRoute(routeId);
+
+    Assert.assertEquals(route, returnedRoute);
+
+  }
+
+  @Test
+  public void removeGlobalRouteTest() throws URISyntaxException {
+    QName type = new QName(new URI("actorRemove"), "actorRemove");
+    RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, type, null);
+    String route = "actorRemove";
+
+    routingTable.addGlobalRoute(routeId, route);
+
+    String returnedRoute = routingTable.getGlobalRoute(routeId);
+
+    Assert.assertEquals(route, returnedRoute);
+
+    routingTable.removeGlobalRoute(routeId);
+
+    String deletedRoute = routingTable.getGlobalRoute(routeId);
+
+    Assert.assertNull(deletedRoute);
+  }
+
+  @Test
+  public void addRoutedRpcNullRouteIdTest() {
+    try {
+      routingTable.addRoutedRpc(null, null);
+
+      Assert.fail("Null pointer exception was not thrown.");
+    } catch (Exception e) {
+      Assert.assertEquals(NullPointerException.class.getName(), e.getClass().getName());
+      Assert.assertEquals("addRoute: routeId cannot be null", e.getMessage());
+    }
+  }
+
+  @Test
+  public void addRoutedRpcNullRouteTest() {
+    try {
+      QName type = new QName(new URI("actor1"), "actor1");
+      RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, type, null);
+
+      routingTable.addRoutedRpc(routeId, null);
+
+      Assert.fail("Null pointer exception was not thrown.");
+    } catch (Exception e) {
+      Assert.assertEquals(NullPointerException.class.getName(), e.getClass().getName());
+      Assert.assertEquals("addRoute: route cannot be null", e.getMessage());
+    }
+  }
+
+  @Test
+  public void getRoutedRpcNullTest() {
+    try {
+      routingTable.getRoutedRpc(null);
+
+      Assert.fail("Null pointer exception was not thrown.");
+    } catch (Exception e) {
+      Assert.assertEquals(NullPointerException.class.getName(), e.getClass().getName());
+      Assert.assertEquals("getRoutes: routeId cannot be null!", e.getMessage());
+    }
+  }
+
+  @Test
+  public void getRoutedRpcTest() throws URISyntaxException {
+    QName type = new QName(new URI("actor1"), "actor1");
+    RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, type, null);
+    String route = "actor1";
+
+    routingTable.addRoutedRpc(routeId, route);
+
+    Set<String> routes = routingTable.getRoutedRpc(routeId);
+
+    Assert.assertEquals(1, routes.size());
+    Assert.assertTrue(routes.contains(route));
+
+  }
+
+  @Test
+  public void getLastRoutedRpcTest() throws URISyntaxException {
+    QName type = new QName(new URI("first1"), "first1");
+    RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, type, null);
+    String route = "first1";
+
+    routingTable.addRoutedRpc(routeId, route);
+
+    String route2 = "second1";
+    routingTable.addRoutedRpc(routeId, route2);
+
+    String latest = routingTable.getLastAddedRoutedRpc(routeId);
+    Assert.assertEquals(route2, latest);
+
+  }
+
+  @Test
+  public void removeRoutedRpcTest() throws URISyntaxException {
+    QName type = new QName(new URI("remove"), "remove");
+    RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, type, null);
+    String route = "remove";
+    routingTable.addRoutedRpc(routeId, route);
+
+    String latest = routingTable.getLastAddedRoutedRpc(routeId);
+    Assert.assertEquals(route, latest);
+
+    routingTable.removeRoute(routeId, route);
+    String removed = routingTable.getLastAddedRoutedRpc(routeId);
+    Assert.assertNull(removed);
+  }
+
+  @Test
+  public void removeRoutedRpcsTest() throws URISyntaxException {
+    QName type = new QName(new URI("remove1"), "remove1");
+    RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, type, null);
+
+    QName type2 = new QName(new URI("remove2"), "remove2");
+    RouteIdentifierImpl routeId2 = new RouteIdentifierImpl(null, type2, null);
+
+    Set<RpcRouter.RouteIdentifier<?, ?, ?>> routeIds = new HashSet<>();
+    routeIds.add(routeId);
+    routeIds.add(routeId2);
+    String route = "remove1";
+
+    routingTable.addRoutedRpcs(routeIds, route);
+    String latest1 = routingTable.getLastAddedRoutedRpc(routeId);
+    Assert.assertEquals(route, latest1);
+
+    String latest2 = routingTable.getLastAddedRoutedRpc(routeId2);
+    Assert.assertEquals(route, latest2);
+
+    routingTable.removeRoutes(routeIds, route);
+    String removed1 = routingTable.getLastAddedRoutedRpc(routeId);
+    Assert.assertNull(removed1);
+
+    String removed2 = routingTable.getLastAddedRoutedRpc(routeId2);
+    Assert.assertNull(removed2);
+  }
+
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/registry/RpcRegistryTest.java b/opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/registry/RpcRegistryTest.java
new file mode 100644 (file)
index 0000000..d011d33
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc.registry;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.testkit.JavaTestKit;
+import junit.framework.Assert;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.remote.rpc.RouteIdentifierImpl;
+import org.opendaylight.controller.remote.rpc.messages.AddRoutedRpc;
+import org.opendaylight.controller.remote.rpc.messages.AddRpc;
+import org.opendaylight.controller.remote.rpc.messages.GetRoutedRpc;
+import org.opendaylight.controller.remote.rpc.messages.GetRoutedRpcReply;
+import org.opendaylight.controller.remote.rpc.messages.GetRpc;
+import org.opendaylight.controller.remote.rpc.messages.GetRpcReply;
+import org.opendaylight.controller.remote.rpc.messages.RemoveRoutedRpc;
+import org.opendaylight.controller.remote.rpc.messages.RemoveRpc;
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.opendaylight.yangtools.yang.common.QName;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashSet;
+import java.util.Set;
+
+public class RpcRegistryTest {
+
+  static ActorSystem system;
+
+
+  @BeforeClass
+  public static void setup() {
+    system = ActorSystem.create();
+  }
+
+  @AfterClass
+  public static void teardown() {
+    JavaTestKit.shutdownActorSystem(system);
+    system = null;
+  }
+
+  /**
+   This test add, read and remove an entry in global rpc
+   */
+  @Test
+  public void testGlobalRpc() throws URISyntaxException {
+    new JavaTestKit(system) {{
+      ActorRef rpcRegistry = system.actorOf(RpcRegistry.props(Mockito.mock(ClusterWrapper.class)));
+      QName type = new QName(new URI("actor1"), "actor1");
+      RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, type, null);
+      final String route = "actor1";
+
+      AddRpc rpcMsg = new AddRpc(routeId, route);
+      rpcRegistry.tell(rpcMsg, getRef());
+      expectMsgEquals(duration("2 second"), "Success");
+
+      GetRpc getRpc = new GetRpc(routeId);
+      rpcRegistry.tell(getRpc, getRef());
+
+      Boolean getMsg = new ExpectMsg<Boolean>("GetRpcReply") {
+        protected Boolean match(Object in) {
+          if (in instanceof GetRpcReply) {
+            GetRpcReply reply = (GetRpcReply)in;
+            return route.equals(reply.getRoutePath());
+          } else {
+            throw noMatch();
+          }
+        }
+      }.get(); // this extracts the received message
+
+      Assert.assertTrue(getMsg);
+
+      RemoveRpc removeMsg = new RemoveRpc(routeId);
+      rpcRegistry.tell(removeMsg, getRef());
+      expectMsgEquals(duration("2 second"), "Success");
+
+      rpcRegistry.tell(getRpc, getRef());
+
+      Boolean getNullMsg = new ExpectMsg<Boolean>("GetRpcReply") {
+        protected Boolean match(Object in) {
+          if (in instanceof GetRpcReply) {
+            GetRpcReply reply = (GetRpcReply)in;
+            return reply.getRoutePath() == null;
+          } else {
+            throw noMatch();
+          }
+        }
+      }.get();
+      Assert.assertTrue(getNullMsg);
+    }};
+
+  }
+
+  /**
+   This test add, read and remove an entry in routed rpc
+   */
+  @Test
+  public void testRoutedRpc() throws URISyntaxException {
+    new JavaTestKit(system) {{
+      ActorRef rpcRegistry = system.actorOf(RpcRegistry.props(Mockito.mock(ClusterWrapper.class)));
+      QName type = new QName(new URI("actor1"), "actor1");
+      RouteIdentifierImpl routeId = new RouteIdentifierImpl(null, type, null);
+      final String route = "actor1";
+
+      Set<RpcRouter.RouteIdentifier<?, ?, ?>> routeIds = new HashSet<>();
+      routeIds.add(routeId);
+
+      AddRoutedRpc rpcMsg = new AddRoutedRpc(routeIds, route);
+      rpcRegistry.tell(rpcMsg, getRef());
+      expectMsgEquals(duration("2 second"), "Success");
+
+      GetRoutedRpc getRpc = new GetRoutedRpc(routeId);
+      rpcRegistry.tell(getRpc, getRef());
+
+      Boolean getMsg = new ExpectMsg<Boolean>("GetRoutedRpcReply") {
+        protected Boolean match(Object in) {
+          if (in instanceof GetRoutedRpcReply) {
+            GetRoutedRpcReply reply = (GetRoutedRpcReply)in;
+            return route.equals(reply.getRoutePath());
+          } else {
+            throw noMatch();
+          }
+        }
+      }.get(); // this extracts the received message
+
+      Assert.assertTrue(getMsg);
+
+      RemoveRoutedRpc removeMsg = new RemoveRoutedRpc(routeIds, route);
+      rpcRegistry.tell(removeMsg, getRef());
+      expectMsgEquals(duration("2 second"), "Success");
+
+      rpcRegistry.tell(getRpc, getRef());
+
+      Boolean getNullMsg = new ExpectMsg<Boolean>("GetRoutedRpcReply") {
+        protected Boolean match(Object in) {
+          if (in instanceof GetRoutedRpcReply) {
+            GetRoutedRpcReply reply = (GetRoutedRpcReply)in;
+            return reply.getRoutePath() == null;
+          } else {
+            throw noMatch();
+          }
+        }
+      }.get();
+      Assert.assertTrue(getNullMsg);
+    }};
+
+  }
+
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/utils/XmlUtilsTest.java b/opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/utils/XmlUtilsTest.java
new file mode 100644 (file)
index 0000000..a408e1d
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.remote.rpc.utils;
+
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.io.ByteSource;
+import junit.framework.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+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.parser.impl.YangParserImpl;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class XmlUtilsTest {
+
+  private static final DocumentBuilderFactory BUILDERFACTORY;
+
+  static {
+    final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+    factory.setNamespaceAware(true);
+    factory.setCoalescing(true);
+    factory.setIgnoringElementContentWhitespace(true);
+    factory.setIgnoringComments(true);
+    BUILDERFACTORY = factory;
+  }
+
+  private SchemaContext schema;
+  private RpcDefinition testRpc;
+
+  public static final String XML_CONTENT = "<add-flow xmlns=\"urn:opendaylight:controller:rpc:test\"><input xmlns=\"urn:opendaylight:controller:rpc:test\">" +
+      "<id>flowid</id>" +
+      "<flow xmlns:ltha=\"urn:opendaylight:controller:rpc:test\">/ltha:node/ltha:node1[ltha:id='3@java.lang.Short']</flow>" +
+      "</input></add-flow>";
+
+  @Before
+  public void setUp() throws Exception {
+    final ByteSource byteSource = new ByteSource() {
+      @Override
+      public InputStream openStream() throws IOException {
+        return XmlUtilsTest.this.getClass().getResourceAsStream("rpcTest.yang");
+      }
+    };
+    schema = new YangParserImpl().parseSources(Lists.newArrayList(byteSource));
+    final Module rpcTestModule = schema.getModules().iterator().next();
+    testRpc = rpcTestModule.getRpcs().iterator().next();
+  }
+
+  @Test
+  public void testNullInputXmlToComposite() {
+    CompositeNode node = XmlUtils.inputXmlToCompositeNode(testRpc.getQName(), null, schema);
+    Assert.assertNull(node);
+  }
+
+  @Test
+  public void testNullRpcXmlToComposite() {
+    CompositeNode node = XmlUtils.inputXmlToCompositeNode(null, XML_CONTENT, schema);
+    Assert.assertNull(node);
+  }
+
+  @Test
+  public void testInputXmlToCompositeNode() {
+    CompositeNode node = XmlUtils.inputXmlToCompositeNode(testRpc.getQName(), XML_CONTENT, schema);
+    ImmutableList<SimpleNode> input = (ImmutableList)node.getValue().get(0).getValue();
+    SimpleNode firstNode = input.get(0);
+
+    Assert.assertEquals("id", firstNode.getNodeType().getLocalName());
+    Assert.assertEquals("flowid", firstNode.getValue());
+
+    SimpleNode secondNode = input.get(1);
+    Assert.assertEquals("flow", secondNode.getNodeType().getLocalName());
+
+    YangInstanceIdentifier instance = (YangInstanceIdentifier) secondNode.getValue();
+    Iterable<YangInstanceIdentifier.PathArgument> iterable = instance.getPathArguments();
+    Iterator it = iterable.iterator();
+    YangInstanceIdentifier.NodeIdentifier firstPath = (YangInstanceIdentifier.NodeIdentifier) it.next();
+    Assert.assertEquals("node", firstPath.getNodeType().getLocalName());
+    YangInstanceIdentifier.NodeIdentifierWithPredicates secondPath = (YangInstanceIdentifier.NodeIdentifierWithPredicates)it.next();
+    Short value = (Short)secondPath.getKeyValues().values().iterator().next();
+    Short expected = 3;
+    Assert.assertEquals(expected, value);
+  }
+
+  @Test
+  public void testInputCompositeNodeToXML() {
+    CompositeNode input = XmlUtils.inputXmlToCompositeNode(testRpc.getQName(), XML_CONTENT, schema);
+    List<Node<?>> childNodes = new ArrayList();
+    childNodes.add(input);
+    QName rpcQName = schema.getOperations().iterator().next().getQName();
+    CompositeNode node = new ImmutableCompositeNode(rpcQName, input.getValue(), ModifyAction.REPLACE);
+    String xml = XmlUtils.inputCompositeNodeToXml(node, schema);
+    Assert.assertNotNull(xml);
+    Assert.assertTrue(xml.contains("3@java.lang.Short"));
+  }
+
+  @Test
+  public void testNullCompositeNodeToXml(){
+    String xml = XmlUtils.inputCompositeNodeToXml(null, schema);
+    Assert.assertTrue(xml.isEmpty());
+  }
+
+  @Test
+  public void testNullSchemaCompositeNodeToXml(){
+    String xml = XmlUtils.inputCompositeNodeToXml(new ImmutableCompositeNode(QName.create("ns", "2013-12-09", "child1"), new ArrayList<Node<?>>(), ModifyAction.REPLACE), null);
+    Assert.assertTrue(xml.isEmpty());
+  }
+
+
+}
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/test/resources/org/opendaylight/controller/remote/rpc/utils/rpcTest.yang b/opendaylight/md-sal/sal-remoterpc-connector/src/test/resources/org/opendaylight/controller/remote/rpc/utils/rpcTest.yang
new file mode 100644 (file)
index 0000000..5fc564f
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+module rpc-test {
+    yang-version 1;
+    namespace "urn:opendaylight:controller:rpc:test";
+    prefix "rpct";
+
+    revision 2014-07-29 {
+       description "rpc test";
+    }
+
+    typedef flow-ref {
+        type instance-identifier;
+    }
+
+    rpc add-flow {
+        input {
+            leaf id {
+                type string;
+            }
+
+            leaf flow {
+                type flow-ref;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector-config/pom.xml b/opendaylight/md-sal/sal-rest-connector-config/pom.xml
new file mode 100644 (file)
index 0000000..6d050cf
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<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.1-SNAPSHOT</version>
+  </parent>
+  <artifactId>sal-rest-connector-config</artifactId>
+  <description>Configuration files for sal-rest-connector</description>
+  <packaging>jar</packaging>
+</project>
diff --git a/opendaylight/md-sal/sal-rest-connector-config/src/main/resources/initial/10-rest-connector.xml b/opendaylight/md-sal/sal-rest-connector-config/src/main/resources/initial/10-rest-connector.xml
new file mode 100644 (file)
index 0000000..2fdc8c7
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<snapshot>
+  <configuration>
+    <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+      <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+        <!-- default OF-switch-connection-provider (port 6633) -->
+        <module>
+          <type xmlns:rest="urn:opendaylight:params:xml:ns:yang:controller:md:sal:rest:connector">rest:rest-connector-impl</type>
+          <name>rest-connector-default-impl</name>
+          <websocket-port>8181</websocket-port>
+          <dom-broker>
+            <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>
+        </module>
+      </modules>
+
+      <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+        <service>
+          <type xmlns:rest="urn:opendaylight:params:xml:ns:yang:controller:md:sal:rest:connector">rest:rest-connector</type>
+          <instance>
+            <name>rest-connector-default</name>
+            <provider>
+              /modules/module[type='rest-connector-impl'][name='rest-connector-default-impl']
+            </provider>
+          </instance>
+        </service>
+      </services>
+    </data>
+  </configuration>
+</snapshot>
index b760263967864947268a3cc34df07e0a309e581b..09fb5b3677538442f154f4ca4a16cbdc4cf05647 100644 (file)
       <groupId>${project.groupId}</groupId>
       <artifactId>sal-core-api</artifactId>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>sal-binding-config</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>config-api</artifactId>
+    </dependency>
     <dependency>
       <groupId>com.google.code.gson</groupId>
       <artifactId>gson</artifactId>
       <groupId>org.opendaylight.yangtools.model</groupId>
       <artifactId>ietf-yang-types-20130715</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools.model</groupId>
+      <artifactId>ietf-inet-types</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
       <artifactId>mockito-all</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-core-spi</artifactId>
+    </dependency>
   </dependencies>
 
   <build>
             <Bundle-Name>MD SAL Restconf Connector</Bundle-Name>
             <Private-Package>org.opendaylight.controller.sal.rest.*,
               org.opendaylight.controller.sal.restconf.rpc.*,
-              org.opendaylight.controller.sal.restconf.impl,</Private-Package>
+              org.opendaylight.controller.sal.restconf.impl,
+              org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.rest.connector.rev140724.*,
+            </Private-Package>
             <Import-Package>*,
             com.sun.jersey.spi.container.servlet</Import-Package>
-            <Bundle-Activator>org.opendaylight.controller.sal.rest.impl.RestconfProvider</Bundle-Activator>
             <Web-ContextPath>/restconf</Web-ContextPath>
           </instructions>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>yang-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>config</id>
+            <goals>
+              <goal>generate-sources</goal>
+            </goals>
+            <configuration>
+              <codeGenerators>
+                <generator>
+                  <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
+                  <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
+                  <additionalConfiguration>
+                    <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
+                  </additionalConfiguration>
+                </generator>
+                <generator>
+                  <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+                  <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+                </generator>
+              </codeGenerators>
+              <inspectDependencies>true</inspectDependencies>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
   <scm>
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/rest/connector/RestConnectorModule.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/rest/connector/RestConnectorModule.java
new file mode 100644 (file)
index 0000000..582c657
--- /dev/null
@@ -0,0 +1,30 @@
+package org.opendaylight.controller.config.yang.md.sal.rest.connector;
+
+import org.opendaylight.controller.sal.rest.impl.RestconfProviderImpl;
+
+public class RestConnectorModule extends org.opendaylight.controller.config.yang.md.sal.rest.connector.AbstractRestConnectorModule {
+
+    public RestConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public RestConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.md.sal.rest.connector.RestConnectorModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        // Create an instance of our provider
+        RestconfProviderImpl instance = new RestconfProviderImpl();
+        // Set its port
+        instance.setWebsocketPort(getWebsocketPort());
+        // Register it with the Broker
+        getDomBrokerDependency().registerProvider(instance);
+        return instance;
+    }
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/rest/connector/RestConnectorModuleFactory.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/rest/connector/RestConnectorModuleFactory.java
new file mode 100644 (file)
index 0000000..957b08f
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: opendaylight-rest-connector yang module local name: rest-connector-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Fri Jul 25 04:33:31 CDT 2014
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.rest.connector;
+
+
+public class RestConnectorModuleFactory extends org.opendaylight.controller.config.yang.md.sal.rest.connector.AbstractRestConnectorModuleFactory {
+
+}
index af763cce0d20e0b03a76a1321580dcd71571446c..51ac43be7c7e27c1a8d32ef12f675e910309f725 100644 (file)
@@ -47,26 +47,24 @@ public class Draft02 {
 
         String ERROR_LIST_SCHEMA_NODE = "error";
 
-        QName IETF_RESTCONF_QNAME = QName.create( Draft02.RestConfModule.NAMESPACE,
-                                                  Draft02.RestConfModule.REVISION,
-                                                  Draft02.RestConfModule.NAME );
+        QName IETF_RESTCONF_QNAME = QName.create(Draft02.RestConfModule.NAMESPACE, Draft02.RestConfModule.REVISION,
+                Draft02.RestConfModule.NAME);
 
-        QName ERRORS_CONTAINER_QNAME = QName.create( IETF_RESTCONF_QNAME, ERRORS_CONTAINER_SCHEMA_NODE );
+        QName ERRORS_CONTAINER_QNAME = QName.create(IETF_RESTCONF_QNAME, ERRORS_CONTAINER_SCHEMA_NODE);
 
-        QName ERROR_LIST_QNAME = QName.create( IETF_RESTCONF_QNAME, ERROR_LIST_SCHEMA_NODE );
+        QName ERROR_LIST_QNAME = QName.create(IETF_RESTCONF_QNAME, ERROR_LIST_SCHEMA_NODE);
 
-        QName ERROR_TYPE_QNAME = QName.create( IETF_RESTCONF_QNAME, "error-type" );
+        QName ERROR_TYPE_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-type");
 
-        QName ERROR_TAG_QNAME = QName.create( IETF_RESTCONF_QNAME, "error-tag" );
+        QName ERROR_TAG_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-tag");
 
-        QName ERROR_APP_TAG_QNAME = QName.create( IETF_RESTCONF_QNAME, "error-app-tag" );
+        QName ERROR_APP_TAG_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-app-tag");
 
-        QName ERROR_MESSAGE_QNAME = QName.create( IETF_RESTCONF_QNAME, "error-message" );
+        QName ERROR_MESSAGE_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-message");
 
-        QName ERROR_INFO_QNAME = QName.create( IETF_RESTCONF_QNAME, "error-info" );
+        QName ERROR_INFO_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-info");
     }
 
-
     public static interface Paths {
 
     }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestConnector.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestConnector.java
new file mode 100644 (file)
index 0000000..fe45a02
--- /dev/null
@@ -0,0 +1,9 @@
+package org.opendaylight.controller.sal.rest.api;
+
+/*
+ * This is a simple dummy interface to allow us to create instances of RestconfProvider
+ * via the config subsystem.
+ */
+public interface RestConnector {
+
+}
index 056be72d4e057b249a17c0286e87b9b0ebe19e72..a6c4ea5ab8d7877930983ed782d4cbc318def278 100644 (file)
@@ -10,42 +10,38 @@ package org.opendaylight.controller.sal.rest.api;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
+import javax.ws.rs.Encoded;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
-import javax.ws.rs.Encoded;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
-
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 /**
- *   The URI hierarchy for the RESTCONF resources consists of an entry
- *   point container, 4 top-level resources, and 1 field.
- *   <ul>
- *    <li><b>/restconf</b> - {@link #getRoot()}
- *     <ul>
- *      <li><b>/config</b> - {@link #readConfigurationData(String)}
- *                              {@link #updateConfigurationData(String, CompositeNode)}
- *                              {@link #createConfigurationData(CompositeNode)}
- *                              {@link #createConfigurationData(String, CompositeNode)}
- *                              {@link #deleteConfigurationData(String)}
- *      <li><b>/operational</b> - {@link #readOperationalData(String)}
- *      <li>/modules - {@link #getModules()}
- *       <ul>
- *        <li>/module
- *       </ul>
- *      <li><b>/operations</b> - {@link #invokeRpc(String, CompositeNode)}
- *                               {@link #invokeRpc(String, CompositeNode)}
- *      <li>/version (field)
- *     </ul>
- *   </ul>
+ * The URI hierarchy for the RESTCONF resources consists of an entry point container, 4 top-level resources, and 1
+ * field.
+ * <ul>
+ * <li><b>/restconf</b> - {@link #getRoot()}
+ * <ul>
+ * <li><b>/config</b> - {@link #readConfigurationData(String)} {@link #updateConfigurationData(String, CompositeNode)}
+ * {@link #createConfigurationData(CompositeNode)} {@link #createConfigurationData(String, CompositeNode)}
+ * {@link #deleteConfigurationData(String)}
+ * <li><b>/operational</b> - {@link #readOperationalData(String)}
+ * <li>/modules - {@link #getModules()}
+ * <ul>
+ * <li>/module
+ * </ul>
+ * <li><b>/operations</b> - {@link #invokeRpc(String, CompositeNode)} {@link #invokeRpc(String, CompositeNode)}
+ * <li>/version (field)
+ * </ul>
+ * </ul>
  */
 @Path("/")
 public interface RestconfService {
@@ -58,81 +54,83 @@ public interface RestconfService {
 
     @GET
     @Path("/modules")
-    @Produces({Draft02.MediaTypes.API+XML, Draft02.MediaTypes.API+JSON,
-               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
-    public StructuredData getModules();
+    @Produces({ Draft02.MediaTypes.API + XML, Draft02.MediaTypes.API + JSON, MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_XML, MediaType.TEXT_XML })
+    public StructuredData getModules(@Context UriInfo uriInfo);
 
     @GET
     @Path("/modules/{identifier:.+}")
-    @Produces({Draft02.MediaTypes.API+XML, Draft02.MediaTypes.API+JSON,
-               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
-    public StructuredData getModules(@PathParam("identifier") String identifier);
+    @Produces({ Draft02.MediaTypes.API + XML, Draft02.MediaTypes.API + JSON, MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_XML, MediaType.TEXT_XML })
+    public StructuredData getModules(@PathParam("identifier") String identifier, @Context UriInfo uriInfo);
 
     @GET
     @Path("/modules/module/{identifier:.+}")
-    @Produces({Draft02.MediaTypes.API+XML, Draft02.MediaTypes.API+JSON,
-               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
-    public StructuredData getModule(@PathParam("identifier") String identifier);
+    @Produces({ Draft02.MediaTypes.API + XML, Draft02.MediaTypes.API + JSON, MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_XML, MediaType.TEXT_XML })
+    public StructuredData getModule(@PathParam("identifier") String identifier, @Context UriInfo uriInfo);
 
     @GET
     @Path("/operations")
-    @Produces({Draft02.MediaTypes.API+XML, Draft02.MediaTypes.API+JSON,
-               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
-    public StructuredData getOperations();
+    @Produces({ Draft02.MediaTypes.API + XML, Draft02.MediaTypes.API + JSON, MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_XML, MediaType.TEXT_XML })
+    public StructuredData getOperations(@Context UriInfo uriInfo);
 
     @GET
     @Path("/operations/{identifier:.+}")
-    @Produces({Draft02.MediaTypes.API+XML, Draft02.MediaTypes.API+JSON,
-               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
-    public StructuredData getOperations(@PathParam("identifier") String identifier);
+    @Produces({ Draft02.MediaTypes.API + XML, Draft02.MediaTypes.API + JSON, MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_XML, MediaType.TEXT_XML })
+    public StructuredData getOperations(@PathParam("identifier") String identifier, @Context UriInfo uriInfo);
 
     @POST
     @Path("/operations/{identifier:.+}")
-    @Produces({Draft02.MediaTypes.OPERATION+JSON, Draft02.MediaTypes.OPERATION+XML,
-               Draft02.MediaTypes.DATA+JSON, Draft02.MediaTypes.DATA+XML,
-               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
-    @Consumes({Draft02.MediaTypes.OPERATION+JSON, Draft02.MediaTypes.OPERATION+XML,
-               Draft02.MediaTypes.DATA+JSON, Draft02.MediaTypes.DATA+XML,
-               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
-    public StructuredData invokeRpc(@Encoded @PathParam("identifier") String identifier, CompositeNode payload);
+    @Produces({ Draft02.MediaTypes.OPERATION + JSON, Draft02.MediaTypes.OPERATION + XML,
+            Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_XML, MediaType.TEXT_XML })
+    @Consumes({ Draft02.MediaTypes.OPERATION + JSON, Draft02.MediaTypes.OPERATION + XML,
+            Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_XML, MediaType.TEXT_XML })
+    public StructuredData invokeRpc(@Encoded @PathParam("identifier") String identifier, CompositeNode payload,
+            @Context UriInfo uriInfo);
 
     @POST
     @Path("/operations/{identifier:.+}")
-    @Produces({Draft02.MediaTypes.OPERATION+JSON, Draft02.MediaTypes.OPERATION+XML,
-               Draft02.MediaTypes.DATA+JSON, Draft02.MediaTypes.DATA+XML,
-               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
-    public StructuredData invokeRpc(@Encoded @PathParam("identifier") String identifier, @DefaultValue("") String noPayload);
+    @Produces({ Draft02.MediaTypes.OPERATION + JSON, Draft02.MediaTypes.OPERATION + XML,
+            Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_XML, MediaType.TEXT_XML })
+    public StructuredData invokeRpc(@Encoded @PathParam("identifier") String identifier,
+            @DefaultValue("") String noPayload, @Context UriInfo uriInfo);
 
     @GET
     @Path("/config/{identifier:.+}")
-    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
-               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
+    @Produces({ Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_XML, MediaType.TEXT_XML })
     public StructuredData readConfigurationData(@Encoded @PathParam("identifier") String identifier,
-                                                @Context UriInfo depth);
+            @Context UriInfo uriInfo);
 
     @GET
     @Path("/operational/{identifier:.+}")
-    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
-               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
+    @Produces({ Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_XML, MediaType.TEXT_XML })
     public StructuredData readOperationalData(@Encoded @PathParam("identifier") String identifier,
-                                              @Context UriInfo depth);
+            @Context UriInfo uriInfo);
 
     @PUT
     @Path("/config/{identifier:.+}")
-    @Consumes({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
-               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
+    @Consumes({ Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_XML, MediaType.TEXT_XML })
     public Response updateConfigurationData(@Encoded @PathParam("identifier") String identifier, CompositeNode payload);
 
     @POST
     @Path("/config/{identifier:.+}")
-    @Consumes({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
-               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
+    @Consumes({ Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_XML, MediaType.TEXT_XML })
     public Response createConfigurationData(@Encoded @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})
+    @Consumes({ Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_XML, MediaType.TEXT_XML })
     public Response createConfigurationData(CompositeNode payload);
 
     @DELETE
@@ -145,9 +143,8 @@ public interface RestconfService {
 
     @GET
     @Path("/streams")
-    @Produces({Draft02.MediaTypes.API+XML, Draft02.MediaTypes.API+JSON,
-            MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
-    public StructuredData getAvailableStreams();
-
+    @Produces({ Draft02.MediaTypes.API + XML, Draft02.MediaTypes.API + JSON, MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_XML, MediaType.TEXT_XML })
+    public StructuredData getAvailableStreams(@Context UriInfo uriInfo);
 
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/gson/JsonParser.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/gson/JsonParser.java
new file mode 100644 (file)
index 0000000..a784be2
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.rest.gson;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonIOException;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonPrimitive;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.internal.LazilyParsedNumber;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.MalformedJsonException;
+import java.io.EOFException;
+import java.io.IOException;
+
+/**
+ * This class parses JSON elements from a gson JsonReader. It disallows multiple elements of the same name unlike the
+ * default gson JsonParser."
+ */
+public class JsonParser {
+    public JsonElement parse(JsonReader reader) throws JsonIOException, JsonSyntaxException {
+        // code copied from gson's JsonParser and Stream classes
+
+        boolean lenient = reader.isLenient();
+        reader.setLenient(true);
+        boolean isEmpty = true;
+        try {
+            reader.peek();
+            isEmpty = false;
+            return read(reader);
+        } catch (EOFException e) {
+            if (isEmpty) {
+                return JsonNull.INSTANCE;
+            }
+            // The stream ended prematurely so it is likely a syntax error.
+            throw new JsonSyntaxException(e);
+        } catch (MalformedJsonException e) {
+            throw new JsonSyntaxException(e);
+        } catch (IOException e) {
+            throw new JsonIOException(e);
+        } catch (NumberFormatException e) {
+            throw new JsonSyntaxException(e);
+        } catch (StackOverflowError | OutOfMemoryError e) {
+            throw new JsonParseException("Failed parsing JSON source: " + reader + " to Json", e);
+        } finally {
+            reader.setLenient(lenient);
+        }
+    }
+
+    public JsonElement read(JsonReader in) throws IOException {
+        switch (in.peek()) {
+        case STRING:
+            return new JsonPrimitive(in.nextString());
+        case NUMBER:
+            String number = in.nextString();
+            return new JsonPrimitive(new LazilyParsedNumber(number));
+        case BOOLEAN:
+            return new JsonPrimitive(in.nextBoolean());
+        case NULL:
+            in.nextNull();
+            return JsonNull.INSTANCE;
+        case BEGIN_ARRAY:
+            JsonArray array = new JsonArray();
+            in.beginArray();
+            while (in.hasNext()) {
+                array.add(read(in));
+            }
+            in.endArray();
+            return array;
+        case BEGIN_OBJECT:
+            JsonObject object = new JsonObject();
+            in.beginObject();
+            while (in.hasNext()) {
+                final String childName = in.nextName();
+                if (object.has(childName)) {
+                    throw new JsonSyntaxException("Duplicate name " + childName + " in JSON input.");
+                }
+                object.add(childName, read(in));
+            }
+            in.endObject();
+            return object;
+        case END_DOCUMENT:
+        case NAME:
+        case END_OBJECT:
+        case END_ARRAY:
+        default:
+            throw new IllegalArgumentException();
+        }
+    }
+}
index 696bf715355e402a0932532a36cde8e795a08236..34aa829b6f5a50e7511583485d33693155d123d8 100644 (file)
@@ -13,6 +13,7 @@ import com.google.common.base.Preconditions;
 import com.google.gson.stream.JsonWriter;
 import java.io.IOException;
 import java.net.URI;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -26,7 +27,7 @@ import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.Predicate
 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.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
@@ -50,16 +51,18 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 class JsonMapper {
+    private static final Logger LOG = LoggerFactory.getLogger(JsonMapper.class);
+    private final MountInstance mountPoint;
 
-    private MountInstance mountPoint;
-    private final Logger logger = LoggerFactory.getLogger(JsonMapper.class);
+    public JsonMapper(final MountInstance mountPoint) {
+        this.mountPoint = mountPoint;
+    }
 
-    public void write(final JsonWriter writer, final CompositeNode data, final DataNodeContainer schema, final MountInstance mountPoint)
+    public void write(final JsonWriter writer, final CompositeNode data, final DataNodeContainer schema)
             throws IOException {
         Preconditions.checkNotNull(writer);
         Preconditions.checkNotNull(data);
         Preconditions.checkNotNull(schema);
-        this.mountPoint = mountPoint;
 
         writer.beginObject();
 
@@ -75,15 +78,14 @@ class JsonMapper {
         writer.endObject();
     }
 
-    private void writeChildrenOfParent(final JsonWriter writer, final CompositeNode parent, final DataNodeContainer parentSchema)
-            throws IOException {
+    private void writeChildrenOfParent(final JsonWriter writer, final CompositeNode parent,
+            final DataNodeContainer parentSchema) throws IOException {
         checkNotNull(parent);
 
         final Set<QName> foundLists = new HashSet<>();
 
-        Set<DataSchemaNode> parentSchemaChildNodes = parentSchema == null ?
-                                   Collections.<DataSchemaNode>emptySet() : parentSchema.getChildNodes();
-
+        Collection<DataSchemaNode> parentSchemaChildNodes = parentSchema == null ? Collections.<DataSchemaNode> emptySet()
+                : parentSchema.getChildNodes();
 
         for (Node<?> child : parent.getValue()) {
             DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchemaChildNodes);
@@ -91,45 +93,43 @@ class JsonMapper {
             if (childSchema == null) {
                 // Node may not conform to schema or allows "anyxml" - we'll process it.
 
-                logger.debug( "No schema found for data node \"" + child.getNodeType() );
+                LOG.debug("No schema found for data node \"{}\"", child.getNodeType());
 
-                if( !foundLists.contains( child.getNodeType() ) ) {
-                    handleNoSchemaFound( writer, child, parent );
+                if (!foundLists.contains(child.getNodeType())) {
+                    handleNoSchemaFound(writer, child, parent);
 
                     // Since we don't have a schema, we don't know which nodes are supposed to be
                     // lists so treat every one as a potential list to avoid outputting duplicates.
 
-                    foundLists.add( child.getNodeType() );
+                    foundLists.add(child.getNodeType());
                 }
-            }
-            else if (childSchema instanceof ContainerSchemaNode) {
+            } else if (childSchema instanceof ContainerSchemaNode) {
                 Preconditions.checkState(child instanceof CompositeNode,
-                        "Data representation of Container should be CompositeNode - " + child.getNodeType());
+                        "Data representation of Container should be CompositeNode - %s", child.getNodeType());
                 writeContainer(writer, (CompositeNode) child, (ContainerSchemaNode) childSchema);
             } else if (childSchema instanceof ListSchemaNode) {
-                if (!foundLists.contains( child.getNodeType() ) ) {
+                if (!foundLists.contains(child.getNodeType())) {
                     Preconditions.checkState(child instanceof CompositeNode,
-                            "Data representation of List should be CompositeNode - " + child.getNodeType());
-                    foundLists.add( child.getNodeType() );
+                            "Data representation of List should be CompositeNode - %s", child.getNodeType());
+                    foundLists.add(child.getNodeType());
                     writeList(writer, parent, (CompositeNode) child, (ListSchemaNode) childSchema);
                 }
             } else if (childSchema instanceof LeafListSchemaNode) {
-                if (!foundLists.contains( child.getNodeType() ) ) {
+                if (!foundLists.contains(child.getNodeType())) {
                     Preconditions.checkState(child instanceof SimpleNode<?>,
-                            "Data representation of LeafList should be SimpleNode - " + child.getNodeType());
-                    foundLists.add( child.getNodeType() );
+                            "Data representation of LeafList should be SimpleNode - %s", child.getNodeType());
+                    foundLists.add(child.getNodeType());
                     writeLeafList(writer, parent, (SimpleNode<?>) child, (LeafListSchemaNode) childSchema);
                 }
             } else if (childSchema instanceof LeafSchemaNode) {
                 Preconditions.checkState(child instanceof SimpleNode<?>,
-                        "Data representation of LeafList should be SimpleNode - " + child.getNodeType());
+                        "Data representation of LeafList should be SimpleNode - %s", child.getNodeType());
                 writeLeaf(writer, (SimpleNode<?>) child, (LeafSchemaNode) childSchema);
             } else if (childSchema instanceof AnyXmlSchemaNode) {
-                if( child instanceof CompositeNode ) {
+                if (child instanceof CompositeNode) {
                     writeContainer(writer, (CompositeNode) child, null);
-                }
-                else {
-                    handleNoSchemaFound( writer, child, parent );
+                } else {
+                    handleNoSchemaFound(writer, child, parent);
                 }
             } else {
                 throw new UnsupportedDataTypeException("Schema can be ContainerSchemaNode, ListSchemaNode, "
@@ -138,51 +138,45 @@ class JsonMapper {
         }
     }
 
-    private void writeValue( final JsonWriter writer, Object value ) throws IOException {
-        if( value != null ) {
-            writer.value( String.valueOf( value ) );
-        }
-        else {
-            writer.value( "" );
-        }
+    private static void writeValue(final JsonWriter writer, final Object value) throws IOException {
+        writer.value(value == null ? "" : String.valueOf(value));
     }
 
-    private void handleNoSchemaFound( final JsonWriter writer, final Node<?> node,
-                                      final CompositeNode parent ) throws IOException {
-        if( node instanceof SimpleNode<?> ) {
-            List<SimpleNode<?>> nodeLeafList = parent.getSimpleNodesByName( node.getNodeType() );
-            if( nodeLeafList.size() == 1 ) {
-                writeName( node, null, writer );
-                writeValue( writer, node.getValue() );
-            }
-            else { // more than 1, write as a json array
-                writeName( node, null, writer );
+    private void handleNoSchemaFound(final JsonWriter writer, final Node<?> node, final CompositeNode parent)
+            throws IOException {
+        if (node instanceof SimpleNode<?>) {
+            List<SimpleNode<?>> nodeLeafList = parent.getSimpleNodesByName(node.getNodeType());
+            if (nodeLeafList.size() == 1) {
+                writeName(node, null, writer);
+                writeValue(writer, node.getValue());
+            } else { // more than 1, write as a json array
+                writeName(node, null, writer);
                 writer.beginArray();
-                for( SimpleNode<?> leafNode: nodeLeafList ) {
-                    writeValue( writer, leafNode.getValue() );
+                for (SimpleNode<?> leafNode : nodeLeafList) {
+                    writeValue(writer, leafNode.getValue());
                 }
 
                 writer.endArray();
             }
         } else { // CompositeNode
-            Preconditions.checkState( node instanceof CompositeNode,
-                    "Data representation of Container should be CompositeNode - " + node.getNodeType() );
-
-            List<CompositeNode> nodeList = parent.getCompositesByName( node.getNodeType() );
-            if( nodeList.size() == 1 ) {
-                writeContainer( writer, (CompositeNode) node, null );
-            }
-            else { // more than 1, write as a json array
-                writeList( writer, parent, (CompositeNode) node, null );
+            Preconditions.checkState(node instanceof CompositeNode,
+                    "Data representation of Container should be CompositeNode - %s", node.getNodeType());
+
+            List<CompositeNode> nodeList = parent.getCompositesByName(node.getNodeType());
+            if (nodeList.size() == 1) {
+                writeContainer(writer, (CompositeNode) node, null);
+            } else { // more than 1, write as a json array
+                writeList(writer, parent, (CompositeNode) node, null);
             }
         }
     }
 
-    private DataSchemaNode findFirstSchemaForNode(final Node<?> node, final Set<DataSchemaNode> dataSchemaNode) {
+    private static DataSchemaNode findFirstSchemaForNode(final Node<?> node, final Iterable<DataSchemaNode> dataSchemaNode) {
         for (DataSchemaNode dsn : dataSchemaNode) {
             if (node.getNodeType().equals(dsn.getQName())) {
                 return dsn;
-            } else if (dsn instanceof ChoiceNode) {
+            }
+            if (dsn instanceof ChoiceNode) {
                 for (ChoiceCaseNode choiceCase : ((ChoiceNode) dsn).getCases()) {
                     DataSchemaNode foundDsn = findFirstSchemaForNode(node, choiceCase.getChildNodes());
                     if (foundDsn != null) {
@@ -194,15 +188,16 @@ class JsonMapper {
         return null;
     }
 
-    private void writeContainer(final JsonWriter writer, final CompositeNode node, final ContainerSchemaNode schema) throws IOException {
+    private void writeContainer(final JsonWriter writer, final CompositeNode node, final ContainerSchemaNode schema)
+            throws IOException {
         writeName(node, schema, writer);
         writer.beginObject();
         writeChildrenOfParent(writer, node, schema);
         writer.endObject();
     }
 
-    private void writeList(final JsonWriter writer, final CompositeNode nodeParent, final CompositeNode node, final ListSchemaNode schema)
-            throws IOException {
+    private void writeList(final JsonWriter writer, final CompositeNode nodeParent, final CompositeNode node,
+            final ListSchemaNode schema) throws IOException {
         writeName(node, schema, writer);
         writer.beginArray();
 
@@ -234,19 +229,20 @@ class JsonMapper {
         writer.endArray();
     }
 
-    private void writeLeaf(final JsonWriter writer, final SimpleNode<?> node, final LeafSchemaNode schema) throws IOException {
+    private void writeLeaf(final JsonWriter writer, final SimpleNode<?> node, final LeafSchemaNode schema)
+            throws IOException {
         writeName(node, schema, writer);
         writeValueOfNodeByType(writer, node, schema.getType(), schema);
     }
 
-    private void writeValueOfNodeByType(final JsonWriter writer, final SimpleNode<?> node, final TypeDefinition<?> type,
-            final DataSchemaNode schema) throws IOException {
+    private void writeValueOfNodeByType(final JsonWriter writer, final SimpleNode<?> node,
+            final TypeDefinition<?> type, final DataSchemaNode schema) throws IOException {
 
         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() + ".");
+            LOG.debug("While generationg JSON output null value was found for type {}.", baseType.getClass()
+                    .getSimpleName());
         }
 
         if (baseType instanceof IdentityrefTypeDefinition) {
@@ -267,12 +263,12 @@ class JsonMapper {
                 writeStringRepresentation(writer, node, baseType, QName.class);
             }
         } else if (baseType instanceof InstanceIdentifierTypeDefinition) {
-            if (node.getValue() instanceof InstanceIdentifier) {
+            if (node.getValue() instanceof YangInstanceIdentifier) {
                 IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(baseType, mountPoint).serialize(
                         node.getValue());
                 writeIdentityValuesDTOToJson(writer, valueDTO);
             } else {
-                writeStringRepresentation(writer, node, baseType, InstanceIdentifier.class);
+                writeStringRepresentation(writer, node, baseType, YangInstanceIdentifier.class);
             }
         } else if (baseType instanceof DecimalTypeDefinition || baseType instanceof IntegerTypeDefinition
                 || baseType instanceof UnsignedIntegerTypeDefinition) {
@@ -291,25 +287,25 @@ class JsonMapper {
         }
     }
 
-    private void writeIdentityValuesDTOToJson(final JsonWriter writer, final IdentityValuesDTO valueDTO) throws IOException {
+    private static void writeIdentityValuesDTOToJson(final JsonWriter writer, final IdentityValuesDTO valueDTO)
+            throws IOException {
         StringBuilder result = new StringBuilder();
         for (IdentityValue identityValue : valueDTO.getValuesWithNamespaces()) {
-            result.append("/");
+            result.append('/');
 
             writeModuleNameAndIdentifier(result, identityValue);
             if (identityValue.getPredicates() != null && !identityValue.getPredicates().isEmpty()) {
                 for (Predicate predicate : identityValue.getPredicates()) {
                     IdentityValue identityValuePredicate = predicate.getName();
-                    result.append("[");
+                    result.append('[');
                     if (identityValuePredicate == null) {
-                        result.append(".");
+                        result.append('.');
                     } else {
                         writeModuleNameAndIdentifier(result, identityValuePredicate);
                     }
                     result.append("='");
                     result.append(predicate.getValue());
-                    result.append("'");
-                    result.append("]");
+                    result.append("']");
                 }
             }
         }
@@ -317,21 +313,21 @@ class JsonMapper {
         writer.value(result.toString());
     }
 
-    private void writeModuleNameAndIdentifier(final StringBuilder result, final IdentityValue identityValue) {
+    private static void writeModuleNameAndIdentifier(final StringBuilder result, final IdentityValue identityValue) {
         String moduleName = ControllerContext.getInstance().findModuleNameByNamespace(
                 URI.create(identityValue.getNamespace()));
         if (moduleName != null && !moduleName.isEmpty()) {
             result.append(moduleName);
-            result.append(":");
+            result.append(':');
         }
         result.append(identityValue.getValue());
     }
 
-    private void writeStringRepresentation(final JsonWriter writer, final SimpleNode<?> node, final TypeDefinition<?> baseType,
-            final Class<?> requiredType) throws IOException {
+    private static void writeStringRepresentation(final JsonWriter writer, final SimpleNode<?> node,
+            final TypeDefinition<?> baseType, final Class<?> requiredType) throws IOException {
         Object value = node.getValue();
-        logger.debug("Value of " + baseType.getQName().getNamespace() + ":" + baseType.getQName().getLocalName()
-                + " is not instance of " + requiredType.getClass() + " but is " + node.getValue().getClass());
+        LOG.debug("Value of {}:{} is not instance of {} but is {}", baseType.getQName().getNamespace(), baseType
+                .getQName().getLocalName(), requiredType.getClass(), node.getValue().getClass());
         if (value == null) {
             writer.value("");
         } else {
@@ -347,7 +343,7 @@ class JsonMapper {
 
     private void writeName(final Node<?> node, final DataSchemaNode schema, final JsonWriter writer) throws IOException {
         String nameForOutput = node.getNodeType().getLocalName();
-        if ( schema != null && schema.isAugmenting()) {
+        if (schema != null && schema.isAugmenting()) {
             ControllerContext contContext = ControllerContext.getInstance();
             CharSequence moduleName = null;
             if (mountPoint == null) {
@@ -358,7 +354,7 @@ class JsonMapper {
             if (moduleName != null) {
                 nameForOutput = moduleName.toString();
             } else {
-                logger.info("Module '{}' was not found in schema from mount point", schema.getQName());
+                LOG.info("Module '{}' was not found in schema from mount point", schema.getQName());
             }
         }
         writer.name(nameForOutput);
index 856e09fabd21a1083cbe716890ba22ae3b2d5bc6..2f3499e26968e17e9fa5f662ab66063965657815 100644 (file)
@@ -11,14 +11,12 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
-
 import javax.ws.rs.Consumes;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.Provider;
-
 import org.opendaylight.controller.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
@@ -34,26 +32,26 @@ import org.slf4j.LoggerFactory;
 public enum JsonToCompositeNodeProvider implements MessageBodyReader<CompositeNode> {
     INSTANCE;
 
-    private final static Logger LOG = LoggerFactory.getLogger( JsonToCompositeNodeProvider.class );
+    private final static Logger LOG = LoggerFactory.getLogger(JsonToCompositeNodeProvider.class);
 
     @Override
-    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+    public boolean isReadable(final Class<?> type, final Type genericType, final Annotation[] annotations,
+            final MediaType mediaType) {
         return true;
     }
 
     @Override
-    public CompositeNode readFrom(Class<CompositeNode> type, Type genericType, Annotation[] annotations,
-            MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
-            throws IOException, WebApplicationException {
-        JsonReader jsonReader = new JsonReader();
+    public CompositeNode readFrom(final Class<CompositeNode> type, final Type genericType,
+            final Annotation[] annotations, final MediaType mediaType,
+            final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws IOException,
+            WebApplicationException {
         try {
-            return jsonReader.read(entityStream);
+            return JsonToCompositeNodeReader.read(entityStream);
         } catch (Exception e) {
-            LOG.debug( "Error parsing json input", e );
-            throw new RestconfDocumentedException(
-                            "Error parsing input: " + e.getMessage(),
-                            ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE );
+            LOG.debug("Error parsing json input", e);
+
+            throw new RestconfDocumentedException("Error parsing input: " + e.getMessage(), ErrorType.PROTOCOL,
+                    ErrorTag.MALFORMED_MESSAGE);
         }
     }
-
 }
@@ -7,33 +7,41 @@
  */
 package org.opendaylight.controller.sal.rest.impl;
 
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterators;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import com.google.gson.stream.JsonReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.URI;
+import java.util.Iterator;
 import java.util.Map.Entry;
 import java.util.Set;
-
+import org.opendaylight.controller.sal.rest.gson.JsonParser;
 import org.opendaylight.controller.sal.rest.impl.RestUtil.PrefixMapingFromJson;
 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.EmptyNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
 import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Lists;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonPrimitive;
+class JsonToCompositeNodeReader {
+    private static final Logger LOG = LoggerFactory.getLogger(JsonReader.class);
+    private static final Splitter COLON_SPLITTER = Splitter.on(':');
+
+    private JsonToCompositeNodeReader() {
 
-class JsonReader {
+    }
 
-    public CompositeNodeWrapper read(InputStream entityStream) throws UnsupportedFormatException {
+    public static CompositeNodeWrapper read(final InputStream entityStream) throws UnsupportedFormatException {
         JsonParser parser = new JsonParser();
 
-        JsonElement rootElement = parser.parse(new InputStreamReader(entityStream));
-        if( rootElement.isJsonNull() )
-        {
-            //no content, so return null to indicate no input
+        JsonElement rootElement = parser.parse(new JsonReader(new InputStreamReader(entityStream)));
+        if (rootElement.isJsonNull()) {
+            // no content, so return null to indicate no input
             return null;
         }
 
@@ -44,29 +52,31 @@ class JsonReader {
         Set<Entry<String, JsonElement>> entrySetsOfRootJsonObject = rootElement.getAsJsonObject().entrySet();
         if (entrySetsOfRootJsonObject.size() != 1) {
             throw new UnsupportedFormatException("Json Object should contain one element");
-        } else {
-            Entry<String, JsonElement> childEntry = Lists.newArrayList(entrySetsOfRootJsonObject).get(0);
-            String firstElementName = childEntry.getKey();
-            JsonElement firstElementType = childEntry.getValue();
-            if (firstElementType.isJsonObject()) { // container in yang
-                return createStructureWithRoot(firstElementName, firstElementType.getAsJsonObject());
-            }
-            if (firstElementType.isJsonArray()) { // list in yang
-                if (firstElementType.getAsJsonArray().size() == 1) {
-                    JsonElement firstElementInArray = firstElementType.getAsJsonArray().get(0);
-                    if (firstElementInArray.isJsonObject()) {
-                        return createStructureWithRoot(firstElementName, firstElementInArray.getAsJsonObject());
-                    }
-                    throw new UnsupportedFormatException(
-                            "Array as the first element in Json Object can have only Object element");
+        }
+
+        Entry<String, JsonElement> childEntry = entrySetsOfRootJsonObject.iterator().next();
+        String firstElementName = childEntry.getKey();
+        JsonElement firstElementType = childEntry.getValue();
+        if (firstElementType.isJsonObject()) {
+            // container in yang
+            return createStructureWithRoot(firstElementName, firstElementType.getAsJsonObject());
+        }
+        if (firstElementType.isJsonArray()) {
+            // list in yang
+            if (firstElementType.getAsJsonArray().size() == 1) {
+                JsonElement firstElementInArray = firstElementType.getAsJsonArray().get(0);
+                if (firstElementInArray.isJsonObject()) {
+                    return createStructureWithRoot(firstElementName, firstElementInArray.getAsJsonObject());
                 }
+                throw new UnsupportedFormatException(
+                        "Array as the first element in Json Object can have only Object element");
             }
-            throw new UnsupportedFormatException(
-                    "First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet.");
         }
+        throw new UnsupportedFormatException(
+                "First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet.");
     }
 
-    private CompositeNodeWrapper createStructureWithRoot(String rootObjectName, JsonObject rootObject) {
+    private static CompositeNodeWrapper createStructureWithRoot(final String rootObjectName, final JsonObject rootObject) {
         CompositeNodeWrapper firstNode = new CompositeNodeWrapper(getNamespaceFor(rootObjectName),
                 getLocalNameFor(rootObjectName));
         for (Entry<String, JsonElement> childOfFirstNode : rootObject.entrySet()) {
@@ -75,9 +85,11 @@ class JsonReader {
         return firstNode;
     }
 
-    private void addChildToParent(String childName, JsonElement childType, CompositeNodeWrapper parent) {
+    private static void addChildToParent(final String childName, final JsonElement childType,
+            final CompositeNodeWrapper parent) {
         if (childType.isJsonObject()) {
-            CompositeNodeWrapper child = new CompositeNodeWrapper(getNamespaceFor(childName), getLocalNameFor(childName));
+            CompositeNodeWrapper child = new CompositeNodeWrapper(getNamespaceFor(childName),
+                    getLocalNameFor(childName));
             parent.addValue(child);
             for (Entry<String, JsonElement> childOfChild : childType.getAsJsonObject().entrySet()) {
                 addChildToParent(childOfChild.getKey(), childOfChild.getValue(), child);
@@ -96,40 +108,48 @@ class JsonReader {
             String value = childPrimitive.getAsString().trim();
             parent.addValue(new SimpleNodeWrapper(getNamespaceFor(childName), getLocalNameFor(childName),
                     resolveValueOfElement(value)));
+        } else {
+            LOG.debug("Ignoring unhandled child type {}", childType);
         }
     }
 
-    private URI getNamespaceFor(String jsonElementName) {
-        String[] moduleNameAndLocalName = jsonElementName.split(":");
-        // it is not "moduleName:localName"
-        if (moduleNameAndLocalName.length != 2) {
-            return null;
+    private static URI getNamespaceFor(final String jsonElementName) {
+        final Iterator<String> it = COLON_SPLITTER.split(jsonElementName).iterator();
+
+        // The string needs to me in form "moduleName:localName"
+        if (it.hasNext()) {
+            final String maybeURI = it.next();
+            if (Iterators.size(it) == 1) {
+                return URI.create(maybeURI);
+            }
         }
-        return URI.create(moduleNameAndLocalName[0]);
+
+        return null;
     }
 
-    private String getLocalNameFor(String jsonElementName) {
-        String[] moduleNameAndLocalName = jsonElementName.split(":");
-        // it is not "moduleName:localName"
-        if (moduleNameAndLocalName.length != 2) {
-            return jsonElementName;
-        }
-        return moduleNameAndLocalName[1];
+    private static String getLocalNameFor(final String jsonElementName) {
+        final Iterator<String> it = COLON_SPLITTER.split(jsonElementName).iterator();
+
+        // The string needs to me in form "moduleName:localName"
+        final String ret = Iterators.get(it, 1, null);
+        return ret != null && !it.hasNext() ? ret : jsonElementName;
     }
 
-    private Object resolveValueOfElement(String value) {
+    private static Object resolveValueOfElement(final String value) {
         // it could be instance-identifier Built-In Type
-        if (value.startsWith("/")) {
+        if (!value.isEmpty() && value.charAt(0) == '/') {
             IdentityValuesDTO resolvedValue = RestUtil.asInstanceIdentifier(value, new PrefixMapingFromJson());
             if (resolvedValue != null) {
                 return resolvedValue;
             }
         }
+
         // it could be identityref Built-In Type
         URI namespace = getNamespaceFor(value);
         if (namespace != null) {
-            return new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null,value);
+            return new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null, value);
         }
+
         // it is not "prefix:value" but just "value"
         return value;
     }
index 290d976b2857c493e7c638592e2715e963a03277..7890931a27fea2585de986ce524718f9df5db6a2 100644 (file)
@@ -11,9 +11,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-
 import javax.xml.stream.events.StartElement;
-
 import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
 import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
 import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.Predicate;
@@ -21,11 +19,13 @@ import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 
 public final class RestUtil {
 
+    // FIXME: BUG-1275: this is code duplicates data.impl.codec
+
     public static final String SQUOTE = "'";
     public static final String DQUOTE = "\"";
     private static final Pattern PREDICATE_PATTERN = Pattern.compile("\\[(.*?)\\]");
 
-    public final static TypeDefinition<?> resolveBaseTypeFrom(TypeDefinition<?> type) {
+    public final static TypeDefinition<?> resolveBaseTypeFrom(final TypeDefinition<?> type) {
         TypeDefinition<?> superType = type;
         while (superType.getBaseType() != null) {
             superType = superType.getBaseType();
@@ -33,7 +33,7 @@ public final class RestUtil {
         return superType;
     }
 
-    public static IdentityValuesDTO asInstanceIdentifier(String value, PrefixesMaping prefixMap) {
+    public static IdentityValuesDTO asInstanceIdentifier(final String value, final PrefixesMaping prefixMap) {
         String valueTrimmed = value.trim();
         if (!valueTrimmed.startsWith("/")) {
             return null;
@@ -63,12 +63,12 @@ public final class RestUtil {
         return identityValuesDTO.getValuesWithNamespaces().isEmpty() ? null : identityValuesDTO;
     }
 
-    private static String getIdAndPrefixAsStr(String pathPart) {
+    private static String getIdAndPrefixAsStr(final String pathPart) {
         int predicateStartIndex = pathPart.indexOf("[");
         return predicateStartIndex == -1 ? pathPart : pathPart.substring(0, predicateStartIndex);
     }
 
-    private static IdentityValue toIdentity(String xPathPart, PrefixesMaping prefixMap) {
+    private static IdentityValue toIdentity(final String xPathPart, final PrefixesMaping prefixMap) {
         String xPathPartTrimmed = xPathPart.trim();
         if (xPathPartTrimmed.isEmpty()) {
             return null;
@@ -87,7 +87,7 @@ public final class RestUtil {
         return new IdentityValue(namespace, identifier, namespace.equals(prefix) ? null : prefix);
     }
 
-    private static List<Predicate> toPredicates(String predicatesStr, PrefixesMaping prefixMap) {
+    private static List<Predicate> toPredicates(final String predicatesStr, final PrefixesMaping prefixMap) {
         List<Predicate> result = new ArrayList<>();
         List<String> predicates = new ArrayList<>();
         Matcher matcher = PREDICATE_PATTERN.matcher(predicatesStr);
@@ -104,8 +104,7 @@ public final class RestUtil {
                     }
                     result.add(new Predicate(null, predicateValue));
                 } else {
-                    IdentityValue identityValue = toIdentity(predicate.substring(0, indexOfEqualityMark),
-                            prefixMap);
+                    IdentityValue identityValue = toIdentity(predicate.substring(0, indexOfEqualityMark), prefixMap);
                     if (identityValue == null || predicateValue == null) {
                         return null;
                     }
@@ -116,7 +115,7 @@ public final class RestUtil {
         return result;
     }
 
-    private static String toPredicateValue(String predicatedValue) {
+    private static String toPredicateValue(final String predicatedValue) {
         String predicatedValueTrimmed = predicatedValue.trim();
         if ((predicatedValueTrimmed.startsWith(DQUOTE) || predicatedValueTrimmed.startsWith(SQUOTE))
                 && (predicatedValueTrimmed.endsWith(DQUOTE) || predicatedValueTrimmed.endsWith(SQUOTE))) {
@@ -132,12 +131,12 @@ public final class RestUtil {
     public static class PrefixMapingFromXml implements PrefixesMaping {
         StartElement startElement = null;
 
-        public PrefixMapingFromXml(StartElement startElement) {
+        public PrefixMapingFromXml(final StartElement startElement) {
             this.startElement = startElement;
         }
 
         @Override
-        public String getNamespace(String prefix) {
+        public String getNamespace(final String prefix) {
             return startElement.getNamespaceContext().getNamespaceURI(prefix);
         }
     }
@@ -145,7 +144,7 @@ public final class RestUtil {
     public static class PrefixMapingFromJson implements PrefixesMaping {
 
         @Override
-        public String getNamespace(String prefix) {
+        public String getNamespace(final String prefix) {
             return prefix;
         }
     }
index a5fd7bdaab2646f35e7463f9698f15ca217de11f..b4b2a1f9ef7249734e128456a33876abc3862ae8 100644 (file)
@@ -7,22 +7,19 @@
  */
 package org.opendaylight.controller.sal.rest.impl;
 
+import com.google.common.collect.ImmutableSet;
 import java.util.HashSet;
 import java.util.Set;
-
 import javax.ws.rs.core.Application;
-
 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 com.google.common.collect.ImmutableSet;
-
 public class RestconfApplication extends Application {
 
     @Override
     public Set<Class<?>> getClasses() {
-        return ImmutableSet.<Class<?>>of( RestconfDocumentedExceptionMapper.class );
+        return ImmutableSet.<Class<?>> of(RestconfDocumentedExceptionMapper.class);
     }
 
     @Override
@@ -43,5 +40,4 @@ public class RestconfApplication extends Application {
         return singletons;
     }
 
-
 }
index 5f6909cea8e3e15d2b7887fe975d2d3e613163b5..63a5b1b54055a81cd3f8f3f736365c4e99e1d8b8 100644 (file)
@@ -17,6 +17,10 @@ import static org.opendaylight.controller.sal.rest.api.Draft02.RestConfModule.ER
 import static org.opendaylight.controller.sal.rest.api.Draft02.RestConfModule.ERROR_TYPE_QNAME;
 import static org.opendaylight.controller.sal.rest.api.Draft02.RestConfModule.NAMESPACE;
 
+import com.google.common.base.Charsets;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.gson.stream.JsonWriter;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
@@ -24,7 +28,6 @@ import java.io.StringReader;
 import java.io.UnsupportedEncodingException;
 import java.util.List;
 import java.util.Map.Entry;
-
 import javax.activation.UnsupportedDataTypeException;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
@@ -41,7 +44,6 @@ import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.TransformerFactoryConfigurationError;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
-
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError;
@@ -57,29 +59,24 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.xml.sax.InputSource;
 
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.gson.stream.JsonWriter;
-
 /**
- * This class defines an ExceptionMapper that handles RestconfDocumentedExceptions thrown by
- * resource implementations and translates appropriately to restconf error response as defined in
- * the RESTCONF RFC draft.
+ * This class defines an ExceptionMapper that handles RestconfDocumentedExceptions thrown by resource implementations
+ * and translates appropriately to restconf error response as defined in the RESTCONF RFC draft.
  *
  * @author Thomas Pantelis
  */
 @Provider
 public class RestconfDocumentedExceptionMapper implements ExceptionMapper<RestconfDocumentedException> {
 
-    private final static Logger LOG = LoggerFactory.getLogger( RestconfDocumentedExceptionMapper.class );
+    private final static Logger LOG = LoggerFactory.getLogger(RestconfDocumentedExceptionMapper.class);
 
     @Context
     private HttpHeaders headers;
 
     @Override
-    public Response toResponse( final RestconfDocumentedException exception ) {
+    public Response toResponse(final RestconfDocumentedException exception) {
 
-        LOG.debug( "In toResponse: {}", exception.getMessage() );
+        LOG.debug("In toResponse: {}", exception.getMessage());
 
         // Default to the content type if there's no Accept header
 
@@ -87,172 +84,158 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
 
         List<MediaType> accepts = headers.getAcceptableMediaTypes();
 
-        LOG.debug( "Accept headers: {}", accepts );
+        LOG.debug("Accept headers: {}", accepts);
 
-        if( accepts != null && accepts.size() > 0 ) {
-            mediaType = accepts.get( 0 ); // just pick the first one
+        if (accepts != null && accepts.size() > 0) {
+            mediaType = accepts.get(0); // just pick the first one
         }
 
-        LOG.debug( "Using MediaType: {}",  mediaType );
+        LOG.debug("Using MediaType: {}", mediaType);
 
         List<RestconfError> errors = exception.getErrors();
-        if( errors.isEmpty() ) {
+        if (errors.isEmpty()) {
             // We don't actually want to send any content but, if we don't set any content here,
             // the tomcat front-end will send back an html error report. To prevent that, set a
             // single space char in the entity.
 
-            return Response.status( exception.getStatus() )
-                    .type( MediaType.TEXT_PLAIN_TYPE )
-                    .entity( " " ).build();
+            return Response.status(exception.getStatus()).type(MediaType.TEXT_PLAIN_TYPE).entity(" ").build();
         }
 
         int status = errors.iterator().next().getErrorTag().getStatusCode();
 
         ControllerContext context = ControllerContext.getInstance();
-        DataNodeContainer errorsSchemaNode = (DataNodeContainer)context.getRestconfModuleErrorsSchemaNode();
+        DataNodeContainer errorsSchemaNode = (DataNodeContainer) context.getRestconfModuleErrorsSchemaNode();
 
-        if( errorsSchemaNode == null ) {
-            return Response.status( status )
-                    .type( MediaType.TEXT_PLAIN_TYPE )
-                    .entity( exception.getMessage() ).build();
+        if (errorsSchemaNode == null) {
+            return Response.status(status).type(MediaType.TEXT_PLAIN_TYPE).entity(exception.getMessage()).build();
         }
 
         ImmutableList.Builder<Node<?>> errorNodes = ImmutableList.<Node<?>> builder();
-        for( RestconfError error: errors ) {
-            errorNodes.add( toDomNode( error ) );
+        for (RestconfError error : errors) {
+            errorNodes.add(toDomNode(error));
         }
 
-        ImmutableCompositeNode errorsNode =
-                ImmutableCompositeNode.create( ERRORS_CONTAINER_QNAME, errorNodes.build() );
+        ImmutableCompositeNode errorsNode = ImmutableCompositeNode.create(ERRORS_CONTAINER_QNAME, errorNodes.build());
 
         Object responseBody;
-        if( mediaType.getSubtype().endsWith( "json" ) ) {
-            responseBody = toJsonResponseBody( errorsNode, errorsSchemaNode );
-        }
-        else {
-            responseBody = toXMLResponseBody( errorsNode, errorsSchemaNode );
+        if (mediaType.getSubtype().endsWith("json")) {
+            responseBody = toJsonResponseBody(errorsNode, errorsSchemaNode);
+        } else {
+            responseBody = toXMLResponseBody(errorsNode, errorsSchemaNode);
         }
 
-        return Response.status( status ).type( mediaType ).entity( responseBody ).build();
+        return Response.status(status).type(mediaType).entity(responseBody).build();
     }
 
-    private Object toJsonResponseBody( final ImmutableCompositeNode errorsNode,
-            final DataNodeContainer errorsSchemaNode ) {
+    private Object toJsonResponseBody(final ImmutableCompositeNode errorsNode, final DataNodeContainer errorsSchemaNode) {
 
-        JsonMapper jsonMapper = new JsonMapper();
+        JsonMapper jsonMapper = new JsonMapper(null);
 
         Object responseBody = null;
         try {
             ByteArrayOutputStream outStream = new ByteArrayOutputStream();
-            JsonWriter writer = new JsonWriter( new OutputStreamWriter( outStream, "UTF-8" ) );
-            writer.setIndent( "    " );
+            JsonWriter writer = new JsonWriter(new OutputStreamWriter(outStream, Charsets.UTF_8));
+            writer.setIndent("    ");
 
-            jsonMapper.write( writer, errorsNode, errorsSchemaNode, null );
+            jsonMapper.write(writer, errorsNode, errorsSchemaNode);
             writer.flush();
 
-            responseBody = outStream.toString( "UTF-8" );
-        }
-        catch( IOException e ) {
-            LOG.error( "Error writing error response body", e );
+            responseBody = outStream.toString("UTF-8");
+        } catch (IOException e) {
+            LOG.error("Error writing error response body", e);
         }
 
         return responseBody;
     }
 
-    private Object toXMLResponseBody( final ImmutableCompositeNode errorsNode,
-            final DataNodeContainer errorsSchemaNode ) {
+    private Object toXMLResponseBody(final ImmutableCompositeNode errorsNode, final DataNodeContainer errorsSchemaNode) {
 
         XmlMapper xmlMapper = new XmlMapper();
 
         Object responseBody = null;
         try {
-            Document xmlDoc = xmlMapper.write( errorsNode, errorsSchemaNode );
+            Document xmlDoc = xmlMapper.write(errorsNode, errorsSchemaNode);
 
-            responseBody = documentToString( xmlDoc );
-        }
-        catch( TransformerException | UnsupportedDataTypeException | UnsupportedEncodingException e ) {
-            LOG.error( "Error writing error response body", e );
+            responseBody = documentToString(xmlDoc);
+        } catch (TransformerException | UnsupportedDataTypeException | UnsupportedEncodingException e) {
+            LOG.error("Error writing error response body", e);
         }
 
         return responseBody;
     }
 
-    private String documentToString( final Document doc ) throws TransformerException, UnsupportedEncodingException {
+    private String documentToString(final Document doc) throws TransformerException, UnsupportedEncodingException {
         Transformer transformer = createTransformer();
         ByteArrayOutputStream outStream = new ByteArrayOutputStream();
 
-        transformer.transform( new DOMSource( doc ), new StreamResult( outStream ) );
+        transformer.transform(new DOMSource(doc), new StreamResult(outStream));
 
-        return outStream.toString( "UTF-8" );
+        return outStream.toString("UTF-8");
     }
 
     private Transformer createTransformer() throws TransformerFactoryConfigurationError,
-    TransformerConfigurationException {
+            TransformerConfigurationException {
         TransformerFactory tf = TransformerFactory.newInstance();
         Transformer transformer = tf.newTransformer();
-        transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "no" );
-        transformer.setOutputProperty( OutputKeys.METHOD, "xml" );
-        transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
-        transformer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
-        transformer.setOutputProperty( "{http://xml.apache.org/xslt}indent-amount", "4" );
+        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
+        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
         return transformer;
     }
 
-    private Node<?> toDomNode( final RestconfError error ) {
+    private Node<?> toDomNode(final RestconfError error) {
 
         CompositeNodeBuilder<ImmutableCompositeNode> builder = ImmutableCompositeNode.builder();
-        builder.setQName( ERROR_LIST_QNAME );
+        builder.setQName(ERROR_LIST_QNAME);
 
-        addLeaf( builder, ERROR_TYPE_QNAME, error.getErrorType().getErrorTypeTag() );
-        addLeaf( builder, ERROR_TAG_QNAME, error.getErrorTag().getTagValue() );
-        addLeaf( builder, ERROR_MESSAGE_QNAME, error.getErrorMessage() );
-        addLeaf( builder, ERROR_APP_TAG_QNAME, error.getErrorAppTag() );
+        addLeaf(builder, ERROR_TYPE_QNAME, error.getErrorType().getErrorTypeTag());
+        addLeaf(builder, ERROR_TAG_QNAME, error.getErrorTag().getTagValue());
+        addLeaf(builder, ERROR_MESSAGE_QNAME, error.getErrorMessage());
+        addLeaf(builder, ERROR_APP_TAG_QNAME, error.getErrorAppTag());
 
-        Node<?> errorInfoNode = parseErrorInfo( error.getErrorInfo() );
-        if( errorInfoNode != null ) {
-            builder.add( errorInfoNode );
+        Node<?> errorInfoNode = parseErrorInfo(error.getErrorInfo());
+        if (errorInfoNode != null) {
+            builder.add(errorInfoNode);
         }
 
         return builder.toInstance();
     }
 
-    private Node<?> parseErrorInfo( final String errorInfo ) {
-        if( Strings.isNullOrEmpty( errorInfo ) ) {
+    private Node<?> parseErrorInfo(final String errorInfo) {
+        if (Strings.isNullOrEmpty(errorInfo)) {
             return null;
         }
 
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        factory.setNamespaceAware( true );
-        factory.setCoalescing( true );
-        factory.setIgnoringElementContentWhitespace( true );
-        factory.setIgnoringComments( true );
+        factory.setNamespaceAware(true);
+        factory.setCoalescing(true);
+        factory.setIgnoringElementContentWhitespace(true);
+        factory.setIgnoringComments(true);
 
         // Wrap the error info content in a root <error-info> element so it can be parsed
         // as XML. The error info content may or may not be XML. If not then it will be
         // parsed as text content of the <error-info> element.
 
-        String errorInfoWithRoot =
-                new StringBuilder( "<error-info xmlns=\"" ).append( NAMESPACE ).append( "\">" )
-                .append( errorInfo ).append( "</error-info>" ).toString();
+        String errorInfoWithRoot = new StringBuilder("<error-info xmlns=\"").append(NAMESPACE).append("\">")
+                .append(errorInfo).append("</error-info>").toString();
 
         Document doc = null;
         try {
-            doc = factory.newDocumentBuilder().parse(
-                    new InputSource( new StringReader( errorInfoWithRoot ) ) );
-        }
-        catch( Exception e ) {
-            // TODO: what if the content is text that happens to contain invalid markup? Could
-            // wrap in CDATA and try again.
+            doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(errorInfoWithRoot)));
+        } catch (Exception e) {
+            // TODO: what if the content is text that happens to contain invalid markup?
+            // Could wrap in CDATA and try again.
 
-            LOG.warn( "Error parsing restconf error-info, \"" + errorInfo + "\", as XML: " +
-                    e.toString() );
+            LOG.warn("Error parsing restconf error-info, \"{}\", as XML", errorInfo, e);
             return null;
         }
 
-        Node<?> errorInfoNode = XmlDocumentUtils.toDomNode( doc );
+        Node<?> errorInfoNode = XmlDocumentUtils.toDomNode(doc);
 
-        if( errorInfoNode instanceof CompositeNode ) {
-            CompositeNode compositeNode = (CompositeNode)XmlDocumentUtils.toDomNode( doc );
+        if (errorInfoNode instanceof CompositeNode) {
+            CompositeNode compositeNode = (CompositeNode) XmlDocumentUtils.toDomNode(doc);
 
             // At this point the QName for the "error-info" CompositeNode doesn't contain the revision
             // as it isn't present in the XML. So we'll copy all the child nodes and create a new
@@ -260,20 +243,20 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
             // locate the schema.
 
             ImmutableList.Builder<Node<?>> childNodes = ImmutableList.builder();
-            for( Entry<QName, List<Node<?>>> entry: compositeNode.entrySet() ) {
-                childNodes.addAll( entry.getValue() );
+            for (Entry<QName, List<Node<?>>> entry : compositeNode.entrySet()) {
+                childNodes.addAll(entry.getValue());
             }
 
-            errorInfoNode = ImmutableCompositeNode.create( ERROR_INFO_QNAME, childNodes.build() );
+            errorInfoNode = ImmutableCompositeNode.create(ERROR_INFO_QNAME, childNodes.build());
         }
 
         return errorInfoNode;
     }
 
-    private void addLeaf( final CompositeNodeBuilder<ImmutableCompositeNode> builder, final QName qname,
-            final String value ) {
-        if( !Strings.isNullOrEmpty( value ) ) {
-            builder.addLeaf( qname, value );
+    private void addLeaf(final CompositeNodeBuilder<ImmutableCompositeNode> builder, final QName qname,
+            final String value) {
+        if (!Strings.isNullOrEmpty(value)) {
+            builder.addLeaf(qname, value);
         }
     }
 }
@@ -10,30 +10,29 @@ package org.opendaylight.controller.sal.rest.impl;
 import java.util.Collection;
 import java.util.Collections;
 
-import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
 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.mount.MountService;
+import org.opendaylight.controller.sal.rest.api.RestConnector;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.controller.sal.streams.websockets.WebSocketServer;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
 
-public class RestconfProvider implements BundleActivator, Provider, ServiceTrackerCustomizer<Broker, Broker> {
+public class RestconfProviderImpl implements Provider, AutoCloseable, RestConnector {
 
     public final static String NOT_INITALIZED_MSG = "Restconf is not initialized yet. Please try again later";
 
     private ListenerRegistration<SchemaServiceListener> listenerRegistration;
-    private ServiceTracker<Broker, Broker> brokerServiceTrancker;
-    private BundleContext bundleContext;
+    private PortNumber port;
+    public void setWebsocketPort(PortNumber port) {
+        this.port = port;
+    }
+
     private Thread webSocketServerThread;
 
     @Override
@@ -47,53 +46,22 @@ public class RestconfProvider implements BundleActivator, Provider, ServiceTrack
         listenerRegistration = schemaService.registerSchemaServiceListener(ControllerContext.getInstance());
         ControllerContext.getInstance().setSchemas(schemaService.getGlobalContext());
         ControllerContext.getInstance().setMountService(session.getService(MountService.class));
-    }
 
-    @Override
-    public void start(BundleContext context) throws Exception {
-        bundleContext = context;
-        brokerServiceTrancker = new ServiceTracker<>(context, Broker.class, this);
-        brokerServiceTrancker.open();
-        webSocketServerThread = new Thread(new WebSocketServer());
-        webSocketServerThread.setName("Web socket server");
+        webSocketServerThread = new Thread(WebSocketServer.createInstance(port.getValue().intValue()));
+        webSocketServerThread.setName("Web socket server on port " + port);
         webSocketServerThread.start();
     }
 
-    @Override
-    public void stop(BundleContext context) {
-        if (listenerRegistration != null) {
-            try {
-                listenerRegistration.close();
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-        webSocketServerThread.interrupt();
-        brokerServiceTrancker.close();
-    }
-
     @Override
     public Collection<ProviderFunctionality> getProviderFunctionality() {
         return Collections.emptySet();
     }
 
     @Override
-    public Broker addingService(ServiceReference<Broker> reference) {
-        Broker broker = bundleContext.getService(reference);
-        broker.registerProvider(this, bundleContext);
-        return broker;
-    }
-
-    @Override
-    public void modifiedService(ServiceReference<Broker> reference, Broker service) {
-        // NOOP
-    }
-
-    @Override
-    public void removedService(ServiceReference<Broker> reference, Broker service) {
-        bundleContext.ungetService(reference);
-        BrokerFacade.getInstance().setContext(null);
-        BrokerFacade.getInstance().setDataService(null);
-        ControllerContext.getInstance().setSchemas(null);
+    public void close() {
+        if (listenerRegistration != null) {
+            listenerRegistration.close();
+        }
+        webSocketServerThread.interrupt();
     }
 }
index 422cf04cca82f7d0bf5d2f535df40a6f7688215e..933ed0f849e7171b7c16c423c5462aa8de1bb25a 100644 (file)
@@ -7,12 +7,13 @@
  */
 package org.opendaylight.controller.sal.rest.impl;
 
+import com.google.common.base.Charsets;
+import com.google.gson.stream.JsonWriter;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
-
 import javax.ws.rs.Produces;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
@@ -20,7 +21,6 @@ import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.MessageBodyWriter;
 import javax.ws.rs.ext.Provider;
-
 import org.opendaylight.controller.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
@@ -28,8 +28,6 @@ import org.opendaylight.controller.sal.restconf.impl.StructuredData;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 
-import com.google.gson.stream.JsonWriter;
-
 @Provider
 @Produces({ Draft02.MediaTypes.API + RestconfService.JSON, Draft02.MediaTypes.DATA + RestconfService.JSON,
         Draft02.MediaTypes.OPERATION + RestconfService.JSON, MediaType.APPLICATION_JSON })
@@ -37,29 +35,36 @@ public enum StructuredDataToJsonProvider implements MessageBodyWriter<Structured
     INSTANCE;
 
     @Override
-    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
-        return type.equals( StructuredData.class );
+    public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations,
+            final MediaType mediaType) {
+        return type.equals(StructuredData.class);
     }
 
     @Override
-    public long getSize(StructuredData t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+    public long getSize(final StructuredData t, final Class<?> type, final Type genericType,
+            final Annotation[] annotations, final MediaType mediaType) {
         return -1;
     }
 
     @Override
-    public void writeTo(StructuredData t, Class<?> type, Type genericType, Annotation[] annotations,
-            MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
-            throws IOException, WebApplicationException {
+    public void writeTo(final StructuredData t, final Class<?> type, final Type genericType,
+            final Annotation[] annotations, final MediaType mediaType,
+            final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException,
+            WebApplicationException {
         CompositeNode data = t.getData();
         if (data == null) {
             throw new RestconfDocumentedException(Response.Status.NOT_FOUND);
         }
 
-        JsonWriter writer = new JsonWriter(new OutputStreamWriter(entityStream, "UTF-8"));
-        writer.setIndent("    ");
-        JsonMapper jsonMapper = new JsonMapper();
-        jsonMapper.write(writer, data, (DataNodeContainer) t.getSchema(), t.getMountPoint());
+        JsonWriter writer = new JsonWriter(new OutputStreamWriter(entityStream, Charsets.UTF_8));
+
+        if (t.isPrettyPrintMode()) {
+            writer.setIndent("    ");
+        } else {
+            writer.setIndent("");
+        }
+        JsonMapper jsonMapper = new JsonMapper(t.getMountPoint());
+        jsonMapper.write(writer, data, (DataNodeContainer) t.getSchema());
         writer.flush();
     }
-
 }
index bcb3c422ff8dc0c33c8a44d27d20b63ec1e3852d..703a2a463476bcfd4704c34419cc17c73a6af3fc 100644 (file)
@@ -11,7 +11,6 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
-
 import javax.ws.rs.Produces;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
@@ -21,11 +20,11 @@ import javax.ws.rs.ext.MessageBodyWriter;
 import javax.ws.rs.ext.Provider;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
 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.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
@@ -44,42 +43,70 @@ import org.w3c.dom.Document;
 public enum StructuredDataToXmlProvider implements MessageBodyWriter<StructuredData> {
     INSTANCE;
 
-    private final static Logger logger = LoggerFactory.getLogger(StructuredDataToXmlProvider.class);
+    private static final Logger LOG = LoggerFactory.getLogger(StructuredDataToXmlProvider.class);
+    private static final TransformerFactory FACTORY = TransformerFactory.newInstance();
+    private static final ThreadLocal<Transformer> TRANSFORMER = new ThreadLocal<Transformer>() {
+        @Override
+        protected Transformer initialValue() {
+            final Transformer ret;
+            try {
+                ret = FACTORY.newTransformer();
+            } catch (TransformerConfigurationException e) {
+                LOG.error("Failed to instantiate XML transformer", e);
+                throw new IllegalStateException("XML encoding currently unavailable", e);
+            }
+
+            ret.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
+            ret.setOutputProperty(OutputKeys.METHOD, "xml");
+            ret.setOutputProperty(OutputKeys.INDENT, "yes");
+            ret.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+            ret.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
+
+            return ret;
+        }
+    };
 
     @Override
-    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
-        return type.equals( StructuredData.class );
+    public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations,
+            final MediaType mediaType) {
+        return type.equals(StructuredData.class);
     }
 
     @Override
-    public long getSize(StructuredData t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+    public long getSize(final StructuredData t, final Class<?> type, final Type genericType,
+            final Annotation[] annotations, final MediaType mediaType) {
         return -1;
     }
 
     @Override
-    public void writeTo(StructuredData t, Class<?> type, Type genericType, Annotation[] annotations,
-            MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
-            throws IOException, WebApplicationException {
+    public void writeTo(final StructuredData t, final Class<?> type, final Type genericType,
+            final Annotation[] annotations, final MediaType mediaType,
+            final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException,
+            WebApplicationException {
         CompositeNode data = t.getData();
         if (data == null) {
             throw new RestconfDocumentedException(Response.Status.NOT_FOUND);
         }
 
-        XmlMapper xmlMapper = new XmlMapper();
-        Document domTree = xmlMapper.write(data, (DataNodeContainer) t.getSchema());
+        final Transformer trans;
+        try {
+            trans = TRANSFORMER.get();
+            if (t.isPrettyPrintMode()) {
+                trans.setOutputProperty(OutputKeys.INDENT, "yes");
+            } else {
+                trans.setOutputProperty(OutputKeys.INDENT, "no");
+            }
+        } catch (RuntimeException e) {
+            throw new RestconfDocumentedException(e.getMessage(), ErrorType.TRANSPORT, ErrorTag.OPERATION_FAILED);
+        }
+
+        // FIXME: BUG-1281: eliminate the intermediate Document
+        final Document domTree = new XmlMapper().write(data, (DataNodeContainer) t.getSchema());
         try {
-            TransformerFactory tf = TransformerFactory.newInstance();
-            Transformer transformer = tf.newTransformer();
-            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
-            transformer.setOutputProperty(OutputKeys.METHOD, "xml");
-            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
-            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
-            transformer.transform(new DOMSource(domTree), new StreamResult(entityStream));
+            trans.transform(new DOMSource(domTree), new StreamResult(entityStream));
         } catch (TransformerException e) {
-            logger.error("Error during translation of Document to OutputStream", e);
-            throw new RestconfDocumentedException( e.getMessage(), ErrorType.TRANSPORT,
-                                                   ErrorTag.OPERATION_FAILED );
+            LOG.error("Error during translation of Document to OutputStream", e);
+            throw new RestconfDocumentedException(e.getMessage(), ErrorType.TRANSPORT, ErrorTag.OPERATION_FAILED);
         }
     }
 
index e76e1962a058bea7c0bdb8a22b6a2c7285e785cd..b0b2cc5e2f0898dd0bc0d7572ec480884b3f9308 100644 (file)
@@ -7,8 +7,8 @@
  */
 package org.opendaylight.controller.sal.rest.impl;
 
+import com.google.common.base.Optional;
 import javax.activation.UnsupportedDataTypeException;
-
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
 import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
@@ -20,8 +20,6 @@ import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.util.Leafref;
 import org.w3c.dom.Document;
 
-import com.google.common.base.Optional;
-
 public class XmlMapper {
     private static final LeafrefCodecImpl LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl(
             Optional.<LeafrefTypeDefinition> absent());
index bc7473864cbb3ffa553c78fbf8a96fb64a7dad6d..31e9c96462541e75205d9ef9c6aac9508abc6e43 100644 (file)
@@ -11,7 +11,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
-
 import javax.ws.rs.Consumes;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
@@ -19,7 +18,6 @@ import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.Provider;
 import javax.xml.stream.XMLStreamException;
-
 import org.opendaylight.controller.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
@@ -35,7 +33,7 @@ import org.slf4j.LoggerFactory;
 public enum XmlToCompositeNodeProvider implements MessageBodyReader<CompositeNode> {
     INSTANCE;
 
-    private final static Logger LOG = LoggerFactory.getLogger( XmlToCompositeNodeProvider.class );
+    private final static Logger LOG = LoggerFactory.getLogger(XmlToCompositeNodeProvider.class);
 
     @Override
     public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
@@ -46,14 +44,13 @@ public enum XmlToCompositeNodeProvider implements MessageBodyReader<CompositeNod
     public CompositeNode readFrom(Class<CompositeNode> type, Type genericType, Annotation[] annotations,
             MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
             throws IOException, WebApplicationException {
-        XmlReader xmlReader = new XmlReader();
+        XmlToCompositeNodeReader xmlReader = new XmlToCompositeNodeReader();
         try {
             return xmlReader.read(entityStream);
         } catch (XMLStreamException | UnsupportedFormatException e) {
-            LOG.debug( "Error parsing json input", e );
-            throw new RestconfDocumentedException(
-                            "Error parsing input: " + e.getMessage(),
-                            ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE );
+            LOG.debug("Error parsing json input", e);
+            throw new RestconfDocumentedException("Error parsing input: " + e.getMessage(), ErrorType.PROTOCOL,
+                    ErrorTag.MALFORMED_MESSAGE);
         }
     }
 
@@ -28,19 +28,18 @@ import org.opendaylight.controller.sal.restconf.impl.NodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
 import org.opendaylight.yangtools.yang.data.api.Node;
 
-public class XmlReader {
+public class XmlToCompositeNodeReader {
 
     private final static XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
     private XMLEventReader eventReader;
 
-    public CompositeNodeWrapper read(InputStream entityStream) throws XMLStreamException,
-                                                                      UnsupportedFormatException,
-                                                                      IOException {
-        //Get an XML stream which can be marked, and reset, so we can check and see if there is
-        //any content being provided.
+    public CompositeNodeWrapper read(InputStream entityStream) throws XMLStreamException, UnsupportedFormatException,
+            IOException {
+        // Get an XML stream which can be marked, and reset, so we can check and
+        // see if there is any content being provided.
         entityStream = getMarkableStream(entityStream);
 
-        if( isInputStreamEmpty( entityStream ) ) {
+        if (isInputStreamEmpty(entityStream)) {
             return null;
         }
 
@@ -103,24 +102,23 @@ public class XmlReader {
     }
 
     /**
-     * If the input stream is not markable, then it wraps the input stream with a buffered stream,
-     * which is mark able. That way we can check if the stream is empty safely.
+     * If the input stream is not markable, then it wraps the input stream with a buffered stream, which is mark able.
+     * That way we can check if the stream is empty safely.
+     *
      * @param entityStream
      * @return
      */
     private InputStream getMarkableStream(InputStream entityStream) {
-        if( !entityStream.markSupported() )
-        {
-            entityStream = new BufferedInputStream( entityStream );
+        if (!entityStream.markSupported()) {
+            entityStream = new BufferedInputStream(entityStream);
         }
         return entityStream;
     }
 
-    private boolean isInputStreamEmpty(InputStream entityStream)
-            throws IOException {
+    private boolean isInputStreamEmpty(InputStream entityStream) throws IOException {
         boolean isEmpty = false;
-        entityStream.mark( 1 );
-        if( entityStream.read() == -1 ){
+        entityStream.mark(1);
+        if (entityStream.read() == -1) {
             isEmpty = true;
         }
         entityStream.reset();
@@ -131,7 +129,7 @@ public class XmlReader {
         checkArgument(event != null, "XML Event cannot be NULL!");
         if (event.isStartElement()) {
             XMLEvent innerEvent = skipCommentsAndWhitespace();
-            if ( innerEvent != null && (innerEvent.isCharacters() || innerEvent.isEndElement())) {
+            if (innerEvent != null && (innerEvent.isCharacters() || innerEvent.isEndElement())) {
                 return true;
             }
         }
@@ -142,7 +140,7 @@ public class XmlReader {
         checkArgument(event != null, "XML Event cannot be NULL!");
         if (event.isStartElement()) {
             XMLEvent innerEvent = skipCommentsAndWhitespace();
-            if( innerEvent != null ) {
+            if (innerEvent != null) {
                 if (innerEvent.isStartElement()) {
                     return true;
                 }
@@ -152,16 +150,16 @@ public class XmlReader {
     }
 
     private XMLEvent skipCommentsAndWhitespace() throws XMLStreamException {
-        while( eventReader.hasNext() ) {
+        while (eventReader.hasNext()) {
             XMLEvent event = eventReader.peek();
-            if( event.getEventType() == XMLStreamConstants.COMMENT ) {
+            if (event.getEventType() == XMLStreamConstants.COMMENT) {
                 eventReader.nextEvent();
                 continue;
             }
 
-            if( event.isCharacters() ) {
+            if (event.isCharacters()) {
                 Characters chars = event.asCharacters();
-                if( chars.isWhiteSpace() ) {
+                if (chars.isWhiteSpace()) {
                     eventReader.nextEvent();
                     continue;
                 }
@@ -235,7 +233,8 @@ public class XmlReader {
     private Object resolveValueOfElement(String value, StartElement startElement) {
         // it could be instance-identifier Built-In Type
         if (value.startsWith("/")) {
-            IdentityValuesDTO iiValue = RestUtil.asInstanceIdentifier(value, new RestUtil.PrefixMapingFromXml(startElement));
+            IdentityValuesDTO iiValue = RestUtil.asInstanceIdentifier(value, new RestUtil.PrefixMapingFromXml(
+                    startElement));
             if (iiValue != null) {
                 return iiValue;
             }
@@ -245,7 +244,7 @@ public class XmlReader {
         if (namespaceAndValue.length == 2) {
             String namespace = startElement.getNamespaceContext().getNamespaceURI(namespaceAndValue[0]);
             if (namespace != null && !namespace.isEmpty()) {
-                return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0],value);
+                return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0], value);
             }
         }
         // it is not "prefix:value" but just "value"
index 62afdbd10df31df5f5a577f3520dec8ab8b59dcd..9560333e711b3e56224f5ca7dab6118bedcb6d7a 100644 (file)
@@ -5,4 +5,4 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.controller.sal.rest.impl;
+package org.opendaylight.controller.sal.rest.impl;
\ No newline at end of file
index 3d047dd07f53e47a4000a5de137fcc52e3affa75..861aaac3d81552957b5798c3b775501d830fadce 100644 (file)
@@ -8,12 +8,13 @@
 package org.opendaylight.controller.sal.restconf.impl;
 
 import com.google.common.util.concurrent.Futures;
-import java.util.Collections;
+
 import java.util.concurrent.Future;
+
 import javax.ws.rs.core.Response.Status;
+
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.api.data.DataReader;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
@@ -24,15 +25,15 @@ import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
 import org.opendaylight.controller.sal.streams.listeners.ListenerAdapter;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
-    private final static Logger LOG = LoggerFactory.getLogger( BrokerFacade.class );
+public class BrokerFacade implements DataReader<YangInstanceIdentifier, CompositeNode> {
+    private final static Logger LOG = LoggerFactory.getLogger(BrokerFacade.class);
 
     private final static BrokerFacade INSTANCE = new BrokerFacade();
 
@@ -42,11 +43,11 @@ public class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNod
     private BrokerFacade() {
     }
 
-    public void setContext( final ConsumerSession context ) {
+    public void setContext(final ConsumerSession context) {
         this.context = context;
     }
 
-    public void setDataService( final DataBrokerService dataService ) {
+    public void setDataService(final DataBrokerService dataService) {
         this.dataService = dataService;
     }
 
@@ -55,145 +56,145 @@ public class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNod
     }
 
     private void checkPreconditions() {
-        if( context == null || dataService == null ) {
-            throw new RestconfDocumentedException( Status.SERVICE_UNAVAILABLE );
+        if (context == null || dataService == null) {
+            throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE);
         }
     }
 
     @Override
-    public CompositeNode readConfigurationData( final InstanceIdentifier path ) {
+    public CompositeNode readConfigurationData(final YangInstanceIdentifier path) {
         this.checkPreconditions();
 
-        LOG.trace( "Read Configuration via Restconf: {}", path );
+        LOG.trace("Read Configuration via Restconf: {}", path);
 
-        return dataService.readConfigurationData( path );
+        return dataService.readConfigurationData(path);
     }
 
-    public CompositeNode readConfigurationDataBehindMountPoint( final MountInstance mountPoint,
-                                                                final InstanceIdentifier path ) {
+    public CompositeNode readConfigurationDataBehindMountPoint(final MountInstance mountPoint,
+            final YangInstanceIdentifier path) {
         this.checkPreconditions();
 
-        LOG.trace( "Read Configuration via Restconf: {}", path );
+        LOG.trace("Read Configuration via Restconf: {}", path);
 
-        return mountPoint.readConfigurationData( path );
+        return mountPoint.readConfigurationData(path);
     }
 
     @Override
-    public CompositeNode readOperationalData( final InstanceIdentifier path ) {
+    public CompositeNode readOperationalData(final YangInstanceIdentifier path) {
         this.checkPreconditions();
 
-        BrokerFacade.LOG.trace( "Read Operational via Restconf: {}", path );
+        BrokerFacade.LOG.trace("Read Operational via Restconf: {}", path);
 
-        return dataService.readOperationalData( path );
+        return dataService.readOperationalData(path);
     }
 
-    public CompositeNode readOperationalDataBehindMountPoint( final MountInstance mountPoint,
-                                                              final InstanceIdentifier path ) {
+    public CompositeNode readOperationalDataBehindMountPoint(final MountInstance mountPoint,
+            final YangInstanceIdentifier path) {
         this.checkPreconditions();
 
-        BrokerFacade.LOG.trace( "Read Operational via Restconf: {}", path );
+        BrokerFacade.LOG.trace("Read Operational via Restconf: {}", path);
 
-        return mountPoint.readOperationalData( path );
+        return mountPoint.readOperationalData(path);
     }
 
-    public Future<RpcResult<CompositeNode>> invokeRpc( final QName type, final CompositeNode payload ) {
+    public Future<RpcResult<CompositeNode>> invokeRpc(final QName type, final CompositeNode payload) {
         this.checkPreconditions();
 
-        return context.rpc( type, payload );
+        return context.rpc(type, payload);
     }
 
-    public Future<RpcResult<TransactionStatus>> commitConfigurationDataPut( final InstanceIdentifier path,
-                                                                            final CompositeNode payload ) {
+    public Future<RpcResult<TransactionStatus>> commitConfigurationDataPut(final YangInstanceIdentifier path,
+            final CompositeNode payload) {
         this.checkPreconditions();
 
         final DataModificationTransaction transaction = dataService.beginTransaction();
-        BrokerFacade.LOG.trace( "Put Configuration via Restconf: {}", path );
-        transaction.putConfigurationData( path, payload );
+        BrokerFacade.LOG.trace("Put Configuration via Restconf: {}", path);
+        transaction.putConfigurationData(path, payload);
         return transaction.commit();
     }
 
     public Future<RpcResult<TransactionStatus>> commitConfigurationDataPutBehindMountPoint(
-            final MountInstance mountPoint, final InstanceIdentifier path, final CompositeNode payload ) {
+            final MountInstance mountPoint, final YangInstanceIdentifier path, final CompositeNode payload) {
         this.checkPreconditions();
 
         final DataModificationTransaction transaction = mountPoint.beginTransaction();
-        BrokerFacade.LOG.trace( "Put Configuration via Restconf: {}", path );
-        transaction.putConfigurationData( path, payload );
+        BrokerFacade.LOG.trace("Put Configuration via Restconf: {}", path);
+        transaction.putConfigurationData(path, payload);
         return transaction.commit();
     }
 
-    public Future<RpcResult<TransactionStatus>> commitConfigurationDataPost( final InstanceIdentifier path,
-                                                                             final CompositeNode payload) {
+    public Future<RpcResult<TransactionStatus>> commitConfigurationDataPost(final YangInstanceIdentifier path,
+            final CompositeNode payload) {
         this.checkPreconditions();
 
         final DataModificationTransaction transaction = dataService.beginTransaction();
         /* check for available Node in Configuration DataStore by path */
-        CompositeNode availableNode = transaction.readConfigurationData( path );
+        CompositeNode availableNode = transaction.readConfigurationData(path);
         if (availableNode != null) {
             String errMsg = "Post Configuration via Restconf was not executed because data already exists";
             BrokerFacade.LOG.warn((new StringBuilder(errMsg)).append(" : ").append(path).toString());
 
-            throw new RestconfDocumentedException(
-                    "Data already exists for path: " + path, ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS );
+            throw new RestconfDocumentedException("Data already exists for path: " + path, ErrorType.PROTOCOL,
+                    ErrorTag.DATA_EXISTS);
         }
-        BrokerFacade.LOG.trace( "Post Configuration via Restconf: {}", path );
-        transaction.putConfigurationData( path, payload );
+        BrokerFacade.LOG.trace("Post Configuration via Restconf: {}", path);
+        transaction.putConfigurationData(path, payload);
         return transaction.commit();
     }
 
     public Future<RpcResult<TransactionStatus>> commitConfigurationDataPostBehindMountPoint(
-            final MountInstance mountPoint, final InstanceIdentifier path, final CompositeNode payload ) {
+            final MountInstance mountPoint, final YangInstanceIdentifier path, final CompositeNode payload) {
         this.checkPreconditions();
 
         final DataModificationTransaction transaction = mountPoint.beginTransaction();
         /* check for available Node in Configuration DataStore by path */
-        CompositeNode availableNode = transaction.readConfigurationData( path );
+        CompositeNode availableNode = transaction.readConfigurationData(path);
         if (availableNode != null) {
             String errMsg = "Post Configuration via Restconf was not executed because data already exists";
             BrokerFacade.LOG.warn((new StringBuilder(errMsg)).append(" : ").append(path).toString());
 
-            throw new RestconfDocumentedException(
-                    "Data already exists for path: " + path, ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS );
+            throw new RestconfDocumentedException("Data already exists for path: " + path, ErrorType.PROTOCOL,
+                    ErrorTag.DATA_EXISTS);
         }
-        BrokerFacade.LOG.trace( "Post Configuration via Restconf: {}", path );
-        transaction.putConfigurationData( path, payload );
+        BrokerFacade.LOG.trace("Post Configuration via Restconf: {}", path);
+        transaction.putConfigurationData(path, payload);
         return transaction.commit();
     }
 
-    public Future<RpcResult<TransactionStatus>> commitConfigurationDataDelete( final InstanceIdentifier path ) {
+    public Future<RpcResult<TransactionStatus>> commitConfigurationDataDelete(final YangInstanceIdentifier path) {
         this.checkPreconditions();
-        return deleteDataAtTarget(path,dataService.beginTransaction());
+        return deleteDataAtTarget(path, dataService.beginTransaction());
     }
 
     public Future<RpcResult<TransactionStatus>> commitConfigurationDataDeleteBehindMountPoint(
-                                          final MountInstance mountPoint, final InstanceIdentifier path ) {
+            final MountInstance mountPoint, final YangInstanceIdentifier path) {
         this.checkPreconditions();
-        return deleteDataAtTarget(path,mountPoint.beginTransaction());
+        return deleteDataAtTarget(path, mountPoint.beginTransaction());
     }
 
-    private Future<RpcResult<TransactionStatus>> deleteDataAtTarget(final InstanceIdentifier path,
+    private Future<RpcResult<TransactionStatus>> deleteDataAtTarget(final YangInstanceIdentifier path,
             final DataModificationTransaction transaction) {
         LOG.info("Delete Configuration via Restconf: {}", path);
         CompositeNode redDataAtPath = transaction.readConfigurationData(path);
         if (redDataAtPath == null) {
-            return Futures.immediateFuture(Rpcs.<TransactionStatus> getRpcResult(true, TransactionStatus.COMMITED,
-                    Collections.<RpcError> emptyList()));
+            return Futures.immediateFuture(RpcResultBuilder.<TransactionStatus>
+                                                    success(TransactionStatus.COMMITED).build());
         }
         transaction.removeConfigurationData(path);
         return transaction.commit();
     }
 
-    public void registerToListenDataChanges( final ListenerAdapter listener ) {
+    public void registerToListenDataChanges(final ListenerAdapter listener) {
         this.checkPreconditions();
 
-        if( listener.isListening() ) {
+        if (listener.isListening()) {
             return;
         }
 
-        InstanceIdentifier path = listener.getPath();
-        final ListenerRegistration<DataChangeListener> registration =
-                                             dataService.registerDataChangeListener( path, listener );
+        YangInstanceIdentifier path = listener.getPath();
+        final ListenerRegistration<DataChangeListener> registration = dataService.registerDataChangeListener(path,
+                listener);
 
-        listener.setRegistration( registration );
+        listener.setRegistration(registration);
     }
 }
index 96ad528a0dd3f9e0591b78b2be702e9b1d004c4c..206dbdeab60a20dff4d13f9fbd3c96c68ac45b4d 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.sal.restconf.impl;
 
+import com.google.common.base.Preconditions;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -14,7 +15,6 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
@@ -23,8 +23,6 @@ import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 
-import com.google.common.base.Preconditions;
-
 public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, CompositeNode {
 
     private MutableCompositeNode compositeNode;
@@ -104,7 +102,7 @@ public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, C
                 name = new QName(namespace, localName);
             }
 
-            List<Node<?>> nodeValues = new ArrayList<>();
+            List<Node<?>> nodeValues = new ArrayList<>(values.size());
             for (NodeWrapper<?> nodeWrapper : values) {
                 nodeValues.add(nodeWrapper.unwrap());
             }
index 6330c0a479caa5acf2926e5ce9820bc3a435e756..dad7a2cda2ff3f647d58d66fcd6a37dd36b10c62 100644 (file)
@@ -7,19 +7,30 @@
  */
 package org.opendaylight.controller.sal.restconf.impl;
 
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URLDecoder;
 import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicReference;
 
 import javax.ws.rs.core.Response.Status;
 
@@ -31,11 +42,11 @@ import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
 import org.opendaylight.yangtools.concepts.Codec;
 import org.opendaylight.yangtools.yang.common.QName;
-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.NodeIdentifier;
-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.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
@@ -55,21 +66,8 @@ import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.HashBiMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
 public class ControllerContext implements SchemaContextListener {
-    private final static Logger LOG = LoggerFactory.getLogger( ControllerContext.class );
+    private final static Logger LOG = LoggerFactory.getLogger(ControllerContext.class);
 
     private final static ControllerContext INSTANCE = new ControllerContext();
 
@@ -83,20 +81,23 @@ public class ControllerContext implements SchemaContextListener {
 
     private final static String URI_ENCODING_CHAR_SET = "ISO-8859-1";
 
+    private static final Splitter SLASH_SPLITTER = Splitter.on('/');
+
     private final BiMap<URI, String> uriToModuleName = HashBiMap.<URI, String> create();
 
     private final Map<String, URI> moduleNameToUri = uriToModuleName.inverse();
 
-    private final Map<QName, RpcDefinition> qnameToRpc = new ConcurrentHashMap<>();
+    private final AtomicReference<Map<QName, RpcDefinition>> qnameToRpc =
+            new AtomicReference<>(Collections.<QName, RpcDefinition>emptyMap());
 
     private volatile SchemaContext globalSchema;
     private volatile MountService mountService;
 
-    public void setGlobalSchema( final SchemaContext globalSchema ) {
+    public void setGlobalSchema(final SchemaContext globalSchema) {
         this.globalSchema = globalSchema;
     }
 
-    public void setMountService( final MountService mountService ) {
+    public void setMountService(final MountService mountService) {
         this.mountService = mountService;
     }
 
@@ -108,164 +109,157 @@ public class ControllerContext implements SchemaContextListener {
     }
 
     private void checkPreconditions() {
-        if( globalSchema == null ) {
-            throw new RestconfDocumentedException( Status.SERVICE_UNAVAILABLE );
+        if (globalSchema == null) {
+            throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE);
         }
     }
 
-    public void setSchemas( final SchemaContext schemas ) {
-        this.onGlobalContextUpdated( schemas );
+    public void setSchemas(final SchemaContext schemas) {
+        this.onGlobalContextUpdated(schemas);
     }
 
-    public InstanceIdWithSchemaNode toInstanceIdentifier( final String restconfInstance ) {
-        return this.toIdentifier( restconfInstance, false );
+    public InstanceIdWithSchemaNode toInstanceIdentifier(final String restconfInstance) {
+        return this.toIdentifier(restconfInstance, false);
     }
 
-    public InstanceIdWithSchemaNode toMountPointIdentifier( final String restconfInstance ) {
-        return this.toIdentifier( restconfInstance, true );
+    public InstanceIdWithSchemaNode toMountPointIdentifier(final String restconfInstance) {
+        return this.toIdentifier(restconfInstance, true);
     }
 
-    private InstanceIdWithSchemaNode toIdentifier( final String restconfInstance,
-            final boolean toMountPointIdentifier ) {
+    private InstanceIdWithSchemaNode toIdentifier(final String restconfInstance, final boolean toMountPointIdentifier) {
         this.checkPreconditions();
 
-        Iterable<String> split = Splitter.on( "/" ).split( restconfInstance );
-        final ArrayList<String> encodedPathArgs = Lists.<String> newArrayList( split );
-        final List<String> pathArgs = this.urlPathArgsDecode( encodedPathArgs );
-        this.omitFirstAndLastEmptyString( pathArgs );
-        if( pathArgs.isEmpty() ) {
+        final List<String> pathArgs = urlPathArgsDecode(SLASH_SPLITTER.split(restconfInstance));
+        omitFirstAndLastEmptyString(pathArgs);
+        if (pathArgs.isEmpty()) {
             return null;
         }
 
         String first = pathArgs.iterator().next();
-        final String startModule = ControllerContext.toModuleName( first );
-        if( startModule == null ) {
-            throw new RestconfDocumentedException(
-                    "First node in URI has to be in format \"moduleName:nodeName\"",
-                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+        final String startModule = ControllerContext.toModuleName(first);
+        if (startModule == null) {
+            throw new RestconfDocumentedException("First node in URI has to be in format \"moduleName:nodeName\"",
+                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
 
-        InstanceIdentifierBuilder builder = InstanceIdentifier.builder();
-        Module latestModule = this.getLatestModule( globalSchema, startModule );
-        InstanceIdWithSchemaNode iiWithSchemaNode = this.collectPathArguments( builder, pathArgs,
-                latestModule, null, toMountPointIdentifier );
+        InstanceIdentifierBuilder builder = YangInstanceIdentifier.builder();
+        Module latestModule = this.getLatestModule(globalSchema, startModule);
+        InstanceIdWithSchemaNode iiWithSchemaNode = this.collectPathArguments(builder, pathArgs, latestModule, null,
+                toMountPointIdentifier);
 
-        if( iiWithSchemaNode == null ) {
-            throw new RestconfDocumentedException(
-                    "URI has bad format", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+        if (iiWithSchemaNode == null) {
+            throw new RestconfDocumentedException("URI has bad format", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
 
         return iiWithSchemaNode;
     }
 
-    private List<String> omitFirstAndLastEmptyString( final List<String> list ) {
-        if( list.isEmpty() ) {
+    private static List<String> omitFirstAndLastEmptyString(final List<String> list) {
+        if (list.isEmpty()) {
             return list;
         }
 
         String head = list.iterator().next();
-        if( head.isEmpty() ) {
-            list.remove( 0 );
+        if (head.isEmpty()) {
+            list.remove(0);
         }
 
-        if( list.isEmpty() ) {
+        if (list.isEmpty()) {
             return list;
         }
 
-        String last = list.get( list.size() - 1 );
-        if( last.isEmpty() ) {
-            list.remove( list.size() - 1 );
+        String last = list.get(list.size() - 1);
+        if (last.isEmpty()) {
+            list.remove(list.size() - 1);
         }
 
         return list;
     }
 
-    private Module getLatestModule( final SchemaContext schema, final String moduleName ) {
-        Preconditions.checkArgument( schema != null );
-        Preconditions.checkArgument( moduleName != null && !moduleName.isEmpty() );
+    private Module getLatestModule(final SchemaContext schema, final String moduleName) {
+        Preconditions.checkArgument(schema != null);
+        Preconditions.checkArgument(moduleName != null && !moduleName.isEmpty());
 
         Predicate<Module> filter = new Predicate<Module>() {
             @Override
-            public boolean apply( final Module m ) {
-                return Objects.equal( m.getName(), moduleName );
+            public boolean apply(final Module m) {
+                return Objects.equal(m.getName(), moduleName);
             }
         };
 
-        Iterable<Module> modules = Iterables.filter( schema.getModules(), filter );
-        return this.filterLatestModule( modules );
+        Iterable<Module> modules = Iterables.filter(schema.getModules(), filter);
+        return this.filterLatestModule(modules);
     }
 
-    private Module filterLatestModule( final Iterable<Module> modules ) {
+    private Module filterLatestModule(final Iterable<Module> modules) {
         Module latestModule = modules.iterator().hasNext() ? modules.iterator().next() : null;
-        for( final Module module : modules ) {
-            if( module.getRevision().after( latestModule.getRevision() ) ) {
+        for (final Module module : modules) {
+            if (module.getRevision().after(latestModule.getRevision())) {
                 latestModule = module;
             }
         }
         return latestModule;
     }
 
-    public Module findModuleByName( final String moduleName ) {
+    public Module findModuleByName(final String moduleName) {
         this.checkPreconditions();
-        Preconditions.checkArgument( moduleName != null && !moduleName.isEmpty() );
-        return this.getLatestModule( globalSchema, moduleName );
+        Preconditions.checkArgument(moduleName != null && !moduleName.isEmpty());
+        return this.getLatestModule(globalSchema, moduleName);
     }
 
-    public Module findModuleByName( final MountInstance mountPoint, final String moduleName ) {
-        Preconditions.checkArgument( moduleName != null && mountPoint != null );
+    public Module findModuleByName(final MountInstance mountPoint, final String moduleName) {
+        Preconditions.checkArgument(moduleName != null && mountPoint != null);
 
         final SchemaContext mountPointSchema = mountPoint.getSchemaContext();
-        return mountPointSchema == null ? null : this.getLatestModule( mountPointSchema, moduleName );
+        return mountPointSchema == null ? null : this.getLatestModule(mountPointSchema, moduleName);
     }
 
-    public Module findModuleByNamespace( final URI namespace ) {
+    public Module findModuleByNamespace(final URI namespace) {
         this.checkPreconditions();
-        Preconditions.checkArgument( namespace != null );
+        Preconditions.checkArgument(namespace != null);
 
-        final Set<Module> moduleSchemas = globalSchema.findModuleByNamespace( namespace );
-        return moduleSchemas == null ? null : this.filterLatestModule( moduleSchemas );
+        final Set<Module> moduleSchemas = globalSchema.findModuleByNamespace(namespace);
+        return moduleSchemas == null ? null : this.filterLatestModule(moduleSchemas);
     }
 
-    public Module findModuleByNamespace( final MountInstance mountPoint, final URI namespace ) {
-        Preconditions.checkArgument( namespace != null && mountPoint != null );
+    public Module findModuleByNamespace(final MountInstance mountPoint, final URI namespace) {
+        Preconditions.checkArgument(namespace != null && mountPoint != null);
 
         final SchemaContext mountPointSchema = mountPoint.getSchemaContext();
-        Set<Module> moduleSchemas = mountPointSchema == null ? null :
-            mountPointSchema.findModuleByNamespace( namespace );
-        return moduleSchemas == null ? null : this.filterLatestModule( moduleSchemas );
+        Set<Module> moduleSchemas = mountPointSchema == null ? null : mountPointSchema.findModuleByNamespace(namespace);
+        return moduleSchemas == null ? null : this.filterLatestModule(moduleSchemas);
     }
 
-    public Module findModuleByNameAndRevision( final QName module ) {
+    public Module findModuleByNameAndRevision(final QName module) {
         this.checkPreconditions();
-        Preconditions.checkArgument( module != null && module.getLocalName() != null &&
-                module.getRevision() != null );
+        Preconditions.checkArgument(module != null && module.getLocalName() != null && module.getRevision() != null);
 
-        return globalSchema.findModuleByName( module.getLocalName(), module.getRevision() );
+        return globalSchema.findModuleByName(module.getLocalName(), module.getRevision());
     }
 
-    public Module findModuleByNameAndRevision( final MountInstance mountPoint, final QName module ) {
+    public Module findModuleByNameAndRevision(final MountInstance mountPoint, final QName module) {
         this.checkPreconditions();
-        Preconditions.checkArgument( module != null && module.getLocalName() != null &&
-                module.getRevision() != null && mountPoint != null );
+        Preconditions.checkArgument(module != null && module.getLocalName() != null && module.getRevision() != null
+                && mountPoint != null);
 
         SchemaContext schemaContext = mountPoint.getSchemaContext();
-        return schemaContext == null ? null :
-            schemaContext.findModuleByName( module.getLocalName(), module.getRevision() );
+        return schemaContext == null ? null : schemaContext.findModuleByName(module.getLocalName(),
+                module.getRevision());
     }
 
-    public DataNodeContainer getDataNodeContainerFor( final InstanceIdentifier path ) {
+    public DataNodeContainer getDataNodeContainerFor(final YangInstanceIdentifier path) {
         this.checkPreconditions();
 
-        final List<PathArgument> elements = path.getPath();
+        final Iterable<PathArgument> elements = path.getPathArguments();
         PathArgument head = elements.iterator().next();
         final QName startQName = head.getNodeType();
-        final Module initialModule = globalSchema.findModuleByNamespaceAndRevision(
-                startQName.getNamespace(), startQName.getRevision() );
+        final Module initialModule = globalSchema.findModuleByNamespaceAndRevision(startQName.getNamespace(),
+                startQName.getRevision());
         DataNodeContainer node = initialModule;
-        for( final PathArgument element : elements ) {
+        for (final PathArgument element : elements) {
             QName _nodeType = element.getNodeType();
-            final DataSchemaNode potentialNode = ControllerContext.childByQName( node, _nodeType );
-            if( potentialNode == null || !this.isListOrContainer( potentialNode ) ) {
+            final DataSchemaNode potentialNode = ControllerContext.childByQName(node, _nodeType);
+            if (potentialNode == null || !ControllerContext.isListOrContainer(potentialNode)) {
                 return null;
             }
             node = (DataNodeContainer) potentialNode;
@@ -274,68 +268,68 @@ public class ControllerContext implements SchemaContextListener {
         return node;
     }
 
-    public String toFullRestconfIdentifier( final InstanceIdentifier path ) {
+    public String toFullRestconfIdentifier(final YangInstanceIdentifier path) {
         this.checkPreconditions();
 
-        final List<PathArgument> elements = path.getPath();
+        final Iterable<PathArgument> elements = path.getPathArguments();
         final StringBuilder builder = new StringBuilder();
         PathArgument head = elements.iterator().next();
         final QName startQName = head.getNodeType();
-        final Module initialModule = globalSchema.findModuleByNamespaceAndRevision(
-                startQName.getNamespace(), startQName.getRevision() );
+        final Module initialModule = globalSchema.findModuleByNamespaceAndRevision(startQName.getNamespace(),
+                startQName.getRevision());
         DataNodeContainer node = initialModule;
-        for( final PathArgument element : elements ) {
+        for (final PathArgument element : elements) {
             QName _nodeType = element.getNodeType();
-            final DataSchemaNode potentialNode = ControllerContext.childByQName( node, _nodeType );
-            if( !this.isListOrContainer( potentialNode ) ) {
+            final DataSchemaNode potentialNode = ControllerContext.childByQName(node, _nodeType);
+            if (!ControllerContext.isListOrContainer(potentialNode)) {
                 return null;
             }
             node = ((DataNodeContainer) potentialNode);
-            builder.append( this.convertToRestconfIdentifier( element, node ) );
+            builder.append(this.convertToRestconfIdentifier(element, node));
         }
 
         return builder.toString();
     }
 
-    public String findModuleNameByNamespace( final URI namespace ) {
+    public String findModuleNameByNamespace(final URI namespace) {
         this.checkPreconditions();
 
-        String moduleName = this.uriToModuleName.get( namespace );
-        if( moduleName == null ) {
-            final Module module = this.findModuleByNamespace( namespace );
-            if( module != null ) {
+        String moduleName = this.uriToModuleName.get(namespace);
+        if (moduleName == null) {
+            final Module module = this.findModuleByNamespace(namespace);
+            if (module != null) {
                 moduleName = module.getName();
-                this.uriToModuleName.put( namespace, moduleName );
+                this.uriToModuleName.put(namespace, moduleName);
             }
         }
 
         return moduleName;
     }
 
-    public String findModuleNameByNamespace( final MountInstance mountPoint, final URI namespace ) {
-        final Module module = this.findModuleByNamespace( mountPoint, namespace );
+    public String findModuleNameByNamespace(final MountInstance mountPoint, final URI namespace) {
+        final Module module = this.findModuleByNamespace(mountPoint, namespace);
         return module == null ? null : module.getName();
     }
 
-    public URI findNamespaceByModuleName( final String moduleName ) {
-        URI namespace = this.moduleNameToUri.get( moduleName );
-        if( namespace == null ) {
-            Module module = this.findModuleByName( moduleName );
-            if( module != null ) {
+    public URI findNamespaceByModuleName(final String moduleName) {
+        URI namespace = this.moduleNameToUri.get(moduleName);
+        if (namespace == null) {
+            Module module = this.findModuleByName(moduleName);
+            if (module != null) {
                 URI _namespace = module.getNamespace();
                 namespace = _namespace;
-                this.uriToModuleName.put( namespace, moduleName );
+                this.uriToModuleName.put(namespace, moduleName);
             }
         }
         return namespace;
     }
 
-    public URI findNamespaceByModuleName( final MountInstance mountPoint, final String moduleName ) {
-        final Module module = this.findModuleByName( mountPoint, moduleName );
+    public URI findNamespaceByModuleName(final MountInstance mountPoint, final String moduleName) {
+        final Module module = this.findModuleByName(mountPoint, moduleName);
         return module == null ? null : module.getNamespace();
     }
 
-    public Set<Module> getAllModules( final MountInstance mountPoint ) {
+    public Set<Module> getAllModules(final MountInstance mountPoint) {
         this.checkPreconditions();
 
         SchemaContext schemaContext = mountPoint == null ? null : mountPoint.getSchemaContext();
@@ -347,55 +341,55 @@ public class ControllerContext implements SchemaContextListener {
         return globalSchema.getModules();
     }
 
-    public CharSequence toRestconfIdentifier( final QName qname ) {
+    public CharSequence toRestconfIdentifier(final QName qname) {
         this.checkPreconditions();
 
-        String module = this.uriToModuleName.get( qname.getNamespace() );
-        if( module == null ) {
-            final Module moduleSchema = globalSchema.findModuleByNamespaceAndRevision(
-                    qname.getNamespace(), qname.getRevision() );
-            if( moduleSchema == null ) {
+        String module = this.uriToModuleName.get(qname.getNamespace());
+        if (module == null) {
+            final Module moduleSchema = globalSchema.findModuleByNamespaceAndRevision(qname.getNamespace(),
+                    qname.getRevision());
+            if (moduleSchema == null) {
                 return null;
             }
 
-            this.uriToModuleName.put( qname.getNamespace(), moduleSchema.getName() );
+            this.uriToModuleName.put(qname.getNamespace(), moduleSchema.getName());
             module = moduleSchema.getName();
         }
 
         StringBuilder builder = new StringBuilder();
-        builder.append( module );
-        builder.append( ":" );
-        builder.append( qname.getLocalName() );
+        builder.append(module);
+        builder.append(":");
+        builder.append(qname.getLocalName());
         return builder.toString();
     }
 
-    public CharSequence toRestconfIdentifier( final MountInstance mountPoint, final QName qname ) {
-        if( mountPoint == null ) {
+    public CharSequence toRestconfIdentifier(final MountInstance mountPoint, final QName qname) {
+        if (mountPoint == null) {
             return null;
         }
 
         SchemaContext schemaContext = mountPoint.getSchemaContext();
 
-        final Module moduleSchema = schemaContext.findModuleByNamespaceAndRevision(
-                qname.getNamespace(), qname.getRevision() );
-        if( moduleSchema == null ) {
+        final Module moduleSchema = schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(),
+                qname.getRevision());
+        if (moduleSchema == null) {
             return null;
         }
 
         StringBuilder builder = new StringBuilder();
-        builder.append( moduleSchema.getName() );
-        builder.append( ":" );
-        builder.append( qname.getLocalName() );
+        builder.append(moduleSchema.getName());
+        builder.append(":");
+        builder.append(qname.getLocalName());
         return builder.toString();
     }
 
     public Module getRestconfModule() {
-        return findModuleByNameAndRevision( Draft02.RestConfModule.IETF_RESTCONF_QNAME );
+        return findModuleByNameAndRevision(Draft02.RestConfModule.IETF_RESTCONF_QNAME);
     }
 
     public DataSchemaNode getRestconfModuleErrorsSchemaNode() {
         Module restconfModule = getRestconfModule();
-        if( restconfModule == null ) {
+        if (restconfModule == null) {
             return null;
         }
 
@@ -404,8 +398,7 @@ public class ControllerContext implements SchemaContextListener {
         final Predicate<GroupingDefinition> filter = new Predicate<GroupingDefinition>() {
             @Override
             public boolean apply(final GroupingDefinition g) {
-                return Objects.equal(g.getQName().getLocalName(),
-                        Draft02.RestConfModule.ERRORS_GROUPING_SCHEMA_NODE);
+                return Objects.equal(g.getQName().getLocalName(), Draft02.RestConfModule.ERRORS_GROUPING_SCHEMA_NODE);
             }
         };
 
@@ -413,20 +406,18 @@ public class ControllerContext implements SchemaContextListener {
 
         final GroupingDefinition restconfGrouping = Iterables.getFirst(filteredGroups, null);
 
-        List<DataSchemaNode> instanceDataChildrenByName =
-                this.findInstanceDataChildrenByName(restconfGrouping,
-                        Draft02.RestConfModule.ERRORS_CONTAINER_SCHEMA_NODE);
+        List<DataSchemaNode> instanceDataChildrenByName = this.findInstanceDataChildrenByName(restconfGrouping,
+                Draft02.RestConfModule.ERRORS_CONTAINER_SCHEMA_NODE);
         return Iterables.getFirst(instanceDataChildrenByName, null);
     }
 
-    public DataSchemaNode getRestconfModuleRestConfSchemaNode( final Module inRestconfModule,
-            final String schemaNodeName ) {
+    public DataSchemaNode getRestconfModuleRestConfSchemaNode(final Module inRestconfModule, final String schemaNodeName) {
         Module restconfModule = inRestconfModule;
-        if( restconfModule == null ) {
+        if (restconfModule == null) {
             restconfModule = getRestconfModule();
         }
 
-        if( restconfModule == null ) {
+        if (restconfModule == null) {
             return null;
         }
 
@@ -435,8 +426,7 @@ public class ControllerContext implements SchemaContextListener {
         final Predicate<GroupingDefinition> filter = new Predicate<GroupingDefinition>() {
             @Override
             public boolean apply(final GroupingDefinition g) {
-                return Objects.equal(g.getQName().getLocalName(),
-                        Draft02.RestConfModule.RESTCONF_GROUPING_SCHEMA_NODE);
+                return Objects.equal(g.getQName().getLocalName(), Draft02.RestConfModule.RESTCONF_GROUPING_SCHEMA_NODE);
             }
         };
 
@@ -444,61 +434,49 @@ public class ControllerContext implements SchemaContextListener {
 
         final GroupingDefinition restconfGrouping = Iterables.getFirst(filteredGroups, null);
 
-        List<DataSchemaNode> instanceDataChildrenByName =
-                this.findInstanceDataChildrenByName(restconfGrouping,
-                        Draft02.RestConfModule.RESTCONF_CONTAINER_SCHEMA_NODE);
+        List<DataSchemaNode> instanceDataChildrenByName = this.findInstanceDataChildrenByName(restconfGrouping,
+                Draft02.RestConfModule.RESTCONF_CONTAINER_SCHEMA_NODE);
         final DataSchemaNode restconfContainer = Iterables.getFirst(instanceDataChildrenByName, null);
 
         if (Objects.equal(schemaNodeName, Draft02.RestConfModule.OPERATIONS_CONTAINER_SCHEMA_NODE)) {
-            List<DataSchemaNode> instances =
-                    this.findInstanceDataChildrenByName(((DataNodeContainer) restconfContainer),
-                            Draft02.RestConfModule.OPERATIONS_CONTAINER_SCHEMA_NODE);
+            List<DataSchemaNode> instances = this.findInstanceDataChildrenByName(
+                    ((DataNodeContainer) restconfContainer), Draft02.RestConfModule.OPERATIONS_CONTAINER_SCHEMA_NODE);
             return Iterables.getFirst(instances, null);
-        }
-        else if(Objects.equal(schemaNodeName, Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE)) {
-            List<DataSchemaNode> instances =
-                    this.findInstanceDataChildrenByName(((DataNodeContainer) restconfContainer),
-                            Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
+        } else if (Objects.equal(schemaNodeName, Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE)) {
+            List<DataSchemaNode> instances = this.findInstanceDataChildrenByName(
+                    ((DataNodeContainer) restconfContainer), Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
             return Iterables.getFirst(instances, null);
-        }
-        else if(Objects.equal(schemaNodeName, Draft02.RestConfModule.STREAM_LIST_SCHEMA_NODE)) {
-            List<DataSchemaNode> instances =
-                    this.findInstanceDataChildrenByName(((DataNodeContainer) restconfContainer),
-                            Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
+        } else if (Objects.equal(schemaNodeName, Draft02.RestConfModule.STREAM_LIST_SCHEMA_NODE)) {
+            List<DataSchemaNode> instances = this.findInstanceDataChildrenByName(
+                    ((DataNodeContainer) restconfContainer), Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
             final DataSchemaNode modules = Iterables.getFirst(instances, null);
             instances = this.findInstanceDataChildrenByName(((DataNodeContainer) modules),
                     Draft02.RestConfModule.STREAM_LIST_SCHEMA_NODE);
             return Iterables.getFirst(instances, null);
-        }
-        else if(Objects.equal(schemaNodeName, Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE)) {
-            List<DataSchemaNode> instances =
-                    this.findInstanceDataChildrenByName(((DataNodeContainer) restconfContainer),
-                            Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
+        } else if (Objects.equal(schemaNodeName, Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE)) {
+            List<DataSchemaNode> instances = this.findInstanceDataChildrenByName(
+                    ((DataNodeContainer) restconfContainer), Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
             return Iterables.getFirst(instances, null);
-        }
-        else if(Objects.equal(schemaNodeName, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE)) {
-            List<DataSchemaNode> instances =
-                    this.findInstanceDataChildrenByName(((DataNodeContainer) restconfContainer),
-                            Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
+        } else if (Objects.equal(schemaNodeName, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE)) {
+            List<DataSchemaNode> instances = this.findInstanceDataChildrenByName(
+                    ((DataNodeContainer) restconfContainer), Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
             final DataSchemaNode modules = Iterables.getFirst(instances, null);
             instances = this.findInstanceDataChildrenByName(((DataNodeContainer) modules),
                     Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
             return Iterables.getFirst(instances, null);
-        }
-        else if(Objects.equal(schemaNodeName, Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE)) {
-            List<DataSchemaNode> instances =
-                    this.findInstanceDataChildrenByName(((DataNodeContainer) restconfContainer),
-                            Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
+        } else if (Objects.equal(schemaNodeName, Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE)) {
+            List<DataSchemaNode> instances = this.findInstanceDataChildrenByName(
+                    ((DataNodeContainer) restconfContainer), Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
             return Iterables.getFirst(instances, null);
         }
 
         return null;
     }
 
-    private static DataSchemaNode childByQName( final ChoiceNode container, final QName name ) {
-        for( final ChoiceCaseNode caze : container.getCases() ) {
-            final DataSchemaNode ret = ControllerContext.childByQName( caze, name );
-            if( ret != null ) {
+    private static DataSchemaNode childByQName(final ChoiceNode container, final QName name) {
+        for (final ChoiceCaseNode caze : container.getCases()) {
+            final DataSchemaNode ret = ControllerContext.childByQName(caze, name);
+            if (ret != null) {
                 return ret;
             }
         }
@@ -506,34 +484,34 @@ public class ControllerContext implements SchemaContextListener {
         return null;
     }
 
-    private static DataSchemaNode childByQName( final ChoiceCaseNode container, final QName name ) {
-        return container.getDataChildByName( name );
+    private static DataSchemaNode childByQName(final ChoiceCaseNode container, final QName name) {
+        return container.getDataChildByName(name);
     }
 
-    private static DataSchemaNode childByQName( final ContainerSchemaNode container, final QName name ) {
-        return ControllerContext.dataNodeChildByQName( container, name );
+    private static DataSchemaNode childByQName(final ContainerSchemaNode container, final QName name) {
+        return ControllerContext.dataNodeChildByQName(container, name);
     }
 
-    private static DataSchemaNode childByQName( final ListSchemaNode container, final QName name ) {
-        return ControllerContext.dataNodeChildByQName( container, name );
+    private static DataSchemaNode childByQName(final ListSchemaNode container, final QName name) {
+        return ControllerContext.dataNodeChildByQName(container, name);
     }
 
-    private static DataSchemaNode childByQName( final Module container, final QName name ) {
-        return ControllerContext.dataNodeChildByQName( container, name );
+    private static DataSchemaNode childByQName(final Module container, final QName name) {
+        return ControllerContext.dataNodeChildByQName(container, name);
     }
 
-    private static DataSchemaNode childByQName( final DataSchemaNode container, final QName name ) {
+    private static DataSchemaNode childByQName(final DataSchemaNode container, final QName name) {
         return null;
     }
 
-    private static DataSchemaNode dataNodeChildByQName( final DataNodeContainer container, final QName name ) {
-        DataSchemaNode ret = container.getDataChildByName( name );
-        if( ret == null ) {
-            for( final DataSchemaNode node : container.getChildNodes() ) {
-                if( (node instanceof ChoiceCaseNode) ) {
+    private static DataSchemaNode dataNodeChildByQName(final DataNodeContainer container, final QName name) {
+        DataSchemaNode ret = container.getDataChildByName(name);
+        if (ret == null) {
+            for (final DataSchemaNode node : container.getChildNodes()) {
+                if ((node instanceof ChoiceCaseNode)) {
                     final ChoiceCaseNode caseNode = ((ChoiceCaseNode) node);
-                    DataSchemaNode childByQName = ControllerContext.childByQName( caseNode, name );
-                    if( childByQName != null ) {
+                    DataSchemaNode childByQName = ControllerContext.childByQName(caseNode, name);
+                    if (childByQName != null) {
                         return childByQName;
                     }
                 }
@@ -542,463 +520,408 @@ public class ControllerContext implements SchemaContextListener {
         return ret;
     }
 
-    private String toUriString( final Object object ) throws UnsupportedEncodingException {
-        return object == null ? "" :
-            URLEncoder.encode( object.toString(), ControllerContext.URI_ENCODING_CHAR_SET );
+    private String toUriString(final Object object) throws UnsupportedEncodingException {
+        return object == null ? "" : URLEncoder.encode(object.toString(), ControllerContext.URI_ENCODING_CHAR_SET);
     }
 
-    private InstanceIdWithSchemaNode collectPathArguments( final InstanceIdentifierBuilder builder,
+    private InstanceIdWithSchemaNode collectPathArguments(final InstanceIdentifierBuilder builder,
             final List<String> strings, final DataNodeContainer parentNode, final MountInstance mountPoint,
-            final boolean returnJustMountPoint ) {
-        Preconditions.<List<String>> checkNotNull( strings );
+            final boolean returnJustMountPoint) {
+        Preconditions.<List<String>> checkNotNull(strings);
 
-        if( parentNode == null ) {
+        if (parentNode == null) {
             return null;
         }
 
-        if( strings.isEmpty() ) {
-            return new InstanceIdWithSchemaNode( builder.toInstance(),
-                    ((DataSchemaNode) parentNode), mountPoint );
+        if (strings.isEmpty()) {
+            return new InstanceIdWithSchemaNode(builder.toInstance(), ((DataSchemaNode) parentNode), mountPoint);
         }
 
         String head = strings.iterator().next();
-        final String nodeName = this.toNodeName( head );
-        final String moduleName = ControllerContext.toModuleName( head );
+        final String nodeName = toNodeName(head);
+        final String moduleName = ControllerContext.toModuleName(head);
 
         DataSchemaNode targetNode = null;
-        if( !Strings.isNullOrEmpty( moduleName ) ) {
-            if( Objects.equal( moduleName, ControllerContext.MOUNT_MODULE ) &&
-                    Objects.equal( nodeName, ControllerContext.MOUNT_NODE ) ) {
-                if( mountPoint != null ) {
-                    throw new RestconfDocumentedException(
-                            "Restconf supports just one mount point in URI.",
-                            ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED );
+        if (!Strings.isNullOrEmpty(moduleName)) {
+            if (Objects.equal(moduleName, ControllerContext.MOUNT_MODULE)
+                    && Objects.equal(nodeName, ControllerContext.MOUNT_NODE)) {
+                if (mountPoint != null) {
+                    throw new RestconfDocumentedException("Restconf supports just one mount point in URI.",
+                            ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED);
                 }
 
-                if( mountService == null ) {
+                if (mountService == null) {
                     throw new RestconfDocumentedException(
                             "MountService was not found. Finding behind mount points does not work.",
-                            ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED );
+                            ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED);
                 }
 
-                final InstanceIdentifier partialPath = builder.toInstance();
-                final MountInstance mount = mountService.getMountPoint( partialPath );
-                if( mount == null ) {
-                    LOG.debug( "Instance identifier to missing mount point: {}", partialPath );
-                    throw new RestconfDocumentedException(
-                            "Mount point does not exist.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT );
+                final YangInstanceIdentifier partialPath = builder.toInstance();
+                final MountInstance mount = mountService.getMountPoint(partialPath);
+                if (mount == null) {
+                    LOG.debug("Instance identifier to missing mount point: {}", partialPath);
+                    throw new RestconfDocumentedException("Mount point does not exist.", ErrorType.PROTOCOL,
+                            ErrorTag.UNKNOWN_ELEMENT);
                 }
 
                 final SchemaContext mountPointSchema = mount.getSchemaContext();
-                if( mountPointSchema == null ) {
-                    throw new RestconfDocumentedException(
-                            "Mount point does not contain any schema with modules.",
-                            ErrorType.APPLICATION, ErrorTag.UNKNOWN_ELEMENT );
+                if (mountPointSchema == null) {
+                    throw new RestconfDocumentedException("Mount point does not contain any schema with modules.",
+                            ErrorType.APPLICATION, ErrorTag.UNKNOWN_ELEMENT);
                 }
 
-                if( returnJustMountPoint ) {
-                    InstanceIdentifier instance = InstanceIdentifier.builder().toInstance();
-                    return new InstanceIdWithSchemaNode( instance, mountPointSchema, mount );
+                if (returnJustMountPoint) {
+                    YangInstanceIdentifier instance = YangInstanceIdentifier.builder().toInstance();
+                    return new InstanceIdWithSchemaNode(instance, mountPointSchema, mount);
                 }
 
-                if( strings.size() == 1 ) {
-                    InstanceIdentifier instance = InstanceIdentifier.builder().toInstance();
-                    return new InstanceIdWithSchemaNode( instance, mountPointSchema, mount );
+                if (strings.size() == 1) {
+                    YangInstanceIdentifier instance = YangInstanceIdentifier.builder().toInstance();
+                    return new InstanceIdWithSchemaNode(instance, mountPointSchema, mount);
                 }
 
-                final String moduleNameBehindMountPoint = toModuleName(  strings.get( 1 ) );
-                if( moduleNameBehindMountPoint == null ) {
+                final String moduleNameBehindMountPoint = toModuleName(strings.get(1));
+                if (moduleNameBehindMountPoint == null) {
                     throw new RestconfDocumentedException(
                             "First node after mount point in URI has to be in format \"moduleName:nodeName\"",
-                            ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                            ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
                 }
 
-                final Module moduleBehindMountPoint = this.getLatestModule( mountPointSchema,
-                        moduleNameBehindMountPoint );
-                if( moduleBehindMountPoint == null ) {
-                    throw new RestconfDocumentedException(
-                            "\"" +moduleName + "\" module does not exist in mount point.",
-                            ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT );
+                final Module moduleBehindMountPoint = this
+                        .getLatestModule(mountPointSchema, moduleNameBehindMountPoint);
+                if (moduleBehindMountPoint == null) {
+                    throw new RestconfDocumentedException("\"" + moduleName
+                            + "\" module does not exist in mount point.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
                 }
 
-                List<String> subList = strings.subList( 1, strings.size() );
-                return this.collectPathArguments( InstanceIdentifier.builder(), subList, moduleBehindMountPoint,
-                        mount, returnJustMountPoint );
+                List<String> subList = strings.subList(1, strings.size());
+                return this.collectPathArguments(YangInstanceIdentifier.builder(), subList, moduleBehindMountPoint, mount,
+                        returnJustMountPoint);
             }
 
             Module module = null;
-            if( mountPoint == null ) {
-                module = this.getLatestModule( globalSchema, moduleName );
-                if( module == null ) {
-                    throw new RestconfDocumentedException(
-                            "\"" + moduleName + "\" module does not exist.",
-                            ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT );
+            if (mountPoint == null) {
+                module = this.getLatestModule(globalSchema, moduleName);
+                if (module == null) {
+                    throw new RestconfDocumentedException("\"" + moduleName + "\" module does not exist.",
+                            ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
                 }
-            }
-            else {
+            } else {
                 SchemaContext schemaContext = mountPoint.getSchemaContext();
-                module = schemaContext == null ? null :
-                    this.getLatestModule( schemaContext, moduleName );
-                if( module == null ) {
-                    throw new RestconfDocumentedException(
-                            "\"" + moduleName + "\" module does not exist in mount point.",
-                            ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT );
+                module = schemaContext == null ? null : this.getLatestModule(schemaContext, moduleName);
+                if (module == null) {
+                    throw new RestconfDocumentedException("\"" + moduleName
+                            + "\" module does not exist in mount point.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
                 }
             }
 
-            targetNode = this.findInstanceDataChildByNameAndNamespace(
-                    parentNode, nodeName, module.getNamespace() );
-            if( targetNode == null ) {
-                throw new RestconfDocumentedException(
-                        "URI has bad format. Possible reasons:\n" +
-                                " 1. \"" + head + "\" was not found in parent data node.\n" +
-                                " 2. \"" + head + "\" is behind mount point. Then it should be in format \"/" +
-                                MOUNT + "/" + head + "\".", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+            targetNode = this.findInstanceDataChildByNameAndNamespace(parentNode, nodeName, module.getNamespace());
+            if (targetNode == null) {
+                throw new RestconfDocumentedException("URI has bad format. Possible reasons:\n" + " 1. \"" + head
+                        + "\" was not found in parent data node.\n" + " 2. \"" + head
+                        + "\" is behind mount point. Then it should be in format \"/" + MOUNT + "/" + head + "\".",
+                        ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
             }
         } else {
-            final List<DataSchemaNode> potentialSchemaNodes =
-                    this.findInstanceDataChildrenByName( parentNode, nodeName );
-            if( potentialSchemaNodes.size() > 1 ) {
+            final List<DataSchemaNode> potentialSchemaNodes = this.findInstanceDataChildrenByName(parentNode, nodeName);
+            if (potentialSchemaNodes.size() > 1) {
                 final StringBuilder strBuilder = new StringBuilder();
-                for( final DataSchemaNode potentialNodeSchema : potentialSchemaNodes ) {
-                    strBuilder.append( "   " )
-                    .append( potentialNodeSchema.getQName().getNamespace() )
-                    .append( "\n" );
+                for (final DataSchemaNode potentialNodeSchema : potentialSchemaNodes) {
+                    strBuilder.append("   ").append(potentialNodeSchema.getQName().getNamespace()).append("\n");
                 }
 
                 throw new RestconfDocumentedException(
-                        "URI has bad format. Node \"" + nodeName +
-                        "\" is added as augment from more than one module. " +
-                        "Therefore the node must have module name and it has to be in format \"moduleName:nodeName\"." +
-                        "\nThe node is added as augment from modules with namespaces:\n" +
-                        strBuilder.toString(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                        "URI has bad format. Node \""
+                                + nodeName
+                                + "\" is added as augment from more than one module. "
+                                + "Therefore the node must have module name and it has to be in format \"moduleName:nodeName\"."
+                                + "\nThe node is added as augment from modules with namespaces:\n"
+                                + strBuilder.toString(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
             }
 
-            if( potentialSchemaNodes.isEmpty() ) {
-                throw new RestconfDocumentedException(
-                        "\"" + nodeName + "\" in URI was not found in parent data node",
-                        ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT );
+            if (potentialSchemaNodes.isEmpty()) {
+                throw new RestconfDocumentedException("\"" + nodeName + "\" in URI was not found in parent data node",
+                        ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
             }
 
             targetNode = potentialSchemaNodes.iterator().next();
         }
 
-        if( !this.isListOrContainer( targetNode ) ) {
-            throw new RestconfDocumentedException(
-                    "URI has bad format. Node \"" + head + "\" must be Container or List yang type.",
-                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+        if (!ControllerContext.isListOrContainer(targetNode)) {
+            throw new RestconfDocumentedException("URI has bad format. Node \"" + head
+                    + "\" must be Container or List yang type.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
 
         int consumed = 1;
-        if( (targetNode instanceof ListSchemaNode) ) {
+        if ((targetNode instanceof ListSchemaNode)) {
             final ListSchemaNode listNode = ((ListSchemaNode) targetNode);
             final int keysSize = listNode.getKeyDefinition().size();
-            if( (strings.size() - consumed) < keysSize ) {
-                throw new RestconfDocumentedException(
-                        "Missing key for list \"" + listNode.getQName().getLocalName() + "\".",
-                        ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+            if ((strings.size() - consumed) < keysSize) {
+                throw new RestconfDocumentedException("Missing key for list \"" + listNode.getQName().getLocalName()
+                        + "\".", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
             }
 
-            final List<String> uriKeyValues = strings.subList( consumed, consumed + keysSize );
+            final List<String> uriKeyValues = strings.subList(consumed, consumed + keysSize);
             final HashMap<QName, Object> keyValues = new HashMap<QName, Object>();
             int i = 0;
-            for( final QName key : listNode.getKeyDefinition() ) {
+            for (final QName key : listNode.getKeyDefinition()) {
                 {
-                    final String uriKeyValue = uriKeyValues.get( i );
-                    if( uriKeyValue.equals( NULL_VALUE ) ) {
-                        throw new RestconfDocumentedException(
-                                "URI has bad format. List \"" + listNode.getQName().getLocalName() +
-                                "\" cannot contain \"null\" value as a key.",
-                                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                    final String uriKeyValue = uriKeyValues.get(i);
+                    if (uriKeyValue.equals(NULL_VALUE)) {
+                        throw new RestconfDocumentedException("URI has bad format. List \""
+                                + listNode.getQName().getLocalName() + "\" cannot contain \"null\" value as a key.",
+                                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
                     }
 
-                    this.addKeyValue( keyValues, listNode.getDataChildByName( key ),
-                            uriKeyValue, mountPoint );
+                    this.addKeyValue(keyValues, listNode.getDataChildByName(key), uriKeyValue, mountPoint);
                     i++;
                 }
             }
 
             consumed = consumed + i;
-            builder.nodeWithKey( targetNode.getQName(), keyValues );
-        }
-        else {
-            builder.node( targetNode.getQName() );
+            builder.nodeWithKey(targetNode.getQName(), keyValues);
+        } else {
+            builder.node(targetNode.getQName());
         }
 
-        if( (targetNode instanceof DataNodeContainer) ) {
-            final List<String> remaining = strings.subList( consumed, strings.size() );
-            return this.collectPathArguments( builder, remaining,
-                    ((DataNodeContainer) targetNode), mountPoint, returnJustMountPoint );
+        if ((targetNode instanceof DataNodeContainer)) {
+            final List<String> remaining = strings.subList(consumed, strings.size());
+            return this.collectPathArguments(builder, remaining, ((DataNodeContainer) targetNode), mountPoint,
+                    returnJustMountPoint);
         }
 
-        return new InstanceIdWithSchemaNode( builder.toInstance(), targetNode, mountPoint );
+        return new InstanceIdWithSchemaNode(builder.toInstance(), targetNode, mountPoint);
     }
 
-    public DataSchemaNode findInstanceDataChildByNameAndNamespace( final DataNodeContainer container,
-            final String name, final URI namespace ) {
-        Preconditions.<URI> checkNotNull( namespace );
+    public DataSchemaNode findInstanceDataChildByNameAndNamespace(final DataNodeContainer container, final String name,
+            final URI namespace) {
+        Preconditions.<URI> checkNotNull(namespace);
 
-        final List<DataSchemaNode> potentialSchemaNodes = this.findInstanceDataChildrenByName( container, name );
+        final List<DataSchemaNode> potentialSchemaNodes = this.findInstanceDataChildrenByName(container, name);
 
         Predicate<DataSchemaNode> filter = new Predicate<DataSchemaNode>() {
             @Override
-            public boolean apply( final DataSchemaNode node ) {
-                return Objects.equal( node.getQName().getNamespace(), namespace );
+            public boolean apply(final DataSchemaNode node) {
+                return Objects.equal(node.getQName().getNamespace(), namespace);
             }
         };
 
-        Iterable<DataSchemaNode> result = Iterables.filter( potentialSchemaNodes, filter );
-        return Iterables.getFirst( result, null );
+        Iterable<DataSchemaNode> result = Iterables.filter(potentialSchemaNodes, filter);
+        return Iterables.getFirst(result, null);
     }
 
-    public List<DataSchemaNode> findInstanceDataChildrenByName( final DataNodeContainer container,
-            final String name ) {
-        Preconditions.<DataNodeContainer> checkNotNull( container );
-        Preconditions.<String> checkNotNull( name );
+    public List<DataSchemaNode> findInstanceDataChildrenByName(final DataNodeContainer container, final String name) {
+        Preconditions.<DataNodeContainer> checkNotNull(container);
+        Preconditions.<String> checkNotNull(name);
 
         List<DataSchemaNode> instantiatedDataNodeContainers = new ArrayList<DataSchemaNode>();
-        this.collectInstanceDataNodeContainers( instantiatedDataNodeContainers, container, name );
+        this.collectInstanceDataNodeContainers(instantiatedDataNodeContainers, container, name);
         return instantiatedDataNodeContainers;
     }
 
-    private void collectInstanceDataNodeContainers( final List<DataSchemaNode> potentialSchemaNodes,
-            final DataNodeContainer container, final String name ) {
-
-        Set<DataSchemaNode> childNodes = container.getChildNodes();
+    private void collectInstanceDataNodeContainers(final List<DataSchemaNode> potentialSchemaNodes,
+            final DataNodeContainer container, final String name) {
 
         Predicate<DataSchemaNode> filter = new Predicate<DataSchemaNode>() {
             @Override
-            public boolean apply( final DataSchemaNode node ) {
-                return Objects.equal( node.getQName().getLocalName(), name );
+            public boolean apply(final DataSchemaNode node) {
+                return Objects.equal(node.getQName().getLocalName(), name);
             }
         };
 
-        Iterable<DataSchemaNode> nodes = Iterables.filter( childNodes, filter );
+        Iterable<DataSchemaNode> nodes = Iterables.filter(container.getChildNodes(), filter);
 
-        // Can't combine this loop with the filter above because the filter is lazily-applied
-        // by Iterables.filter.
-        for( final DataSchemaNode potentialNode : nodes ) {
-            if( this.isInstantiatedDataSchema( potentialNode ) ) {
-                potentialSchemaNodes.add( potentialNode );
+        // Can't combine this loop with the filter above because the filter is
+        // lazily-applied by Iterables.filter.
+        for (final DataSchemaNode potentialNode : nodes) {
+            if (this.isInstantiatedDataSchema(potentialNode)) {
+                potentialSchemaNodes.add(potentialNode);
             }
         }
 
-        Iterable<ChoiceNode> choiceNodes = Iterables.<ChoiceNode> filter( container.getChildNodes(),
-                ChoiceNode.class );
+        Iterable<ChoiceNode> choiceNodes = Iterables.<ChoiceNode> filter(container.getChildNodes(), ChoiceNode.class);
 
-        final Function<ChoiceNode, Set<ChoiceCaseNode>> choiceFunction =
-                new Function<ChoiceNode, Set<ChoiceCaseNode>>() {
+        final Function<ChoiceNode, Set<ChoiceCaseNode>> choiceFunction = new Function<ChoiceNode, Set<ChoiceCaseNode>>() {
             @Override
-            public Set<ChoiceCaseNode> apply( final ChoiceNode node ) {
+            public Set<ChoiceCaseNode> apply(final ChoiceNode node) {
                 return node.getCases();
             }
         };
 
-        Iterable<Set<ChoiceCaseNode>> map = Iterables.<ChoiceNode, Set<ChoiceCaseNode>> transform(
-                choiceNodes, choiceFunction );
+        Iterable<Set<ChoiceCaseNode>> map = Iterables.<ChoiceNode, Set<ChoiceCaseNode>> transform(choiceNodes,
+                choiceFunction);
 
-        final Iterable<ChoiceCaseNode> allCases = Iterables.<ChoiceCaseNode> concat( map );
-        for( final ChoiceCaseNode caze : allCases ) {
-            this.collectInstanceDataNodeContainers( potentialSchemaNodes, caze, name );
+        final Iterable<ChoiceCaseNode> allCases = Iterables.<ChoiceCaseNode> concat(map);
+        for (final ChoiceCaseNode caze : allCases) {
+            this.collectInstanceDataNodeContainers(potentialSchemaNodes, caze, name);
         }
     }
 
-    public boolean isInstantiatedDataSchema( final DataSchemaNode node ) {
-        return node instanceof LeafSchemaNode || node instanceof LeafListSchemaNode ||
-               node instanceof ContainerSchemaNode || node instanceof ListSchemaNode ||
-               node instanceof AnyXmlSchemaNode;
+    public boolean isInstantiatedDataSchema(final DataSchemaNode node) {
+        return node instanceof LeafSchemaNode || node instanceof LeafListSchemaNode
+                || node instanceof ContainerSchemaNode || node instanceof ListSchemaNode
+                || node instanceof AnyXmlSchemaNode;
     }
 
-    private void addKeyValue( final HashMap<QName, Object> map, final DataSchemaNode node,
-            final String uriValue, final MountInstance mountPoint ) {
-        Preconditions.<String> checkNotNull( uriValue );
-        Preconditions.checkArgument( (node instanceof LeafSchemaNode) );
+    private void addKeyValue(final HashMap<QName, Object> map, final DataSchemaNode node, final String uriValue,
+            final MountInstance mountPoint) {
+        Preconditions.<String> checkNotNull(uriValue);
+        Preconditions.checkArgument((node instanceof LeafSchemaNode));
 
-        final String urlDecoded = urlPathArgDecode( uriValue );
+        final String urlDecoded = urlPathArgDecode(uriValue);
         final TypeDefinition<? extends Object> typedef = ((LeafSchemaNode) node).getType();
-        Codec<Object, Object> codec = RestCodec.from( typedef, mountPoint );
+        Codec<Object, Object> codec = RestCodec.from(typedef, mountPoint);
 
-        Object decoded = codec == null ? null : codec.deserialize( urlDecoded );
+        Object decoded = codec == null ? null : codec.deserialize(urlDecoded);
         String additionalInfo = "";
-        if( decoded == null ) {
-            TypeDefinition<? extends Object> baseType = RestUtil.resolveBaseTypeFrom( typedef );
-            if( (baseType instanceof IdentityrefTypeDefinition) ) {
-                decoded = this.toQName( urlDecoded );
+        if (decoded == null) {
+            TypeDefinition<? extends Object> baseType = RestUtil.resolveBaseTypeFrom(typedef);
+            if ((baseType instanceof IdentityrefTypeDefinition)) {
+                decoded = this.toQName(urlDecoded);
                 additionalInfo = "For key which is of type identityref it should be in format module_name:identity_name.";
             }
         }
 
-        if( decoded == null ) {
-            throw new RestconfDocumentedException(
-                    uriValue + " from URI can't be resolved. " + additionalInfo,
-                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+        if (decoded == null) {
+            throw new RestconfDocumentedException(uriValue + " from URI can't be resolved. " + additionalInfo,
+                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
 
-        map.put( node.getQName(), decoded );
+        map.put(node.getQName(), decoded);
     }
 
-    private static String toModuleName( final String str ) {
-        Preconditions.<String> checkNotNull( str );
-        if( str.contains( ":" ) ) {
-            final String[] args = str.split( ":" );
-            if( args.length == 2 ) {
-                return args[0];
-            }
+    private static String toModuleName(final String str) {
+        final int idx = str.indexOf(':');
+        if (idx == -1) {
+            return null;
         }
-        return null;
-    }
 
-    private String toNodeName( final String str ) {
-        if( str.contains( ":" ) ) {
-            final String[] args = str.split( ":" );
-            if( args.length == 2 ) {
-                return args[1];
-            }
+        // Make sure there is only one occurrence
+        if (str.indexOf(':', idx + 1) != -1) {
+            return null;
         }
-        return str;
-    }
-
-    private QName toQName( final String name ) {
-        final String module = toModuleName( name );
-        final String node = this.toNodeName( name );
-        Set<Module> modules = globalSchema.getModules();
 
-        final Comparator<Module> comparator = new Comparator<Module>() {
-            @Override
-            public int compare( final Module o1, final Module o2 ) {
-                return o1.getRevision().compareTo( o2.getRevision() );
-            }
-        };
+        return str.substring(0, idx);
+    }
 
-        List<Module> sorted = new ArrayList<Module>( modules );
-        Collections.<Module> sort( new ArrayList<Module>( modules ), comparator );
+    private static String toNodeName(final String str) {
+        final int idx = str.indexOf(':');
+        if (idx == -1) {
+            return str;
+        }
 
-        final Function<Module, QName> transform = new Function<Module, QName>() {
-            @Override
-            public QName apply( final Module m ) {
-                return QName.create( m.getNamespace(), m.getRevision(), m.getName() );
-            }
-        };
+        // Make sure there is only one occurrence
+        if (str.indexOf(':', idx + 1) != -1) {
+            return str;
+        }
 
-        final Predicate<QName> findFirst = new Predicate<QName>() {
-            @Override
-            public boolean apply( final QName qn ) {
-                return Objects.equal( module, qn.getLocalName() );
-            }
-        };
+        return str.substring(idx + 1);
+    }
 
-        Optional<QName> namespace = FluentIterable.from( sorted )
-                .transform( transform )
-                .firstMatch( findFirst );
-        return namespace.isPresent() ? QName.create( namespace.get(), node ) : null;
+    private QName toQName(final String name) {
+        final String module = toModuleName(name);
+        final String node = toNodeName(name);
+        final Module m = globalSchema.findModuleByName(module, null);
+        return m == null ? null : QName.create(m.getQNameModule(), node);
     }
 
-    private boolean isListOrContainer( final DataSchemaNode node ) {
+    private static boolean isListOrContainer(final DataSchemaNode node) {
         return node instanceof ListSchemaNode || node instanceof ContainerSchemaNode;
     }
 
-    public RpcDefinition getRpcDefinition( final String name ) {
-        final QName validName = this.toQName( name );
-        return validName == null ? null : this.qnameToRpc.get( validName );
+    public RpcDefinition getRpcDefinition(final String name) {
+        final QName validName = this.toQName(name);
+        return validName == null ? null : this.qnameToRpc.get().get(validName);
     }
 
     @Override
-    public void onGlobalContextUpdated( final SchemaContext context ) {
-        if( context != null ) {
-            this.qnameToRpc.clear();
-            this.setGlobalSchema( context );
-            Set<RpcDefinition> _operations = context.getOperations();
-            for( final RpcDefinition operation : _operations ) {
-                {
-                    this.qnameToRpc.put( operation.getQName(), operation );
-                }
+    public void onGlobalContextUpdated(final SchemaContext context) {
+        if (context != null) {
+            final Collection<RpcDefinition> defs = context.getOperations();
+            final Map<QName, RpcDefinition> newMap = new HashMap<>(defs.size());
+
+            for (final RpcDefinition operation : defs) {
+                newMap.put(operation.getQName(), operation);
             }
+
+            // FIXME: still not completely atomic
+            this.qnameToRpc.set(ImmutableMap.copyOf(newMap));
+            this.setGlobalSchema(context);
         }
     }
 
-    public List<String> urlPathArgsDecode( final List<String> strings ) {
+    public static List<String> urlPathArgsDecode(final Iterable<String> strings) {
         try {
             List<String> decodedPathArgs = new ArrayList<String>();
-            for( final String pathArg : strings ) {
-                String _decode = URLDecoder.decode( pathArg, URI_ENCODING_CHAR_SET );
-                decodedPathArgs.add( _decode );
+            for (final String pathArg : strings) {
+                String _decode = URLDecoder.decode(pathArg, URI_ENCODING_CHAR_SET);
+                decodedPathArgs.add(_decode);
             }
             return decodedPathArgs;
-        }
-        catch( UnsupportedEncodingException e ) {
-            throw new RestconfDocumentedException(
-                    "Invalid URL path '" + strings + "': " + e.getMessage(),
-                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+        } catch (UnsupportedEncodingException e) {
+            throw new RestconfDocumentedException("Invalid URL path '" + strings + "': " + e.getMessage(),
+                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
     }
 
-    public String urlPathArgDecode( final String pathArg ) {
-        if( pathArg != null ) {
+    public String urlPathArgDecode(final String pathArg) {
+        if (pathArg != null) {
             try {
-                return URLDecoder.decode( pathArg, URI_ENCODING_CHAR_SET );
-            }
-            catch( UnsupportedEncodingException e ) {
-                throw new RestconfDocumentedException(
-                        "Invalid URL path arg '" + pathArg + "': " + e.getMessage(),
-                        ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                return URLDecoder.decode(pathArg, URI_ENCODING_CHAR_SET);
+            } catch (UnsupportedEncodingException e) {
+                throw new RestconfDocumentedException("Invalid URL path arg '" + pathArg + "': " + e.getMessage(),
+                        ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
             }
         }
 
         return null;
     }
 
-    private CharSequence convertToRestconfIdentifier( final PathArgument argument,
-            final DataNodeContainer node ) {
-        if( argument instanceof NodeIdentifier && node instanceof ContainerSchemaNode ) {
-            return convertToRestconfIdentifier( (NodeIdentifier) argument, (ContainerSchemaNode) node );
-        }
-        else if( argument instanceof NodeIdentifierWithPredicates && node instanceof ListSchemaNode ) {
-            return convertToRestconfIdentifier( (NodeIdentifierWithPredicates) argument, (ListSchemaNode) node );
-        }
-        else if( argument != null && node != null ) {
-            throw new IllegalArgumentException(
-                    "Conversion of generic path argument is not supported" );
-        }
-        else {
-            throw new IllegalArgumentException( "Unhandled parameter types: "
-                    + Arrays.<Object> asList( argument, node ).toString() );
+    private CharSequence convertToRestconfIdentifier(final PathArgument argument, final DataNodeContainer node) {
+        if (argument instanceof NodeIdentifier && node instanceof ContainerSchemaNode) {
+            return convertToRestconfIdentifier((NodeIdentifier) argument, (ContainerSchemaNode) node);
+        } else if (argument instanceof NodeIdentifierWithPredicates && node instanceof ListSchemaNode) {
+            return convertToRestconfIdentifier((NodeIdentifierWithPredicates) argument, (ListSchemaNode) node);
+        } else if (argument != null && node != null) {
+            throw new IllegalArgumentException("Conversion of generic path argument is not supported");
+        } else {
+            throw new IllegalArgumentException("Unhandled parameter types: "
+                    + Arrays.<Object> asList(argument, node).toString());
         }
     }
 
-    private CharSequence convertToRestconfIdentifier( final NodeIdentifier argument,
-            final ContainerSchemaNode node ) {
+    private CharSequence convertToRestconfIdentifier(final NodeIdentifier argument, final ContainerSchemaNode node) {
         StringBuilder builder = new StringBuilder();
-        builder.append( "/" );
+        builder.append("/");
         QName nodeType = argument.getNodeType();
-        builder.append( this.toRestconfIdentifier( nodeType ) );
+        builder.append(this.toRestconfIdentifier(nodeType));
         return builder.toString();
     }
 
-    private CharSequence convertToRestconfIdentifier( final NodeIdentifierWithPredicates argument,
-            final ListSchemaNode node ) {
+    private CharSequence convertToRestconfIdentifier(final NodeIdentifierWithPredicates argument,
+            final ListSchemaNode node) {
         QName nodeType = argument.getNodeType();
-        final CharSequence nodeIdentifier = this.toRestconfIdentifier( nodeType );
+        final CharSequence nodeIdentifier = this.toRestconfIdentifier(nodeType);
         final Map<QName, Object> keyValues = argument.getKeyValues();
 
         StringBuilder builder = new StringBuilder();
-        builder.append( "/" );
-        builder.append( nodeIdentifier );
-        builder.append( "/" );
+        builder.append("/");
+        builder.append(nodeIdentifier);
+        builder.append("/");
 
         List<QName> keyDefinition = node.getKeyDefinition();
         boolean hasElements = false;
-        for( final QName key : keyDefinition ) {
-            if( !hasElements ) {
+        for (final QName key : keyDefinition) {
+            if (!hasElements) {
                 hasElements = true;
-            }
-            else {
-                builder.append( "/" );
+            } else {
+                builder.append("/");
             }
 
             try {
-                builder.append( this.toUriString( keyValues.get( key ) ) );
-            } catch( UnsupportedEncodingException e ) {
-                LOG.error( "Error parsing URI: " + keyValues.get( key ), e );
+                builder.append(this.toUriString(keyValues.get(key)));
+            } catch (UnsupportedEncodingException e) {
+                LOG.error("Error parsing URI: {}", keyValues.get(key), e);
                 return null;
             }
         }
@@ -1006,28 +929,22 @@ public class ControllerContext implements SchemaContextListener {
         return builder.toString();
     }
 
-    private static DataSchemaNode childByQName( final Object container, final QName name ) {
-        if( container instanceof ChoiceCaseNode ) {
-            return childByQName( (ChoiceCaseNode) container, name );
-        }
-        else if( container instanceof ChoiceNode ) {
-            return childByQName( (ChoiceNode) container, name );
-        }
-        else if( container instanceof ContainerSchemaNode ) {
-            return childByQName( (ContainerSchemaNode) container, name );
-        }
-        else if( container instanceof ListSchemaNode ) {
-            return childByQName( (ListSchemaNode) container, name );
-        }
-        else if( container instanceof DataSchemaNode ) {
-            return childByQName( (DataSchemaNode) container, name );
-        }
-        else if( container instanceof Module ) {
-            return childByQName( (Module) container, name );
-        }
-        else {
-            throw new IllegalArgumentException( "Unhandled parameter types: "
-                    + Arrays.<Object> asList( container, name ).toString() );
+    private static DataSchemaNode childByQName(final Object container, final QName name) {
+        if (container instanceof ChoiceCaseNode) {
+            return childByQName((ChoiceCaseNode) container, name);
+        } else if (container instanceof ChoiceNode) {
+            return childByQName((ChoiceNode) container, name);
+        } else if (container instanceof ContainerSchemaNode) {
+            return childByQName((ContainerSchemaNode) container, name);
+        } else if (container instanceof ListSchemaNode) {
+            return childByQName((ListSchemaNode) container, name);
+        } else if (container instanceof DataSchemaNode) {
+            return childByQName((DataSchemaNode) container, name);
+        } else if (container instanceof Module) {
+            return childByQName((Module) container, name);
+        } else {
+            throw new IllegalArgumentException("Unhandled parameter types: "
+                    + Arrays.<Object> asList(container, name).toString());
         }
     }
 }
index 934d4434c38a3e724279405da05198099eba2f70..a3d44d3572106232e10edaad73e91d1b4d46039a 100644 (file)
@@ -7,16 +7,14 @@
  */
 package org.opendaylight.controller.sal.restconf.impl;
 
+import com.google.common.base.Preconditions;
 import java.net.URI;
 import java.util.Collections;
-
 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.NodeFactory;
 
-import com.google.common.base.Preconditions;
-
 public final class EmptyNodeWrapper implements NodeWrapper<Node<?>>, Node<Void> {
 
     private Node<?> unwrapped;
@@ -31,17 +29,17 @@ public final class EmptyNodeWrapper implements NodeWrapper<Node<?>>, Node<Void>
         return composite;
     }
 
-    public void setComposite(boolean composite) {
+    public void setComposite(final boolean composite) {
         this.composite = composite;
     }
 
-    public EmptyNodeWrapper(URI namespace, String localName) {
+    public EmptyNodeWrapper(final URI namespace, final String localName) {
         this.localName = Preconditions.checkNotNull(localName);
         this.namespace = namespace;
     }
 
     @Override
-    public void setQname(QName name) {
+    public void setQname(final QName name) {
         Preconditions.checkState(unwrapped == null, "Cannot change the object, due to data inconsistencies.");
         this.name = name;
     }
@@ -68,7 +66,7 @@ public final class EmptyNodeWrapper implements NodeWrapper<Node<?>>, Node<Void>
     }
 
     @Override
-    public void setNamespace(URI namespace) {
+    public void setNamespace(final URI namespace) {
         Preconditions.checkState(unwrapped == null, "Cannot change the object, due to data inconsistencies.");
         this.namespace = namespace;
     }
@@ -85,8 +83,9 @@ public final class EmptyNodeWrapper implements NodeWrapper<Node<?>>, Node<Void>
                 Preconditions.checkNotNull(namespace);
                 name = new QName(namespace, localName);
             }
-            if(composite) {
-                unwrapped = NodeFactory.createImmutableCompositeNode(name, null, Collections.<Node<?>>emptyList(),null);
+            if (composite) {
+                unwrapped = NodeFactory.createImmutableCompositeNode(name, null, Collections.<Node<?>> emptyList(),
+                        null);
             } else {
                 unwrapped = NodeFactory.createImmutableSimpleNode(name, null, null);
             }
@@ -103,6 +102,7 @@ public final class EmptyNodeWrapper implements NodeWrapper<Node<?>>, Node<Void>
     }
 
     @Override
+    @Deprecated
     public CompositeNode getParent() {
         return unwrap().getParent();
     }
@@ -118,7 +118,7 @@ public final class EmptyNodeWrapper implements NodeWrapper<Node<?>>, Node<Void>
     }
 
     @Override
-    public Void setValue(Void value) {
+    public Void setValue(final Void value) {
         return null;
     }
 
index d66e1610a58e62b07a1834b0c7b61197f49b2ab4..4e797d905739a6b894d2c6a9179b2219af621943 100644 (file)
@@ -16,7 +16,7 @@ public final class IdentityValuesDTO {
     private final List<IdentityValue> elementData = new ArrayList<>();
     private final String originValue;
 
-    public IdentityValuesDTO(String namespace, String value, String prefix,String originValue) {
+    public IdentityValuesDTO(String namespace, String value, String prefix, String originValue) {
         elementData.add(new IdentityValue(namespace, value, prefix));
         this.originValue = originValue;
     }
@@ -37,7 +37,6 @@ public final class IdentityValuesDTO {
         elementData.add(identityValue);
     }
 
-
     public List<IdentityValue> getValuesWithNamespaces() {
         return Collections.unmodifiableList(elementData);
     }
index 68135dea95f1e90e8574d230d7adb202355e8d4d..12c1ba66ecc3df3ad2d5c838a1ee916d85a21f5c 100644 (file)
@@ -8,22 +8,23 @@
 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.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
 public class InstanceIdWithSchemaNode {
 
-    private final InstanceIdentifier instanceIdentifier;
+    private final YangInstanceIdentifier instanceIdentifier;
     private final DataSchemaNode schemaNode;
     private final MountInstance mountPoint;
 
-    public InstanceIdWithSchemaNode(InstanceIdentifier instanceIdentifier, DataSchemaNode schemaNode, MountInstance mountPoint) {
+    public InstanceIdWithSchemaNode(YangInstanceIdentifier instanceIdentifier, DataSchemaNode schemaNode,
+            MountInstance mountPoint) {
         this.instanceIdentifier = instanceIdentifier;
         this.schemaNode = schemaNode;
         this.mountPoint = mountPoint;
     }
 
-    public InstanceIdentifier getInstanceIdentifier() {
+    public YangInstanceIdentifier getInstanceIdentifier() {
         return instanceIdentifier;
     }
 
index 48fd1a3dfc49e4abf6d22ae040cf504781ff0bc8..9637a36268860e13e8ac296004089aed6c8ce825 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.sal.restconf.impl;
 
 import java.net.URI;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.Node;
 
index 265cc5db4536c96ecbf51bf4005ff4ced54e8c14..ff90dd8439582969d8db755c2ae08f4e91129cc5 100644 (file)
@@ -12,18 +12,17 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-
 import org.opendaylight.controller.sal.core.api.mount.MountInstance;
 import org.opendaylight.controller.sal.rest.impl.RestUtil;
 import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
 import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.Predicate;
 import org.opendaylight.yangtools.concepts.Codec;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.codec.IdentityrefCodec;
 import org.opendaylight.yangtools.yang.data.api.codec.InstanceIdentifierCodec;
 import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
@@ -47,7 +46,8 @@ public class RestCodec {
     private RestCodec() {
     }
 
-    public static final Codec<Object, Object> from(TypeDefinition<?> typeDefinition, MountInstance mountPoint) {
+    public static final Codec<Object, Object> from(final TypeDefinition<?> typeDefinition,
+            final MountInstance mountPoint) {
         return new ObjectCodec(typeDefinition, mountPoint);
     }
 
@@ -62,7 +62,7 @@ public class RestCodec {
 
         private final TypeDefinition<?> type;
 
-        private ObjectCodec(TypeDefinition<?> typeDefinition, MountInstance mountPoint) {
+        private ObjectCodec(final TypeDefinition<?> typeDefinition, final MountInstance mountPoint) {
             type = RestUtil.resolveBaseTypeFrom(typeDefinition);
             if (type instanceof IdentityrefTypeDefinition) {
                 identityrefCodec = new IdentityrefCodecImpl(mountPoint);
@@ -78,19 +78,19 @@ public class RestCodec {
 
         @SuppressWarnings("unchecked")
         @Override
-        public Object deserialize(Object input) {
+        public Object deserialize(final Object input) {
             try {
                 if (type instanceof IdentityrefTypeDefinition) {
                     if (input instanceof IdentityValuesDTO) {
                         return identityrefCodec.deserialize(input);
                     }
-                    logger.info(
+                    logger.debug(
                             "Value is not instance of IdentityrefTypeDefinition but is {}. Therefore NULL is used as translation of  - {}",
                             input == null ? "null" : input.getClass(), String.valueOf(input));
                     return null;
                 } else if (type instanceof LeafrefTypeDefinition) {
                     if (input instanceof IdentityValuesDTO) {
-                        return LEAFREF_DEFAULT_CODEC.deserialize(((IdentityValuesDTO)input).getOriginValue());
+                        return LEAFREF_DEFAULT_CODEC.deserialize(((IdentityValuesDTO) input).getOriginValue());
                     }
                     return LEAFREF_DEFAULT_CODEC.deserialize(input);
                 } else if (type instanceof InstanceIdentifierTypeDefinition) {
@@ -106,7 +106,7 @@ public class RestCodec {
                             .from(type);
                     if (typeAwarecodec != null) {
                         if (input instanceof IdentityValuesDTO) {
-                            return typeAwarecodec.deserialize(((IdentityValuesDTO)input).getOriginValue());
+                            return typeAwarecodec.deserialize(((IdentityValuesDTO) input).getOriginValue());
                         }
                         return typeAwarecodec.deserialize(String.valueOf(input));
                     } else {
@@ -115,8 +115,7 @@ public class RestCodec {
                         return null;
                     }
                 }
-            } catch (ClassCastException e) { // TODO remove this catch when
-                                             // everyone use codecs
+            } 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);
@@ -126,7 +125,7 @@ public class RestCodec {
 
         @SuppressWarnings("unchecked")
         @Override
-        public Object serialize(Object input) {
+        public Object serialize(final Object input) {
             try {
                 if (type instanceof IdentityrefTypeDefinition) {
                     return identityrefCodec.serialize(input);
@@ -145,8 +144,7 @@ public class RestCodec {
                         return null;
                     }
                 }
-            } catch (ClassCastException e) { // TODO remove this catch when
-                                             // everyone use codecs
+            } 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);
@@ -162,17 +160,17 @@ public class RestCodec {
 
         private final MountInstance mountPoint;
 
-        public IdentityrefCodecImpl(MountInstance mountPoint) {
+        public IdentityrefCodecImpl(final MountInstance mountPoint) {
             this.mountPoint = mountPoint;
         }
 
         @Override
-        public IdentityValuesDTO serialize(QName data) {
-            return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix(),null);
+        public IdentityValuesDTO serialize(final QName data) {
+            return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix(), null);
         }
 
         @Override
-        public QName deserialize(IdentityValuesDTO data) {
+        public QName deserialize(final IdentityValuesDTO data) {
             IdentityValue valueWithNamespace = data.getValuesWithNamespaces().get(0);
             Module module = getModuleByNamespace(valueWithNamespace.getNamespace(), mountPoint);
             if (module == null) {
@@ -189,12 +187,12 @@ public class RestCodec {
     public static class LeafrefCodecImpl implements LeafrefCodec<String> {
 
         @Override
-        public String serialize(Object data) {
+        public String serialize(final Object data) {
             return String.valueOf(data);
         }
 
         @Override
-        public Object deserialize(String data) {
+        public Object deserialize(final String data) {
             return data;
         }
 
@@ -204,15 +202,14 @@ public class RestCodec {
         private final Logger logger = LoggerFactory.getLogger(InstanceIdentifierCodecImpl.class);
         private final MountInstance mountPoint;
 
-        public InstanceIdentifierCodecImpl(MountInstance mountPoint) {
+        public InstanceIdentifierCodecImpl(final MountInstance mountPoint) {
             this.mountPoint = mountPoint;
         }
 
         @Override
-        public IdentityValuesDTO serialize(InstanceIdentifier data) {
-            List<PathArgument> pathArguments = data.getPath();
+        public IdentityValuesDTO serialize(final YangInstanceIdentifier data) {
             IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO();
-            for (PathArgument pathArgument : pathArguments) {
+            for (PathArgument pathArgument : data.getPathArguments()) {
                 IdentityValue identityValue = qNameToIdentityValue(pathArgument.getNodeType());
                 if (pathArgument instanceof NodeIdentifierWithPredicates && identityValue != null) {
                     List<Predicate> predicates = keyValuesToPredicateList(((NodeIdentifierWithPredicates) pathArgument)
@@ -230,13 +227,15 @@ public class RestCodec {
         }
 
         @Override
-        public InstanceIdentifier deserialize(IdentityValuesDTO data) {
+        public YangInstanceIdentifier deserialize(final IdentityValuesDTO data) {
             List<PathArgument> result = new ArrayList<PathArgument>();
             IdentityValue valueWithNamespace = data.getValuesWithNamespaces().get(0);
             Module module = getModuleByNamespace(valueWithNamespace.getNamespace(), mountPoint);
             if (module == null) {
-                logger.info("Module by namespace '{}' of first node in instance-identiefier was not found.", valueWithNamespace.getNamespace());
-                logger.info("Instance-identifier will be translated as NULL for data - {}", String.valueOf(valueWithNamespace.getValue()));
+                logger.info("Module by namespace '{}' of first node in instance-identiefier was not found.",
+                        valueWithNamespace.getNamespace());
+                logger.info("Instance-identifier will be translated as NULL for data - {}",
+                        String.valueOf(valueWithNamespace.getValue()));
                 return null;
             }
 
@@ -249,7 +248,8 @@ public class RestCodec {
                         parentContainer, identityValue.getValue(), validNamespace);
                 if (node == null) {
                     logger.info("'{}' node was not found in {}", identityValue, parentContainer.getChildNodes());
-                    logger.info("Instance-identifier will be translated as NULL for data - {}", String.valueOf(identityValue.getValue()));
+                    logger.info("Instance-identifier will be translated as NULL for data - {}",
+                            String.valueOf(identityValue.getValue()));
                     return null;
                 }
                 QName qName = node.getQName();
@@ -261,7 +261,8 @@ public class RestCodec {
                         Predicate leafListPredicate = identityValue.getPredicates().get(0);
                         if (!leafListPredicate.isLeafList()) {
                             logger.info("Predicate's data is not type of leaf-list. It should be in format \".='value'\"");
-                            logger.info("Instance-identifier will be translated as NULL for data - {}", String.valueOf(identityValue.getValue()));
+                            logger.info("Instance-identifier will be translated as NULL for data - {}",
+                                    String.valueOf(identityValue.getValue()));
                             return null;
                         }
                         pathArgument = new NodeWithValue(qName, leafListPredicate.getValue());
@@ -270,33 +271,37 @@ public class RestCodec {
                         Map<QName, Object> predicatesMap = new HashMap<>();
                         for (Predicate predicate : identityValue.getPredicates()) {
                             validNamespace = resolveValidNamespace(predicate.getName().getNamespace(), mountPoint);
-                            DataSchemaNode listKey = ControllerContext.getInstance().findInstanceDataChildByNameAndNamespace(
-                                    listNode, predicate.getName().getValue(), validNamespace);
+                            DataSchemaNode listKey = ControllerContext.getInstance()
+                                    .findInstanceDataChildByNameAndNamespace(listNode, predicate.getName().getValue(),
+                                            validNamespace);
                             predicatesMap.put(listKey.getQName(), predicate.getValue());
                         }
                         pathArgument = new NodeIdentifierWithPredicates(qName, predicatesMap);
                     } else {
                         logger.info("Node {} is not List or Leaf-list.", node);
-                        logger.info("Instance-identifier will be translated as NULL for data - {}", String.valueOf(identityValue.getValue()));
+                        logger.info("Instance-identifier will be translated as NULL for data - {}",
+                                String.valueOf(identityValue.getValue()));
                         return null;
                     }
                 }
                 result.add(pathArgument);
-                if (i < identities.size() - 1) { // last element in instance-identifier can be other than DataNodeContainer
+                if (i < identities.size() - 1) { // last element in instance-identifier can be other than
+                                                 // DataNodeContainer
                     if (node instanceof DataNodeContainer) {
                         parentContainer = (DataNodeContainer) node;
                     } else {
                         logger.info("Node {} isn't instance of DataNodeContainer", node);
-                        logger.info("Instance-identifier will be translated as NULL for data - {}", String.valueOf(identityValue.getValue()));
+                        logger.info("Instance-identifier will be translated as NULL for data - {}",
+                                String.valueOf(identityValue.getValue()));
                         return null;
                     }
                 }
             }
 
-            return result.isEmpty() ? null : new InstanceIdentifier(result);
+            return result.isEmpty() ? null : YangInstanceIdentifier.create(result);
         }
 
-        private List<Predicate> keyValuesToPredicateList(Map<QName, Object> keyValues) {
+        private List<Predicate> keyValuesToPredicateList(final Map<QName, Object> keyValues) {
             List<Predicate> result = new ArrayList<>();
             for (QName qName : keyValues.keySet()) {
                 Object value = keyValues.get(qName);
@@ -305,7 +310,7 @@ public class RestCodec {
             return result;
         }
 
-        private IdentityValue qNameToIdentityValue(QName qName) {
+        private IdentityValue qNameToIdentityValue(final QName qName) {
             if (qName != null) {
                 return new IdentityValue(qName.getNamespace().toString(), qName.getLocalName(), qName.getPrefix());
             }
@@ -313,7 +318,7 @@ public class RestCodec {
         }
     }
 
-    private static Module getModuleByNamespace(String namespace, MountInstance mountPoint) {
+    private static Module getModuleByNamespace(final String namespace, final MountInstance mountPoint) {
         URI validNamespace = resolveValidNamespace(namespace, mountPoint);
 
         Module module = null;
@@ -329,7 +334,7 @@ public class RestCodec {
         return module;
     }
 
-    private static URI resolveValidNamespace(String namespace, MountInstance mountPoint) {
+    private static URI resolveValidNamespace(final String namespace, final MountInstance mountPoint) {
         URI validNamespace;
         if (mountPoint != null) {
             validNamespace = ControllerContext.getInstance().findNamespaceByModuleName(mountPoint, namespace);
index 0548e95044e081592ef9bb7d49513b8be7ab48bb..e3e0c3a2bdc49cbf8fca3bb8104e673fa2ea0b2c 100644 (file)
@@ -8,20 +8,17 @@
 
 package org.opendaylight.controller.sal.restconf.impl;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
 import java.util.List;
-
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response.Status;
-
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-
 /**
- * Unchecked exception to communicate error information, as defined in the ietf restcong draft,
- * to be sent to the client.
+ * Unchecked exception to communicate error information, as defined in the ietf restcong draft, to be sent to the
+ * client.
  *
  * @author Devin Avery
  * @author Thomas Pantelis
@@ -35,70 +32,76 @@ public class RestconfDocumentedException extends WebApplicationException {
     private final Status status;
 
     /**
-     * Constructs an instance with an error message. The error type defaults to APPLICATION and
-     * the error tag defaults to OPERATION_FAILED.
+     * Constructs an instance with an error message. The error type defaults to APPLICATION and the error tag defaults
+     * to OPERATION_FAILED.
      *
-     * @param message A string which provides a plain text string describing the error.
+     * @param message
+     *            A string which provides a plain text string describing the error.
      */
-    public RestconfDocumentedException( String message ) {
-        this( message, RestconfError.ErrorType.APPLICATION, RestconfError.ErrorTag.OPERATION_FAILED );
+    public RestconfDocumentedException(String message) {
+        this(message, RestconfError.ErrorType.APPLICATION, RestconfError.ErrorTag.OPERATION_FAILED);
     }
 
     /**
      * Constructs an instance with an error message, error type, and error tag.
      *
-     * @param message A string which provides a plain text string describing the error.
-     * @param errorType The enumerated type indicating the layer where the error occurred.
-     * @param errorTag The enumerated tag representing a more specific error cause.
+     * @param message
+     *            A string which provides a plain text string describing the error.
+     * @param errorType
+     *            The enumerated type indicating the layer where the error occurred.
+     * @param errorTag
+     *            The enumerated tag representing a more specific error cause.
      */
-    public RestconfDocumentedException( String message, ErrorType errorType, ErrorTag errorTag ) {
-        this( null, new RestconfError( errorType, errorTag, message ) );
+    public RestconfDocumentedException(String message, ErrorType errorType, ErrorTag errorTag) {
+        this(null, new RestconfError(errorType, errorTag, message));
     }
 
     /**
-     * Constructs an instance with an error message and exception cause. The stack trace of the
-     * exception is included in the error info.
+     * Constructs an instance with an error message and exception cause. The stack trace of the exception is included in
+     * the error info.
      *
-     * @param message A string which provides a plain text string describing the error.
-     * @param cause The underlying exception cause.
+     * @param message
+     *            A string which provides a plain text string describing the error.
+     * @param cause
+     *            The underlying exception cause.
      */
-    public RestconfDocumentedException( String message, Throwable cause ) {
-        this( cause, new RestconfError( RestconfError.ErrorType.APPLICATION,
-                                        RestconfError.ErrorTag.OPERATION_FAILED, message,
-                                        null, RestconfError.toErrorInfo( cause ) ) );
+    public RestconfDocumentedException(String message, Throwable cause) {
+        this(cause, new RestconfError(RestconfError.ErrorType.APPLICATION, RestconfError.ErrorTag.OPERATION_FAILED,
+                message, null, RestconfError.toErrorInfo(cause)));
     }
 
     /**
      * Constructs an instance with the given error.
      */
-    public RestconfDocumentedException( RestconfError error ) {
-        this( null, error );
+    public RestconfDocumentedException(RestconfError error) {
+        this(null, error);
     }
 
     /**
      * Constructs an instance with the given errors.
      */
-    public RestconfDocumentedException( List<RestconfError> errors ) {
-        this.errors = ImmutableList.copyOf( errors );
-        Preconditions.checkArgument( !this.errors.isEmpty(), "RestconfError list can't be empty" );
+    public RestconfDocumentedException(List<RestconfError> errors) {
+        this.errors = ImmutableList.copyOf(errors);
+        Preconditions.checkArgument(!this.errors.isEmpty(), "RestconfError list can't be empty");
         status = null;
     }
 
     /**
      * Constructs an instance with an HTTP status and no error information.
      *
-     * @param status the HTTP status.
+     * @param status
+     *            the HTTP status.
      */
-    public RestconfDocumentedException( Status status ) {
-        Preconditions.checkNotNull( status, "Status can't be null" );
+    public RestconfDocumentedException(Status status) {
+        Preconditions.checkNotNull(status, "Status can't be null");
         errors = ImmutableList.of();
         this.status = status;
     }
 
-    private RestconfDocumentedException( Throwable cause, RestconfError error ) {
-        super( cause );
-        Preconditions.checkNotNull( error, "RestconfError can't be null" );
-        errors = ImmutableList.of( error );
+    private RestconfDocumentedException(Throwable cause, RestconfError error) {
+        super(cause);
+        Preconditions.checkNotNull(error, "RestconfError can't be null");
+        errors = ImmutableList.of(error);
         status = null;
     }
 
@@ -110,7 +113,6 @@ public class RestconfDocumentedException extends WebApplicationException {
         return status;
     }
 
-
     @Override
     public String getMessage() {
         return "errors: " + errors + (status != null ? ", status: " + status : "");
index cc279cbd58e68cfc98634364a30002051f698441..ed20bd01a5047e4d746858ff4adde4fe7de0c701 100644 (file)
@@ -1,23 +1,23 @@
 /*
-* Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
-*
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v1.0 which accompanies this distribution,
-* and is available at http://www.eclipse.org/legal/epl-v10.html
-*/
+ * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.sal.restconf.impl;
 
+import com.google.common.base.Preconditions;
 import java.io.PrintWriter;
 import java.io.StringWriter;
-
 import org.opendaylight.yangtools.yang.common.RpcError;
 
-import com.google.common.base.Preconditions;
-
 /**
  * Encapsulates a restconf error as defined in the ietf restconf draft.
  *
- * <br><br><b>Note:</b> Enumerations defined within are provided by the ietf restconf draft.
+ * <br>
+ * <br>
+ * <b>Note:</b> Enumerations defined within are provided by the ietf restconf draft.
  *
  * @author Devin Avery
  * @see {@link https://tools.ietf.org/html/draft-bierman-netconf-restconf-02}
@@ -38,37 +38,35 @@ public class RestconfError {
             return name().toLowerCase();
         }
 
-        public static ErrorType valueOfCaseInsensitive( String value )
-        {
+        public static ErrorType valueOfCaseInsensitive(String value) {
             try {
-                return ErrorType.valueOf( ErrorType.class, value.toUpperCase() );
-            }
-            catch( IllegalArgumentException e ) {
+                return ErrorType.valueOf(ErrorType.class, value.toUpperCase());
+            } catch (IllegalArgumentException e) {
                 return APPLICATION;
             }
         }
     }
 
     public static enum ErrorTag {
-        IN_USE( "in-use", 409 /*Conflict*/ ),
-        INVALID_VALUE( "invalid-value", 400 /*Bad Request*/ ),
-        TOO_BIG( "too-big", 413 /*Request Entity Too Large*/ ),
-        MISSING_ATTRIBUTE( "missing-attribute", 400 /*Bad Request*/ ),
-        BAD_ATTRIBUTE( "bad-attribute", 400 /*Bad Request*/ ),
-        UNKNOWN_ATTRIBUTE( "unknown-attribute", 400 /*Bad Request*/ ),
-        BAD_ELEMENT( "bad-element", 400 /*Bad Request*/ ),
-        UNKNOWN_ELEMENT( "unknown-element", 400 /*Bad Request*/ ),
-        UNKNOWN_NAMESPACE( "unknown-namespace", 400 /*Bad Request*/ ),
-        ACCESS_DENIED( "access-denied", 403 /*Forbidden*/ ),
-        LOCK_DENIED( "lock-denied", 409 /*Conflict*/ ),
-        RESOURCE_DENIED( "resource-denied", 409 /*Conflict*/ ),
-        ROLLBACK_FAILED( "rollback-failed", 500 /*INTERNAL_SERVER_ERROR*/ ),
-        DATA_EXISTS( "data-exists", 409 /*Conflict*/ ),
-        DATA_MISSING( "data-missing", 409 /*Conflict*/ ),
-        OPERATION_NOT_SUPPORTED( "operation-not-supported", 501 /*Not Implemented*/ ),
-        OPERATION_FAILED( "operation-failed", 500 /*INTERNAL_SERVER_ERROR*/ ),
-        PARTIAL_OPERATION( "partial-operation", 500 /*INTERNAL_SERVER_ERROR*/ ),
-        MALFORMED_MESSAGE( "malformed-message", 400 /*Bad Request*/ );
+        IN_USE("in-use", 409 /* Conflict */),
+        INVALID_VALUE("invalid-value", 400 /* Bad Request */),
+        TOO_BIG("too-big", 413 /* Request Entity Too Large */),
+        MISSING_ATTRIBUTE("missing-attribute", 400 /* Bad Request */),
+        BAD_ATTRIBUTE("bad-attribute", 400 /* Bad Request */),
+        UNKNOWN_ATTRIBUTE("unknown-attribute", 400 /* Bad Request */),
+        BAD_ELEMENT("bad-element", 400 /* Bad Request */),
+        UNKNOWN_ELEMENT("unknown-element", 400 /* Bad Request */),
+        UNKNOWN_NAMESPACE("unknown-namespace", 400 /* Bad Request */),
+        ACCESS_DENIED("access-denied", 403 /* Forbidden */),
+        LOCK_DENIED("lock-denied", 409 /* Conflict */),
+        RESOURCE_DENIED("resource-denied", 409 /* Conflict */),
+        ROLLBACK_FAILED("rollback-failed", 500 /* INTERNAL_SERVER_ERROR */),
+        DATA_EXISTS("data-exists", 409 /* Conflict */),
+        DATA_MISSING("data-missing", 409 /* Conflict */),
+        OPERATION_NOT_SUPPORTED("operation-not-supported", 501 /* Not Implemented */),
+        OPERATION_FAILED("operation-failed", 500 /* INTERNAL_SERVER_ERROR */),
+        PARTIAL_OPERATION("partial-operation", 500 /* INTERNAL_SERVER_ERROR */),
+        MALFORMED_MESSAGE("malformed-message", 400 /* Bad Request */);
 
         private final String tagValue;
         private final int statusCode;
@@ -82,12 +80,10 @@ public class RestconfError {
             return this.tagValue.toLowerCase();
         }
 
-        public static ErrorTag valueOfCaseInsensitive( String value )
-        {
+        public static ErrorTag valueOfCaseInsensitive(String value) {
             try {
-                return ErrorTag.valueOf( ErrorTag.class, value.toUpperCase().replaceAll( "-","_" ) );
-            }
-            catch( IllegalArgumentException e ) {
+                return ErrorTag.valueOf(ErrorTag.class, value.toUpperCase().replaceAll("-", "_"));
+            } catch (IllegalArgumentException e) {
                 return OPERATION_FAILED;
             }
         }
@@ -102,53 +98,63 @@ public class RestconfError {
     private final String errorInfo;
     private final String errorAppTag;
     private final String errorMessage;
-    //TODO: Add in the error-path concept as defined in the ietf draft.
 
-    static String toErrorInfo( Throwable cause ) {
+    // TODO: Add in the error-path concept as defined in the ietf draft.
+
+    static String toErrorInfo(Throwable cause) {
         StringWriter writer = new StringWriter();
-        cause.printStackTrace( new PrintWriter( writer ) );
+        cause.printStackTrace(new PrintWriter(writer));
         return writer.toString();
     }
 
     /**
      * Constructs a RestConfError
      *
-     * @param errorType The enumerated type indicating the layer where the error occurred.
-     * @param errorTag The enumerated tag representing a more specific error cause.
-     * @param errorMessage A string which provides a plain text string describing the error.
+     * @param errorType
+     *            The enumerated type indicating the layer where the error occurred.
+     * @param errorTag
+     *            The enumerated tag representing a more specific error cause.
+     * @param errorMessage
+     *            A string which provides a plain text string describing the error.
      */
     public RestconfError(ErrorType errorType, ErrorTag errorTag, String errorMessage) {
-        this( errorType, errorTag, errorMessage, null );
+        this(errorType, errorTag, errorMessage, null);
     }
 
     /**
      * Constructs a RestConfError object.
      *
-     * @param errorType The enumerated type indicating the layer where the error occurred.
-     * @param errorTag The enumerated tag representing a more specific error cause.
-     * @param errorMessage A string which provides a plain text string describing the error.
-     * @param errorAppTag A string which represents an application-specific error tag that further
-     *                    specifies the error cause.
+     * @param errorType
+     *            The enumerated type indicating the layer where the error occurred.
+     * @param errorTag
+     *            The enumerated tag representing a more specific error cause.
+     * @param errorMessage
+     *            A string which provides a plain text string describing the error.
+     * @param errorAppTag
+     *            A string which represents an application-specific error tag that further specifies the error cause.
      */
-    public RestconfError(ErrorType errorType, ErrorTag errorTag, String errorMessage,
-                         String errorAppTag) {
-        this( errorType, errorTag, errorMessage, errorAppTag, null );
+    public RestconfError(ErrorType errorType, ErrorTag errorTag, String errorMessage, String errorAppTag) {
+        this(errorType, errorTag, errorMessage, errorAppTag, null);
     }
 
     /**
      * Constructs a RestConfError object.
      *
-     * @param errorType The enumerated type indicating the layer where the error occurred.
-     * @param errorTag The enumerated tag representing a more specific error cause.
-     * @param errorMessage A string which provides a plain text string describing the error.
-     * @param errorAppTag A string which represents an application-specific error tag that further
-     *                    specifies the error cause.
-     * @param errorInfo A string, <b>formatted as XML</b>, which contains additional error information.
+     * @param errorType
+     *            The enumerated type indicating the layer where the error occurred.
+     * @param errorTag
+     *            The enumerated tag representing a more specific error cause.
+     * @param errorMessage
+     *            A string which provides a plain text string describing the error.
+     * @param errorAppTag
+     *            A string which represents an application-specific error tag that further specifies the error cause.
+     * @param errorInfo
+     *            A string, <b>formatted as XML</b>, which contains additional error information.
      */
-    public RestconfError(ErrorType errorType, ErrorTag errorTag, String errorMessage,
-                         String errorAppTag, String errorInfo) {
-        Preconditions.checkNotNull( errorType, "Error type is required for RestConfError" );
-        Preconditions.checkNotNull( errorTag, "Error tag is required for RestConfError");
+    public RestconfError(ErrorType errorType, ErrorTag errorTag, String errorMessage, String errorAppTag,
+            String errorInfo) {
+        Preconditions.checkNotNull(errorType, "Error type is required for RestConfError");
+        Preconditions.checkNotNull(errorTag, "Error tag is required for RestConfError");
         this.errorType = errorType;
         this.errorTag = errorTag;
         this.errorMessage = errorMessage;
@@ -159,28 +165,25 @@ public class RestconfError {
     /**
      * Constructs a RestConfError object from an RpcError.
      */
-    public RestconfError( RpcError rpcError ) {
+    public RestconfError(RpcError rpcError) {
 
-        this.errorType = rpcError.getErrorType() == null ? ErrorType.APPLICATION :
-                               ErrorType.valueOfCaseInsensitive( rpcError.getErrorType().name() );
+        this.errorType = rpcError.getErrorType() == null ? ErrorType.APPLICATION : ErrorType
+                .valueOfCaseInsensitive(rpcError.getErrorType().name());
 
-        this.errorTag = rpcError.getTag() == null ? ErrorTag.OPERATION_FAILED :
-                                    ErrorTag.valueOfCaseInsensitive( rpcError.getTag().toString() );
+        this.errorTag = rpcError.getTag() == null ? ErrorTag.OPERATION_FAILED : ErrorTag
+                .valueOfCaseInsensitive(rpcError.getTag().toString());
 
         this.errorMessage = rpcError.getMessage();
         this.errorAppTag = rpcError.getApplicationTag();
 
         String errorInfo = null;
-        if( rpcError.getInfo() == null ) {
-            if( rpcError.getCause() != null ) {
-                errorInfo = toErrorInfo( rpcError.getCause() );
+        if (rpcError.getInfo() == null) {
+            if (rpcError.getCause() != null) {
+                errorInfo = toErrorInfo(rpcError.getCause());
+            } else if (rpcError.getSeverity() != null) {
+                errorInfo = "<severity>" + rpcError.getSeverity().toString().toLowerCase() + "</severity>";
             }
-            else if( rpcError.getSeverity() != null ) {
-                errorInfo = "<severity>" + rpcError.getSeverity().toString().toLowerCase() +
-                            "</severity>";
-            }
-        }
-        else {
+        } else {
             errorInfo = rpcError.getInfo();
         }
 
@@ -209,8 +212,7 @@ public class RestconfError {
 
     @Override
     public String toString() {
-        return "error-type: " + errorType.getErrorTypeTag()
-                + ", error-tag: " + errorTag.getTagValue() + ", "
+        return "error-type: " + errorType.getErrorTypeTag() + ", error-tag: " + errorTag.getTagValue() + ", "
                 + (errorAppTag != null ? "error-app-tag: " + errorAppTag + ", " : "")
                 + (errorMessage != null ? "error-message: " + errorMessage : "")
                 + (errorInfo != null ? "error-info: " + errorInfo + ", " : "") + "]";
index 4716a02be2f26230721be7e08eb697eaeb0224cc..4c005c6ae5e9e109604a1890cd5ee0c5f81d264a 100644 (file)
@@ -25,6 +25,7 @@ import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Future;
 import javax.ws.rs.core.Response;
@@ -49,8 +50,10 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcError;
 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.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
@@ -75,13 +78,29 @@ import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBu
 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
 
 public class RestconfImpl implements RestconfService {
+    private enum UriParameters {
+        PRETTY_PRINT("prettyPrint"),
+        DEPTH("depth");
+
+        private String uriParameterName;
+
+        UriParameters(String uriParameterName) {
+            this.uriParameterName = uriParameterName;
+        }
+
+        @Override
+        public String toString() {
+            return uriParameterName;
+        }
+    }
+
     private final static RestconfImpl INSTANCE = new RestconfImpl();
 
     private static final int CHAR_NOT_FOUND = -1;
 
     private final static String MOUNT_POINT_MODULE_NAME = "ietf-netconf";
 
-    private final static SimpleDateFormat REVISION_FORMAT =  new SimpleDateFormat("yyyy-MM-dd");
+    private final static SimpleDateFormat REVISION_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
 
     private final static String SAL_REMOTE_NAMESPACE = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote";
 
@@ -107,12 +126,12 @@ public class RestconfImpl implements RestconfService {
     }
 
     @Override
-    public StructuredData getModules() {
+    public StructuredData getModules(final UriInfo uriInfo) {
         final Module restconfModule = this.getRestconfModule();
 
         final List<Node<?>> modulesAsData = new ArrayList<Node<?>>();
-        final DataSchemaNode moduleSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
-                                        restconfModule, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
+        final DataSchemaNode moduleSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(restconfModule,
+                Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
 
         Set<Module> allModules = this.controllerContext.getAllModules();
         for (final Module module : allModules) {
@@ -120,135 +139,128 @@ public class RestconfImpl implements RestconfService {
             modulesAsData.add(moduleCompositeNode);
         }
 
-        final DataSchemaNode modulesSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
-                                   restconfModule, Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
+        final DataSchemaNode modulesSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(restconfModule,
+                Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
         QName qName = modulesSchemaNode.getQName();
         final CompositeNode modulesNode = NodeFactory.createImmutableCompositeNode(qName, null, modulesAsData);
-        return new StructuredData(modulesNode, modulesSchemaNode, null);
+        return new StructuredData(modulesNode, modulesSchemaNode, null, parsePrettyPrintParameter(uriInfo));
     }
 
     @Override
-    public StructuredData getAvailableStreams() {
+    public StructuredData getAvailableStreams(final UriInfo uriInfo) {
         Set<String> availableStreams = Notificator.getStreamNames();
 
         final List<Node<?>> streamsAsData = new ArrayList<Node<?>>();
         Module restconfModule = this.getRestconfModule();
-        final DataSchemaNode streamSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
-                                             restconfModule, Draft02.RestConfModule.STREAM_LIST_SCHEMA_NODE);
+        final DataSchemaNode streamSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(restconfModule,
+                Draft02.RestConfModule.STREAM_LIST_SCHEMA_NODE);
         for (final String streamName : availableStreams) {
             streamsAsData.add(this.toStreamCompositeNode(streamName, streamSchemaNode));
         }
 
-        final DataSchemaNode streamsSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
-                                     restconfModule, Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
+        final DataSchemaNode streamsSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(restconfModule,
+                Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
         QName qName = streamsSchemaNode.getQName();
         final CompositeNode streamsNode = NodeFactory.createImmutableCompositeNode(qName, null, streamsAsData);
-        return new StructuredData(streamsNode, streamsSchemaNode, null);
+        return new StructuredData(streamsNode, streamsSchemaNode, null, parsePrettyPrintParameter(uriInfo));
     }
 
     @Override
-    public StructuredData getModules(final String identifier) {
+    public StructuredData getModules(final String identifier, final UriInfo uriInfo) {
         Set<Module> modules = null;
         MountInstance mountPoint = null;
         if (identifier.contains(ControllerContext.MOUNT)) {
-            InstanceIdWithSchemaNode mountPointIdentifier =
-                                           this.controllerContext.toMountPointIdentifier(identifier);
+            InstanceIdWithSchemaNode mountPointIdentifier = this.controllerContext.toMountPointIdentifier(identifier);
             mountPoint = mountPointIdentifier.getMountPoint();
             modules = this.controllerContext.getAllModules(mountPoint);
-        }
-        else {
+        } else {
             throw new RestconfDocumentedException(
-                    "URI has bad format. If modules behind mount point should be showed, URI has to end with " +
-                    ControllerContext.MOUNT, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                    "URI has bad format. If modules behind mount point should be showed, URI has to end with "
+                            + ControllerContext.MOUNT, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
 
         final List<Node<?>> modulesAsData = new ArrayList<Node<?>>();
         Module restconfModule = this.getRestconfModule();
-        final DataSchemaNode moduleSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
-                                         restconfModule, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
+        final DataSchemaNode moduleSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(restconfModule,
+                Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
 
         for (final Module module : modules) {
             modulesAsData.add(this.toModuleCompositeNode(module, moduleSchemaNode));
         }
 
-        final DataSchemaNode modulesSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
-                                  restconfModule, Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
+        final DataSchemaNode modulesSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(restconfModule,
+                Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
         QName qName = modulesSchemaNode.getQName();
         final CompositeNode modulesNode = NodeFactory.createImmutableCompositeNode(qName, null, modulesAsData);
-        return new StructuredData(modulesNode, modulesSchemaNode, mountPoint);
+        return new StructuredData(modulesNode, modulesSchemaNode, mountPoint, parsePrettyPrintParameter(uriInfo));
     }
 
     @Override
-    public StructuredData getModule(final String identifier) {
+    public StructuredData getModule(final String identifier, final UriInfo uriInfo) {
         final QName moduleNameAndRevision = this.getModuleNameAndRevision(identifier);
         Module module = null;
         MountInstance mountPoint = null;
         if (identifier.contains(ControllerContext.MOUNT)) {
-            InstanceIdWithSchemaNode mountPointIdentifier =
-                                            this.controllerContext.toMountPointIdentifier(identifier);
+            InstanceIdWithSchemaNode mountPointIdentifier = this.controllerContext.toMountPointIdentifier(identifier);
             mountPoint = mountPointIdentifier.getMountPoint();
             module = this.controllerContext.findModuleByNameAndRevision(mountPoint, moduleNameAndRevision);
-        }
-        else {
+        } else {
             module = this.controllerContext.findModuleByNameAndRevision(moduleNameAndRevision);
         }
 
         if (module == null) {
-            throw new RestconfDocumentedException(
-                    "Module with name '" + moduleNameAndRevision.getLocalName() + "' and revision '" +
-                    moduleNameAndRevision.getRevision() + "' was not found.",
-                    ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT );
+            throw new RestconfDocumentedException("Module with name '" + moduleNameAndRevision.getLocalName()
+                    + "' and revision '" + moduleNameAndRevision.getRevision() + "' was not found.",
+                    ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
         }
 
         Module restconfModule = this.getRestconfModule();
-        final DataSchemaNode moduleSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
-                                          restconfModule, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
+        final DataSchemaNode moduleSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(restconfModule,
+                Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
         final CompositeNode moduleNode = this.toModuleCompositeNode(module, moduleSchemaNode);
-        return new StructuredData(moduleNode, moduleSchemaNode, mountPoint);
+        return new StructuredData(moduleNode, moduleSchemaNode, mountPoint, parsePrettyPrintParameter(uriInfo));
     }
 
     @Override
-    public StructuredData getOperations() {
+    public StructuredData getOperations(final UriInfo uriInfo) {
         Set<Module> allModules = this.controllerContext.getAllModules();
-        return this.operationsFromModulesToStructuredData(allModules, null);
+        return this.operationsFromModulesToStructuredData(allModules, null, parsePrettyPrintParameter(uriInfo));
     }
 
     @Override
-    public StructuredData getOperations(final String identifier) {
+    public StructuredData getOperations(final String identifier, final UriInfo uriInfo) {
         Set<Module> modules = null;
         MountInstance mountPoint = null;
         if (identifier.contains(ControllerContext.MOUNT)) {
-            InstanceIdWithSchemaNode mountPointIdentifier =
-                                         this.controllerContext.toMountPointIdentifier(identifier);
+            InstanceIdWithSchemaNode mountPointIdentifier = this.controllerContext.toMountPointIdentifier(identifier);
             mountPoint = mountPointIdentifier.getMountPoint();
             modules = this.controllerContext.getAllModules(mountPoint);
-        }
-        else {
+        } else {
             throw new RestconfDocumentedException(
-                    "URI has bad format. If operations behind mount point should be showed, URI has to end with " +
-                    ControllerContext.MOUNT, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                    "URI has bad format. If operations behind mount point should be showed, URI has to end with "
+                            + ControllerContext.MOUNT, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
 
-        return this.operationsFromModulesToStructuredData(modules, mountPoint);
+        return this.operationsFromModulesToStructuredData(modules, mountPoint, parsePrettyPrintParameter(uriInfo));
     }
 
     private StructuredData operationsFromModulesToStructuredData(final Set<Module> modules,
-                                                                 final MountInstance mountPoint) {
+            final MountInstance mountPoint, boolean prettyPrint) {
         final List<Node<?>> operationsAsData = new ArrayList<Node<?>>();
         Module restconfModule = this.getRestconfModule();
         final DataSchemaNode operationsSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
-                              restconfModule, Draft02.RestConfModule.OPERATIONS_CONTAINER_SCHEMA_NODE);
+                restconfModule, Draft02.RestConfModule.OPERATIONS_CONTAINER_SCHEMA_NODE);
         QName qName = operationsSchemaNode.getQName();
         SchemaPath path = operationsSchemaNode.getPath();
-        ContainerSchemaNodeBuilder containerSchemaNodeBuilder =
-                             new ContainerSchemaNodeBuilder(Draft02.RestConfModule.NAME, 0, qName, path);
+        ContainerSchemaNodeBuilder containerSchemaNodeBuilder = new ContainerSchemaNodeBuilder(
+                Draft02.RestConfModule.NAME, 0, qName, path);
         final ContainerSchemaNodeBuilder fakeOperationsSchemaNode = containerSchemaNodeBuilder;
         for (final Module module : modules) {
             Set<RpcDefinition> rpcs = module.getRpcs();
             for (final RpcDefinition rpc : rpcs) {
                 QName rpcQName = rpc.getQName();
-                SimpleNode<Object> immutableSimpleNode =
-                                     NodeFactory.<Object>createImmutableSimpleNode(rpcQName, null, null);
+                SimpleNode<Object> immutableSimpleNode = NodeFactory.<Object> createImmutableSimpleNode(rpcQName, null,
+                        null);
                 operationsAsData.add(immutableSimpleNode);
 
                 String name = module.getName();
@@ -263,18 +275,16 @@ public class RestconfImpl implements RestconfService {
             }
         }
 
-        final CompositeNode operationsNode =
-                                  NodeFactory.createImmutableCompositeNode(qName, null, operationsAsData);
+        final CompositeNode operationsNode = NodeFactory.createImmutableCompositeNode(qName, null, operationsAsData);
         ContainerSchemaNode schemaNode = fakeOperationsSchemaNode.build();
-        return new StructuredData(operationsNode, schemaNode, mountPoint);
+        return new StructuredData(operationsNode, schemaNode, mountPoint, prettyPrint);
     }
 
     private Module getRestconfModule() {
         Module restconfModule = controllerContext.getRestconfModule();
         if (restconfModule == null) {
-            throw new RestconfDocumentedException(
-                    "ietf-restconf module was not found.", ErrorType.APPLICATION,
-                    ErrorTag.OPERATION_NOT_SUPPORTED );
+            throw new RestconfDocumentedException("ietf-restconf module was not found.", ErrorType.APPLICATION,
+                    ErrorTag.OPERATION_NOT_SUPPORTED);
         }
 
         return restconfModule;
@@ -285,96 +295,91 @@ public class RestconfImpl implements RestconfService {
         String moduleNameAndRevision = "";
         if (mountIndex >= 0) {
             moduleNameAndRevision = identifier.substring(mountIndex + ControllerContext.MOUNT.length());
-        }
-        else {
+        } else {
             moduleNameAndRevision = identifier;
         }
 
         Splitter splitter = Splitter.on("/").omitEmptyStrings();
         Iterable<String> split = splitter.split(moduleNameAndRevision);
-        final List<String> pathArgs = Lists.<String>newArrayList(split);
+        final List<String> pathArgs = Lists.<String> newArrayList(split);
         if (pathArgs.size() < 2) {
             throw new RestconfDocumentedException(
-                    "URI has bad format. End of URI should be in format \'moduleName/yyyy-MM-dd\'",
-                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                    "URI has bad format. End of URI should be in format \'moduleName/yyyy-MM-dd\'", ErrorType.PROTOCOL,
+                    ErrorTag.INVALID_VALUE);
         }
 
         try {
-            final String moduleName = pathArgs.get( 0 );
+            final String moduleName = pathArgs.get(0);
             String revision = pathArgs.get(1);
             final Date moduleRevision = REVISION_FORMAT.parse(revision);
             return QName.create(null, moduleRevision, moduleName);
-        }
-        catch (ParseException e) {
-            throw new RestconfDocumentedException(
-                    "URI has bad format. It should be \'moduleName/yyyy-MM-dd\'",
-                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+        } catch (ParseException e) {
+            throw new RestconfDocumentedException("URI has bad format. It should be \'moduleName/yyyy-MM-dd\'",
+                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
     }
 
     private CompositeNode toStreamCompositeNode(final String streamName, final DataSchemaNode streamSchemaNode) {
         final List<Node<?>> streamNodeValues = new ArrayList<Node<?>>();
-        List<DataSchemaNode> instanceDataChildrenByName =
-                this.controllerContext.findInstanceDataChildrenByName(((DataNodeContainer) streamSchemaNode),
-                                                                       "name");
+        List<DataSchemaNode> instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
+                ((DataNodeContainer) streamSchemaNode), "name");
         final DataSchemaNode nameSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
-        streamNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(nameSchemaNode.getQName(), null,
-                                                                           streamName));
+        streamNodeValues
+                .add(NodeFactory.<String> createImmutableSimpleNode(nameSchemaNode.getQName(), null, streamName));
 
         instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
-                                                 ((DataNodeContainer) streamSchemaNode), "description");
+                ((DataNodeContainer) streamSchemaNode), "description");
         final DataSchemaNode descriptionSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
-        streamNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(descriptionSchemaNode.getQName(), null,
-                                                                           "DESCRIPTION_PLACEHOLDER"));
+        streamNodeValues.add(NodeFactory.<String> createImmutableSimpleNode(descriptionSchemaNode.getQName(), null,
+                "DESCRIPTION_PLACEHOLDER"));
 
         instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
-                                               ((DataNodeContainer) streamSchemaNode), "replay-support");
+                ((DataNodeContainer) streamSchemaNode), "replay-support");
         final DataSchemaNode replaySupportSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
-        streamNodeValues.add(NodeFactory.<Boolean>createImmutableSimpleNode(replaySupportSchemaNode.getQName(), null,
-                                                                            Boolean.valueOf(true)));
+        streamNodeValues.add(NodeFactory.<Boolean> createImmutableSimpleNode(replaySupportSchemaNode.getQName(), null,
+                Boolean.valueOf(true)));
 
         instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
-                                           ((DataNodeContainer) streamSchemaNode), "replay-log-creation-time");
+                ((DataNodeContainer) streamSchemaNode), "replay-log-creation-time");
         final DataSchemaNode replayLogCreationTimeSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
-        streamNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(replayLogCreationTimeSchemaNode.getQName(),
-                                                                           null, ""));
+        streamNodeValues.add(NodeFactory.<String> createImmutableSimpleNode(replayLogCreationTimeSchemaNode.getQName(),
+                null, ""));
 
         instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
-                                                        ((DataNodeContainer) streamSchemaNode), "events");
+                ((DataNodeContainer) streamSchemaNode), "events");
         final DataSchemaNode eventsSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
-        streamNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(eventsSchemaNode.getQName(),
-                                                                           null, ""));
+        streamNodeValues.add(NodeFactory.<String> createImmutableSimpleNode(eventsSchemaNode.getQName(), null, ""));
 
         return NodeFactory.createImmutableCompositeNode(streamSchemaNode.getQName(), null, streamNodeValues);
     }
 
     private CompositeNode toModuleCompositeNode(final Module module, final DataSchemaNode moduleSchemaNode) {
         final List<Node<?>> moduleNodeValues = new ArrayList<Node<?>>();
-        List<DataSchemaNode> instanceDataChildrenByName =
-            this.controllerContext.findInstanceDataChildrenByName(((DataNodeContainer) moduleSchemaNode), "name");
+        List<DataSchemaNode> instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
+                ((DataNodeContainer) moduleSchemaNode), "name");
         final DataSchemaNode nameSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
-        moduleNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(nameSchemaNode.getQName(),
-                                                                           null, module.getName()));
+        moduleNodeValues.add(NodeFactory.<String> createImmutableSimpleNode(nameSchemaNode.getQName(), null,
+                module.getName()));
 
         instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
-                                                          ((DataNodeContainer) moduleSchemaNode), "revision");
+                ((DataNodeContainer) moduleSchemaNode), "revision");
         final DataSchemaNode revisionSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
         Date _revision = module.getRevision();
-        moduleNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(revisionSchemaNode.getQName(), null,
-                                                                           REVISION_FORMAT.format(_revision)));
+        moduleNodeValues.add(NodeFactory.<String> createImmutableSimpleNode(revisionSchemaNode.getQName(), null,
+                REVISION_FORMAT.format(_revision)));
 
         instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
-                                                        ((DataNodeContainer) moduleSchemaNode), "namespace");
+                ((DataNodeContainer) moduleSchemaNode), "namespace");
         final DataSchemaNode namespaceSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
-        moduleNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(namespaceSchemaNode.getQName(), null,
-                                                                           module.getNamespace().toString()));
+        moduleNodeValues.add(NodeFactory.<String> createImmutableSimpleNode(namespaceSchemaNode.getQName(), null,
+                module.getNamespace().toString()));
 
         instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
-                                                           ((DataNodeContainer) moduleSchemaNode), "feature");
+                ((DataNodeContainer) moduleSchemaNode), "feature");
         final DataSchemaNode featureSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
         for (final FeatureDefinition feature : module.getFeatures()) {
-            moduleNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(featureSchemaNode.getQName(), null,
-                                                                               feature.getQName().getLocalName()));
+            moduleNodeValues.add(NodeFactory.<String> createImmutableSimpleNode(featureSchemaNode.getQName(), null,
+                    feature.getQName().getLocalName()));
         }
 
         return NodeFactory.createImmutableCompositeNode(moduleSchemaNode.getQName(), null, moduleNodeValues);
@@ -386,58 +391,50 @@ public class RestconfImpl implements RestconfService {
     }
 
     @Override
-    public StructuredData invokeRpc(final String identifier, final CompositeNode payload) {
+    public StructuredData invokeRpc(final String identifier, final CompositeNode payload, final UriInfo uriInfo) {
         final RpcExecutor rpc = this.resolveIdentifierInInvokeRpc(identifier);
         QName rpcName = rpc.getRpcDefinition().getQName();
         URI rpcNamespace = rpcName.getNamespace();
-        if (Objects.equal(rpcNamespace.toString(), SAL_REMOTE_NAMESPACE) &&
-            Objects.equal(rpcName.getLocalName(), SAL_REMOTE_RPC_SUBSRCIBE)) {
-            return invokeSalRemoteRpcSubscribeRPC(payload, rpc.getRpcDefinition());
+        if (Objects.equal(rpcNamespace.toString(), SAL_REMOTE_NAMESPACE)
+                && Objects.equal(rpcName.getLocalName(), SAL_REMOTE_RPC_SUBSRCIBE)) {
+            return invokeSalRemoteRpcSubscribeRPC(payload, rpc.getRpcDefinition(), parsePrettyPrintParameter(uriInfo));
         }
 
-        validateInput( rpc.getRpcDefinition().getInput(), payload );
+        validateInput(rpc.getRpcDefinition().getInput(), payload);
 
-        return callRpc(rpc, payload);
+        return callRpc(rpc, payload, parsePrettyPrintParameter(uriInfo));
     }
 
-    private void validateInput(DataSchemaNode inputSchema, CompositeNode payload) {
-        if( inputSchema != null && payload == null )
-        {
-            //expected a non null payload
-            throw new RestconfDocumentedException( "Input is required.",
-                                                   ErrorType.PROTOCOL,
-                                                   ErrorTag.MALFORMED_MESSAGE );
-        }
-        else if( inputSchema == null && payload != null )
-        {
-            //did not expect any input
-            throw new RestconfDocumentedException( "No input expected.",
-                                                   ErrorType.PROTOCOL,
-                                                   ErrorTag.MALFORMED_MESSAGE );
-        }
-        //else
-        //{
-            //TODO: Validate "mandatory" and "config" values here??? Or should those be
+    private void validateInput(final DataSchemaNode inputSchema, final CompositeNode payload) {
+        if (inputSchema != null && payload == null) {
+            // expected a non null payload
+            throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
+        } else if (inputSchema == null && payload != null) {
+            // did not expect any input
+            throw new RestconfDocumentedException("No input expected.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
+        }
+        // else
+        // {
+        // TODO: Validate "mandatory" and "config" values here??? Or should those be
         // validate in a more central location inside MD-SAL core.
-        //}
+        // }
     }
 
-    private StructuredData invokeSalRemoteRpcSubscribeRPC(final CompositeNode payload,
-                                                          final RpcDefinition rpc) {
+    private StructuredData invokeSalRemoteRpcSubscribeRPC(final CompositeNode payload, final RpcDefinition rpc,
+            final boolean prettyPrint) {
         final CompositeNode value = this.normalizeNode(payload, rpc.getInput(), null);
-        final SimpleNode<? extends Object> pathNode = value == null ? null :
-                               value.getFirstSimpleByName( QName.create(rpc.getQName(), "path") );
+        final SimpleNode<? extends Object> pathNode = value == null ? null : value.getFirstSimpleByName(QName.create(
+                rpc.getQName(), "path"));
         final Object pathValue = pathNode == null ? null : pathNode.getValue();
 
-        if (!(pathValue instanceof InstanceIdentifier)) {
-            throw new RestconfDocumentedException(
-                    "Instance identifier was not normalized correctly.",
-                    ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED );
+        if (!(pathValue instanceof YangInstanceIdentifier)) {
+            throw new RestconfDocumentedException("Instance identifier was not normalized correctly.",
+                    ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED);
         }
 
-        final InstanceIdentifier pathIdentifier = ((InstanceIdentifier) pathValue);
+        final YangInstanceIdentifier pathIdentifier = ((YangInstanceIdentifier) pathValue);
         String streamName = null;
-        if (!Iterables.isEmpty(pathIdentifier.getPath())) {
+        if (!Iterables.isEmpty(pathIdentifier.getPathArguments())) {
             String fullRestconfIdentifier = this.controllerContext.toFullRestconfIdentifier(pathIdentifier);
             streamName = Notificator.createStreamNameFromUri(fullRestconfIdentifier);
         }
@@ -445,31 +442,30 @@ public class RestconfImpl implements RestconfService {
         if (Strings.isNullOrEmpty(streamName)) {
             throw new RestconfDocumentedException(
                     "Path is empty or contains data node which is not Container or List build-in type.",
-                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
 
-        final SimpleNode<String> streamNameNode = NodeFactory.<String>createImmutableSimpleNode(
-                             QName.create(rpc.getOutput().getQName(), "stream-name"), null, streamName);
+        final SimpleNode<String> streamNameNode = NodeFactory.<String> createImmutableSimpleNode(
+                QName.create(rpc.getOutput().getQName(), "stream-name"), null, streamName);
         final List<Node<?>> output = new ArrayList<Node<?>>();
         output.add(streamNameNode);
 
-        final MutableCompositeNode responseData = NodeFactory.createMutableCompositeNode(
-                                              rpc.getOutput().getQName(), null, output, null, null);
+        final MutableCompositeNode responseData = NodeFactory.createMutableCompositeNode(rpc.getOutput().getQName(),
+                null, output, null, null);
 
         if (!Notificator.existListenerFor(pathIdentifier)) {
             Notificator.createListener(pathIdentifier, streamName);
         }
 
-        return new StructuredData(responseData, rpc.getOutput(), null);
+        return new StructuredData(responseData, rpc.getOutput(), null, prettyPrint);
     }
 
     @Override
-    public StructuredData invokeRpc(final String identifier, final String noPayload) {
+    public StructuredData invokeRpc(final String identifier, final String noPayload, final UriInfo uriInfo) {
         if (StringUtils.isNotBlank(noPayload)) {
-            throw new RestconfDocumentedException(
-                    "Content must be empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+            throw new RestconfDocumentedException("Content must be empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
-        return invokeRpc( identifier, (CompositeNode)null );
+        return invokeRpc(identifier, (CompositeNode) null, uriInfo);
     }
 
     private RpcExecutor resolveIdentifierInInvokeRpc(final String identifier) {
@@ -477,8 +473,7 @@ public class RestconfImpl implements RestconfService {
         MountInstance mountPoint = null;
         if (identifier.contains(ControllerContext.MOUNT)) {
             // mounted RPC call - look up mount instance.
-            InstanceIdWithSchemaNode mountPointId = controllerContext
-                    .toMountPointIdentifier(identifier);
+            InstanceIdWithSchemaNode mountPointId = controllerContext.toMountPointIdentifier(identifier);
             mountPoint = mountPointId.getMountPoint();
 
             int startOfRemoteRpcName = identifier.lastIndexOf(ControllerContext.MOUNT)
@@ -487,22 +482,24 @@ public class RestconfImpl implements RestconfService {
             identifierEncoded = remoteRpcName;
 
         } else if (identifier.indexOf("/") != CHAR_NOT_FOUND) {
-            final String slashErrorMsg = String
-                    .format("Identifier %n%s%ncan\'t contain slash "
-                            + "character (/).%nIf slash is part of identifier name then use %%2F placeholder.",
-                            identifier);
-            throw new RestconfDocumentedException(
-                    slashErrorMsg, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+            final String slashErrorMsg = String.format("Identifier %n%s%ncan\'t contain slash "
+                    + "character (/).%nIf slash is part of identifier name then use %%2F placeholder.", identifier);
+            throw new RestconfDocumentedException(slashErrorMsg, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         } else {
             identifierEncoded = identifier;
         }
 
         final String identifierDecoded = controllerContext.urlPathArgDecode(identifierEncoded);
-        RpcDefinition rpc = controllerContext.getRpcDefinition(identifierDecoded);
+
+        RpcDefinition rpc = null;
+        if (mountPoint == null) {
+            rpc = controllerContext.getRpcDefinition(identifierDecoded);
+        } else {
+            rpc = findRpc(mountPoint.getSchemaContext(), identifierDecoded);
+        }
 
         if (rpc == null) {
-            throw new RestconfDocumentedException(
-                    "RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT );
+            throw new RestconfDocumentedException("RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT);
         }
 
         if (mountPoint == null) {
@@ -513,10 +510,28 @@ public class RestconfImpl implements RestconfService {
 
     }
 
-    private StructuredData callRpc(final RpcExecutor rpcExecutor, final CompositeNode payload) {
+    private RpcDefinition findRpc(final SchemaContext schemaContext, final String identifierDecoded) {
+        final String[] splittedIdentifier = identifierDecoded.split(":");
+        if (splittedIdentifier.length != 2) {
+            throw new RestconfDocumentedException(identifierDecoded
+                    + " couldn't be splitted to 2 parts (module:rpc name)", ErrorType.APPLICATION,
+                    ErrorTag.INVALID_VALUE);
+        }
+        for (Module module : schemaContext.getModules()) {
+            if (module.getName().equals(splittedIdentifier[0])) {
+                for (RpcDefinition rpcDefinition : module.getRpcs()) {
+                    if (rpcDefinition.getQName().getLocalName().equals(splittedIdentifier[1])) {
+                        return rpcDefinition;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private StructuredData callRpc(final RpcExecutor rpcExecutor, final CompositeNode payload, boolean prettyPrint) {
         if (rpcExecutor == null) {
-            throw new RestconfDocumentedException(
-                    "RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT );
+            throw new RestconfDocumentedException("RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT);
         }
 
         CompositeNode rpcRequest = null;
@@ -539,108 +554,109 @@ public class RestconfImpl implements RestconfService {
             return null;
         }
 
-        if( rpc.getOutput() == null )
-        {
-            return null; //no output, nothing to send back.
+        if (rpc.getOutput() == null) {
+            return null; // no output, nothing to send back.
         }
 
-        return new StructuredData(rpcResult.getResult(), rpc.getOutput(), null);
+        return new StructuredData(rpcResult.getResult(), rpc.getOutput(), null, prettyPrint);
     }
 
-    private void checkRpcSuccessAndThrowException(RpcResult<CompositeNode> rpcResult) {
+    private void checkRpcSuccessAndThrowException(final RpcResult<CompositeNode> rpcResult) {
         if (rpcResult.isSuccessful() == false) {
 
             Collection<RpcError> rpcErrors = rpcResult.getErrors();
-            if( rpcErrors == null || rpcErrors.isEmpty() ) {
+            if (rpcErrors == null || rpcErrors.isEmpty()) {
                 throw new RestconfDocumentedException(
-                    "The operation was not successful and there were no RPC errors returned",
-                    ErrorType.RPC, ErrorTag.OPERATION_FAILED );
+                        "The operation was not successful and there were no RPC errors returned", ErrorType.RPC,
+                        ErrorTag.OPERATION_FAILED);
             }
 
             List<RestconfError> errorList = Lists.newArrayList();
-            for( RpcError rpcError: rpcErrors ) {
-                errorList.add( new RestconfError( rpcError ) );
+            for (RpcError rpcError : rpcErrors) {
+                errorList.add(new RestconfError(rpcError));
             }
 
-            throw new RestconfDocumentedException( errorList );
+            throw new RestconfDocumentedException(errorList);
         }
     }
 
     @Override
-    public StructuredData readConfigurationData(final String identifier, UriInfo info) {
+    public StructuredData readConfigurationData(final String identifier, final UriInfo uriInfo) {
         final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
         CompositeNode data = null;
         MountInstance mountPoint = iiWithData.getMountPoint();
         if (mountPoint != null) {
             data = broker.readConfigurationDataBehindMountPoint(mountPoint, iiWithData.getInstanceIdentifier());
-        }
-        else {
+        } else {
             data = broker.readConfigurationData(iiWithData.getInstanceIdentifier());
         }
 
-        data = pruneDataAtDepth( data, parseDepthParameter( info ) );
-        return new StructuredData(data, iiWithData.getSchemaNode(), iiWithData.getMountPoint());
+        data = pruneDataAtDepth(data, parseDepthParameter(uriInfo));
+        boolean prettyPrintMode = parsePrettyPrintParameter(uriInfo);
+        return new StructuredData(data, iiWithData.getSchemaNode(), iiWithData.getMountPoint(), prettyPrintMode);
     }
 
     @SuppressWarnings("unchecked")
-    private <T extends Node<?>> T pruneDataAtDepth( T node, Integer depth ) {
-        if( depth == null ) {
+    private <T extends Node<?>> T pruneDataAtDepth(final T node, final Integer depth) {
+        if (depth == null) {
             return node;
         }
 
-        if( node instanceof CompositeNode ) {
+        if (node instanceof CompositeNode) {
             ImmutableList.Builder<Node<?>> newChildNodes = ImmutableList.<Node<?>> builder();
-            if( depth > 1 ) {
-                for( Node<?> childNode: ((CompositeNode)node).getValue() ) {
-                    newChildNodes.add( pruneDataAtDepth( childNode, depth - 1 ) );
+            if (depth > 1) {
+                for (Node<?> childNode : ((CompositeNode) node).getValue()) {
+                    newChildNodes.add(pruneDataAtDepth(childNode, depth - 1));
                 }
             }
 
-            return (T) ImmutableCompositeNode.create( node.getNodeType(), newChildNodes.build() );
-        }
-        else { // SimpleNode
+            return (T) ImmutableCompositeNode.create(node.getNodeType(), newChildNodes.build());
+        } else { // SimpleNode
             return node;
         }
     }
 
-    private Integer parseDepthParameter( UriInfo info ) {
-        String param = info.getQueryParameters( false ).getFirst( "depth" );
-        if( Strings.isNullOrEmpty( param ) || "unbounded".equals( param ) ) {
+    private Integer parseDepthParameter(final UriInfo info) {
+        String param = info.getQueryParameters(false).getFirst(UriParameters.DEPTH.toString());
+        if (Strings.isNullOrEmpty(param) || "unbounded".equals(param)) {
             return null;
         }
 
         try {
-            Integer depth = Integer.valueOf( param );
-            if( depth < 1 ) {
-                throw new RestconfDocumentedException( new RestconfError(
-                        ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Invalid depth parameter: " + depth,
-                        null, "The depth parameter must be an integer > 1 or \"unbounded\"" ) );
+            Integer depth = Integer.valueOf(param);
+            if (depth < 1) {
+                throw new RestconfDocumentedException(new RestconfError(ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
+                        "Invalid depth parameter: " + depth, null,
+                        "The depth parameter must be an integer > 1 or \"unbounded\""));
             }
 
             return depth;
-        }
-        catch( NumberFormatException e ) {
-            throw new RestconfDocumentedException( new RestconfError(
-                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
-                    "Invalid depth parameter: " + e.getMessage(),
-                    null, "The depth parameter must be an integer > 1 or \"unbounded\"" ) );
+        } catch (NumberFormatException e) {
+            throw new RestconfDocumentedException(new RestconfError(ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
+                    "Invalid depth parameter: " + e.getMessage(), null,
+                    "The depth parameter must be an integer > 1 or \"unbounded\""));
         }
     }
 
     @Override
-    public StructuredData readOperationalData(final String identifier, UriInfo info) {
+    public StructuredData readOperationalData(final String identifier, final UriInfo info) {
         final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
         CompositeNode data = null;
         MountInstance mountPoint = iiWithData.getMountPoint();
         if (mountPoint != null) {
             data = broker.readOperationalDataBehindMountPoint(mountPoint, iiWithData.getInstanceIdentifier());
-        }
-        else {
+        } else {
             data = broker.readOperationalData(iiWithData.getInstanceIdentifier());
         }
 
-        data = pruneDataAtDepth( data, parseDepthParameter( info ) );
-        return new StructuredData(data, iiWithData.getSchemaNode(), mountPoint);
+        data = pruneDataAtDepth(data, parseDepthParameter(info));
+        boolean prettyPrintMode = parsePrettyPrintParameter(info);
+        return new StructuredData(data, iiWithData.getSchemaNode(), mountPoint, prettyPrintMode);
+    }
+
+    private boolean parsePrettyPrintParameter(UriInfo info) {
+        String param = info.getQueryParameters(false).getFirst(UriParameters.PRETTY_PRINT.toString());
+        return Boolean.parseBoolean(param);
     }
 
     @Override
@@ -651,73 +667,114 @@ public class RestconfImpl implements RestconfService {
 
         MountInstance mountPoint = iiWithData.getMountPoint();
         final CompositeNode value = this.normalizeNode(payload, iiWithData.getSchemaNode(), mountPoint);
+        validateListKeysEqualityInPayloadAndUri(iiWithData, payload);
         RpcResult<TransactionStatus> status = null;
 
         try {
             if (mountPoint != null) {
-                status = broker.commitConfigurationDataPutBehindMountPoint(
-                                                mountPoint, iiWithData.getInstanceIdentifier(), value).get();
+                status = broker.commitConfigurationDataPutBehindMountPoint(mountPoint,
+                        iiWithData.getInstanceIdentifier(), value).get();
             } else {
                 status = broker.commitConfigurationDataPut(iiWithData.getInstanceIdentifier(), value).get();
             }
-        }
-        catch( Exception e ) {
-            throw new RestconfDocumentedException( "Error updating data", e );
+        } catch (Exception e) {
+            throw new RestconfDocumentedException("Error updating data", e);
         }
 
-        if( status.getResult() == TransactionStatus.COMMITED )
+        if (status.getResult() == TransactionStatus.COMMITED) {
             return Response.status(Status.OK).build();
+        }
 
         return Response.status(Status.INTERNAL_SERVER_ERROR).build();
     }
 
+    /**
+     * Validates whether keys in {@code payload} are equal to values of keys in {@code iiWithData} for list schema node
+     *
+     * @throws RestconfDocumentedException
+     *             if key values or key count in payload and URI isn't equal
+     *
+     */
+    private void validateListKeysEqualityInPayloadAndUri(final InstanceIdWithSchemaNode iiWithData,
+            final CompositeNode payload) {
+        if (iiWithData.getSchemaNode() instanceof ListSchemaNode) {
+            final List<QName> keyDefinitions = ((ListSchemaNode) iiWithData.getSchemaNode()).getKeyDefinition();
+            final PathArgument lastPathArgument = iiWithData.getInstanceIdentifier().getLastPathArgument();
+            if (lastPathArgument instanceof NodeIdentifierWithPredicates) {
+                final Map<QName, Object> uriKeyValues = ((NodeIdentifierWithPredicates) lastPathArgument)
+                        .getKeyValues();
+                isEqualUriAndPayloadKeyValues(uriKeyValues, payload, keyDefinitions);
+            }
+        }
+    }
+
+    private void isEqualUriAndPayloadKeyValues(final Map<QName, Object> uriKeyValues, final CompositeNode payload,
+            final List<QName> keyDefinitions) {
+        for (QName keyDefinition : keyDefinitions) {
+            final Object uriKeyValue = uriKeyValues.get(keyDefinition);
+            // should be caught during parsing URI to InstanceIdentifier
+            if (uriKeyValue == null) {
+                throw new RestconfDocumentedException("Missing key " + keyDefinition + " in URI.", ErrorType.PROTOCOL,
+                        ErrorTag.DATA_MISSING);
+            }
+            final List<SimpleNode<?>> payloadKeyValues = payload.getSimpleNodesByName(keyDefinition.getLocalName());
+            if (payloadKeyValues.isEmpty()) {
+                throw new RestconfDocumentedException("Missing key " + keyDefinition.getLocalName()
+                        + " in the message body.", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
+            }
+
+            Object payloadKeyValue = payloadKeyValues.iterator().next().getValue();
+            if (!uriKeyValue.equals(payloadKeyValue)) {
+                throw new RestconfDocumentedException("The value '" + uriKeyValue + "' for key '"
+                        + keyDefinition.getLocalName() + "' specified in the URI doesn't match the value '"
+                        + payloadKeyValue + "' specified in the message body. ", ErrorType.PROTOCOL,
+                        ErrorTag.INVALID_VALUE);
+            }
+        }
+    }
+
     @Override
     public Response createConfigurationData(final String identifier, final CompositeNode payload) {
-        if( payload == null ) {
-            throw new RestconfDocumentedException( "Input is required.",
-                    ErrorType.PROTOCOL,
-                    ErrorTag.MALFORMED_MESSAGE );
+        if (payload == null) {
+            throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
         }
 
         URI payloadNS = this.namespace(payload);
         if (payloadNS == null) {
             throw new RestconfDocumentedException(
-                 "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)",
-                 ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE );
+                    "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)",
+                    ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE);
         }
 
         InstanceIdWithSchemaNode iiWithData = null;
         CompositeNode value = null;
         if (this.representsMountPointRootData(payload)) {
-             // payload represents mount point data and URI represents path to the mount point
+            // payload represents mount point data and URI represents path to the mount point
 
             if (this.endsWithMountPoint(identifier)) {
-                throw new RestconfDocumentedException(
-                        "URI has bad format. URI should be without \"" + ControllerContext.MOUNT +
-                        "\" for POST operation.",
-                        ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                throw new RestconfDocumentedException("URI has bad format. URI should be without \""
+                        + ControllerContext.MOUNT + "\" for POST operation.", ErrorType.PROTOCOL,
+                        ErrorTag.INVALID_VALUE);
             }
 
             final String completeIdentifier = this.addMountPointIdentifier(identifier);
             iiWithData = this.controllerContext.toInstanceIdentifier(completeIdentifier);
 
             value = this.normalizeNode(payload, iiWithData.getSchemaNode(), iiWithData.getMountPoint());
-        }
-        else {
-            final InstanceIdWithSchemaNode incompleteInstIdWithData =
-                                               this.controllerContext.toInstanceIdentifier(identifier);
+        } else {
+            final InstanceIdWithSchemaNode incompleteInstIdWithData = this.controllerContext
+                    .toInstanceIdentifier(identifier);
             final DataNodeContainer parentSchema = (DataNodeContainer) incompleteInstIdWithData.getSchemaNode();
             MountInstance mountPoint = incompleteInstIdWithData.getMountPoint();
             final Module module = this.findModule(mountPoint, payload);
             if (module == null) {
-                throw new RestconfDocumentedException(
-                        "Module was not found for \"" + payloadNS + "\"",
-                        ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT );
+                throw new RestconfDocumentedException("Module was not found for \"" + payloadNS + "\"",
+                        ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
             }
 
             String payloadName = this.getName(payload);
             final DataSchemaNode schemaNode = this.controllerContext.findInstanceDataChildByNameAndNamespace(
-                                                              parentSchema, payloadName, module.getNamespace());
+                    parentSchema, payloadName, module.getNamespace());
             value = this.normalizeNode(payload, schemaNode, mountPoint);
 
             iiWithData = this.addLastIdentifierFromData(incompleteInstIdWithData, value, schemaNode);
@@ -727,56 +784,52 @@ public class RestconfImpl implements RestconfService {
         MountInstance mountPoint = iiWithData.getMountPoint();
         try {
             if (mountPoint != null) {
-                Future<RpcResult<TransactionStatus>> future =
-                                          broker.commitConfigurationDataPostBehindMountPoint(
-                                                       mountPoint, iiWithData.getInstanceIdentifier(), value);
+                Future<RpcResult<TransactionStatus>> future = broker.commitConfigurationDataPostBehindMountPoint(
+                        mountPoint, iiWithData.getInstanceIdentifier(), value);
                 status = future == null ? null : future.get();
-            }
-            else {
-                Future<RpcResult<TransactionStatus>> future =
-                               broker.commitConfigurationDataPost(iiWithData.getInstanceIdentifier(), value);
+            } else {
+                Future<RpcResult<TransactionStatus>> future = broker.commitConfigurationDataPost(
+                        iiWithData.getInstanceIdentifier(), value);
                 status = future == null ? null : future.get();
             }
-        }
-        catch( Exception e ) {
-            throw new RestconfDocumentedException( "Error creating data", e );
+        } catch (Exception e) {
+            throw new RestconfDocumentedException("Error creating data", e);
         }
 
         if (status == null) {
             return Response.status(Status.ACCEPTED).build();
         }
 
-        if( status.getResult() == TransactionStatus.COMMITED )
+        if (status.getResult() == TransactionStatus.COMMITED) {
             return Response.status(Status.NO_CONTENT).build();
+        }
 
         return Response.status(Status.INTERNAL_SERVER_ERROR).build();
     }
 
     @Override
     public Response createConfigurationData(final CompositeNode payload) {
-        if( payload == null ) {
-            throw new RestconfDocumentedException( "Input is required.",
-                    ErrorType.PROTOCOL,
-                    ErrorTag.MALFORMED_MESSAGE );
+        if (payload == null) {
+            throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
         }
 
         URI payloadNS = this.namespace(payload);
         if (payloadNS == null) {
             throw new RestconfDocumentedException(
-                "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)",
-                ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE );
+                    "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)",
+                    ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE);
         }
 
         final Module module = this.findModule(null, payload);
         if (module == null) {
             throw new RestconfDocumentedException(
                     "Data has bad format. Root element node has incorrect namespace (XML format) or module name(JSON format)",
-                    ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE );
+                    ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE);
         }
 
         String payloadName = this.getName(payload);
-        final DataSchemaNode schemaNode = this.controllerContext.findInstanceDataChildByNameAndNamespace(
-                                                                   module, payloadName, module.getNamespace());
+        final DataSchemaNode schemaNode = this.controllerContext.findInstanceDataChildByNameAndNamespace(module,
+                payloadName, module.getNamespace());
         final CompositeNode value = this.normalizeNode(payload, schemaNode, null);
         final InstanceIdWithSchemaNode iiWithData = this.addLastIdentifierFromData(null, value, schemaNode);
         RpcResult<TransactionStatus> status = null;
@@ -784,27 +837,25 @@ public class RestconfImpl implements RestconfService {
 
         try {
             if (mountPoint != null) {
-                Future<RpcResult<TransactionStatus>> future =
-                                             broker.commitConfigurationDataPostBehindMountPoint(
-                                                          mountPoint, iiWithData.getInstanceIdentifier(), value);
+                Future<RpcResult<TransactionStatus>> future = broker.commitConfigurationDataPostBehindMountPoint(
+                        mountPoint, iiWithData.getInstanceIdentifier(), value);
                 status = future == null ? null : future.get();
-            }
-            else {
-                Future<RpcResult<TransactionStatus>> future =
-                                 broker.commitConfigurationDataPost(iiWithData.getInstanceIdentifier(), value);
+            } else {
+                Future<RpcResult<TransactionStatus>> future = broker.commitConfigurationDataPost(
+                        iiWithData.getInstanceIdentifier(), value);
                 status = future == null ? null : future.get();
             }
-        }
-        catch( Exception e ) {
-            throw new RestconfDocumentedException( "Error creating data", e );
+        } catch (Exception e) {
+            throw new RestconfDocumentedException("Error creating data", e);
         }
 
         if (status == null) {
             return Response.status(Status.ACCEPTED).build();
         }
 
-        if( status.getResult() == TransactionStatus.COMMITED )
+        if (status.getResult() == TransactionStatus.COMMITED) {
             return Response.status(Status.NO_CONTENT).build();
+        }
 
         return Response.status(Status.INTERNAL_SERVER_ERROR).build();
     }
@@ -817,19 +868,18 @@ public class RestconfImpl implements RestconfService {
 
         try {
             if (mountPoint != null) {
-                status = broker.commitConfigurationDataDeleteBehindMountPoint(
-                                        mountPoint, iiWithData.getInstanceIdentifier()).get();
-            }
-            else {
+                status = broker.commitConfigurationDataDeleteBehindMountPoint(mountPoint,
+                        iiWithData.getInstanceIdentifier()).get();
+            } else {
                 status = broker.commitConfigurationDataDelete(iiWithData.getInstanceIdentifier()).get();
             }
-        }
-        catch( Exception e ) {
-            throw new RestconfDocumentedException( "Error creating data", e );
+        } catch (Exception e) {
+            throw new RestconfDocumentedException("Error creating data", e);
         }
 
-        if( status.getResult() == TransactionStatus.COMMITED )
+        if (status.getResult() == TransactionStatus.COMMITED) {
             return Response.status(Status.OK).build();
+        }
 
         return Response.status(Status.INTERNAL_SERVER_ERROR).build();
     }
@@ -838,20 +888,18 @@ public class RestconfImpl implements RestconfService {
     public Response subscribeToStream(final String identifier, final UriInfo uriInfo) {
         final String streamName = Notificator.createStreamNameFromUri(identifier);
         if (Strings.isNullOrEmpty(streamName)) {
-            throw new RestconfDocumentedException(
-                    "Stream name is empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+            throw new RestconfDocumentedException("Stream name is empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
 
         final ListenerAdapter listener = Notificator.getListenerFor(streamName);
         if (listener == null) {
-            throw new RestconfDocumentedException(
-                    "Stream was not found.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT );
+            throw new RestconfDocumentedException("Stream was not found.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
         }
 
         broker.registerToListenDataChanges(listener);
 
         final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
-        UriBuilder port = uriBuilder.port(WebSocketServer.PORT);
+        UriBuilder port = uriBuilder.port(WebSocketServer.getInstance().getPort());
         final URI uriToWebsocketServer = port.replacePath(streamName).build();
 
         return Response.status(Status.OK).location(uriToWebsocketServer).build();
@@ -859,26 +907,23 @@ public class RestconfImpl implements RestconfService {
 
     private Module findModule(final MountInstance mountPoint, final CompositeNode data) {
         if (data instanceof CompositeNodeWrapper) {
-            return findModule(mountPoint, (CompositeNodeWrapper)data);
-        }
-        else if (data != null) {
+            return findModule(mountPoint, (CompositeNodeWrapper) data);
+        } else if (data != null) {
             URI namespace = data.getNodeType().getNamespace();
             if (mountPoint != null) {
                 return this.controllerContext.findModuleByNamespace(mountPoint, namespace);
-            }
-            else {
+            } else {
                 return this.controllerContext.findModuleByNamespace(namespace);
             }
-        }
-        else {
-            throw new IllegalArgumentException("Unhandled parameter types: " +
-                    Arrays.<Object>asList(mountPoint, data).toString());
+        } else {
+            throw new IllegalArgumentException("Unhandled parameter types: "
+                    + Arrays.<Object> asList(mountPoint, data).toString());
         }
     }
 
     private Module findModule(final MountInstance mountPoint, final CompositeNodeWrapper data) {
         URI namespace = data.getNamespace();
-        Preconditions.<URI>checkNotNull(namespace);
+        Preconditions.<URI> checkNotNull(namespace);
 
         Module module = null;
         if (mountPoint != null) {
@@ -886,8 +931,7 @@ public class RestconfImpl implements RestconfService {
             if (module == null) {
                 module = this.controllerContext.findModuleByName(mountPoint, namespace.toString());
             }
-        }
-        else {
+        } else {
             module = this.controllerContext.findModuleByNamespace(namespace);
             if (module == null) {
                 module = this.controllerContext.findModuleByName(namespace.toString());
@@ -897,43 +941,39 @@ public class RestconfImpl implements RestconfService {
         return module;
     }
 
-    private InstanceIdWithSchemaNode addLastIdentifierFromData(
-                                              final InstanceIdWithSchemaNode identifierWithSchemaNode,
-                                              final CompositeNode data, final DataSchemaNode schemaOfData) {
-        InstanceIdentifier instanceIdentifier = null;
+    private InstanceIdWithSchemaNode addLastIdentifierFromData(final InstanceIdWithSchemaNode identifierWithSchemaNode,
+            final CompositeNode data, final DataSchemaNode schemaOfData) {
+        YangInstanceIdentifier instanceIdentifier = null;
         if (identifierWithSchemaNode != null) {
             instanceIdentifier = identifierWithSchemaNode.getInstanceIdentifier();
         }
 
-        final InstanceIdentifier iiOriginal = instanceIdentifier;
+        final YangInstanceIdentifier iiOriginal = instanceIdentifier;
         InstanceIdentifierBuilder iiBuilder = null;
         if (iiOriginal == null) {
-            iiBuilder = InstanceIdentifier.builder();
-        }
-        else {
-            iiBuilder = InstanceIdentifier.builder(iiOriginal);
+            iiBuilder = YangInstanceIdentifier.builder();
+        } else {
+            iiBuilder = YangInstanceIdentifier.builder(iiOriginal);
         }
 
         if ((schemaOfData instanceof ListSchemaNode)) {
-            HashMap<QName,Object> keys = this.resolveKeysFromData(((ListSchemaNode) schemaOfData), data);
+            HashMap<QName, Object> keys = this.resolveKeysFromData(((ListSchemaNode) schemaOfData), data);
             iiBuilder.nodeWithKey(schemaOfData.getQName(), keys);
-        }
-        else {
+        } else {
             iiBuilder.node(schemaOfData.getQName());
         }
 
-        InstanceIdentifier instance = iiBuilder.toInstance();
+        YangInstanceIdentifier instance = iiBuilder.toInstance();
         MountInstance mountPoint = null;
         if (identifierWithSchemaNode != null) {
-            mountPoint=identifierWithSchemaNode.getMountPoint();
+            mountPoint = identifierWithSchemaNode.getMountPoint();
         }
 
         return new InstanceIdWithSchemaNode(instance, schemaOfData, mountPoint);
     }
 
-    private HashMap<QName,Object> resolveKeysFromData(final ListSchemaNode listNode,
-                                                      final CompositeNode dataNode) {
-        final HashMap<QName,Object> keyValues = new HashMap<QName, Object>();
+    private HashMap<QName, Object> resolveKeysFromData(final ListSchemaNode listNode, final CompositeNode dataNode) {
+        final HashMap<QName, Object> keyValues = new HashMap<QName, Object>();
         List<QName> _keyDefinition = listNode.getKeyDefinition();
         for (final QName key : _keyDefinition) {
             SimpleNode<? extends Object> head = null;
@@ -949,10 +989,9 @@ public class RestconfImpl implements RestconfService {
             }
 
             if (dataNodeKeyValueObject == null) {
-                throw new RestconfDocumentedException(
-                        "Data contains list \"" + dataNode.getNodeType().getLocalName() +
-                        "\" which does not contain key: \"" + key.getLocalName() + "\"",
-                        ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                throw new RestconfDocumentedException("Data contains list \"" + dataNode.getNodeType().getLocalName()
+                        + "\" which does not contain key: \"" + key.getLocalName() + "\"", ErrorType.PROTOCOL,
+                        ErrorTag.INVALID_VALUE);
             }
 
             keyValues.put(key, dataNodeKeyValueObject);
@@ -962,15 +1001,16 @@ public class RestconfImpl implements RestconfService {
     }
 
     private boolean endsWithMountPoint(final String identifier) {
-        return identifier.endsWith(ControllerContext.MOUNT) ||
-               identifier.endsWith(ControllerContext.MOUNT + "/");
+        return identifier.endsWith(ControllerContext.MOUNT) || identifier.endsWith(ControllerContext.MOUNT + "/");
     }
 
     private boolean representsMountPointRootData(final CompositeNode data) {
         URI namespace = this.namespace(data);
-        return (SchemaContext.NAME.getNamespace().equals( namespace ) /* ||
-                MOUNT_POINT_MODULE_NAME.equals( namespace.toString() )*/ ) &&
-                SchemaContext.NAME.getLocalName().equals( this.localName(data) );
+        return (SchemaContext.NAME.getNamespace().equals(namespace) /*
+                                                                     * || MOUNT_POINT_MODULE_NAME .equals( namespace .
+                                                                     * toString( ) )
+                                                                     */)
+                && SchemaContext.NAME.getLocalName().equals(this.localName(data));
     }
 
     private String addMountPointIdentifier(final String identifier) {
@@ -983,20 +1023,18 @@ public class RestconfImpl implements RestconfService {
     }
 
     private CompositeNode normalizeNode(final CompositeNode node, final DataSchemaNode schema,
-                                        final MountInstance mountPoint) {
+            final MountInstance mountPoint) {
         if (schema == null) {
             QName nodeType = node == null ? null : node.getNodeType();
             String localName = nodeType == null ? null : nodeType.getLocalName();
 
-            throw new RestconfDocumentedException(
-                    "Data schema node was not found for " + localName,
-                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+            throw new RestconfDocumentedException("Data schema node was not found for " + localName,
+                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
 
         if (!(schema instanceof DataNodeContainer)) {
-            throw new RestconfDocumentedException(
-                    "Root element has to be container or list yang datatype.",
-                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+            throw new RestconfDocumentedException("Root element has to be container or list yang datatype.",
+                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
 
         if ((node instanceof CompositeNodeWrapper)) {
@@ -1004,10 +1042,8 @@ public class RestconfImpl implements RestconfService {
             if (isChangeAllowed) {
                 try {
                     this.normalizeNode(((CompositeNodeWrapper) node), schema, null, mountPoint);
-                }
-                catch (IllegalArgumentException e) {
-                    throw new RestconfDocumentedException(
-                                    e.getMessage(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                } catch (IllegalArgumentException e) {
+                    throw new RestconfDocumentedException(e.getMessage(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
                 }
             }
 
@@ -1017,66 +1053,56 @@ public class RestconfImpl implements RestconfService {
         return node;
     }
 
-    private void normalizeNode(final NodeWrapper<? extends Object> nodeBuilder,
-                               final DataSchemaNode schema, final QName previousAugment,
-                               final MountInstance mountPoint) {
+    private void normalizeNode(final NodeWrapper<? extends Object> nodeBuilder, final DataSchemaNode schema,
+            final QName previousAugment, final MountInstance mountPoint) {
         if (schema == null) {
-            throw new RestconfDocumentedException(
-                    "Data has bad format.\n\"" + nodeBuilder.getLocalName() +
-                    "\" does not exist in yang schema.",
-                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+            throw new RestconfDocumentedException("Data has bad format.\n\"" + nodeBuilder.getLocalName()
+                    + "\" does not exist in yang schema.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
 
         QName currentAugment = null;
         if (nodeBuilder.getQname() != null) {
             currentAugment = previousAugment;
-        }
-        else {
+        } else {
             currentAugment = this.normalizeNodeName(nodeBuilder, schema, previousAugment, mountPoint);
             if (nodeBuilder.getQname() == null) {
                 throw new RestconfDocumentedException(
-                        "Data has bad format.\nIf data is in XML format then namespace for \"" +
-                        nodeBuilder.getLocalName() +
-                        "\" should be \"" + schema.getQName().getNamespace() + "\".\n" +
-                        "If data is in JSON format then module name for \"" + nodeBuilder.getLocalName() +
-                         "\" should be corresponding to namespace \"" +
-                        schema.getQName().getNamespace() + "\".",
-                        ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                        "Data has bad format.\nIf data is in XML format then namespace for \""
+                                + nodeBuilder.getLocalName() + "\" should be \"" + schema.getQName().getNamespace()
+                                + "\".\n" + "If data is in JSON format then module name for \""
+                                + nodeBuilder.getLocalName() + "\" should be corresponding to namespace \""
+                                + schema.getQName().getNamespace() + "\".", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
             }
         }
 
-        if ( nodeBuilder instanceof CompositeNodeWrapper ) {
-            if( schema instanceof DataNodeContainer ) {
-                normalizeCompositeNode( (CompositeNodeWrapper)nodeBuilder, (DataNodeContainer)schema,
-                                        mountPoint, currentAugment );
+        if (nodeBuilder instanceof CompositeNodeWrapper) {
+            if (schema instanceof DataNodeContainer) {
+                normalizeCompositeNode((CompositeNodeWrapper) nodeBuilder, (DataNodeContainer) schema, mountPoint,
+                        currentAugment);
+            } else if (schema instanceof AnyXmlSchemaNode) {
+                normalizeAnyXmlNode((CompositeNodeWrapper) nodeBuilder, (AnyXmlSchemaNode) schema);
             }
-            else if( schema instanceof AnyXmlSchemaNode ) {
-                normalizeAnyXmlNode( (CompositeNodeWrapper)nodeBuilder, (AnyXmlSchemaNode)schema );
-            }
-        }
-        else if ( nodeBuilder instanceof SimpleNodeWrapper ) {
-            normalizeSimpleNode( (SimpleNodeWrapper) nodeBuilder, schema, mountPoint );
-        }
-        else if ((nodeBuilder instanceof EmptyNodeWrapper)) {
-            normalizeEmptyNode( (EmptyNodeWrapper) nodeBuilder, schema );
+        } else if (nodeBuilder instanceof SimpleNodeWrapper) {
+            normalizeSimpleNode((SimpleNodeWrapper) nodeBuilder, schema, mountPoint);
+        } else if ((nodeBuilder instanceof EmptyNodeWrapper)) {
+            normalizeEmptyNode((EmptyNodeWrapper) nodeBuilder, schema);
         }
     }
 
-    private void normalizeAnyXmlNode( CompositeNodeWrapper compositeNode, AnyXmlSchemaNode schema ) {
+    private void normalizeAnyXmlNode(final CompositeNodeWrapper compositeNode, final AnyXmlSchemaNode schema) {
         List<NodeWrapper<?>> children = compositeNode.getValues();
-        for( NodeWrapper<? extends Object> child : children ) {
-            child.setNamespace( schema.getQName().getNamespace() );
-            if( child instanceof CompositeNodeWrapper ) {
-                normalizeAnyXmlNode( (CompositeNodeWrapper)child, schema );
+        for (NodeWrapper<? extends Object> child : children) {
+            child.setNamespace(schema.getQName().getNamespace());
+            if (child instanceof CompositeNodeWrapper) {
+                normalizeAnyXmlNode((CompositeNodeWrapper) child, schema);
             }
         }
     }
 
-    private void normalizeEmptyNode( EmptyNodeWrapper emptyNodeBuilder, DataSchemaNode schema ) {
+    private void normalizeEmptyNode(final EmptyNodeWrapper emptyNodeBuilder, final DataSchemaNode schema) {
         if ((schema instanceof LeafSchemaNode)) {
             emptyNodeBuilder.setComposite(false);
-        }
-        else {
+        } else {
             if ((schema instanceof ContainerSchemaNode)) {
                 // FIXME: Add presence check
                 emptyNodeBuilder.setComposite(true);
@@ -1084,58 +1110,55 @@ public class RestconfImpl implements RestconfService {
         }
     }
 
-    private void normalizeSimpleNode( SimpleNodeWrapper simpleNode, DataSchemaNode schema,
-                                      MountInstance mountPoint ) {
+    private void normalizeSimpleNode(final SimpleNodeWrapper simpleNode, final DataSchemaNode schema,
+            final MountInstance mountPoint) {
         final Object value = simpleNode.getValue();
         Object inputValue = value;
         TypeDefinition<? extends Object> typeDefinition = this.typeDefinition(schema);
         if ((typeDefinition instanceof IdentityrefTypeDefinition)) {
             if ((value instanceof String)) {
-                inputValue = new IdentityValuesDTO( simpleNode.getNamespace().toString(),
-                        (String) value, null, (String) value );
+                inputValue = new IdentityValuesDTO(simpleNode.getNamespace().toString(), (String) value, null,
+                        (String) value);
             } // else value is already instance of IdentityValuesDTO
         }
 
         Object outputValue = inputValue;
 
-        if( typeDefinition != null ) {
-            Codec<Object,Object> codec = RestCodec.from(typeDefinition, mountPoint);
+        if (typeDefinition != null) {
+            Codec<Object, Object> codec = RestCodec.from(typeDefinition, mountPoint);
             outputValue = codec == null ? null : codec.deserialize(inputValue);
         }
 
         simpleNode.setValue(outputValue);
     }
 
-    private void normalizeCompositeNode( CompositeNodeWrapper compositeNodeBuilder,
-                                         DataNodeContainer schema, MountInstance mountPoint,
-                                         QName currentAugment ) {
+    private void normalizeCompositeNode(final CompositeNodeWrapper compositeNodeBuilder,
+            final DataNodeContainer schema, final MountInstance mountPoint, final QName currentAugment) {
         final List<NodeWrapper<?>> children = compositeNodeBuilder.getValues();
+        checkNodeMultiplicityAccordingToSchema(schema, children);
         for (final NodeWrapper<? extends Object> child : children) {
-            final List<DataSchemaNode> potentialSchemaNodes =
-                    this.controllerContext.findInstanceDataChildrenByName(
-                                                           schema, child.getLocalName());
+            final List<DataSchemaNode> potentialSchemaNodes = this.controllerContext.findInstanceDataChildrenByName(
+                    schema, child.getLocalName());
 
             if (potentialSchemaNodes.size() > 1 && child.getNamespace() == null) {
                 StringBuilder builder = new StringBuilder();
                 for (final DataSchemaNode potentialSchemaNode : potentialSchemaNodes) {
-                    builder.append("   ").append(potentialSchemaNode.getQName().getNamespace().toString())
-                           .append("\n");
+                    builder.append("   ").append(potentialSchemaNode.getQName().getNamespace().toString()).append("\n");
                 }
 
-                throw new RestconfDocumentedException(
-                             "Node \"" + child.getLocalName() +
-                             "\" is added as augment from more than one module. " +
-                             "Therefore node must have namespace (XML format) or module name (JSON format)." +
-                             "\nThe node is added as augment from modules with namespaces:\n" + builder,
-                             ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                throw new RestconfDocumentedException("Node \"" + child.getLocalName()
+                        + "\" is added as augment from more than one module. "
+                        + "Therefore node must have namespace (XML format) or module name (JSON format)."
+                        + "\nThe node is added as augment from modules with namespaces:\n" + builder,
+                        ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
             }
 
             boolean rightNodeSchemaFound = false;
             for (final DataSchemaNode potentialSchemaNode : potentialSchemaNodes) {
                 if (!rightNodeSchemaFound) {
-                    final QName potentialCurrentAugment =
-                            this.normalizeNodeName(child, potentialSchemaNode, currentAugment, mountPoint);
-                    if (child.getQname() != null ) {
+                    final QName potentialCurrentAugment = this.normalizeNodeName(child, potentialSchemaNode,
+                            currentAugment, mountPoint);
+                    if (child.getQname() != null) {
                         this.normalizeNode(child, potentialSchemaNode, potentialCurrentAugment, mountPoint);
                         rightNodeSchemaFound = true;
                     }
@@ -1143,14 +1166,13 @@ public class RestconfImpl implements RestconfService {
             }
 
             if (!rightNodeSchemaFound) {
-                throw new RestconfDocumentedException(
-                           "Schema node \"" + child.getLocalName() + "\" was not found in module.",
-                           ErrorType.APPLICATION, ErrorTag.UNKNOWN_ELEMENT );
+                throw new RestconfDocumentedException("Schema node \"" + child.getLocalName()
+                        + "\" was not found in module.", ErrorType.APPLICATION, ErrorTag.UNKNOWN_ELEMENT);
             }
         }
 
         if ((schema instanceof ListSchemaNode)) {
-            ListSchemaNode listSchemaNode = (ListSchemaNode)schema;
+            ListSchemaNode listSchemaNode = (ListSchemaNode) schema;
             final List<QName> listKeys = listSchemaNode.getKeyDefinition();
             for (final QName listKey : listKeys) {
                 boolean foundKey = false;
@@ -1161,42 +1183,64 @@ public class RestconfImpl implements RestconfService {
                 }
 
                 if (!foundKey) {
-                    throw new RestconfDocumentedException(
-                                   "Missing key in URI \"" + listKey.getLocalName() +
-                                   "\" of list \"" + listSchemaNode.getQName().getLocalName() + "\"",
-                                   ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                    throw new RestconfDocumentedException("Missing key in URI \"" + listKey.getLocalName()
+                            + "\" of list \"" + listSchemaNode.getQName().getLocalName() + "\"", ErrorType.PROTOCOL,
+                            ErrorTag.DATA_MISSING);
                 }
             }
         }
     }
 
-    private QName normalizeNodeName(final NodeWrapper<? extends Object> nodeBuilder,
-                                    final DataSchemaNode schema, final QName previousAugment,
-                                    final MountInstance mountPoint) {
+    private void checkNodeMultiplicityAccordingToSchema(final DataNodeContainer dataNodeContainer,
+            final List<NodeWrapper<?>> nodes) {
+        Map<String, Integer> equalNodeNamesToCounts = new HashMap<String, Integer>();
+        for (NodeWrapper<?> child : nodes) {
+            Integer count = equalNodeNamesToCounts.get(child.getLocalName());
+            equalNodeNamesToCounts.put(child.getLocalName(), count == null ? 1 : ++count);
+        }
+
+        for (DataSchemaNode childSchemaNode : dataNodeContainer.getChildNodes()) {
+            if (childSchemaNode instanceof ContainerSchemaNode || childSchemaNode instanceof LeafSchemaNode) {
+                String localName = childSchemaNode.getQName().getLocalName();
+                Integer count = equalNodeNamesToCounts.get(localName);
+                if (count != null && count > 1) {
+                    throw new RestconfDocumentedException("Multiple input data elements were specified for '"
+                            + childSchemaNode.getQName().getLocalName()
+                            + "'. The data for this element type can only be specified once.", ErrorType.APPLICATION,
+                            ErrorTag.BAD_ELEMENT);
+                }
+            }
+        }
+    }
+
+    private QName normalizeNodeName(final NodeWrapper<? extends Object> nodeBuilder, final DataSchemaNode schema,
+            final QName previousAugment, final MountInstance mountPoint) {
         QName validQName = schema.getQName();
         QName currentAugment = previousAugment;
         if (schema.isAugmenting()) {
             currentAugment = schema.getQName();
-        }
-        else if (previousAugment != null &&
-                 !Objects.equal( schema.getQName().getNamespace(), previousAugment.getNamespace())) {
+        } else if (previousAugment != null
+                && !Objects.equal(schema.getQName().getNamespace(), previousAugment.getNamespace())) {
             validQName = QName.create(currentAugment, schema.getQName().getLocalName());
         }
 
         String moduleName = null;
         if (mountPoint == null) {
             moduleName = controllerContext.findModuleNameByNamespace(validQName.getNamespace());
-        }
-        else {
+        } else {
             moduleName = controllerContext.findModuleNameByNamespace(mountPoint, validQName.getNamespace());
         }
 
-        if (nodeBuilder.getNamespace() == null ||
-            Objects.equal(nodeBuilder.getNamespace(), validQName.getNamespace()) ||
-            Objects.equal(nodeBuilder.getNamespace().toString(), moduleName) /*||
-            Note: this check is wrong - can never be true as it compares a URI with a String
-                  not sure what the intention is so commented out...
-            Objects.equal(nodeBuilder.getNamespace(), MOUNT_POINT_MODULE_NAME)*/ ) {
+        if (nodeBuilder.getNamespace() == null || Objects.equal(nodeBuilder.getNamespace(), validQName.getNamespace())
+                || Objects.equal(nodeBuilder.getNamespace().toString(), moduleName) /*
+                                                                                     * || Note : this check is wrong -
+                                                                                     * can never be true as it compares
+                                                                                     * a URI with a String not sure what
+                                                                                     * the intention is so commented out
+                                                                                     * ... Objects . equal ( nodeBuilder
+                                                                                     * . getNamespace ( ) ,
+                                                                                     * MOUNT_POINT_MODULE_NAME )
+                                                                                     */) {
 
             nodeBuilder.setQname(validQName);
         }
@@ -1206,40 +1250,31 @@ public class RestconfImpl implements RestconfService {
 
     private URI namespace(final CompositeNode data) {
         if (data instanceof CompositeNodeWrapper) {
-            return ((CompositeNodeWrapper)data).getNamespace();
-        }
-        else if (data != null) {
+            return ((CompositeNodeWrapper) data).getNamespace();
+        } else if (data != null) {
             return data.getNodeType().getNamespace();
-        }
-        else {
-            throw new IllegalArgumentException("Unhandled parameter types: " +
-                    Arrays.<Object>asList(data).toString());
+        } else {
+            throw new IllegalArgumentException("Unhandled parameter types: " + Arrays.<Object> asList(data).toString());
         }
     }
 
     private String localName(final CompositeNode data) {
         if (data instanceof CompositeNodeWrapper) {
-            return ((CompositeNodeWrapper)data).getLocalName();
-        }
-        else if (data != null) {
+            return ((CompositeNodeWrapper) data).getLocalName();
+        } else if (data != null) {
             return data.getNodeType().getLocalName();
-        }
-        else {
-            throw new IllegalArgumentException("Unhandled parameter types: " +
-                    Arrays.<Object>asList(data).toString());
+        } else {
+            throw new IllegalArgumentException("Unhandled parameter types: " + Arrays.<Object> asList(data).toString());
         }
     }
 
     private String getName(final CompositeNode data) {
         if (data instanceof CompositeNodeWrapper) {
-            return ((CompositeNodeWrapper)data).getLocalName();
-        }
-        else if (data != null) {
+            return ((CompositeNodeWrapper) data).getLocalName();
+        } else if (data != null) {
             return data.getNodeType().getLocalName();
-        }
-        else {
-            throw new IllegalArgumentException("Unhandled parameter types: " +
-                    Arrays.<Object>asList(data).toString());
+        } else {
+            throw new IllegalArgumentException("Unhandled parameter types: " + Arrays.<Object> asList(data).toString());
         }
     }
 
@@ -1263,17 +1298,13 @@ public class RestconfImpl implements RestconfService {
 
     private TypeDefinition<? extends Object> typeDefinition(final DataSchemaNode node) {
         if (node instanceof LeafListSchemaNode) {
-            return typeDefinition((LeafListSchemaNode)node);
-        }
-        else if (node instanceof LeafSchemaNode) {
-            return _typeDefinition((LeafSchemaNode)node);
-        }
-        else if (node instanceof AnyXmlSchemaNode) {
+            return typeDefinition((LeafListSchemaNode) node);
+        } else if (node instanceof LeafSchemaNode) {
+            return _typeDefinition((LeafSchemaNode) node);
+        } else if (node instanceof AnyXmlSchemaNode) {
             return null;
-        }
-        else {
-            throw new IllegalArgumentException("Unhandled parameter types: " +
-                    Arrays.<Object>asList(node).toString());
+        } else {
+            throw new IllegalArgumentException("Unhandled parameter types: " + Arrays.<Object> asList(node).toString());
         }
     }
 }
index 3131668ed9ed23ae8fb8f0edb75076c8635a235d..854e9635cf3cde883d97bbcc28f29c99bbda5c9c 100644 (file)
@@ -7,8 +7,8 @@
  */
 package org.opendaylight.controller.sal.restconf.impl;
 
+import com.google.common.base.Preconditions;
 import java.net.URI;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
@@ -16,8 +16,6 @@ import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 
-import com.google.common.base.Preconditions;
-
 public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, SimpleNode<Object> {
 
     private SimpleNode<Object> simpleNode;
@@ -27,18 +25,18 @@ public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, Simp
     private URI namespace;
     private QName name;
 
-    public SimpleNodeWrapper(String localName, Object value) {
+    public SimpleNodeWrapper(final String localName, final Object value) {
         this.localName = Preconditions.checkNotNull(localName);
         this.value = value;
     }
 
-    public SimpleNodeWrapper(URI namespace, String localName, Object value) {
+    public SimpleNodeWrapper(final URI namespace, final String localName, final Object value) {
         this(localName, value);
         this.namespace = namespace;
     }
 
     @Override
-    public void setQname(QName name) {
+    public void setQname(final QName name) {
         Preconditions.checkState(simpleNode == null, "Cannot change the object, due to data inconsistencies.");
         this.name = name;
     }
@@ -65,7 +63,7 @@ public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, Simp
     }
 
     @Override
-    public void setNamespace(URI namespace) {
+    public void setNamespace(final URI namespace) {
         Preconditions.checkState(simpleNode == null, "Cannot change the object, due to data inconsistencies.");
         this.namespace = namespace;
     }
@@ -89,7 +87,7 @@ public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, Simp
             localName = null;
             name = null;
         }
-        return (SimpleNode<Object>) simpleNode;
+        return simpleNode;
     }
 
     @Override
@@ -98,6 +96,7 @@ public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, Simp
     }
 
     @Override
+    @Deprecated
     public CompositeNode getParent() {
         return unwrap().getParent();
     }
@@ -108,6 +107,7 @@ public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, Simp
     }
 
     @Override
+    @Deprecated
     public ModifyAction getModificationAction() {
         return unwrap().getModificationAction();
     }
@@ -123,10 +123,8 @@ public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, Simp
     }
 
     @Override
-    public Object setValue(Object value) {
+    public Object setValue(final Object value) {
         return unwrap().setValue(value);
     }
 
-
-
 }
index 231fe7e02eedfdee29d2996a7d0ebc4839f73646..c745a8009deac75a70a7249626b07f56457d9243 100644 (file)
@@ -16,11 +16,18 @@ public class StructuredData {
     private final CompositeNode data;
     private final DataSchemaNode schema;
     private final MountInstance mountPoint;
+    private final boolean prettyPrintMode;
 
     public StructuredData(final CompositeNode data, final DataSchemaNode schema, final MountInstance mountPoint) {
+        this(data, schema, mountPoint, false);
+    }
+
+    public StructuredData(final CompositeNode data, final DataSchemaNode schema, final MountInstance mountPoint,
+            final boolean preattyPrintMode) {
         this.data = data;
         this.schema = schema;
         this.mountPoint = mountPoint;
+        this.prettyPrintMode = preattyPrintMode;
     }
 
     public CompositeNode getData() {
@@ -34,4 +41,8 @@ public class StructuredData {
     public MountInstance getMountPoint() {
         return mountPoint;
     }
+
+    public boolean isPrettyPrintMode() {
+        return prettyPrintMode;
+    }
 }
index 6008b1d3c7d8f1f3d5d3e131a569f5eb42b960d3..120c67d3d5f5c3f44bb387d861fc371a829a1700 100644 (file)
@@ -5,4 +5,4 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.controller.sal.restconf.impl;
+package org.opendaylight.controller.sal.restconf.impl;
\ No newline at end of file
index 417cca653365bf96e925925226ee313513a79417..148b33bd6545ffe544418ddc6b393258535c5c9a 100644 (file)
@@ -1,16 +1,15 @@
 /*
-* Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
-*
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v1.0 which accompanies this distribution,
-* and is available at http://www.eclipse.org/legal/epl-v10.html
-*/
+ * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.sal.restconf.rpc.impl;
 
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
-
 import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
@@ -21,7 +20,7 @@ import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 public abstract class AbstractRpcExecutor implements RpcExecutor {
     private final RpcDefinition rpcDef;
 
-    public AbstractRpcExecutor( RpcDefinition rpcDef ){
+    public AbstractRpcExecutor(RpcDefinition rpcDef) {
         this.rpcDef = rpcDef;
     }
 
@@ -31,60 +30,49 @@ public abstract class AbstractRpcExecutor implements RpcExecutor {
     }
 
     @Override
-    public RpcResult<CompositeNode> invokeRpc( CompositeNode rpcRequest )
-                                                   throws RestconfDocumentedException {
+    public RpcResult<CompositeNode> invokeRpc(CompositeNode rpcRequest) throws RestconfDocumentedException {
         try {
-            return getRpcResult( invokeRpcUnchecked( rpcRequest ) );
-        }
-        catch( IllegalArgumentException e ) {
-            throw new RestconfDocumentedException(
-                                e.getMessage(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
-        }
-        catch( UnsupportedOperationException e ) {
-            throw new RestconfDocumentedException(
-                                e.getMessage(), ErrorType.RPC, ErrorTag.OPERATION_NOT_SUPPORTED );
-        }
-        catch( Exception e ) {
-            throw new RestconfDocumentedException(
-                    "The operation encountered an unexpected error while executing.", e );
+            return getRpcResult(invokeRpcUnchecked(rpcRequest));
+        } catch (IllegalArgumentException e) {
+            throw new RestconfDocumentedException(e.getMessage(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
+        } catch (UnsupportedOperationException e) {
+            throw new RestconfDocumentedException(e.getMessage(), ErrorType.RPC, ErrorTag.OPERATION_NOT_SUPPORTED);
+        } catch (RestconfDocumentedException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.", e);
         }
     }
 
-    protected abstract Future<RpcResult<CompositeNode>> invokeRpcUnchecked( CompositeNode rpcRequest );
+    protected abstract Future<RpcResult<CompositeNode>> invokeRpcUnchecked(CompositeNode rpcRequest);
 
-    protected RpcResult<CompositeNode> getRpcResult(
-                                            Future<RpcResult<CompositeNode>> fromFuture ) {
+    protected RpcResult<CompositeNode> getRpcResult(Future<RpcResult<CompositeNode>> fromFuture) {
         try {
             return fromFuture.get();
-        }
-        catch( InterruptedException e ) {
+        } catch (InterruptedException e) {
             throw new RestconfDocumentedException(
-                        "The operation was interrupted while executing and did not complete.",
-                        ErrorType.RPC, ErrorTag.PARTIAL_OPERATION );
-        }
-        catch( ExecutionException e ) {
+                    "The operation was interrupted while executing and did not complete.", ErrorType.RPC,
+                    ErrorTag.PARTIAL_OPERATION);
+        } catch (ExecutionException e) {
             Throwable cause = e.getCause();
-            if( cause instanceof CancellationException ) {
-                throw new RestconfDocumentedException(
-                        "The operation was cancelled while executing.",
-                        ErrorType.RPC, ErrorTag.PARTIAL_OPERATION );
-            }
-            else if( cause != null ){
-                while( cause.getCause() != null ) {
+            if (cause instanceof CancellationException) {
+                throw new RestconfDocumentedException("The operation was cancelled while executing.", ErrorType.RPC,
+                        ErrorTag.PARTIAL_OPERATION);
+            } else if (cause != null) {
+                while (cause.getCause() != null) {
                     cause = cause.getCause();
                 }
 
-                if( cause instanceof IllegalArgumentException ) {
-                    throw new RestconfDocumentedException(
-                            cause.getMessage(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+                if (cause instanceof IllegalArgumentException) {
+                    throw new RestconfDocumentedException(cause.getMessage(), ErrorType.PROTOCOL,
+                            ErrorTag.INVALID_VALUE);
                 }
 
-                throw new RestconfDocumentedException(
-                       "The operation encountered an unexpected error while executing.", cause );
-            }
-            else {
-                throw new RestconfDocumentedException(
-                        "The operation encountered an unexpected error while executing.", e );
+                throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.",
+                        cause);
+            } else {
+                throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.",
+                        e);
             }
         }
     }
index e23e95faab21e2cc129a745ba4959dbaa7da5ef3..146e69f0112214792c9b7067025615e922bb5408 100644 (file)
@@ -1,14 +1,13 @@
 /*
-* Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
-*
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v1.0 which accompanies this distribution,
-* and is available at http://www.eclipse.org/legal/epl-v10.html
-*/
+ * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.sal.restconf.rpc.impl;
 
 import java.util.concurrent.Future;
-
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
@@ -17,14 +16,13 @@ import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 public class BrokerRpcExecutor extends AbstractRpcExecutor {
     private final BrokerFacade broker;
 
-    public BrokerRpcExecutor( RpcDefinition rpcDef, BrokerFacade broker )
-    {
-        super( rpcDef );
+    public BrokerRpcExecutor(RpcDefinition rpcDef, BrokerFacade broker) {
+        super(rpcDef);
         this.broker = broker;
     }
 
     @Override
-    protected Future<RpcResult<CompositeNode>> invokeRpcUnchecked( CompositeNode rpcRequest ) {
-        return broker.invokeRpc( getRpcDefinition().getQName(), rpcRequest );
+    protected Future<RpcResult<CompositeNode>> invokeRpcUnchecked(CompositeNode rpcRequest) {
+        return broker.invokeRpc(getRpcDefinition().getQName(), rpcRequest);
     }
 }
\ No newline at end of file
index 26cb3b81028637c1b513e5d89aad837923684a79..36502656c22834829deaaa73f01defce0be1885d 100644 (file)
@@ -1,23 +1,22 @@
 /*
-* Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
-*
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v1.0 which accompanies this distribution,
-* and is available at http://www.eclipse.org/legal/epl-v10.html
-*/
+ * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.sal.restconf.rpc.impl;
 
+import com.google.common.base.Preconditions;
 import java.util.concurrent.Future;
-
 import org.opendaylight.controller.sal.core.api.mount.MountInstance;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 
-import com.google.common.base.Preconditions;
-
 /**
  * Provides an implementation which invokes rpc methods via a mounted yang data model.
+ *
  * @author Devin Avery
  *
  */
@@ -25,13 +24,13 @@ public class MountPointRpcExecutor extends AbstractRpcExecutor {
     private final MountInstance mountPoint;
 
     public MountPointRpcExecutor(RpcDefinition rpcDef, MountInstance mountPoint) {
-        super( rpcDef );
+        super(rpcDef);
         this.mountPoint = mountPoint;
-        Preconditions.checkNotNull( mountPoint, "MountInstance can not be null." );
+        Preconditions.checkNotNull(mountPoint, "MountInstance can not be null.");
     }
 
     @Override
-    protected Future<RpcResult<CompositeNode>> invokeRpcUnchecked( CompositeNode rpcRequest ) {
-        return mountPoint.rpc( getRpcDefinition().getQName(), rpcRequest );
+    protected Future<RpcResult<CompositeNode>> invokeRpcUnchecked(CompositeNode rpcRequest) {
+        return mountPoint.rpc(getRpcDefinition().getQName(), rpcRequest);
     }
 }
\ No newline at end of file
index f628a63393d40e3016a96afb9b09c1fa196933e0..3430226c3a32174ffef9e3a6daac0230af91c98e 100644 (file)
@@ -1,10 +1,10 @@
 /*
-* Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
-*
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v1.0 which accompanies this distribution,
-* and is available at http://www.eclipse.org/legal/epl-v10.html
-*/
+ * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.sal.restconf.rpc.impl;
 
 import org.opendaylight.yangtools.yang.common.RpcResult;
@@ -12,7 +12,7 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 
 public interface RpcExecutor {
-    RpcResult<CompositeNode> invokeRpc( CompositeNode rpcRequest );
+    RpcResult<CompositeNode> invokeRpc(CompositeNode rpcRequest);
 
     RpcDefinition getRpcDefinition();
 }
\ No newline at end of file
index 6282f37602be8236a737fe3e8ef42852816756bc..2b7b0246e35ac2356ce90f87126d5e4f43076a2c 100644 (file)
@@ -7,10 +7,14 @@
  */
 package org.opendaylight.controller.sal.streams.listeners;
 
+import com.google.common.base.Charsets;
+import com.google.common.base.Preconditions;
+import com.google.common.eventbus.AsyncEventBus;
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
 import io.netty.channel.Channel;
 import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
 import io.netty.util.internal.ConcurrentSet;
-
 import java.io.ByteArrayOutputStream;
 import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
@@ -23,7 +27,7 @@ import java.util.Map.Entry;
 import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.Executors;
-
+import java.util.regex.Pattern;
 import javax.activation.UnsupportedDataTypeException;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -34,7 +38,6 @@ 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.data.DataChangeEvent;
 import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
 import org.opendaylight.controller.sal.rest.impl.XmlMapper;
@@ -42,10 +45,10 @@ import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 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.InstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -53,24 +56,20 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
-import com.google.common.base.Preconditions;
-import com.google.common.eventbus.AsyncEventBus;
-import com.google.common.eventbus.EventBus;
-import com.google.common.eventbus.Subscribe;
-
 /**
- * {@link ListenerAdapter} is responsible to track events, which occurred by
- * changing data in data source.
+ * {@link ListenerAdapter} is responsible to track events, which occurred by changing data in data source.
  */
 public class ListenerAdapter implements DataChangeListener {
 
-    private static final Logger logger = LoggerFactory
-            .getLogger(ListenerAdapter.class);
+    private static final Logger LOG = LoggerFactory.getLogger(ListenerAdapter.class);
+    private static final DocumentBuilderFactory DBF = DocumentBuilderFactory.newInstance();
+    private static final TransformerFactory FACTORY = TransformerFactory.newInstance();
+    private static final Pattern RFC3339_PATTERN = Pattern.compile("(\\d\\d)(\\d\\d)$");
+
     private final XmlMapper xmlMapper = new XmlMapper();
-    private final SimpleDateFormat rfc3339 = new SimpleDateFormat(
-            "yyyy-MM-dd'T'hh:mm:ssZ");
+    private final SimpleDateFormat rfc3339 = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ");
 
-    private final InstanceIdentifier path;
+    private final YangInstanceIdentifier path;
     private ListenerRegistration<DataChangeListener> registration;
     private final String streamName;
     private Set<Channel> subscribers = new ConcurrentSet<>();
@@ -78,18 +77,16 @@ public class ListenerAdapter implements DataChangeListener {
     private final EventBusChangeRecorder eventBusChangeRecorder;
 
     /**
-     * Creates new {@link ListenerAdapter} listener specified by path and stream
-     * name.
+     * Creates new {@link ListenerAdapter} listener specified by path and stream name.
      *
      * @param path
      *            Path to data in data store.
      * @param streamName
      *            The name of the stream.
      */
-    ListenerAdapter(InstanceIdentifier path, String streamName) {
+    ListenerAdapter(final YangInstanceIdentifier path, final String streamName) {
         Preconditions.checkNotNull(path);
-        Preconditions
-                .checkArgument(streamName != null && !streamName.isEmpty());
+        Preconditions.checkArgument(streamName != null && !streamName.isEmpty());
         this.path = path;
         this.streamName = streamName;
         eventBus = new AsyncEventBus(Executors.newSingleThreadExecutor());
@@ -98,14 +95,10 @@ public class ListenerAdapter implements DataChangeListener {
     }
 
     @Override
-    public void onDataChanged(
-            DataChangeEvent<InstanceIdentifier, CompositeNode> change) {
-        if (!change.getCreatedConfigurationData().isEmpty()
-                || !change.getCreatedOperationalData().isEmpty()
-                || !change.getUpdatedConfigurationData().isEmpty()
-                || !change.getUpdatedOperationalData().isEmpty()
-                || !change.getRemovedConfigurationData().isEmpty()
-                || !change.getRemovedOperationalData().isEmpty()) {
+    public void onDataChanged(final DataChangeEvent<YangInstanceIdentifier, CompositeNode> change) {
+        if (!change.getCreatedConfigurationData().isEmpty() || !change.getCreatedOperationalData().isEmpty()
+                || !change.getUpdatedConfigurationData().isEmpty() || !change.getUpdatedOperationalData().isEmpty()
+                || !change.getRemovedConfigurationData().isEmpty() || !change.getRemovedOperationalData().isEmpty()) {
             String xml = prepareXmlFrom(change);
             Event event = new Event(EventType.NOTIFY);
             event.setData(xml);
@@ -118,7 +111,7 @@ public class ListenerAdapter implements DataChangeListener {
      */
     private final class EventBusChangeRecorder {
         @Subscribe
-        public void recordCustomerChange(Event event) {
+        public void recordCustomerChange(final Event event) {
             if (event.getType() == EventType.REGISTER) {
                 Channel subscriber = event.getSubscriber();
                 if (!subscribers.contains(subscriber)) {
@@ -126,19 +119,14 @@ public class ListenerAdapter implements DataChangeListener {
                 }
             } else if (event.getType() == EventType.DEREGISTER) {
                 subscribers.remove(event.getSubscriber());
-                Notificator
-                        .removeListenerIfNoSubscriberExists(ListenerAdapter.this);
+                Notificator.removeListenerIfNoSubscriberExists(ListenerAdapter.this);
             } else if (event.getType() == EventType.NOTIFY) {
                 for (Channel subscriber : subscribers) {
                     if (subscriber.isActive()) {
-                        logger.debug("Data are sent to subscriber {}:",
-                                subscriber.remoteAddress());
-                        subscriber.writeAndFlush(new TextWebSocketFrame(event
-                                .getData()));
+                        LOG.debug("Data are sent to subscriber {}:", subscriber.remoteAddress());
+                        subscriber.writeAndFlush(new TextWebSocketFrame(event.getData()));
                     } else {
-                        logger.debug(
-                                "Subscriber {} is removed - channel is not active yet.",
-                                subscriber.remoteAddress());
+                        LOG.debug("Subscriber {} is removed - channel is not active yet.", subscriber.remoteAddress());
                         subscribers.remove(subscriber);
                     }
                 }
@@ -147,8 +135,7 @@ public class ListenerAdapter implements DataChangeListener {
     }
 
     /**
-     * Represents event of specific {@link EventType} type, holds data and
-     * {@link Channel} subscriber.
+     * Represents event of specific {@link EventType} type, holds data and {@link Channel} subscriber.
      */
     private final class Event {
         private final EventType type;
@@ -161,7 +148,7 @@ public class ListenerAdapter implements DataChangeListener {
          * @param type
          *            EventType
          */
-        public Event(EventType type) {
+        public Event(final EventType type) {
             this.type = type;
         }
 
@@ -180,7 +167,7 @@ public class ListenerAdapter implements DataChangeListener {
          * @param subscriber
          *            Channel
          */
-        public void setSubscriber(Channel subscriber) {
+        public void setSubscriber(final Channel subscriber) {
             this.subscriber = subscriber;
         }
 
@@ -199,7 +186,7 @@ public class ListenerAdapter implements DataChangeListener {
          * @param String
          *            data.
          */
-        public void setData(String data) {
+        public void setData(final String data) {
             this.data = data;
         }
 
@@ -217,7 +204,9 @@ public class ListenerAdapter implements DataChangeListener {
      * Type of the event.
      */
     private enum EventType {
-        REGISTER, DEREGISTER, NOTIFY;
+        REGISTER,
+        DEREGISTER,
+        NOTIFY;
     }
 
     /**
@@ -227,11 +216,9 @@ public class ListenerAdapter implements DataChangeListener {
      *            DataChangeEvent
      * @return Data in printable form.
      */
-    private String prepareXmlFrom(
-            DataChangeEvent<InstanceIdentifier, CompositeNode> change) {
+    private String prepareXmlFrom(final DataChangeEvent<YangInstanceIdentifier, CompositeNode> change) {
         Document doc = createDocument();
-        Element notificationElement = doc.createElementNS(
-                "urn:ietf:params:xml:ns:netconf:notification:1.0",
+        Element notificationElement = doc.createElementNS("urn:ietf:params:xml:ns:netconf:notification:1.0",
                 "notification");
         doc.appendChild(notificationElement);
 
@@ -240,30 +227,24 @@ public class ListenerAdapter implements DataChangeListener {
         notificationElement.appendChild(eventTimeElement);
 
         Element dataChangedNotificationEventElement = doc.createElementNS(
-                "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote",
-                "data-changed-notification");
-        addValuesToDataChangedNotificationEventElement(doc,
-                dataChangedNotificationEventElement, change);
+                "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote", "data-changed-notification");
+        addValuesToDataChangedNotificationEventElement(doc, dataChangedNotificationEventElement, change);
         notificationElement.appendChild(dataChangedNotificationEventElement);
 
         try {
             ByteArrayOutputStream out = new ByteArrayOutputStream();
-            TransformerFactory tf = TransformerFactory.newInstance();
-            Transformer transformer = tf.newTransformer();
-            transformer
-                    .setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
+            Transformer transformer = FACTORY.newTransformer();
+            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
             transformer.setOutputProperty(OutputKeys.METHOD, "xml");
             transformer.setOutputProperty(OutputKeys.INDENT, "yes");
             transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
-            transformer.setOutputProperty(
-                    "{http://xml.apache.org/xslt}indent-amount", "4");
-            transformer.transform(new DOMSource(doc), new StreamResult(
-                    new OutputStreamWriter(out, "UTF-8")));
+            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
+            transformer.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(out, Charsets.UTF_8)));
             byte[] charData = out.toByteArray();
             return new String(charData, "UTF-8");
         } catch (TransformerException | UnsupportedEncodingException e) {
             String msg = "Error during transformation of Document into String";
-            logger.error(msg, e);
+            LOG.error(msg, e);
             return msg;
         }
     }
@@ -275,8 +256,8 @@ public class ListenerAdapter implements DataChangeListener {
      *            Date
      * @return Data specified by RFC3339.
      */
-    private String toRFC3339(Date d) {
-        return rfc3339.format(d).replaceAll("(\\d\\d)(\\d\\d)$", "$1:$2");
+    private String toRFC3339(final Date d) {
+        return RFC3339_PATTERN.matcher(rfc3339.format(d)).replaceAll("$1:$2");
     }
 
     /**
@@ -285,15 +266,13 @@ public class ListenerAdapter implements DataChangeListener {
      * @return {@link Document} document.
      */
     private Document createDocument() {
-        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-        Document doc = null;
+        final DocumentBuilder bob;
         try {
-            DocumentBuilder bob = dbf.newDocumentBuilder();
-            doc = bob.newDocument();
+            bob = DBF.newDocumentBuilder();
         } catch (ParserConfigurationException e) {
             return null;
         }
-        return doc;
+        return bob.newDocument();
     }
 
     /**
@@ -306,32 +285,25 @@ public class ListenerAdapter implements DataChangeListener {
      * @param change
      *            {@link DataChangeEvent}
      */
-    private void addValuesToDataChangedNotificationEventElement(Document doc,
-            Element dataChangedNotificationEventElement,
-            DataChangeEvent<InstanceIdentifier, CompositeNode> change) {
-        addValuesFromDataToElement(doc, change.getCreatedConfigurationData(),
-                dataChangedNotificationEventElement, Store.CONFIG,
-                Operation.CREATED);
-        addValuesFromDataToElement(doc, change.getCreatedOperationalData(),
-                dataChangedNotificationEventElement, Store.OPERATION,
-                Operation.CREATED);
+    private void addValuesToDataChangedNotificationEventElement(final Document doc,
+            final Element dataChangedNotificationEventElement,
+            final DataChangeEvent<YangInstanceIdentifier, CompositeNode> change) {
+        addValuesFromDataToElement(doc, change.getCreatedConfigurationData(), dataChangedNotificationEventElement,
+                Store.CONFIG, Operation.CREATED);
+        addValuesFromDataToElement(doc, change.getCreatedOperationalData(), dataChangedNotificationEventElement,
+                Store.OPERATION, Operation.CREATED);
         if (change.getCreatedConfigurationData().isEmpty()) {
-            addValuesFromDataToElement(doc,
-                    change.getUpdatedConfigurationData(),
-                    dataChangedNotificationEventElement, Store.CONFIG,
-                    Operation.UPDATED);
+            addValuesFromDataToElement(doc, change.getUpdatedConfigurationData(), dataChangedNotificationEventElement,
+                    Store.CONFIG, Operation.UPDATED);
         }
         if (change.getCreatedOperationalData().isEmpty()) {
-            addValuesFromDataToElement(doc, change.getUpdatedOperationalData(),
-                    dataChangedNotificationEventElement, Store.OPERATION,
-                    Operation.UPDATED);
+            addValuesFromDataToElement(doc, change.getUpdatedOperationalData(), dataChangedNotificationEventElement,
+                    Store.OPERATION, Operation.UPDATED);
         }
-        addValuesFromDataToElement(doc, change.getRemovedConfigurationData(),
-                dataChangedNotificationEventElement, Store.CONFIG,
-                Operation.DELETED);
-        addValuesFromDataToElement(doc, change.getRemovedOperationalData(),
-                dataChangedNotificationEventElement, Store.OPERATION,
-                Operation.DELETED);
+        addValuesFromDataToElement(doc, change.getRemovedConfigurationData(), dataChangedNotificationEventElement,
+                Store.CONFIG, Operation.DELETED);
+        addValuesFromDataToElement(doc, change.getRemovedOperationalData(), dataChangedNotificationEventElement,
+                Store.OPERATION, Operation.DELETED);
     }
 
     /**
@@ -340,7 +312,7 @@ public class ListenerAdapter implements DataChangeListener {
      * @param doc
      *            {@link Document}
      * @param data
-     *            Set of {@link InstanceIdentifier}.
+     *            Set of {@link YangInstanceIdentifier}.
      * @param element
      *            {@link Element}
      * @param store
@@ -348,15 +320,13 @@ public class ListenerAdapter implements DataChangeListener {
      * @param operation
      *            {@link Operation}
      */
-    private void addValuesFromDataToElement(Document doc,
-            Set<InstanceIdentifier> data, Element element, Store store,
-            Operation operation) {
+    private void addValuesFromDataToElement(final Document doc, final Set<YangInstanceIdentifier> data,
+            final Element element, final Store store, final Operation operation) {
         if (data == null || data.isEmpty()) {
             return;
         }
-        for (InstanceIdentifier path : data) {
-            Node node = createDataChangeEventElement(doc, path, null, store,
-                    operation);
+        for (YangInstanceIdentifier path : data) {
+            Node node = createDataChangeEventElement(doc, path, null, store, operation);
             element.appendChild(node);
         }
     }
@@ -367,7 +337,7 @@ public class ListenerAdapter implements DataChangeListener {
      * @param doc
      *            {@link Document}
      * @param data
-     *            Map of {@link InstanceIdentifier} and {@link CompositeNode}.
+     *            Map of {@link YangInstanceIdentifier} and {@link CompositeNode}.
      * @param element
      *            {@link Element}
      * @param store
@@ -375,15 +345,13 @@ public class ListenerAdapter implements DataChangeListener {
      * @param operation
      *            {@link Operation}
      */
-    private void addValuesFromDataToElement(Document doc,
-            Map<InstanceIdentifier, CompositeNode> data, Element element,
-            Store store, Operation operation) {
+    private void addValuesFromDataToElement(final Document doc, final Map<YangInstanceIdentifier, CompositeNode> data,
+            final Element element, final Store store, final Operation operation) {
         if (data == null || data.isEmpty()) {
             return;
         }
-        for (Entry<InstanceIdentifier, CompositeNode> entry : data.entrySet()) {
-            Node node = createDataChangeEventElement(doc, entry.getKey(),
-                    entry.getValue(), store, operation);
+        for (Entry<YangInstanceIdentifier, CompositeNode> entry : data.entrySet()) {
+            Node node = createDataChangeEventElement(doc, entry.getKey(), entry.getValue(), store, operation);
             element.appendChild(node);
         }
     }
@@ -403,9 +371,8 @@ public class ListenerAdapter implements DataChangeListener {
      *            {@link Operation}
      * @return {@link Node} node represented by changed event element.
      */
-    private Node createDataChangeEventElement(Document doc,
-            InstanceIdentifier path, CompositeNode data, Store store,
-            Operation operation) {
+    private Node createDataChangeEventElement(final Document doc, final YangInstanceIdentifier path,
+            final CompositeNode data, final Store store, final Operation operation) {
         Element dataChangeEventElement = doc.createElement("data-change-event");
 
         Element pathElement = doc.createElement("path");
@@ -440,11 +407,10 @@ public class ListenerAdapter implements DataChangeListener {
      *            {@link CompositeNode}
      * @return Data in XML format.
      */
-    private Node translateToXml(InstanceIdentifier path, CompositeNode data) {
-        DataNodeContainer schemaNode = ControllerContext.getInstance()
-                .getDataNodeContainerFor(path);
+    private Node translateToXml(final YangInstanceIdentifier path, final CompositeNode data) {
+        DataNodeContainer schemaNode = ControllerContext.getInstance().getDataNodeContainerFor(path);
         if (schemaNode == null) {
-            logger.info(
+            LOG.info(
                     "Path '{}' contains node with unsupported type (supported type is Container or List) or some node was not found.",
                     path);
             return null;
@@ -453,9 +419,7 @@ public class ListenerAdapter implements DataChangeListener {
             Document xml = xmlMapper.write(data, schemaNode);
             return xml.getFirstChild();
         } catch (UnsupportedDataTypeException e) {
-            logger.error(
-                    "Error occured during translation of notification to XML.",
-                    e);
+            LOG.error("Error occured during translation of notification to XML.", e);
             return null;
         }
     }
@@ -468,25 +432,22 @@ public class ListenerAdapter implements DataChangeListener {
      * @param element
      *            {@link Element}
      */
-    private void addPathAsValueToElement(InstanceIdentifier path,
-            Element element) {
+    private void addPathAsValueToElement(final YangInstanceIdentifier path, final Element element) {
         // Map< key = namespace, value = prefix>
         Map<String, String> prefixes = new HashMap<>();
-        InstanceIdentifier instanceIdentifier = path;
+        YangInstanceIdentifier instanceIdentifier = path;
         StringBuilder textContent = new StringBuilder();
-        for (PathArgument pathArgument : instanceIdentifier.getPath()) {
+
+        // FIXME: BUG-1281: this is duplicated code from yangtools (BUG-1275)
+        for (PathArgument pathArgument : instanceIdentifier.getPathArguments()) {
             textContent.append("/");
-            writeIdentifierWithNamespacePrefix(element, textContent,
-                    pathArgument.getNodeType(), prefixes);
+            writeIdentifierWithNamespacePrefix(element, textContent, pathArgument.getNodeType(), prefixes);
             if (pathArgument instanceof NodeIdentifierWithPredicates) {
-                Map<QName, Object> predicates = ((NodeIdentifierWithPredicates) pathArgument)
-                        .getKeyValues();
+                Map<QName, Object> predicates = ((NodeIdentifierWithPredicates) pathArgument).getKeyValues();
                 for (QName keyValue : predicates.keySet()) {
-                    String predicateValue = String.valueOf(predicates
-                            .get(keyValue));
+                    String predicateValue = String.valueOf(predicates.get(keyValue));
                     textContent.append("[");
-                    writeIdentifierWithNamespacePrefix(element, textContent,
-                            keyValue, prefixes);
+                    writeIdentifierWithNamespacePrefix(element, textContent, keyValue, prefixes);
                     textContent.append("='");
                     textContent.append(predicateValue);
                     textContent.append("'");
@@ -514,14 +475,13 @@ public class ListenerAdapter implements DataChangeListener {
      * @param prefixes
      *            Map of namespaces and prefixes.
      */
-    private static void writeIdentifierWithNamespacePrefix(Element element,
-            StringBuilder textContent, QName qName, Map<String, String> prefixes) {
+    private static void writeIdentifierWithNamespacePrefix(final Element element, final StringBuilder textContent,
+            final QName qName, final Map<String, String> prefixes) {
         String namespace = qName.getNamespace().toString();
         String prefix = prefixes.get(namespace);
         if (prefix == null) {
             prefix = qName.getPrefix();
-            if (prefix == null || prefix.isEmpty()
-                    || prefixes.containsValue(prefix)) {
+            if (prefix == null || prefix.isEmpty() || prefixes.containsValue(prefix)) {
                 prefix = generateNewPrefix(prefixes.values());
             }
         }
@@ -541,7 +501,7 @@ public class ListenerAdapter implements DataChangeListener {
      *            Collection of prefixes.
      * @return New prefix which consists of four random characters <a-z>.
      */
-    private static String generateNewPrefix(Collection<String> prefixes) {
+    private static String generateNewPrefix(final Collection<String> prefixes) {
         StringBuilder result = null;
         Random random = new Random();
         do {
@@ -560,7 +520,7 @@ public class ListenerAdapter implements DataChangeListener {
      *
      * @return Path pointed to data in data store.
      */
-    public InstanceIdentifier getPath() {
+    public YangInstanceIdentifier getPath() {
         return path;
     }
 
@@ -570,8 +530,7 @@ public class ListenerAdapter implements DataChangeListener {
      * @param registration
      *            ListenerRegistration<DataChangeListener>
      */
-    public void setRegistration(
-            ListenerRegistration<DataChangeListener> registration) {
+    public void setRegistration(final ListenerRegistration<DataChangeListener> registration) {
         this.registration = registration;
     }
 
@@ -585,8 +544,7 @@ public class ListenerAdapter implements DataChangeListener {
     }
 
     /**
-     * Removes all subscribers and unregisters event bus change recorder form
-     * event bus.
+     * Removes all subscribers and unregisters event bus change recorder form event bus.
      */
     public void close() throws Exception {
         subscribers = new ConcurrentSet<>();
@@ -605,16 +563,15 @@ public class ListenerAdapter implements DataChangeListener {
     }
 
     /**
-     * Creates event of type {@link EventType#REGISTER}, set {@link Channel}
-     * subscriber to the event and post event into event bus.
+     * Creates event of type {@link EventType#REGISTER}, set {@link Channel} subscriber to the event and post event into
+     * event bus.
      *
      * @param subscriber
      *            Channel
      */
-    public void addSubscriber(Channel subscriber) {
+    public void addSubscriber(final Channel subscriber) {
         if (!subscriber.isActive()) {
-            logger.debug("Channel is not active between websocket server and subscriber {}"
-                    + subscriber.remoteAddress());
+            LOG.debug("Channel is not active between websocket server and subscriber {}" + subscriber.remoteAddress());
         }
         Event event = new Event(EventType.REGISTER);
         event.setSubscriber(subscriber);
@@ -622,13 +579,13 @@ public class ListenerAdapter implements DataChangeListener {
     }
 
     /**
-     * Creates event of type {@link EventType#DEREGISTER}, sets {@link Channel}
-     * subscriber to the event and posts event into event bus.
+     * Creates event of type {@link EventType#DEREGISTER}, sets {@link Channel} subscriber to the event and posts event
+     * into event bus.
      *
      * @param subscriber
      */
-    public void removeSubscriber(Channel subscriber) {
-        logger.debug("Subscriber {} is removed.", subscriber.remoteAddress());
+    public void removeSubscriber(final Channel subscriber) {
+        LOG.debug("Subscriber {} is removed.", subscriber.remoteAddress());
         Event event = new Event(EventType.DEREGISTER);
         event.setSubscriber(subscriber);
         eventBus.post(event);
@@ -637,8 +594,7 @@ public class ListenerAdapter implements DataChangeListener {
     /**
      * Checks if exists at least one {@link Channel} subscriber.
      *
-     * @return True if exist at least one {@link Channel} subscriber, false
-     *         otherwise.
+     * @return True if exist at least one {@link Channel} subscriber, false otherwise.
      */
     public boolean hasSubscribers() {
         return !subscribers.isEmpty();
@@ -648,25 +604,27 @@ public class ListenerAdapter implements DataChangeListener {
      * Consists of two types {@link Store#CONFIG} and {@link Store#OPERATION}.
      */
     private static enum Store {
-        CONFIG("config"), OPERATION("operation");
+        CONFIG("config"),
+        OPERATION("operation");
 
         private final String value;
 
-        private Store(String value) {
+        private Store(final String value) {
             this.value = value;
         }
     }
 
     /**
-     * Consists of three types {@link Operation#CREATED},
-     * {@link Operation#UPDATED} and {@link Operation#DELETED}.
+     * Consists of three types {@link Operation#CREATED}, {@link Operation#UPDATED} and {@link Operation#DELETED}.
      */
     private static enum Operation {
-        CREATED("created"), UPDATED("updated"), DELETED("deleted");
+        CREATED("created"),
+        UPDATED("updated"),
+        DELETED("deleted");
 
         private final String value;
 
-        private Operation(String value) {
+        private Operation(final String value) {
             this.value = value;
         }
     }
index a576eed26978fb0380cd8a28613712409bf6ce53..cf1bcd6a30b6c4d22464e3678f2c468a995479c8 100644 (file)
@@ -12,8 +12,7 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
-
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 /**
  * {@link Notificator} is responsible to create, remove and find {@link ListenerAdapter} listener.
@@ -21,7 +20,7 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 public class Notificator {
 
     private static Map<String, ListenerAdapter> listenersByStreamName = new ConcurrentHashMap<>();
-    private static Map<InstanceIdentifier, ListenerAdapter> listenersByInstanceIdentifier = new ConcurrentHashMap<>();
+    private static Map<YangInstanceIdentifier, ListenerAdapter> listenersByInstanceIdentifier = new ConcurrentHashMap<>();
     private static final Lock lock = new ReentrantLock();
 
     private Notificator() {
@@ -34,7 +33,6 @@ public class Notificator {
         return listenersByStreamName.keySet();
     }
 
-
     /**
      * Gets {@link ListenerAdapter} specified by stream name.
      *
@@ -47,42 +45,37 @@ public class Notificator {
     }
 
     /**
-     * Gets {@link ListenerAdapter} listener specified by
-     * {@link InstanceIdentifier} path.
+     * Gets {@link ListenerAdapter} listener specified by {@link YangInstanceIdentifier} path.
      *
      * @param path
      *            Path to data in data repository.
      * @return ListenerAdapter
      */
-    public static ListenerAdapter getListenerFor(InstanceIdentifier path) {
+    public static ListenerAdapter getListenerFor(YangInstanceIdentifier path) {
         return listenersByInstanceIdentifier.get(path);
     }
 
     /**
-     * Checks if the listener specified by {@link InstanceIdentifier} path
-     * exist.
+     * Checks if the listener specified by {@link YangInstanceIdentifier} path exist.
      *
      * @param path
      *            Path to data in data repository.
      * @return True if the listener exist, false otherwise.
      */
-    public static boolean existListenerFor(InstanceIdentifier path) {
+    public static boolean existListenerFor(YangInstanceIdentifier path) {
         return listenersByInstanceIdentifier.containsKey(path);
     }
 
     /**
-     * Creates new {@link ListenerAdapter} listener from
-     * {@link InstanceIdentifier} path and stream name.
+     * Creates new {@link ListenerAdapter} listener from {@link YangInstanceIdentifier} path and stream name.
      *
      * @param path
      *            Path to data in data repository.
      * @param streamName
      *            The name of the stream.
-     * @return New {@link ListenerAdapter} listener from
-     *         {@link InstanceIdentifier} path and stream name.
+     * @return New {@link ListenerAdapter} listener from {@link YangInstanceIdentifier} path and stream name.
      */
-    public static ListenerAdapter createListener(InstanceIdentifier path,
-            String streamName) {
+    public static ListenerAdapter createListener(YangInstanceIdentifier path, String streamName) {
         ListenerAdapter listener = new ListenerAdapter(path, streamName);
         try {
             lock.lock();
@@ -95,20 +88,18 @@ public class Notificator {
     }
 
     /**
-     * Looks for listener determined by {@link InstanceIdentifier} path and
-     * removes it.
+     * Looks for listener determined by {@link YangInstanceIdentifier} path and removes it.
      *
      * @param path
      *            InstanceIdentifier
      */
-    public static void removeListener(InstanceIdentifier path) {
+    public static void removeListener(YangInstanceIdentifier path) {
         ListenerAdapter listener = listenersByInstanceIdentifier.get(path);
         deleteListener(listener);
     }
 
     /**
-     * Creates String representation of stream name from URI. Removes slash from
-     * URI in start and end position.
+     * Creates String representation of stream name from URI. Removes slash from URI in start and end position.
      *
      * @param uri
      *            URI for creation stream name.
@@ -148,14 +139,12 @@ public class Notificator {
     }
 
     /**
-     * Checks if listener has at least one subscriber. In case it doesn't have any, delete
-     * listener.
+     * Checks if listener has at least one subscriber. In case it doesn't have any, delete listener.
      *
      * @param listener
      *            ListenerAdapter
      */
-    public static void removeListenerIfNoSubscriberExists(
-            ListenerAdapter listener) {
+    public static void removeListenerIfNoSubscriberExists(ListenerAdapter listener) {
         if (!listener.hasSubscribers()) {
             deleteListener(listener);
         }
index fcfa8858ee940065baee9f4c8c4df2fb3a73089c..67ed44f84ea86020b54553f3f0b4f108e4ada66f 100644 (file)
@@ -1,27 +1,76 @@
 package org.opendaylight.controller.sal.streams.websockets;
 
+import com.google.common.base.Preconditions;
 import io.netty.bootstrap.ServerBootstrap;
 import io.netty.channel.Channel;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.nio.NioServerSocketChannel;
-
 import org.opendaylight.controller.sal.streams.listeners.Notificator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * {@link WebSocketServer} is responsible to start and stop web socket server at
- * {@link #PORT}.
+ * {@link WebSocketServer} is responsible to start and stop web socket server
  */
 public class WebSocketServer implements Runnable {
 
-    private static final Logger logger = LoggerFactory
-            .getLogger(WebSocketServer.class);
-
-    public static final int PORT = 8181;
+    private static final Logger logger = LoggerFactory.getLogger(WebSocketServer.class);
+    public static final String WEBSOCKET_SERVER_CONFIG_PROPERTY = "restconf.websocket.port";
+    public static final int DEFAULT_PORT = 8181;
     private EventLoopGroup bossGroup;
     private EventLoopGroup workerGroup;
+    private static WebSocketServer singleton = null;
+    private int port = DEFAULT_PORT;
+
+    private WebSocketServer(int port) {
+        this.port = port;
+    }
+
+    /**
+     * Create instance of {@link WebSocketServer}
+     *
+     * @param port
+     *            TCP port used for this server
+     * @return instance of {@link WebSocketServer}
+     */
+    public static WebSocketServer createInstance(int port) {
+        if (singleton != null) {
+            throw new IllegalStateException("createInstance() has already been called");
+        }
+        if (port < 1024) {
+            throw new IllegalArgumentException("Privileged port (below 1024) is not allowed");
+        }
+        singleton = new WebSocketServer(port);
+        return singleton;
+    }
+
+    /**
+     * Return websocket TCP port
+     */
+    public int getPort() {
+        return port;
+    }
+
+    /**
+     * Get instance of {@link WebSocketServer} created by {@link #createInstance(int)}
+     *
+     * @return instance of {@link WebSocketServer}
+     */
+    public static WebSocketServer getInstance() {
+        Preconditions.checkNotNull(singleton, "createInstance() must be called prior to getInstance()");
+        return singleton;
+    }
+
+    /**
+     * Destroy this already created instance
+     */
+    public static void destroyInstance() {
+        if (singleton == null) {
+            throw new IllegalStateException("createInstance() must be called prior to destroyInstance()");
+        }
+        getInstance().stop();
+    }
 
     @Override
     public void run() {
@@ -29,12 +78,11 @@ public class WebSocketServer implements Runnable {
         workerGroup = new NioEventLoopGroup();
         try {
             ServerBootstrap b = new ServerBootstrap();
-            b.group(bossGroup, workerGroup)
-                    .channel(NioServerSocketChannel.class)
+            b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                     .childHandler(new WebSocketServerInitializer());
 
-            Channel ch = b.bind(PORT).sync().channel();
-            logger.info("Web socket server started at port {}.", PORT);
+            Channel ch = b.bind(port).sync().channel();
+            logger.info("Web socket server started at port {}.", port);
 
             ch.closeFuture().sync();
         } catch (InterruptedException e) {
index b5d6a6ea9be647d22c1dc8a75609506433e850f6..ce12d34e083f2ca440c754ab736aed1834276e0f 100644 (file)
@@ -8,6 +8,7 @@ import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
 import static io.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN;
 import static io.netty.handler.codec.http.HttpResponseStatus.INTERNAL_SERVER_ERROR;
 import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
+
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelFuture;
@@ -25,29 +26,24 @@ import io.netty.handler.codec.http.websocketx.WebSocketFrame;
 import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
 import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
 import io.netty.util.CharsetUtil;
-
 import java.io.IOException;
-
 import org.opendaylight.controller.sal.streams.listeners.ListenerAdapter;
 import org.opendaylight.controller.sal.streams.listeners.Notificator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * {@link WebSocketServerHandler} is implementation of
- * {@link SimpleChannelInboundHandler} which allow handle
+ * {@link WebSocketServerHandler} is implementation of {@link SimpleChannelInboundHandler} which allow handle
  * {@link FullHttpRequest} and {@link WebSocketFrame} messages.
  */
 public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object> {
 
-    private static final Logger logger = LoggerFactory
-            .getLogger(WebSocketServerHandler.class);
+    private static final Logger logger = LoggerFactory.getLogger(WebSocketServerHandler.class);
 
     private WebSocketServerHandshaker handshaker;
 
     @Override
-    protected void channelRead0(ChannelHandlerContext ctx, Object msg)
-            throws Exception {
+    protected void channelRead0(final ChannelHandlerContext ctx, final Object msg) throws Exception {
         if (msg instanceof FullHttpRequest) {
             handleHttpRequest(ctx, (FullHttpRequest) msg);
         } else if (msg instanceof WebSocketFrame) {
@@ -56,27 +52,23 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
     }
 
     /**
-     * Checks if HTTP request method is GET and if is possible to decode HTTP
-     * result of request.
+     * Checks if HTTP request method is GET and if is possible to decode HTTP result of request.
      *
      * @param ctx
      *            ChannelHandlerContext
      * @param req
      *            FullHttpRequest
      */
-    private void handleHttpRequest(ChannelHandlerContext ctx,
-            FullHttpRequest req) throws Exception {
+    private void handleHttpRequest(final ChannelHandlerContext ctx, final FullHttpRequest req) throws Exception {
         // Handle a bad request.
         if (!req.getDecoderResult().isSuccess()) {
-            sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1,
-                    BAD_REQUEST));
+            sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST));
             return;
         }
 
         // Allow only GET methods.
         if (req.getMethod() != GET) {
-            sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1,
-                    FORBIDDEN));
+            sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN));
             return;
         }
 
@@ -86,19 +78,16 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
             listener.addSubscriber(ctx.channel());
             logger.debug("Subscriber successfully registered.");
         } else {
-            logger.error("Listener for stream with name '{}' was not found.",
-                    streamName);
-            sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1,
-                    INTERNAL_SERVER_ERROR));
+            logger.error("Listener for stream with name '{}' was not found.", streamName);
+            sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, INTERNAL_SERVER_ERROR));
         }
 
         // Handshake
-        WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
-                getWebSocketLocation(req), null, false);
+        WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketLocation(req),
+                null, false);
         handshaker = wsFactory.newHandshaker(req);
         if (handshaker == null) {
-            WebSocketServerHandshakerFactory
-                    .sendUnsupportedWebSocketVersionResponse(ctx.channel());
+            WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
         } else {
             handshaker.handshake(ctx.channel(), req);
         }
@@ -115,12 +104,11 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
      * @param res
      *            FullHttpResponse
      */
-    private static void sendHttpResponse(ChannelHandlerContext ctx,
-            HttpRequest req, FullHttpResponse res) {
+    private static void sendHttpResponse(final ChannelHandlerContext ctx, final HttpRequest req,
+            final FullHttpResponse res) {
         // Generate an error page if response getStatus code is not OK (200).
         if (res.getStatus().code() != 200) {
-            ByteBuf buf = Unpooled.copiedBuffer(res.getStatus().toString(),
-                    CharsetUtil.UTF_8);
+            ByteBuf buf = Unpooled.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8);
             res.content().writeBytes(buf);
             buf.release();
             setContentLength(res, res.content().readableBytes());
@@ -141,14 +129,10 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
      * @param frame
      *            {@link WebSocketFrame}
      */
-    private void handleWebSocketFrame(ChannelHandlerContext ctx,
-            WebSocketFrame frame) throws IOException {
+    private void handleWebSocketFrame(final ChannelHandlerContext ctx, final WebSocketFrame frame) throws IOException {
         if (frame instanceof CloseWebSocketFrame) {
-            handshaker.close(ctx.channel(),
-                    (CloseWebSocketFrame) frame.retain());
-            String streamName = Notificator
-                    .createStreamNameFromUri(((CloseWebSocketFrame) frame)
-                            .reasonText());
+            handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
+            String streamName = Notificator.createStreamNameFromUri(((CloseWebSocketFrame) frame).reasonText());
             ListenerAdapter listener = Notificator.getListenerFor(streamName);
             if (listener != null) {
                 listener.removeSubscriber(ctx.channel());
@@ -157,15 +141,13 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
             Notificator.removeListenerIfNoSubscriberExists(listener);
             return;
         } else if (frame instanceof PingWebSocketFrame) {
-            ctx.channel().write(
-                    new PongWebSocketFrame(frame.content().retain()));
+            ctx.channel().write(new PongWebSocketFrame(frame.content().retain()));
             return;
         }
     }
 
     @Override
-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
-            throws Exception {
+    public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) throws Exception {
         if (cause instanceof java.nio.channels.ClosedChannelException == false) {
             // cause.printStackTrace();
         }
@@ -179,7 +161,7 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
      *            HTTP request from which the location will be returned
      * @return String representation of web socket location.
      */
-    private static String getWebSocketLocation(HttpRequest req) {
+    private static String getWebSocketLocation(final HttpRequest req) {
         return "http://" + req.headers().get(HOST) + req.getUri();
     }
 
index d188a029e7582a7672a67af0a956f978df79cc1b..754f156dde52d7b57eee9bc85b510685681bfc4c 100644 (file)
@@ -7,8 +7,8 @@ import io.netty.handler.codec.http.HttpObjectAggregator;
 import io.netty.handler.codec.http.HttpServerCodec;
 
 /**
- * {@link WebSocketServerInitializer} is used to setup the
- * {@link ChannelPipeline} of a {@link io.netty.channel.Channel}.
+ * {@link WebSocketServerInitializer} is used to setup the {@link ChannelPipeline} of a {@link io.netty.channel.Channel}
+ * .
  */
 public class WebSocketServerInitializer extends ChannelInitializer<SocketChannel> {
 
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/yang/opendaylight-rest-connector.yang b/opendaylight/md-sal/sal-rest-connector/src/main/yang/opendaylight-rest-connector.yang
new file mode 100644 (file)
index 0000000..a8fc8ff
--- /dev/null
@@ -0,0 +1,47 @@
+module opendaylight-rest-connector {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:rest:connector";
+    prefix "md-sal-rest-connector";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import opendaylight-md-sal-dom {prefix dom; revision-date 2013-10-28;}
+    import opendaylight-md-sal-binding {prefix sal; revision-date 2013-10-28;}
+    import ietf-inet-types {prefix inet; revision-date 2010-09-24;}
+    description
+        "Service definition for Rest Connector";
+    revision "2014-07-24" {
+        description
+            "Initial revision";
+    }
+    
+    identity rest-connector {
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.sal.rest.api.RestConnector";
+    }
+    
+    identity rest-connector-impl {
+        base config:module-type;
+        config:provided-service rest-connector;
+        config:java-name-prefix RestConnector;
+    }
+    
+    augment "/config:modules/config:module/config:configuration" {
+        case rest-connector-impl {
+            when "/config:modules/config:module/config:type = 'rest-connector-impl'";
+            leaf websocket-port {
+                mandatory true;
+                type inet:port-number;
+            }
+            container dom-broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity dom:dom-broker-osgi-registry;
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
index d978a2f0de25af2f26c106dea7c79a759fea4ce0..0f059f5024cdc7c70dc7042f488e9fa22c32da55 100644 (file)
@@ -13,13 +13,13 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
 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;
@@ -37,9 +37,6 @@ 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 CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
 
     @BeforeClass
@@ -48,8 +45,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
     }
 
     /**
-     * Test of json output when as input are specified composite node with empty
-     * data + YANG file
+     * Test of json output when as input are specified composite node with empty data + YANG file
      */
 
     @Test
@@ -67,8 +63,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
     }
 
     /**
-     * Test of json output when as input are specified xml file (no empty
-     * elements)and YANG file
+     * Test of json output when as input are specified xml file (no empty elements)and YANG file
      */
     @Test
     public void xmlAndYangTypesWithJsonReaderTest() {
@@ -355,11 +350,8 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         assertEquals(1, lst11_1.getLfs().size());
         assertEquals(1, lst11_1.getConts().size());
         assertEquals(1, lst11_1.getLsts().size());
-        assertEquals(
-                lst11_1.getLsts().get("lst111"),
-                new Lst("lst111").addLstItem(new LstItem().addLf("lf1111", 35))
-                .addLstItem(new LstItem().addLf("lf1111", 34)).addLstItem(new LstItem())
-                .addLstItem(new LstItem()));
+        assertEquals(lst11_1.getLsts().get("lst111"), new Lst("lst111").addLstItem(new LstItem().addLf("lf1111", 35))
+                .addLstItem(new LstItem().addLf("lf1111", 34)).addLstItem(new LstItem()).addLstItem(new LstItem()));
         assertEquals(lst11_1.getConts().get("cont111"), new Cont("cont111"));
         // : lst11_1
 
@@ -378,8 +370,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         assertEquals(1, lst11_2_cont111.getLsts().size());
         assertTrue(lst11_2_cont111.getConts().isEmpty());
 
-        assertEquals(new LfLst("lflst1111").addLf(1024).addLf(4096),
-                lst11_2_cont111.getLfLsts().get("lflst1111"));
+        assertEquals(new LfLst("lflst1111").addLf(1024).addLf(4096), lst11_2_cont111.getLfLsts().get("lflst1111"));
         assertEquals(
                 new Lst("lst1111").addLstItem(new LstItem().addLf("lf1111B", 4)).addLstItem(
                         new LstItem().addLf("lf1111A", "lf1111A str12")), lst11_2_cont111.getLsts().get("lst1111"));
@@ -539,90 +530,108 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
                 TestUtils.buildQName("cont1", "simple:yang:types", "2013-11-5"), null, null, ModifyAction.CREATE, null);
 
         // lst11_1
-        MutableCompositeNode lst11_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1,
-                null, ModifyAction.CREATE, null);
+        MutableCompositeNode lst11_1 = NodeFactory
+                .createMutableCompositeNode(TestUtils.buildQName("lst11", "simple:yang:types", "2013-11-5"), cont1,
+                        null, ModifyAction.CREATE, null);
         cont1.getValue().add(lst11_1);
 
-        MutableSimpleNode<?> lf111_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_1,
-                (short) 1, ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf111_1 = NodeFactory.createMutableSimpleNode(
+                TestUtils.buildQName("lf111", "simple:yang:types", "2013-11-5"), lst11_1, (short) 1,
+                ModifyAction.CREATE, null);
         lst11_1.getValue().add(lf111_1);
 
         // lst111_1_1
-        MutableCompositeNode lst111_1_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"),
-                lst11_1, null, ModifyAction.CREATE, null);
+        MutableCompositeNode lst111_1_1 = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("lst111", "simple:yang:types", "2013-11-5"), lst11_1, null, ModifyAction.CREATE,
+                null);
         lst11_1.getValue().add(lst111_1_1);
-        MutableSimpleNode<?> lf1111_1_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111","simple:yang:types","2013-11-5"),
-                lst111_1_1, 34, ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf1111_1_1 = NodeFactory.createMutableSimpleNode(
+                TestUtils.buildQName("lf1111", "simple:yang:types", "2013-11-5"), lst111_1_1, 34, ModifyAction.CREATE,
+                null);
         lst111_1_1.getValue().add(lf1111_1_1);
         lst111_1_1.init();
         // :lst111_1_1
 
         // lst111_1_2
-        MutableCompositeNode lst111_1_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"),
-                lst11_1, null, ModifyAction.CREATE, null);
+        MutableCompositeNode lst111_1_2 = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("lst111", "simple:yang:types", "2013-11-5"), lst11_1, null, ModifyAction.CREATE,
+                null);
         lst11_1.getValue().add(lst111_1_2);
-        MutableSimpleNode<?> lf1111_1_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111","simple:yang:types","2013-11-5"),
-                lst111_1_2, 35, ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf1111_1_2 = NodeFactory.createMutableSimpleNode(
+                TestUtils.buildQName("lf1111", "simple:yang:types", "2013-11-5"), lst111_1_2, 35, ModifyAction.CREATE,
+                null);
         lst111_1_2.getValue().add(lf1111_1_2);
         lst111_1_2.init();
         // :lst111_1_2
 
         // lst111_1_3
-        MutableCompositeNode lst111_1_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"),
-                lst11_1, null, ModifyAction.CREATE, null);
+        MutableCompositeNode lst111_1_3 = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("lst111", "simple:yang:types", "2013-11-5"), lst11_1, null, ModifyAction.CREATE,
+                null);
         lst11_1.getValue().add(lst111_1_3);
         lst111_1_2.init();
         // :lst111_1_3
 
         // lst111_1_4
-        MutableCompositeNode lst111_1_4 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"),
-                lst11_1, null, ModifyAction.CREATE, null);
+        MutableCompositeNode lst111_1_4 = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("lst111", "simple:yang:types", "2013-11-5"), lst11_1, null, ModifyAction.CREATE,
+                null);
         lst11_1.getValue().add(lst111_1_4);
         lst111_1_2.init();
         // :lst111_1_4
 
-        MutableCompositeNode cont111_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"),
-                lst11_1, null, ModifyAction.CREATE, null);
+        MutableCompositeNode cont111_1 = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("cont111", "simple:yang:types", "2013-11-5"), lst11_1, null, ModifyAction.CREATE,
+                null);
         lst11_1.getValue().add(cont111_1);
 
         lst11_1.init();
         // :lst11_1
 
         // lst11_2
-        MutableCompositeNode lst11_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1,
-                null, ModifyAction.CREATE, null);
+        MutableCompositeNode lst11_2 = NodeFactory
+                .createMutableCompositeNode(TestUtils.buildQName("lst11", "simple:yang:types", "2013-11-5"), cont1,
+                        null, ModifyAction.CREATE, null);
         cont1.getValue().add(lst11_2);
 
-        MutableSimpleNode<?> lf111_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_2,
-                (short) 2, ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf111_2 = NodeFactory.createMutableSimpleNode(
+                TestUtils.buildQName("lf111", "simple:yang:types", "2013-11-5"), lst11_2, (short) 2,
+                ModifyAction.CREATE, null);
         lst11_2.getValue().add(lf111_2);
 
         // cont111_2
-        MutableCompositeNode cont111_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"),
-                lst11_2, null, ModifyAction.CREATE, null);
+        MutableCompositeNode cont111_2 = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("cont111", "simple:yang:types", "2013-11-5"), lst11_2, null, ModifyAction.CREATE,
+                null);
         lst11_2.getValue().add(cont111_2);
 
-        MutableSimpleNode<?> lflst1111_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111","simple:yang:types","2013-11-5"),
-                cont111_2, 1024, ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lflst1111_2_2 = NodeFactory.createMutableSimpleNode(
+                TestUtils.buildQName("lflst1111", "simple:yang:types", "2013-11-5"), cont111_2, 1024,
+                ModifyAction.CREATE, null);
         cont111_2.getValue().add(lflst1111_2_2);
-        MutableSimpleNode<?> lflst1111_2_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111","simple:yang:types","2013-11-5"),
-                cont111_2, 4096, ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lflst1111_2_3 = NodeFactory.createMutableSimpleNode(
+                TestUtils.buildQName("lflst1111", "simple:yang:types", "2013-11-5"), cont111_2, 4096,
+                ModifyAction.CREATE, null);
         cont111_2.getValue().add(lflst1111_2_3);
 
         // lst1111_2
-        MutableCompositeNode lst1111_2_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"),
-                cont111_2, null, ModifyAction.CREATE, null);
+        MutableCompositeNode lst1111_2_1 = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("lst1111", "simple:yang:types", "2013-11-5"), cont111_2, null,
+                ModifyAction.CREATE, null);
         cont111_2.getValue().add(lst1111_2_1);
-        MutableSimpleNode<?> lf1111B_2_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111B","simple:yang:types","2013-11-5"),
-                lst1111_2_1, (short) 4, ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf1111B_2_1 = NodeFactory.createMutableSimpleNode(
+                TestUtils.buildQName("lf1111B", "simple:yang:types", "2013-11-5"), lst1111_2_1, (short) 4,
+                ModifyAction.CREATE, null);
         lst1111_2_1.getValue().add(lf1111B_2_1);
         lst1111_2_1.init();
 
-        MutableCompositeNode lst1111_2_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"),
-                cont111_2, null, ModifyAction.CREATE, null);
+        MutableCompositeNode lst1111_2_2 = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("lst1111", "simple:yang:types", "2013-11-5"), cont111_2, null,
+                ModifyAction.CREATE, null);
         cont111_2.getValue().add(lst1111_2_2);
-        MutableSimpleNode<?> lf1111A_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111A","simple:yang:types","2013-11-5"),
-                lst1111_2_2, "lf1111A str12", ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf1111A_2_2 = NodeFactory.createMutableSimpleNode(
+                TestUtils.buildQName("lf1111A", "simple:yang:types", "2013-11-5"), lst1111_2_2, "lf1111A str12",
+                ModifyAction.CREATE, null);
         lst1111_2_2.getValue().add(lf1111A_2_2);
         lst1111_2_2.init();
         // :lst1111_2
@@ -630,8 +639,9 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         cont111_2.init();
         // :cont111_2
 
-        MutableCompositeNode lst112_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst112","simple:yang:types","2013-11-5"), lst11_2,
-                null, ModifyAction.CREATE, null);
+        MutableCompositeNode lst112_2 = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("lst112", "simple:yang:types", "2013-11-5"), lst11_2, null, ModifyAction.CREATE,
+                null);
         lst11_2.getValue().add(lst112_2);
         lst112_2.init();
         lst11_2.init();
@@ -639,26 +649,31 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         // :lst11_2
 
         // lst11_3
-        MutableCompositeNode lst11_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1,
-                null, ModifyAction.CREATE, null);
+        MutableCompositeNode lst11_3 = NodeFactory
+                .createMutableCompositeNode(TestUtils.buildQName("lst11", "simple:yang:types", "2013-11-5"), cont1,
+                        null, ModifyAction.CREATE, null);
         cont1.getValue().add(lst11_3);
 
-        MutableSimpleNode<?> lf111_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_3,
-                (short) 3, ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf111_3 = NodeFactory.createMutableSimpleNode(
+                TestUtils.buildQName("lf111", "simple:yang:types", "2013-11-5"), lst11_3, (short) 3,
+                ModifyAction.CREATE, null);
         lst11_3.getValue().add(lf111_3);
 
         // cont111_3
-        MutableCompositeNode cont111_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"),
-                lst11_3, null, ModifyAction.CREATE, null);
+        MutableCompositeNode cont111_3 = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("cont111", "simple:yang:types", "2013-11-5"), lst11_3, null, ModifyAction.CREATE,
+                null);
         lst11_3.getValue().add(cont111_3);
 
-        MutableCompositeNode lst1111_3_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"),
-                cont111_3, null, ModifyAction.CREATE, null);
+        MutableCompositeNode lst1111_3_1 = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("lst1111", "simple:yang:types", "2013-11-5"), cont111_3, null,
+                ModifyAction.CREATE, null);
         cont111_3.getValue().add(lst1111_3_1);
         lst1111_3_1.init();
 
-        MutableCompositeNode lst1111_3_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"),
-                cont111_3, null, ModifyAction.CREATE, null);
+        MutableCompositeNode lst1111_3_2 = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("lst1111", "simple:yang:types", "2013-11-5"), cont111_3, null,
+                ModifyAction.CREATE, null);
         cont111_3.getValue().add(lst1111_3_2);
         lst1111_3_2.init();
 
index 21590ecb335fa81c309012bc34b92c1975da169c..0d0ce5cdd36908e458e50ac242ef356d4008287e 100644 (file)
@@ -10,9 +10,7 @@ package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.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.StructuredDataToJsonProvider;
@@ -29,9 +27,8 @@ public class CnSnJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
     }
 
     /**
-     * Test when some data are in one case node and other in another. This isn't
-     * correct. Next Json validator should return error because nodes has to be
-     * from one case below concrete choice.
+     * Test when some data are in one case node and other in another. This isn't correct. Next Json validator should
+     * return error because nodes has to be from one case below concrete choice.
      *
      */
     @Test
@@ -40,10 +37,9 @@ public class CnSnJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
     }
 
     /**
-     * Test when some data are in one case node and other in another.
-     * Additionally data are loadef from various choices. This isn't correct.
-     * Next Json validator should return error because nodes has to be from one
-     * case below concrete choice.
+     * Test when some data are in one case node and other in another. Additionally data are loadef from various choices.
+     * This isn't correct. Next Json validator should return error because nodes has to be from one case below concrete
+     * choice.
      *
      */
     @Test
@@ -53,8 +49,8 @@ public class CnSnJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
     }
 
     /**
-     * Test when second level data are red first, then first and at the end
-     * third level. Level represents pass through couple choice-case
+     * Test when second level data are red first, then first and at the end third level. Level represents pass through
+     * couple choice-case
      */
 
     @Test
@@ -103,8 +99,8 @@ public class CnSnJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
     }
 
     /**
-     * Test whether is possible to find data schema for node which is specified
-     * as dirrect subnode of choice (case without CASE key word)
+     * Test whether is possible to find data schema for node which is specified as dirrect subnode of choice (case
+     * without CASE key word)
      */
     @Test
     public void nodeSchemasInCaseNotDefinedWithCaseKeyword() {
index 93d32a14992e9df0209be9409cbea91074db514a..4b8b71440a7688334897bafc3c3117e8e2dfb937 100644 (file)
@@ -13,10 +13,12 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 
+import com.google.common.collect.Maps;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
 import java.io.IOException;
 import java.io.StringReader;
 import java.util.Map;
-
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
@@ -27,10 +29,6 @@ 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 com.google.common.collect.Maps;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonToken;
-
 public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader {
 
     static abstract class LeafVerifier {
@@ -38,15 +36,15 @@ public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader
         Object expectedValue;
         JsonToken expectedToken;
 
-        LeafVerifier( Object expectedValue, JsonToken expectedToken ) {
+        LeafVerifier(Object expectedValue, JsonToken expectedToken) {
             this.expectedValue = expectedValue;
             this.expectedToken = expectedToken;
         }
 
-        abstract Object getActualValue( JsonReader reader ) throws IOException;
+        abstract Object getActualValue(JsonReader reader) throws IOException;
 
-        void verify( JsonReader reader, String keyName ) throws IOException {
-            assertEquals( "Json value for key " + keyName, expectedValue, getActualValue( reader ) );
+        void verify(JsonReader reader, String keyName) throws IOException {
+            assertEquals("Json value for key " + keyName, expectedValue, getActualValue(reader));
         }
 
         JsonToken expectedTokenType() {
@@ -56,31 +54,29 @@ public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader
 
     static class BooleanVerifier extends LeafVerifier {
 
-        public BooleanVerifier( boolean expected ) {
-            super( expected, JsonToken.BOOLEAN );
+        public BooleanVerifier(boolean expected) {
+            super(expected, JsonToken.BOOLEAN);
         }
 
         @Override
-        Object getActualValue( JsonReader reader ) throws IOException {
+        Object getActualValue(JsonReader reader) throws IOException {
             return reader.nextBoolean();
         }
     }
 
     static class NumberVerifier extends LeafVerifier {
 
-        public NumberVerifier( Number expected ) {
-            super( expected, JsonToken.NUMBER );
+        public NumberVerifier(Number expected) {
+            super(expected, JsonToken.NUMBER);
         }
 
         @Override
-        Object getActualValue( JsonReader reader ) throws IOException {
-            if( expectedValue instanceof Double ) {
+        Object getActualValue(JsonReader reader) throws IOException {
+            if (expectedValue instanceof Double) {
                 return reader.nextDouble();
-            }
-            else if( expectedValue instanceof Long ) {
+            } else if (expectedValue instanceof Long) {
                 return reader.nextLong();
-            }
-            else if( expectedValue instanceof Integer ) {
+            } else if (expectedValue instanceof Integer) {
                 return reader.nextInt();
             }
 
@@ -90,12 +86,12 @@ public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader
 
     static class StringVerifier extends LeafVerifier {
 
-        StringVerifier( String expected ) {
-            super( expected, JsonToken.STRING );
+        StringVerifier(String expected) {
+            super(expected, JsonToken.STRING);
         }
 
         @Override
-        Object getActualValue( JsonReader reader ) throws IOException {
+        Object getActualValue(JsonReader reader) throws IOException {
             return reader.nextString();
         }
     }
@@ -103,11 +99,11 @@ public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader
     static class EmptyVerifier extends LeafVerifier {
 
         EmptyVerifier() {
-            super( null, null );
+            super(null, null);
         }
 
         @Override
-        Object getActualValue( JsonReader reader ) throws IOException {
+        Object getActualValue(JsonReader reader) throws IOException {
             reader.beginArray();
             reader.nextNull();
             reader.endArray();
@@ -119,68 +115,68 @@ public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader
     static class ComplexAnyXmlVerifier extends LeafVerifier {
 
         ComplexAnyXmlVerifier() {
-            super( null, JsonToken.BEGIN_OBJECT );
+            super(null, JsonToken.BEGIN_OBJECT);
         }
 
         @Override
-        void verify( JsonReader reader, String keyName ) throws IOException {
+        void verify(JsonReader reader, String keyName) throws IOException {
 
             reader.beginObject();
             String innerKey = reader.nextName();
-            assertEquals( "Json reader child key for " + keyName, "data", innerKey );
-            assertEquals( "Json token type for key " + innerKey, JsonToken.BEGIN_OBJECT, reader.peek() );
+            assertEquals("Json reader child key for " + keyName, "data", innerKey);
+            assertEquals("Json token type for key " + innerKey, JsonToken.BEGIN_OBJECT, reader.peek());
 
             reader.beginObject();
-            verifyLeaf( reader, innerKey, "leaf1", "leaf1-value" );
-            verifyLeaf( reader, innerKey, "leaf2", "leaf2-value" );
+            verifyLeaf(reader, innerKey, "leaf1", "leaf1-value");
+            verifyLeaf(reader, innerKey, "leaf2", "leaf2-value");
 
             String nextName = reader.nextName();
-            assertEquals( "Json reader child key for " + innerKey, "leaf-list", nextName );
+            assertEquals("Json reader child key for " + innerKey, "leaf-list", nextName);
             reader.beginArray();
-            assertEquals( "Json value for key " + nextName, "leaf-list-value1", reader.nextString() );
-            assertEquals( "Json value for key " + nextName, "leaf-list-value2", reader.nextString() );
+            assertEquals("Json value for key " + nextName, "leaf-list-value1", reader.nextString());
+            assertEquals("Json value for key " + nextName, "leaf-list-value2", reader.nextString());
             reader.endArray();
 
             nextName = reader.nextName();
-            assertEquals( "Json reader child key for " + innerKey, "list", nextName );
+            assertEquals("Json reader child key for " + innerKey, "list", nextName);
             reader.beginArray();
-            verifyNestedLists( reader, 1 );
-            verifyNestedLists( reader, 3 );
+            verifyNestedLists(reader, 1);
+            verifyNestedLists(reader, 3);
             reader.endArray();
 
             reader.endObject();
             reader.endObject();
         }
 
-        void verifyNestedLists( JsonReader reader, int leafNum ) throws IOException {
+        void verifyNestedLists(JsonReader reader, int leafNum) throws IOException {
             reader.beginObject();
 
             String nextName = reader.nextName();
-            assertEquals( "Json reader next name", "nested-list", nextName );
+            assertEquals("Json reader next name", "nested-list", nextName);
 
             reader.beginArray();
 
             reader.beginObject();
-            verifyLeaf( reader, "nested-list", "nested-leaf", "nested-value" + leafNum++ );
+            verifyLeaf(reader, "nested-list", "nested-leaf", "nested-value" + leafNum++);
             reader.endObject();
 
             reader.beginObject();
-            verifyLeaf( reader, "nested-list", "nested-leaf", "nested-value" + leafNum );
+            verifyLeaf(reader, "nested-list", "nested-leaf", "nested-value" + leafNum);
             reader.endObject();
 
             reader.endArray();
             reader.endObject();
         }
 
-        void verifyLeaf( JsonReader reader, String parent, String name, String value ) throws IOException {
+        void verifyLeaf(JsonReader reader, String parent, String name, String value) throws IOException {
             String nextName = reader.nextName();
-            assertEquals( "Json reader child key for " + parent, name, nextName );
-            assertEquals( "Json token type for key " + parent, JsonToken.STRING, reader.peek() );
-            assertEquals( "Json value for key " + nextName, value, reader.nextString() );
+            assertEquals("Json reader child key for " + parent, name, nextName);
+            assertEquals("Json token type for key " + parent, JsonToken.STRING, reader.peek());
+            assertEquals("Json value for key " + nextName, value, reader.nextString());
         }
 
         @Override
-        Object getActualValue( JsonReader reader ) throws IOException {
+        Object getActualValue(JsonReader reader) throws IOException {
             return null;
         }
     }
@@ -199,7 +195,7 @@ public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader
         TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont");
 
         String jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
-                    StructuredDataToJsonProvider.INSTANCE);
+                StructuredDataToJsonProvider.INSTANCE);
 
         assertNotNull(jsonOutput);
 
@@ -236,68 +232,68 @@ public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader
     private void jsonReadContElements(JsonReader jReader) throws IOException {
         jReader.beginObject();
 
-        Map<String,LeafVerifier> expectedMap = Maps.newHashMap();
-        expectedMap.put( "lfnint8Min", new NumberVerifier( Integer.valueOf( -128 ) ) );
-        expectedMap.put( "lfnint8Max", new NumberVerifier( Integer.valueOf( 127 ) ) );
-        expectedMap.put( "lfnint16Min", new NumberVerifier( Integer.valueOf( -32768 ) ) );
-        expectedMap.put( "lfnint16Max", new NumberVerifier( Integer.valueOf( 32767 ) ) );
-        expectedMap.put( "lfnint32Min", new NumberVerifier( Integer.valueOf( -2147483648 ) ) );
-        expectedMap.put( "lfnint32Max", new NumberVerifier( Long.valueOf( 2147483647 ) ) );
-        expectedMap.put( "lfnint64Min", new NumberVerifier( Long.valueOf( -9223372036854775808L ) ) );
-        expectedMap.put( "lfnint64Max", new NumberVerifier( Long.valueOf( 9223372036854775807L ) ) );
-        expectedMap.put( "lfnuint8Max", new NumberVerifier( Integer.valueOf( 255 ) ) );
-        expectedMap.put( "lfnuint16Max", new NumberVerifier( Integer.valueOf( 65535 ) ) );
-        expectedMap.put( "lfnuint32Max", new NumberVerifier( Long.valueOf( 4294967295L ) ) );
-        expectedMap.put( "lfstr", new StringVerifier( "lfstr" ) );
-        expectedMap.put( "lfstr1", new StringVerifier( "" ) );
-        expectedMap.put( "lfbool1", new BooleanVerifier( true ) );
-        expectedMap.put( "lfbool2", new BooleanVerifier( false ) );
-        expectedMap.put( "lfbool3", new BooleanVerifier( false ) );
-        expectedMap.put( "lfdecimal1", new NumberVerifier( new Double( 43.32 ) ) );
-        expectedMap.put( "lfdecimal2", new NumberVerifier( new Double( -0.43 ) ) );
-        expectedMap.put( "lfdecimal3", new NumberVerifier( new Double( 43 ) ) );
-        expectedMap.put( "lfdecimal4", new NumberVerifier( new Double( 43E3 ) ) );
-        expectedMap.put( "lfdecimal6", new NumberVerifier( new Double( 33.12345 ) ) );
-        expectedMap.put( "lfenum", new StringVerifier( "enum3" ) );
-        expectedMap.put( "lfbits", new StringVerifier( "bit3 bit2" ) );
-        expectedMap.put( "lfbinary", new StringVerifier( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ) );
-        expectedMap.put( "lfunion1", new StringVerifier( "324" ) );
-        expectedMap.put( "lfunion2", new StringVerifier( "33.3" ) );
-        expectedMap.put( "lfunion3", new StringVerifier( "55" ) );
-        expectedMap.put( "lfunion4", new StringVerifier( "true" ) );
-        expectedMap.put( "lfunion5", new StringVerifier( "true" ) );
-        expectedMap.put( "lfunion6", new StringVerifier( "10" ) );
-        expectedMap.put( "lfunion7", new StringVerifier( "" ) );
-        expectedMap.put( "lfunion8", new StringVerifier( "" ) );
-        expectedMap.put( "lfunion9", new StringVerifier( "" ) );
-        expectedMap.put( "lfunion10", new StringVerifier( "bt1" ) );
-        expectedMap.put( "lfunion11", new StringVerifier( "33" ) );
-        expectedMap.put( "lfunion12", new StringVerifier( "false" ) );
-        expectedMap.put( "lfunion13", new StringVerifier( "b1" ) );
-        expectedMap.put( "lfunion14", new StringVerifier( "zero" ) );
-        expectedMap.put( "lfempty", new EmptyVerifier() );
-        expectedMap.put( "identityref1", new StringVerifier( "simple-data-types:iden" ) );
-        expectedMap.put( "complex-any", new ComplexAnyXmlVerifier() );
-        expectedMap.put( "simple-any", new StringVerifier( "simple" ) );
-        expectedMap.put( "empty-any", new StringVerifier( "" ) );
+        Map<String, LeafVerifier> expectedMap = Maps.newHashMap();
+        expectedMap.put("lfnint8Min", new NumberVerifier(Integer.valueOf(-128)));
+        expectedMap.put("lfnint8Max", new NumberVerifier(Integer.valueOf(127)));
+        expectedMap.put("lfnint16Min", new NumberVerifier(Integer.valueOf(-32768)));
+        expectedMap.put("lfnint16Max", new NumberVerifier(Integer.valueOf(32767)));
+        expectedMap.put("lfnint32Min", new NumberVerifier(Integer.valueOf(-2147483648)));
+        expectedMap.put("lfnint32Max", new NumberVerifier(Long.valueOf(2147483647)));
+        expectedMap.put("lfnint64Min", new NumberVerifier(Long.valueOf(-9223372036854775808L)));
+        expectedMap.put("lfnint64Max", new NumberVerifier(Long.valueOf(9223372036854775807L)));
+        expectedMap.put("lfnuint8Max", new NumberVerifier(Integer.valueOf(255)));
+        expectedMap.put("lfnuint16Max", new NumberVerifier(Integer.valueOf(65535)));
+        expectedMap.put("lfnuint32Max", new NumberVerifier(Long.valueOf(4294967295L)));
+        expectedMap.put("lfstr", new StringVerifier("lfstr"));
+        expectedMap.put("lfstr1", new StringVerifier(""));
+        expectedMap.put("lfbool1", new BooleanVerifier(true));
+        expectedMap.put("lfbool2", new BooleanVerifier(false));
+        expectedMap.put("lfbool3", new BooleanVerifier(false));
+        expectedMap.put("lfdecimal1", new NumberVerifier(new Double(43.32)));
+        expectedMap.put("lfdecimal2", new NumberVerifier(new Double(-0.43)));
+        expectedMap.put("lfdecimal3", new NumberVerifier(new Double(43)));
+        expectedMap.put("lfdecimal4", new NumberVerifier(new Double(43E3)));
+        expectedMap.put("lfdecimal6", new NumberVerifier(new Double(33.12345)));
+        expectedMap.put("lfenum", new StringVerifier("enum3"));
+        expectedMap.put("lfbits", new StringVerifier("bit3 bit2"));
+        expectedMap.put("lfbinary", new StringVerifier("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
+        expectedMap.put("lfunion1", new StringVerifier("324"));
+        expectedMap.put("lfunion2", new StringVerifier("33.3"));
+        expectedMap.put("lfunion3", new StringVerifier("55"));
+        expectedMap.put("lfunion4", new StringVerifier("true"));
+        expectedMap.put("lfunion5", new StringVerifier("true"));
+        expectedMap.put("lfunion6", new StringVerifier("10"));
+        expectedMap.put("lfunion7", new StringVerifier(""));
+        expectedMap.put("lfunion8", new StringVerifier(""));
+        expectedMap.put("lfunion9", new StringVerifier(""));
+        expectedMap.put("lfunion10", new StringVerifier("bt1"));
+        expectedMap.put("lfunion11", new StringVerifier("33"));
+        expectedMap.put("lfunion12", new StringVerifier("false"));
+        expectedMap.put("lfunion13", new StringVerifier("b1"));
+        expectedMap.put("lfunion14", new StringVerifier("zero"));
+        expectedMap.put("lfempty", new EmptyVerifier());
+        expectedMap.put("identityref1", new StringVerifier("simple-data-types:iden"));
+        expectedMap.put("complex-any", new ComplexAnyXmlVerifier());
+        expectedMap.put("simple-any", new StringVerifier("simple"));
+        expectedMap.put("empty-any", new StringVerifier(""));
 
         while (jReader.hasNext()) {
             String keyName = jReader.nextName();
             JsonToken peek = jReader.peek();
 
-            LeafVerifier verifier = expectedMap.remove( keyName );
-            assertNotNull( "Found unexpected leaf: " + keyName , verifier );
+            LeafVerifier verifier = expectedMap.remove(keyName);
+            assertNotNull("Found unexpected leaf: " + keyName, verifier);
 
             JsonToken expToken = verifier.expectedTokenType();
-            if( expToken != null ) {
-                assertEquals( "Json token type for key " + keyName, expToken, peek );
+            if (expToken != null) {
+                assertEquals("Json token type for key " + keyName, expToken, peek);
             }
 
-            verifier.verify( jReader, keyName );
+            verifier.verify(jReader, keyName);
         }
 
-        if( !expectedMap.isEmpty() ) {
-            fail( "Missing leaf nodes in Json output: " +expectedMap.keySet() );
+        if (!expectedMap.isEmpty()) {
+            fail("Missing leaf nodes in Json output: " + expectedMap.keySet());
         }
 
         jReader.endObject();
@@ -307,15 +303,13 @@ public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader
     public void testBadData() throws Exception {
 
         try {
-            CompositeNode compositeNode = TestUtils.readInputToCnSn(
-                                               "/cnsn-to-json/simple-data-types/xml/bad-data.xml",
-                                               XmlToCompositeNodeProvider.INSTANCE);
+            CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/bad-data.xml",
+                    XmlToCompositeNodeProvider.INSTANCE);
 
             TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont");
-            fail( "Expected RestconfDocumentedException" );
-        }
-        catch( RestconfDocumentedException e ) {
-            assertEquals( "getErrorTag", ErrorTag.INVALID_VALUE, e.getErrors().get( 0 ).getErrorTag() );
+            fail("Expected RestconfDocumentedException");
+        } catch (RestconfDocumentedException e) {
+            assertEquals("getErrorTag", ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
         }
     }
 }
index fdd3aa6684303babcabc9c849792e37c6cbf758e..506ca847a936c4abc006c099b02f970a6022fe36 100644 (file)
@@ -13,9 +13,7 @@ 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;
@@ -74,14 +72,16 @@ public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
     }
 
     private CompositeNode prepareCompositeNode(final Object value) {
-        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont","identityref:module","2013-12-2"), null, null,
-                ModifyAction.CREATE, null);
-        MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont1","identityref:module","2013-12-2"), cont, null,
-                ModifyAction.CREATE, null);
+        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("cont", "identityref:module", "2013-12-2"), null, null, ModifyAction.CREATE, null);
+        MutableCompositeNode cont1 = NodeFactory
+                .createMutableCompositeNode(TestUtils.buildQName("cont1", "identityref:module", "2013-12-2"), cont,
+                        null, ModifyAction.CREATE, null);
         cont.getValue().add(cont1);
 
-        MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1","identityref:module","2013-12-2"), cont1, value,
-                ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf1 = NodeFactory
+                .createMutableSimpleNode(TestUtils.buildQName("lf1", "identityref:module", "2013-12-2"), cont1, value,
+                        ModifyAction.CREATE, null);
 
         cont1.getValue().add(lf1);
         cont1.init();
index 050a9925ff3f7f767af0c371ef651d2d3e0ba7a5..50c834b1ffee46f96787d73ac47c9f6e49d6ffd4 100644 (file)
@@ -12,10 +12,8 @@ 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;
@@ -147,7 +145,8 @@ public class CnSnToJsonIncorrectTopLevelTest extends YangAndXmlAndDataSchemaLoad
     @Test
     public void incorrectTopLevelElementTest() {
 
-        CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml", XmlToCompositeNodeProvider.INSTANCE);
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml",
+                XmlToCompositeNodeProvider.INSTANCE);
         DataSchemaNode incorrectDataSchema = null;
         incorrectDataSchema = new IncorrectDataSchema();
 
index 21a46a6cc32b60de0e3db3c9c74e71c96e5385ec..6e41dcb57769b6fd633edb2bea9ea0ede1c9014a 100644 (file)
@@ -13,9 +13,7 @@ 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;
@@ -50,8 +48,8 @@ public class CnSnToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
     }
 
     /**
-     * Tests case when reference to not existing element is present. In this
-     * case value from single node is printed as string.
+     * 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() {
@@ -60,8 +58,7 @@ public class CnSnToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
     }
 
     /**
-     * Tests case when non leaf element is referenced. In this case value from
-     * single node is printed as string.
+     * Tests case when non leaf element is referenced. In this case value from single node is printed as string.
      */
     @Test
     public void leafrefToNotLeafTest() {
index 24dba17c90cdff4e9a87d0a059160357dcbaad88..3ca29c8d65cd485002ef8b46ad7b675d4a4bc581 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.opendaylight.controller.sal.restconf.impl.test.TestUtils.containsStringData;
 
 import java.io.IOException;
 import java.util.Collections;
@@ -45,12 +46,12 @@ public class CnSnToJsonNotExistingLeafTypeTest extends YangAndXmlAndDataSchemaLo
     @Test
     public void incorrectTopLevelElementTest() throws WebApplicationException, IOException {
         String jsonOutput = null;
-        jsonOutput = TestUtils
-                .writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(),
-                        Collections.<Module>emptySet(), prepareDataSchemaNode(),
-                        StructuredDataToJsonProvider.INSTANCE);
+        jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(),
+                Collections.<Module> emptySet(), prepareDataSchemaNode(), StructuredDataToJsonProvider.INSTANCE);
         assertNotNull(jsonOutput);
-        assertTrue(jsonOutput.contains("\"lf1\": \"\""));
+
+        // pattern for e.g. > "lf1" : "" < or >"lf1":""<
+        assertTrue(containsStringData(jsonOutput, "\"lf1\"", ":", "\"\""));
     }
 
     private CompositeNode prepareCompositeNode() {
index e116129bf7cc63736760688234b1f7665dcf9533..eb6a5b9e00f7c7af65d2398bd2e21e87f650fe9f 100644 (file)
@@ -9,11 +9,10 @@ package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.opendaylight.controller.sal.restconf.impl.test.TestUtils.containsStringData;
 
 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;
@@ -30,8 +29,7 @@ public class CnSnToJsonWithAugmentTest extends YangAndXmlAndDataSchemaLoader {
     }
 
     /**
-     * Test of json output when as input are specified composite node with empty
-     * data + YANG file
+     * Test of json output when as input are specified composite node with empty data + YANG file
      */
     @Test
     public void augmentedElementsToJson() {
@@ -47,12 +45,12 @@ public class CnSnToJsonWithAugmentTest extends YangAndXmlAndDataSchemaLoader {
         }
         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\": ["));
+        assertTrue(containsStringData(jsonOutput, "\"augment-leaf:lf2\"", ":", "\"lf2\""));
+        assertTrue(containsStringData(jsonOutput, "\"augment-container:cont1\"", ":", "\\{"));
+        assertTrue(containsStringData(jsonOutput, "\"augment-container:lf11\"", ":", "\"lf11\""));
+        assertTrue(containsStringData(jsonOutput, "\"augment-list:lst1\"", ":", "\\["));
+        assertTrue(containsStringData(jsonOutput, "\"augment-list:lf11\"", ":", "\"lf1_1\""));
+        assertTrue(containsStringData(jsonOutput, "\"augment-list:lf11\"", ":", "\"lf1_2\""));
+        assertTrue(containsStringData(jsonOutput, "\"augment-leaflist:lflst1\"", ":", "\\["));
     }
 }
index 052bb1a2be762ffca684a54109f724bd4d188ce9..a84fc79b86fbc9bb1d028859b629aeb1ecbfe622 100644 (file)
@@ -13,9 +13,7 @@ import java.io.IOException;
 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;
index 086e648097294354cb8a34baca155581397dad15..3ab880fe7e19a5eb156608e8c34435819ad6c568 100644 (file)
@@ -12,9 +12,7 @@ import static org.junit.Assert.assertNotNull;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
-
 import javax.ws.rs.WebApplicationException;
-
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
@@ -26,9 +24,8 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 /**
  *
- * 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
+ * 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 CnSnInstanceIdentifierToXmlTest extends YangAndXmlAndDataSchemaLoader {
@@ -40,7 +37,7 @@ public class CnSnInstanceIdentifierToXmlTest extends YangAndXmlAndDataSchemaLoad
 
     @Test
     public void snAsYangInstanceIdentifier() throws WebApplicationException, IOException, URISyntaxException {
-        CompositeNode cnSnData = prepareCnStructForYangData( );
+        CompositeNode cnSnData = prepareCnStructForYangData();
         String xmlOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSnData, modules, dataSchemaNode,
                 StructuredDataToXmlProvider.INSTANCE);
         assertNotNull(xmlOutput);
index 2ada6e13e9a64c2e62101f693027e3686645d025..800e2d3b486998e0993a136a0e7b0a1de6551c4c 100644 (file)
@@ -11,9 +11,7 @@ import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
 import java.util.Collections;
-
 import javax.ws.rs.WebApplicationException;
-
 import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
@@ -41,8 +39,8 @@ public class CnSnToXmlNotExistingLeafTypeTest {
 
         boolean nullPointerExceptionRaised = false;
         try {
-            TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(),
-                    Collections.<Module>emptySet(), prepareDataSchemaNode(), StructuredDataToXmlProvider.INSTANCE);
+            TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(), Collections.<Module> emptySet(),
+                    prepareDataSchemaNode(), StructuredDataToXmlProvider.INSTANCE);
         } catch (WebApplicationException | IOException e) {
             LOG.error("WebApplicationException or IOException was raised");
         } catch (NullPointerException e) {
index 9318af529b74c6ec4097331f6e374b7aa7038e9b..3d5fee3ab8aff5ef3adfde3dbbcdc91a9a13923e 100644 (file)
@@ -12,12 +12,12 @@ import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
 import java.io.IOException;
 import java.util.List;
-
 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.StructuredDataToXmlProvider;
@@ -50,14 +50,10 @@ import org.opendaylight.yangtools.yang.model.util.Uint64;
 import org.opendaylight.yangtools.yang.model.util.Uint8;
 import org.opendaylight.yangtools.yang.model.util.UnionType;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-
 /**
  *
- * 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
+ * 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 CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader {
@@ -87,76 +83,77 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader {
         serializeToXml(prepareLeafrefData(), "<lfBoolean>true</lfBoolean>", "<lfLfref>true</lfLfref>");
     }
 
-
     @Test
     public void snAsYangStringToXmlTest() {
         serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(StringType.getInstance()).deserialize("lfStr value"),
-                        "lfStr"), "<lfStr>lfStr value</lfStr>");
+                prepareCnStructForYangData(
+                        TypeDefinitionAwareCodec.from(StringType.getInstance()).deserialize("lfStr value"), "lfStr"),
+                "<lfStr>lfStr value</lfStr>");
     }
 
     @Test
     public void snAsYangInt8ToXmlTest() {
         String elName = "lfInt8";
         serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Int8.getInstance()).deserialize("14"), elName), "<"
-                        + elName + ">14</" + elName + ">");
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Int8.getInstance()).deserialize("14"), elName),
+                "<" + elName + ">14</" + elName + ">");
     }
 
     @Test
     public void snAsYangInt16ToXmlTest() {
         String elName = "lfInt16";
         serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Int16.getInstance()).deserialize("3000"), elName),
-                "<" + elName + ">3000</" + elName + ">");
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Int16.getInstance()).deserialize("3000"),
+                        elName), "<" + elName + ">3000</" + elName + ">");
     }
 
     @Test
     public void snAsYangInt32ToXmlTest() {
         String elName = "lfInt32";
         serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Int32.getInstance()).deserialize("201234"), elName),
-                "<" + elName + ">201234</" + elName + ">");
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Int32.getInstance()).deserialize("201234"),
+                        elName), "<" + elName + ">201234</" + elName + ">");
     }
 
     @Test
     public void snAsYangInt64ToXmlTest() {
         String elName = "lfInt64";
         serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Int64.getInstance()).deserialize("5123456789"),
-                        elName), "<" + elName + ">5123456789</" + elName + ">");
+                prepareCnStructForYangData(
+                        TypeDefinitionAwareCodec.from(Int64.getInstance()).deserialize("5123456789"), elName), "<"
+                        + elName + ">5123456789</" + elName + ">");
     }
 
     @Test
     public void snAsYangUint8ToXmlTest() {
         String elName = "lfUint8";
         serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Uint8.getInstance()).deserialize("200"), elName),
-                "<" + elName + ">200</" + elName + ">");
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Uint8.getInstance()).deserialize("200"),
+                        elName), "<" + elName + ">200</" + elName + ">");
     }
 
     @Test
     public void snAsYangUint16ToXmlTest() {
         String elName = "lfUint16";
         serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Uint16.getInstance()).deserialize("4000"), elName),
-                "<" + elName + ">4000</" + elName + ">");
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Uint16.getInstance()).deserialize("4000"),
+                        elName), "<" + elName + ">4000</" + elName + ">");
     }
 
     @Test
     public void snAsYangUint32ToXmlTest() {
         String elName = "lfUint32";
         serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Uint32.getInstance()).deserialize("4123456789"),
-                        elName), "<" + elName + ">4123456789</" + elName + ">");
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Uint32.getInstance())
+                        .deserialize("4123456789"), elName), "<" + elName + ">4123456789</" + elName + ">");
     }
 
     @Test
     public void snAsYangUint64ToXmlTest() {
         String elName = "lfUint64";
         serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Uint64.getInstance()).deserialize("5123456789"),
-                        elName), "<" + elName + ">5123456789</" + elName + ">");
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(Uint64.getInstance())
+                        .deserialize("5123456789"), elName), "<" + elName + ">5123456789</" + elName + ">");
     }
 
     @Test
@@ -164,92 +161,87 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader {
         String elName = "lfBinary";
         serializeToXml(
                 prepareCnStructForYangData(
-                        TypeDefinitionAwareCodec.from(BinaryType.getInstance())
-                        .deserialize("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"),
-                        elName), "<" + elName + ">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567</"
-                                + elName + ">");
+                        TypeDefinitionAwareCodec.from(BinaryType.getInstance()).deserialize(
+                                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"), elName), "<" + elName
+                        + ">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567</" + elName + ">");
     }
 
     @Test
     public void snAsYangBitsToXmlTest() {
-        BitsTypeDefinition.Bit mockBit1 = mock( BitsTypeDefinition.Bit.class );
-        when( mockBit1.getName() ).thenReturn( "one" );
-        BitsTypeDefinition.Bit mockBit2 = mock( BitsTypeDefinition.Bit.class );
-        when( mockBit2.getName() ).thenReturn( "two" );
-        List<BitsTypeDefinition.Bit> bitList = Lists.newArrayList( mockBit1, mockBit2 );
+        BitsTypeDefinition.Bit mockBit1 = mock(BitsTypeDefinition.Bit.class);
+        when(mockBit1.getName()).thenReturn("one");
+        BitsTypeDefinition.Bit mockBit2 = mock(BitsTypeDefinition.Bit.class);
+        when(mockBit2.getName()).thenReturn("two");
+        List<BitsTypeDefinition.Bit> bitList = Lists.newArrayList(mockBit1, mockBit2);
 
         String elName = "lfBits";
         serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(
-                        BitsType.create( mock( SchemaPath.class ), bitList ) )
-                        .deserialize("one two"), elName),
-                        "<" + elName + ">one two</" + elName + ">", "<" + elName + ">two one</" + elName + ">");
+                prepareCnStructForYangData(
+                        TypeDefinitionAwareCodec.from(BitsType.create(mock(SchemaPath.class), bitList)).deserialize(
+                                "one two"), elName), "<" + elName + ">one two</" + elName + ">", "<" + elName
+                        + ">two one</" + elName + ">");
     }
 
     @Test
     public void snAsYangEnumerationToXmlTest() {
-        EnumTypeDefinition.EnumPair mockEnum = mock( EnumTypeDefinition.EnumPair.class );
-        when( mockEnum.getName() ).thenReturn( "enum2" );
-        List<EnumPair> enumList = Lists.newArrayList( mockEnum );
+        EnumTypeDefinition.EnumPair mockEnum = mock(EnumTypeDefinition.EnumPair.class);
+        when(mockEnum.getName()).thenReturn("enum2");
+        List<EnumPair> enumList = Lists.newArrayList(mockEnum);
 
         String elName = "lfEnumeration";
         serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(
-                        EnumerationType.create( mock( SchemaPath.class ), enumList,
-                                Optional.<EnumTypeDefinition.EnumPair>absent() ) )
-                                .deserialize("enum2"),
-                                elName), "<" + elName + ">enum2</" + elName + ">");
+                prepareCnStructForYangData(
+                        TypeDefinitionAwareCodec.from(
+                                EnumerationType.create(mock(SchemaPath.class), enumList,
+                                        Optional.<EnumTypeDefinition.EnumPair> absent())).deserialize("enum2"), elName),
+                "<" + elName + ">enum2</" + elName + ">");
     }
 
     @Test
     public void snAsYangEmptyToXmlTest() {
         String elName = "lfEmpty";
         serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(EmptyType.getInstance()).deserialize(null), elName), "<"
-                        + elName + "/>");
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(EmptyType.getInstance()).deserialize(null),
+                        elName), "<" + elName + "/>");
     }
 
     @Test
     public void snAsYangBooleanToXmlTest() {
         String elName = "lfBoolean";
         serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(BooleanType.getInstance()).deserialize("str"), elName),
-                "<" + elName + ">false</" + elName + ">");
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(BooleanType.getInstance()).deserialize("str"),
+                        elName), "<" + elName + ">false</" + elName + ">");
         serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(BooleanType.getInstance()).deserialize("true"), elName),
-                "<" + elName + ">true</" + elName + ">");
+                prepareCnStructForYangData(
+                        TypeDefinitionAwareCodec.from(BooleanType.getInstance()).deserialize("true"), elName), "<"
+                        + elName + ">true</" + elName + ">");
     }
 
     @Test
     public void snAsYangUnionToXmlTest() {
 
-        BitsTypeDefinition.Bit mockBit1 = mock( BitsTypeDefinition.Bit.class );
-        when( mockBit1.getName() ).thenReturn( "first" );
-        BitsTypeDefinition.Bit mockBit2 = mock( BitsTypeDefinition.Bit.class );
-        when( mockBit1.getName() ).thenReturn( "second" );
-        List<BitsTypeDefinition.Bit> bitList = Lists.newArrayList( mockBit1, mockBit2 );
+        BitsTypeDefinition.Bit mockBit1 = mock(BitsTypeDefinition.Bit.class);
+        when(mockBit1.getName()).thenReturn("first");
+        BitsTypeDefinition.Bit mockBit2 = mock(BitsTypeDefinition.Bit.class);
+        when(mockBit2.getName()).thenReturn("second");
+        List<BitsTypeDefinition.Bit> bitList = Lists.newArrayList(mockBit1, mockBit2);
 
-        List<TypeDefinition<?>> types = Lists.<TypeDefinition<?>>newArrayList(
-                Int8.getInstance(),
-                BitsType.create( mock( SchemaPath.class ) , bitList ),
-                BooleanType.getInstance() );
-        UnionType unionType = UnionType.create( types );
+        List<TypeDefinition<?>> types = Lists.<TypeDefinition<?>> newArrayList(Int8.getInstance(),
+                BitsType.create(mock(SchemaPath.class), bitList), BooleanType.getInstance());
+        UnionType unionType = UnionType.create(types);
 
         String elName = "lfUnion";
         String int8 = "15";
-        serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(unionType).deserialize(int8), elName), "<"
-                        + elName + ">15</" + elName + ">");
+        serializeToXml(prepareCnStructForYangData(TypeDefinitionAwareCodec.from(unionType).deserialize(int8), elName),
+                "<" + elName + ">15</" + elName + ">");
 
         String bits = "first second";
-        serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(unionType).deserialize(bits), elName), "<"
-                        + elName + ">first second</" + elName + ">");
+        serializeToXml(prepareCnStructForYangData(TypeDefinitionAwareCodec.from(unionType).deserialize(bits), elName),
+                "<" + elName + ">first second</" + elName + ">");
 
         String bool = "str";
-        serializeToXml(
-                prepareCnStructForYangData(TypeDefinitionAwareCodec.from(unionType).deserialize(bool), elName), "<"
-                        + elName + ">str</" + elName + ">");
+        serializeToXml(prepareCnStructForYangData(TypeDefinitionAwareCodec.from(unionType).deserialize(bool), elName),
+                "<" + elName + ">str</" + elName + ">");
     }
 
     private void serializeToXml(final CompositeNode compositeNode, final String... xmlRepresentation)
index ac7fe20818f31fc7fbb5bfd24b4399b2113cadee..8e5449029c78dccaba89861feb71e018d22c6ab2 100644 (file)
@@ -10,9 +10,7 @@ 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;
@@ -26,9 +24,8 @@ 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
+ * 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 {
index f8d04c157f2e9d1678da36c6636bd872e05e4cc7..1e366dcaec88dd5171a191581a6877409afc696a 100644 (file)
@@ -14,9 +14,7 @@ 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;
@@ -31,7 +29,7 @@ public class CnSnToXmlWithDataFromSeveralModulesTest extends YangAndXmlAndDataSc
 
     @BeforeClass
     public static void initialize() {
-        dataLoad("/xml-to-cnsn/data-of-several-modules/yang",2,"module1","cont_m1");
+        dataLoad("/xml-to-cnsn/data-of-several-modules/yang", 2, "module1", "cont_m1");
     }
 
     @Test
@@ -40,19 +38,19 @@ public class CnSnToXmlWithDataFromSeveralModulesTest extends YangAndXmlAndDataSc
         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>");
+        // 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("^");
@@ -61,7 +59,6 @@ public class CnSnToXmlWithDataFromSeveralModulesTest extends YangAndXmlAndDataSc
         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(".*>");
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/input/to/cnsn/test/RestPutListDataTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/input/to/cnsn/test/RestPutListDataTest.java
new file mode 100644 (file)
index 0000000..4210944
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.restconf.impl.input.to.cnsn.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.FileNotFoundException;
+import java.net.URI;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+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.RestconfDocumentedException;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.test.DummyFuture;
+import org.opendaylight.controller.sal.restconf.impl.test.DummyFuture.Builder;
+import org.opendaylight.controller.sal.restconf.impl.test.DummyRpcResult;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class RestPutListDataTest {
+
+    private static BrokerFacade brokerFacade;
+    private static RestconfImpl restconfImpl;
+    private static SchemaContext schemaContextTestModule;
+
+    private static final String TEST_MODULE_NS_STRING = "test:module";
+    private static final URI TEST_MODULE_NS;
+    private static final String TEST_MODULE_REVISION = "2014-01-09";
+
+    static {
+        TEST_MODULE_NS = URI.create("test:module");
+    }
+
+    @Before
+    public void initialize() throws FileNotFoundException {
+        ControllerContext controllerContext = ControllerContext.getInstance();
+        schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
+        controllerContext.setSchemas(schemaContextTestModule);
+        brokerFacade = mock(BrokerFacade.class);
+        restconfImpl = RestconfImpl.getInstance();
+        restconfImpl.setBroker(brokerFacade);
+        restconfImpl.setControllerContext(controllerContext);
+        Builder<TransactionStatus> futureBuilder = new DummyFuture.Builder<TransactionStatus>();
+        futureBuilder.rpcResult(new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
+                .build());
+        when(brokerFacade.commitConfigurationDataPut(any(YangInstanceIdentifier.class), any(CompositeNode.class)))
+                .thenReturn(futureBuilder.build());
+    }
+
+    /**
+     * Tests whether no exception is raised if number and values of keys in URI
+     * and payload are equal
+     */
+    @Test
+    public void testValidKeys() {
+        putListDataTest("key1value", "15", "key1value", (short) 15);
+    }
+
+    /**
+     * Tests whether an exception is raised if key values in URI and payload are
+     * different.
+     *
+     * The exception should be raised from validation method
+     * {@code RestconfImpl#validateListEqualityOfListInDataAndUri}
+     */
+    @Test
+    public void testUriAndPayloadKeysDifferent() {
+        try {
+            putListDataTest("key1value", "15", "key1value", (short) 16);
+            fail("RestconfDocumentedException expected");
+        } catch (RestconfDocumentedException e) {
+            verifyException(e, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
+        }
+
+        try {
+            putListDataTest("key1value", "15", "key1value1", (short) 16);
+            fail("RestconfDocumentedException expected");
+        } catch (RestconfDocumentedException e) {
+            verifyException(e, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
+        }
+    }
+
+    /**
+     * Tests whether an exception is raised if URI contains less key values then
+     * payload.
+     *
+     * The exception is raised during {@code InstanceIdentifier} instance is
+     * built from URI
+     */
+    @Test
+    public void testMissingKeysInUri() {
+        try {
+            putListDataTest("key1value", null, "key1value", (short) 15);
+            fail("RestconfDocumentedException expected");
+        } catch (RestconfDocumentedException e) {
+            verifyException(e, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
+        }
+    }
+
+    /**
+     * Tests whether an exception is raised if URI contains more key values then
+     * payload.
+     *
+     * The exception should be raised from validation method
+     * {@code RestconfImpl#validateListEqualityOfListInDataAndUri}
+     */
+    @Test
+    public void testMissingKeysInPayload() {
+        try {
+            putListDataTest("key1value", "15", "key1value", null);
+            fail("RestconfDocumentedException expected");
+        } catch (RestconfDocumentedException e) {
+            verifyException(e, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
+        }
+        try {
+            putListDataWithWrapperTest("key1value", "15", "key1value", null);
+            fail("RestconfDocumentedException expected");
+        } catch (RestconfDocumentedException e) {
+            // this exception is raised from RestconfImpl.normalizeCompositeNode()
+            verifyException(e, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
+        }
+
+    }
+
+    private void verifyException(final RestconfDocumentedException e, final ErrorType errorType, final ErrorTag errorTag) {
+        List<RestconfError> errors = e.getErrors();
+        assertEquals("getErrors() size", 1, errors.size());
+        assertEquals("RestconfError getErrorType()", errorType, errors.get(0).getErrorType());
+        assertEquals("RestconfError getErrorTag()", errorTag, errors.get(0).getErrorTag());
+    }
+
+    public void putListDataTest(final String uriKey1, final String uriKey2, final String payloadKey1,
+            final Short payloadKey2) {
+        QName lstWithCompositeKey = QName.create(TEST_MODULE_NS_STRING, TEST_MODULE_REVISION, "lst-with-composite-key");
+        QName key1 = QName.create(TEST_MODULE_NS_STRING, TEST_MODULE_REVISION, "key1");
+        QName key2 = QName.create(TEST_MODULE_NS_STRING, TEST_MODULE_REVISION, "key2");
+
+        CompositeNodeBuilder<ImmutableCompositeNode> payloadBuilder = ImmutableCompositeNode.builder();
+        payloadBuilder.setQName(lstWithCompositeKey).addLeaf(key1, payloadKey1);
+        if (payloadKey2 != null) {
+            payloadBuilder.addLeaf(key2, payloadKey2);
+        }
+
+        restconfImpl.updateConfigurationData(toUri(uriKey1, uriKey2), payloadBuilder.toInstance());
+    }
+
+    public void putListDataWithWrapperTest(final String uriKey1, final String uriKey2, final String payloadKey1,
+            final Short payloadKey2) {
+        CompositeNodeWrapper payloadBuilder = new CompositeNodeWrapper(TEST_MODULE_NS, "lst-with-composite-key");
+        payloadBuilder.addValue(new SimpleNodeWrapper(TEST_MODULE_NS, "key1", payloadKey1));
+        if (payloadKey2 != null) {
+            payloadBuilder.addValue(new SimpleNodeWrapper(TEST_MODULE_NS, "key2", payloadKey2));
+        }
+        restconfImpl.updateConfigurationData(toUri(uriKey1, uriKey2), payloadBuilder);
+    }
+
+    private String toUri(final String uriKey1, final String uriKey2) {
+        final StringBuilder uriBuilder = new StringBuilder("/test-module:lst-with-composite-key/");
+        uriBuilder.append(uriKey1);
+        if (uriKey2 != null) {
+            uriBuilder.append("/");
+            uriBuilder.append(uriKey2);
+        }
+        return uriBuilder.toString();
+    }
+
+}
index 0c9e95173fd3f1e309b6e512a90260eaf8bbb899..23b040a9a3846b6e273dedcb0fcb42e8c36ff5f4 100644 (file)
@@ -12,7 +12,6 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.util.List;
-
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
index 79dd026fd0dc5cf21b69d7dae886070b009a5999..913e9f2d707bd310feb103313d53d5c8a83928df 100644 (file)
@@ -28,8 +28,7 @@ public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader {
     }
 
     /**
-     * JSON values which represents leafref are always loaded to simple node as
-     * string
+     * JSON values which represents leafref are always loaded to simple node as string
      */
     @Test
     public void jsonIdentityrefToCompositeNode() {
index 47e329cc3ef11a4cdfc8842c9a1285a445989517..7b71e42ab8ed669516c4e724231628c8d6bd4908 100644 (file)
@@ -17,7 +17,6 @@ import java.io.InputStream;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-
 import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
@@ -82,8 +81,8 @@ public class JsonToCnSnTest {
     }
 
     /**
-     * List contains 4 items and in every item are other elements. It is
-     * supposed that there should be: lf11, lflst11, cont11, lst11
+     * List contains 4 items and in every item are other elements. It is supposed that there should be: lf11, lflst11,
+     * cont11, lst11
      */
     @Test
     public void multipleItemsInListTest() {
@@ -116,14 +115,19 @@ public class JsonToCnSnTest {
     public void incorrectTopLevelElementsTest() {
         RestconfDocumentedException cause1 = null;
         try {
-            TestUtils.readInputToCnSn("/json-to-cnsn/wrong-top-level1.json", true, JsonToCompositeNodeProvider.INSTANCE);
+            TestUtils
+                    .readInputToCnSn("/json-to-cnsn/wrong-top-level1.json", true, JsonToCompositeNodeProvider.INSTANCE);
         } catch (RestconfDocumentedException e) {
             cause1 = e;
         }
 
         assertNotNull(cause1);
-        assertTrue(cause1.getErrors().get( 0 ).getErrorMessage().contains(
-            "First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet."));
+        assertTrue(cause1
+                .getErrors()
+                .get(0)
+                .getErrorMessage()
+                .contains(
+                        "First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet."));
 
         RestconfDocumentedException cause2 = null;
         try {
@@ -133,26 +137,29 @@ public class JsonToCnSnTest {
             cause2 = e;
         }
         assertNotNull(cause2);
-        assertTrue(cause2.getErrors().get( 0 ).getErrorMessage().contains(
-                                                     "Json Object should contain one element"));
+        assertTrue(cause2.getErrors().get(0).getErrorMessage().contains("Json Object should contain one element"));
 
         RestconfDocumentedException cause3 = null;
         try {
             TestUtils
 
-                    .readInputToCnSn("/json-to-cnsn/wrong-top-level3.json", true, JsonToCompositeNodeProvider.INSTANCE);
+            .readInputToCnSn("/json-to-cnsn/wrong-top-level3.json", true, JsonToCompositeNodeProvider.INSTANCE);
         } catch (RestconfDocumentedException e) {
             cause3 = e;
         }
         assertNotNull(cause3);
-        assertTrue(cause3.getErrors().get( 0 ).getErrorMessage().contains(
-            "First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet."));
+        assertTrue(cause3
+                .getErrors()
+                .get(0)
+                .getErrorMessage()
+                .contains(
+                        "First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet."));
 
     }
 
     /**
-     * if leaf list with no data is in json then no corresponding data is
-     * created in composite node. if leaf with no data then exception is raised
+     * if leaf list with no data is in json then no corresponding data is created in composite node. if leaf with no
+     * data then exception is raised
      */
     @Test
     public void emptyDataReadTest() {
@@ -172,7 +179,7 @@ public class JsonToCnSnTest {
         try {
             TestUtils.readInputToCnSn("/json-to-cnsn/empty-data1.json", true, JsonToCompositeNodeProvider.INSTANCE);
         } catch (RestconfDocumentedException e) {
-            reason = e.getErrors().get( 0 ).getErrorMessage();
+            reason = e.getErrors().get(0).getErrorMessage();
         }
 
         assertTrue(reason.contains("Expected value at line"));
@@ -180,17 +187,16 @@ public class JsonToCnSnTest {
     }
 
     @Test
-    public void testJsonBlankInput() throws Exception{
-        InputStream inputStream = new ByteArrayInputStream( "".getBytes() );
-        CompositeNode compositeNode =
-                JsonToCompositeNodeProvider.INSTANCE.readFrom(null, null, null, null, null, inputStream);
-        assertNull( compositeNode );
+    public void testJsonBlankInput() throws Exception {
+        InputStream inputStream = new ByteArrayInputStream("".getBytes());
+        CompositeNode compositeNode = JsonToCompositeNodeProvider.INSTANCE.readFrom(null, null, null, null, null,
+                inputStream);
+        assertNull(compositeNode);
     }
 
     /**
-     * Tests whether namespace <b>stay unchanged</b> if concrete values are
-     * present in composite or simple node and if the method for update is
-     * called.
+     * Tests whether namespace <b>stay unchanged</b> if concrete values are present in composite or simple node and if
+     * the method for update is called.
      *
      */
     @Test
@@ -284,13 +290,14 @@ public class JsonToCnSnTest {
 
     }
 
-    private void simpleTest(final String jsonPath, final String yangPath, final String topLevelElementName, final String namespace,
-            final String moduleName) {
+    private void simpleTest(final String jsonPath, final String yangPath, final String topLevelElementName,
+            final String namespace, final String moduleName) {
         CompositeNode compNode = loadAndNormalizeData(jsonPath, yangPath, topLevelElementName, moduleName);
         verifyCompositeNode(compNode, namespace);
     }
 
-    private CompositeNode loadAndNormalizeData(final String jsonPath, final String yangPath, final String topLevelElementName, final String moduleName) {
+    private CompositeNode loadAndNormalizeData(final String jsonPath, final String yangPath,
+            final String topLevelElementName, final String moduleName) {
         CompositeNode compositeNode = TestUtils.readInputToCnSn(jsonPath, false, JsonToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
 
@@ -395,7 +402,7 @@ public class JsonToCnSnTest {
             TestUtils.readInputToCnSn("/json-to-cnsn/unsupported-json-format.json", true,
                     JsonToCompositeNodeProvider.INSTANCE);
         } catch (RestconfDocumentedException e) {
-            exceptionMessage = e.getErrors().get( 0 ).getErrorMessage();
+            exceptionMessage = e.getErrors().get(0).getErrorMessage();
         }
         assertTrue(exceptionMessage.contains("Root element of Json has to be Object"));
     }
index 19ca812f8e9a90c1aad698be0df347b2b651b26f..73f828c6466a886a2f5d7de7029c590389c5e662 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 package org.opendaylight.controller.sal.restconf.impl.test;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertSame;
@@ -42,7 +43,7 @@ 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.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
 
 /**
@@ -66,268 +67,252 @@ public class BrokerFacadeTest {
 
     BrokerFacade brokerFacade = BrokerFacade.getInstance();
 
-    CompositeNode dataNode = TestUtils.readInputToCnSn( "/parts/ietf-interfaces_interfaces.xml",
-                                                        XmlToCompositeNodeProvider.INSTANCE );
+    CompositeNode dataNode = TestUtils.readInputToCnSn("/parts/ietf-interfaces_interfaces.xml",
+            XmlToCompositeNodeProvider.INSTANCE);
 
-    QName qname = QName.create( "node" );
+    QName qname = QName.create("node");
 
-    InstanceIdentifier instanceID = InstanceIdentifier.builder().node( qname ).toInstance();
+    YangInstanceIdentifier instanceID = YangInstanceIdentifier.builder().node(qname).toInstance();
 
     @Before
     public void setUp() throws Exception {
-        MockitoAnnotations.initMocks( this );
+        MockitoAnnotations.initMocks(this);
 
-        brokerFacade.setDataService( dataBroker );
-        brokerFacade.setContext( mockConsumerSession );
+        brokerFacade.setDataService(dataBroker);
+        brokerFacade.setContext(mockConsumerSession);
     }
 
     @Test
     public void testReadConfigurationData() {
-        when( dataBroker.readConfigurationData( instanceID ) ).thenReturn( dataNode );
+        when(dataBroker.readConfigurationData(instanceID)).thenReturn(dataNode);
 
-        CompositeNode actualNode = brokerFacade.readConfigurationData( instanceID );
+        CompositeNode actualNode = brokerFacade.readConfigurationData(instanceID);
 
-        assertSame( "readConfigurationData", dataNode, actualNode );
+        assertSame("readConfigurationData", dataNode, actualNode);
     }
 
     @Test
     public void testReadConfigurationDataBehindMountPoint() {
-        when( mockMountInstance.readConfigurationData( instanceID ) ).thenReturn( dataNode );
+        when(mockMountInstance.readConfigurationData(instanceID)).thenReturn(dataNode);
 
-        CompositeNode actualNode = brokerFacade.readConfigurationDataBehindMountPoint(
-                                                                              mockMountInstance, instanceID );
+        CompositeNode actualNode = brokerFacade.readConfigurationDataBehindMountPoint(mockMountInstance, instanceID);
 
-        assertSame( "readConfigurationDataBehindMountPoint", dataNode, actualNode );
+        assertSame("readConfigurationDataBehindMountPoint", dataNode, actualNode);
     }
 
     @Test
     public void testReadOperationalData() {
-        when( dataBroker.readOperationalData( instanceID ) ).thenReturn( dataNode );
+        when(dataBroker.readOperationalData(instanceID)).thenReturn(dataNode);
 
-        CompositeNode actualNode = brokerFacade.readOperationalData( instanceID );
+        CompositeNode actualNode = brokerFacade.readOperationalData(instanceID);
 
-        assertSame( "readOperationalData", dataNode, actualNode );
+        assertSame("readOperationalData", dataNode, actualNode);
     }
 
     @Test
     public void testReadOperationalDataBehindMountPoint() {
-        when( mockMountInstance.readOperationalData( instanceID ) ).thenReturn( dataNode );
+        when(mockMountInstance.readOperationalData(instanceID)).thenReturn(dataNode);
 
-        CompositeNode actualNode = brokerFacade.readOperationalDataBehindMountPoint(
-                                                                              mockMountInstance, instanceID );
+        CompositeNode actualNode = brokerFacade.readOperationalDataBehindMountPoint(mockMountInstance, instanceID);
 
-        assertSame( "readOperationalDataBehindMountPoint", dataNode, actualNode );
+        assertSame("readOperationalDataBehindMountPoint", dataNode, actualNode);
     }
 
-    @Test(expected=RestconfDocumentedException.class)
+    @Test(expected = RestconfDocumentedException.class)
     public void testReadOperationalDataWithNoDataBroker() {
-        brokerFacade.setDataService( null );
+        brokerFacade.setDataService(null);
 
-        brokerFacade.readOperationalData( instanceID );
+        brokerFacade.readOperationalData(instanceID);
     }
 
     @SuppressWarnings("unchecked")
     @Test
     public void testInvokeRpc() throws Exception {
-        RpcResult<CompositeNode> expResult = mock( RpcResult.class );
-        Future<RpcResult<CompositeNode>> future = Futures.immediateFuture( expResult );
-        when( mockConsumerSession.rpc( qname, dataNode ) ).thenReturn( future );
+        RpcResult<CompositeNode> expResult = mock(RpcResult.class);
+        Future<RpcResult<CompositeNode>> future = Futures.immediateFuture(expResult);
+        when(mockConsumerSession.rpc(qname, dataNode)).thenReturn(future);
 
-        Future<RpcResult<CompositeNode>> actualFuture = brokerFacade.invokeRpc( qname, dataNode );
-        assertNotNull( "Future is null", actualFuture );
+        Future<RpcResult<CompositeNode>> actualFuture = brokerFacade.invokeRpc(qname, dataNode);
+        assertNotNull("Future is null", actualFuture);
         RpcResult<CompositeNode> actualResult = actualFuture.get();
 
-        assertSame( "invokeRpc", expResult, actualResult );
+        assertSame("invokeRpc", expResult, actualResult);
     }
 
-    @Test(expected=RestconfDocumentedException.class)
+    @Test(expected = RestconfDocumentedException.class)
     public void testInvokeRpcWithNoConsumerSession() {
-        brokerFacade.setContext( null );
+        brokerFacade.setContext(null);
 
-        brokerFacade.invokeRpc( qname, dataNode );
+        brokerFacade.invokeRpc(qname, dataNode);
     }
 
     @Test
     public void testCommitConfigurationDataPut() {
-        Future<RpcResult<TransactionStatus>> expFuture =  Futures.immediateFuture( null );
+        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture(null);
 
-        when( dataBroker.beginTransaction() ).thenReturn( mockTransaction );
-        mockTransaction.putConfigurationData( instanceID, dataNode );
-        when( mockTransaction.commit() ).thenReturn( expFuture );
+        when(dataBroker.beginTransaction()).thenReturn(mockTransaction);
+        mockTransaction.putConfigurationData(instanceID, dataNode);
+        when(mockTransaction.commit()).thenReturn(expFuture);
 
-        Future<RpcResult<TransactionStatus>> actualFuture =
-                             brokerFacade.commitConfigurationDataPut( instanceID, dataNode );
+        Future<RpcResult<TransactionStatus>> actualFuture = brokerFacade.commitConfigurationDataPut(instanceID,
+                dataNode);
 
-        assertSame( "invokeRpc", expFuture, actualFuture );
+        assertSame("invokeRpc", expFuture, actualFuture);
 
-        InOrder inOrder = inOrder( dataBroker, mockTransaction );
-        inOrder.verify( dataBroker ).beginTransaction();
-        inOrder.verify( mockTransaction ).putConfigurationData( instanceID, dataNode );
-        inOrder.verify( mockTransaction ).commit();
+        InOrder inOrder = inOrder(dataBroker, mockTransaction);
+        inOrder.verify(dataBroker).beginTransaction();
+        inOrder.verify(mockTransaction).putConfigurationData(instanceID, dataNode);
+        inOrder.verify(mockTransaction).commit();
     }
 
     @Test
     public void testCommitConfigurationDataPutBehindMountPoint() {
-        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture( null );
+        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture(null);
 
-        when( mockMountInstance.beginTransaction() ).thenReturn( mockTransaction );
-        mockTransaction.putConfigurationData( instanceID, dataNode );
-        when( mockTransaction.commit() ).thenReturn( expFuture );
+        when(mockMountInstance.beginTransaction()).thenReturn(mockTransaction);
+        mockTransaction.putConfigurationData(instanceID, dataNode);
+        when(mockTransaction.commit()).thenReturn(expFuture);
 
-        Future<RpcResult<TransactionStatus>> actualFuture =
-                 brokerFacade.commitConfigurationDataPutBehindMountPoint(
-                                                       mockMountInstance, instanceID, dataNode );
+        Future<RpcResult<TransactionStatus>> actualFuture = brokerFacade.commitConfigurationDataPutBehindMountPoint(
+                mockMountInstance, instanceID, dataNode);
 
-        assertSame( "invokeRpc", expFuture, actualFuture );
+        assertSame("invokeRpc", expFuture, actualFuture);
 
-        InOrder inOrder = inOrder( mockMountInstance, mockTransaction );
-        inOrder.verify( mockMountInstance ).beginTransaction();
-        inOrder.verify( mockTransaction ).putConfigurationData( instanceID, dataNode );
-        inOrder.verify( mockTransaction ).commit();
+        InOrder inOrder = inOrder(mockMountInstance, mockTransaction);
+        inOrder.verify(mockMountInstance).beginTransaction();
+        inOrder.verify(mockTransaction).putConfigurationData(instanceID, dataNode);
+        inOrder.verify(mockTransaction).commit();
     }
 
     @Test
     public void testCommitConfigurationDataPost() {
-        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture( null );
+        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture(null);
 
-        Map<InstanceIdentifier, CompositeNode> nodeMap =
-                new ImmutableMap.Builder<InstanceIdentifier,CompositeNode>()
-                                                             .put( instanceID, dataNode ).build();
+        Map<YangInstanceIdentifier, CompositeNode> nodeMap = new ImmutableMap.Builder<YangInstanceIdentifier, CompositeNode>()
+                .put(instanceID, dataNode).build();
 
-        when( dataBroker.beginTransaction() ).thenReturn( mockTransaction );
-        mockTransaction.putConfigurationData( instanceID, dataNode );
-        when( mockTransaction.getCreatedConfigurationData() ).thenReturn( nodeMap );
-        when( mockTransaction.commit() ).thenReturn( expFuture );
+        when(dataBroker.beginTransaction()).thenReturn(mockTransaction);
+        mockTransaction.putConfigurationData(instanceID, dataNode);
+        when(mockTransaction.getCreatedConfigurationData()).thenReturn(nodeMap);
+        when(mockTransaction.commit()).thenReturn(expFuture);
 
-        Future<RpcResult<TransactionStatus>> actualFuture =
-                             brokerFacade.commitConfigurationDataPost( instanceID, dataNode );
+        Future<RpcResult<TransactionStatus>> actualFuture = brokerFacade.commitConfigurationDataPost(instanceID,
+                dataNode);
 
-        assertSame( "commitConfigurationDataPut", expFuture, actualFuture );
+        assertSame("commitConfigurationDataPut", expFuture, actualFuture);
 
-        InOrder inOrder = inOrder( dataBroker, mockTransaction );
-        inOrder.verify( dataBroker ).beginTransaction();
-        inOrder.verify( mockTransaction ).putConfigurationData( instanceID, dataNode );
-        inOrder.verify( mockTransaction ).commit();
+        InOrder inOrder = inOrder(dataBroker, mockTransaction);
+        inOrder.verify(dataBroker).beginTransaction();
+        inOrder.verify(mockTransaction).putConfigurationData(instanceID, dataNode);
+        inOrder.verify(mockTransaction).commit();
     }
 
-    @Test(expected=RestconfDocumentedException.class)
+    @Test(expected = RestconfDocumentedException.class)
     public void testCommitConfigurationDataPostAlreadyExists() {
-        when( dataBroker.beginTransaction() ).thenReturn( mockTransaction );
-        mockTransaction.putConfigurationData( instanceID, dataNode );
-        when ( mockTransaction.readConfigurationData( instanceID ) )
-            .thenReturn( dataNode );
+        when(dataBroker.beginTransaction()).thenReturn(mockTransaction);
+        mockTransaction.putConfigurationData(instanceID, dataNode);
+        when(mockTransaction.readConfigurationData(instanceID)).thenReturn(dataNode);
         try {
-            brokerFacade.commitConfigurationDataPost( instanceID, dataNode );
-        }
-        catch (RestconfDocumentedException e) {
-            assertEquals("getErrorTag",
-                    RestconfError.ErrorTag.DATA_EXISTS, e.getErrors().get( 0 ).getErrorTag());
+            brokerFacade.commitConfigurationDataPost(instanceID, dataNode);
+        } catch (RestconfDocumentedException e) {
+            assertEquals("getErrorTag", RestconfError.ErrorTag.DATA_EXISTS, e.getErrors().get(0).getErrorTag());
             throw e;
         }
     }
 
     @Test
     public void testCommitConfigurationDataPostBehindMountPoint() {
-        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture( null );
+        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture(null);
 
-        Map<InstanceIdentifier, CompositeNode> nodeMap =
-                new ImmutableMap.Builder<InstanceIdentifier,CompositeNode>()
-                                                           .put( instanceID, dataNode ).build();
+        Map<YangInstanceIdentifier, CompositeNode> nodeMap = new ImmutableMap.Builder<YangInstanceIdentifier, CompositeNode>()
+                .put(instanceID, dataNode).build();
 
-        when( mockMountInstance.beginTransaction() ).thenReturn( mockTransaction );
-        mockTransaction.putConfigurationData( instanceID, dataNode );
-        when( mockTransaction.getCreatedConfigurationData() ).thenReturn( nodeMap );
-        when( mockTransaction.commit() ).thenReturn( expFuture );
+        when(mockMountInstance.beginTransaction()).thenReturn(mockTransaction);
+        mockTransaction.putConfigurationData(instanceID, dataNode);
+        when(mockTransaction.getCreatedConfigurationData()).thenReturn(nodeMap);
+        when(mockTransaction.commit()).thenReturn(expFuture);
 
-        Future<RpcResult<TransactionStatus>> actualFuture =
-                brokerFacade.commitConfigurationDataPostBehindMountPoint( mockMountInstance,
-                                                                          instanceID, dataNode );
+        Future<RpcResult<TransactionStatus>> actualFuture = brokerFacade.commitConfigurationDataPostBehindMountPoint(
+                mockMountInstance, instanceID, dataNode);
 
-        assertSame( "commitConfigurationDataPostBehindMountPoint", expFuture, actualFuture );
+        assertSame("commitConfigurationDataPostBehindMountPoint", expFuture, actualFuture);
 
-        InOrder inOrder = inOrder( mockMountInstance, mockTransaction );
-        inOrder.verify( mockMountInstance ).beginTransaction();
-        inOrder.verify( mockTransaction ).putConfigurationData( instanceID, dataNode );
-        inOrder.verify( mockTransaction ).commit();
+        InOrder inOrder = inOrder(mockMountInstance, mockTransaction);
+        inOrder.verify(mockMountInstance).beginTransaction();
+        inOrder.verify(mockTransaction).putConfigurationData(instanceID, dataNode);
+        inOrder.verify(mockTransaction).commit();
     }
 
-    @Test(expected=RestconfDocumentedException.class)
+    @Test(expected = RestconfDocumentedException.class)
     public void testCommitConfigurationDataPostBehindMountPointAlreadyExists() {
 
-        when( mockMountInstance.beginTransaction() ).thenReturn( mockTransaction );
-        mockTransaction.putConfigurationData( instanceID, dataNode );
-        when ( mockTransaction.readConfigurationData( instanceID ) )
-            .thenReturn( dataNode );
+        when(mockMountInstance.beginTransaction()).thenReturn(mockTransaction);
+        mockTransaction.putConfigurationData(instanceID, dataNode);
+        when(mockTransaction.readConfigurationData(instanceID)).thenReturn(dataNode);
         try {
-            brokerFacade.commitConfigurationDataPostBehindMountPoint( mockMountInstance,
-                    instanceID, dataNode );
-        }
-        catch (RestconfDocumentedException e) {
-            assertEquals("getErrorTag",
-                    RestconfError.ErrorTag.DATA_EXISTS, e.getErrors().get( 0 ).getErrorTag());
+            brokerFacade.commitConfigurationDataPostBehindMountPoint(mockMountInstance, instanceID, dataNode);
+        } catch (RestconfDocumentedException e) {
+            assertEquals("getErrorTag", RestconfError.ErrorTag.DATA_EXISTS, e.getErrors().get(0).getErrorTag());
             throw e;
         }
     }
 
     @Test
     public void testCommitConfigurationDataDelete() {
-        Future<RpcResult<TransactionStatus>> expFuture =  Futures.immediateFuture( null );
+        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture(null);
 
-        when( dataBroker.beginTransaction() ).thenReturn( mockTransaction );
-        when(mockTransaction.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(
+        when(dataBroker.beginTransaction()).thenReturn(mockTransaction);
+        when(mockTransaction.readConfigurationData(any(YangInstanceIdentifier.class))).thenReturn(
                 ImmutableCompositeNode.builder().toInstance());
-        mockTransaction.removeConfigurationData( instanceID );
-        when( mockTransaction.commit() ).thenReturn( expFuture );
+        mockTransaction.removeConfigurationData(instanceID);
+        when(mockTransaction.commit()).thenReturn(expFuture);
 
-        Future<RpcResult<TransactionStatus>> actualFuture =
-                             brokerFacade.commitConfigurationDataDelete( instanceID );
+        Future<RpcResult<TransactionStatus>> actualFuture = brokerFacade.commitConfigurationDataDelete(instanceID);
 
-        assertSame( "commitConfigurationDataDelete", expFuture, actualFuture );
+        assertSame("commitConfigurationDataDelete", expFuture, actualFuture);
 
-        InOrder inOrder = inOrder( dataBroker, mockTransaction );
-        inOrder.verify( dataBroker ).beginTransaction();
-        inOrder.verify( mockTransaction ).removeConfigurationData( instanceID );
-        inOrder.verify( mockTransaction ).commit();
+        InOrder inOrder = inOrder(dataBroker, mockTransaction);
+        inOrder.verify(dataBroker).beginTransaction();
+        inOrder.verify(mockTransaction).removeConfigurationData(instanceID);
+        inOrder.verify(mockTransaction).commit();
     }
 
     @Test
     public void testCommitConfigurationDataDeleteBehindMountPoint() {
-        Future<RpcResult<TransactionStatus>> expFuture =  Futures.immediateFuture( null );
+        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture(null);
 
-        when( mockMountInstance.beginTransaction() ).thenReturn( mockTransaction );
-        when(mockTransaction.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(
+        when(mockMountInstance.beginTransaction()).thenReturn(mockTransaction);
+        when(mockTransaction.readConfigurationData(any(YangInstanceIdentifier.class))).thenReturn(
                 ImmutableCompositeNode.builder().toInstance());
-        mockTransaction.removeConfigurationData( instanceID );
-        when( mockTransaction.commit() ).thenReturn( expFuture );
+        mockTransaction.removeConfigurationData(instanceID);
+        when(mockTransaction.commit()).thenReturn(expFuture);
 
-        Future<RpcResult<TransactionStatus>> actualFuture =
-                             brokerFacade.commitConfigurationDataDeleteBehindMountPoint(
-                                                              mockMountInstance, instanceID );
+        Future<RpcResult<TransactionStatus>> actualFuture = brokerFacade.commitConfigurationDataDeleteBehindMountPoint(
+                mockMountInstance, instanceID);
 
-        assertSame( "commitConfigurationDataDeleteBehindMountPoint", expFuture, actualFuture );
+        assertSame("commitConfigurationDataDeleteBehindMountPoint", expFuture, actualFuture);
 
-        InOrder inOrder = inOrder( mockMountInstance, mockTransaction );
-        inOrder.verify( mockMountInstance ).beginTransaction();
-        inOrder.verify( mockTransaction ).removeConfigurationData( instanceID );
-        inOrder.verify( mockTransaction ).commit();
+        InOrder inOrder = inOrder(mockMountInstance, mockTransaction);
+        inOrder.verify(mockMountInstance).beginTransaction();
+        inOrder.verify(mockTransaction).removeConfigurationData(instanceID);
+        inOrder.verify(mockTransaction).commit();
     }
 
     @SuppressWarnings("unchecked")
     @Test
     public void testRegisterToListenDataChanges() {
-        ListenerAdapter listener = Notificator.createListener( instanceID, "stream" );
+        ListenerAdapter listener = Notificator.createListener(instanceID, "stream");
 
-        ListenerRegistration<DataChangeListener> mockRegistration = mock( ListenerRegistration.class );
-        when( dataBroker.registerDataChangeListener( instanceID, listener ) )
-            .thenReturn( mockRegistration );
+        ListenerRegistration<DataChangeListener> mockRegistration = mock(ListenerRegistration.class);
+        when(dataBroker.registerDataChangeListener(instanceID, listener)).thenReturn(mockRegistration);
 
-        brokerFacade.registerToListenDataChanges( listener );
+        brokerFacade.registerToListenDataChanges(listener);
 
-        verify( dataBroker ).registerDataChangeListener( instanceID, listener );
+        verify(dataBroker).registerDataChangeListener(instanceID, listener);
 
-        assertEquals( "isListening", true, listener.isListening() );
+        assertEquals("isListening", true, listener.isListening());
 
-        brokerFacade.registerToListenDataChanges( listener );
-        verifyNoMoreInteractions( dataBroker );
+        brokerFacade.registerToListenDataChanges(listener);
+        verifyNoMoreInteractions(dataBroker);
     }
 }
index 07d781028b99feaa03cd8dc610f499f63a0ca1dc..79e51681ca127955231057740d021a513d2e89ee 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.sal.restconf.impl.test;
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.opendaylight.controller.sal.restconf.impl.test.TestUtils.containsStringData;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
@@ -19,29 +20,27 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-
 import javax.ws.rs.WebApplicationException;
 import javax.xml.stream.XMLEventReader;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.events.StartElement;
 import javax.xml.stream.events.XMLEvent;
-
 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.rest.impl.StructuredDataToXmlProvider;
 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.InstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
-import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
 
 public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSchemaLoader {
 
@@ -55,21 +54,16 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch
         CompositeNode cnSn = prepareCnSn(createInstanceIdentifier());
         String output = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSn, modules, dataSchemaNode,
                 StructuredDataToXmlProvider.INSTANCE);
-        //uncomment for debug
-        // System.out.println(output);
         validateXmlOutput(output);
 
     }
 
-    @Ignore
     @Test
     public void saveCnSnWithLeafListInstIdentifierToXmlTest() throws WebApplicationException, IOException,
-    URISyntaxException, XMLStreamException {
+            URISyntaxException, XMLStreamException {
         CompositeNode cnSn = prepareCnSn(createInstanceIdentifierWithLeafList());
         String output = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSn, modules, dataSchemaNode,
                 StructuredDataToXmlProvider.INSTANCE);
-        //uncomment for debug
-        // System.out.println(output);
         validateXmlOutputWithLeafList(output);
     }
 
@@ -79,33 +73,40 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch
         String output = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSn, modules, dataSchemaNode,
                 StructuredDataToJsonProvider.INSTANCE);
         boolean strInOutput = false;
-        strInOutput = output
-                .contains("\"augment-augment-module:lf111\": \"/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module:lst11[augment-module:keyvalue111=\\\"value1\\\"][augment-module:keyvalue112=\\\"value2\\\"]/augment-augment-module:lf112\"");
+        strInOutput = containsStringData(
+                output,
+                "\"augment-augment-module:lf111\"",
+                ":",
+                "\"/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module:lst11\\[augment-module:keyvalue111=\\\\\"value1\\\\\"\\]\\[augment-module:keyvalue112=\\\\\"value2\\\\\"\\]/augment-augment-module:lf112\"");
 
         if (!strInOutput) {
-            strInOutput = output
-                    .contains("\"augment-augment-module:lf111\": \"/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module:lst11[augment-module:keyvalue111='value1'][augment-module:keyvalue112='value2']/augment-augment-module:lf112\"");
+            strInOutput = containsStringData(
+                    output,
+                    "\"augment-augment-module:lf111\"",
+                    ":",
+                    "\"/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module:lst11\\[augment-module:keyvalue111='value1'\\]\\[augment-module:keyvalue112='value2'\\]/augment-augment-module:lf112\"");
         }
-        //uncomment for debug
-        // System.out.println(output);
         assertTrue(strInOutput);
     }
 
-
     @Test
     public void saveCnSnWithLeafListInstIdentifierToJsonTest() throws WebApplicationException, IOException,
-    URISyntaxException {
+            URISyntaxException {
         CompositeNode cnSn = prepareCnSn(createInstanceIdentifierWithLeafList());
         String output = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSn, modules, dataSchemaNode,
                 StructuredDataToJsonProvider.INSTANCE);
-        //uncomment for debug
-        // System.out.println(output);
         boolean strInOutput = false;
-        strInOutput = output
-                .contains("\"augment-augment-module:lf111\": \"/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module-leaf-list:lflst11[.='lflst11_1']\"");
+        strInOutput = containsStringData(
+                output,
+                "\"augment-augment-module:lf111\"",
+                ":",
+                "\"/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module-leaf-list:lflst11\\[.='lflst11_1'\\]\"");
         if (!strInOutput) {
-            strInOutput = output
-                    .contains("\"augment-augment-module:lf111\": \"/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module-leaf-list:lflst11[.=\\\"lflst11_1\\\"]\"");
+            strInOutput = containsStringData(
+                    output,
+                    "\"augment-augment-module:lf111\"",
+                    ":",
+                    "\"/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module-leaf-list:lflst11\\[.=\\\\\"lflst11_1\\\\\"\\]\"");
         }
 
         assertTrue(strInOutput);
@@ -188,31 +189,25 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch
 
     }
 
-    private CompositeNode prepareCnSn(final InstanceIdentifier instanceIdentifier) throws URISyntaxException {
-        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
-                TestUtils.buildQName("cont", "instance:identifier:module", "2014-01-17"), null, null,null,null);
-        MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(
-                TestUtils.buildQName("cont1", "instance:identifier:module", "2014-01-17"), cont, null,null,null);
-        MutableCompositeNode lst11 = NodeFactory.createMutableCompositeNode(
-                TestUtils.buildQName("lst11", "augment:module", "2014-01-17"), cont1, null,null,null);
-
-        MutableSimpleNode<?> lf111 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111", "augment:augment:module", "2014-01-17"),
-                lst11, instanceIdentifier,null,null);
-
-
-        lst11.getValue().add(lf111);
-        lst11.init();
+    private CompositeNode prepareCnSn(final YangInstanceIdentifier instanceIdentifier) throws URISyntaxException {
+        CompositeNodeBuilder<ImmutableCompositeNode> cont = ImmutableCompositeNode.builder();
+        cont.setQName(QName.create("instance:identifier:module", "2014-01-17", "cont"));
 
-        cont1.getValue().add(lst11);
-        cont1.init();
+        CompositeNodeBuilder<ImmutableCompositeNode> cont1 = ImmutableCompositeNode.builder();
+        cont1.setQName(QName.create("instance:identifier:module", "2014-01-17", "cont1"));
 
-        cont.getValue().add(cont1);
-        cont.init();
+        CompositeNodeBuilder<ImmutableCompositeNode> lst11 = ImmutableCompositeNode.builder();
+        lst11.setQName(QName.create("augment:module", "2014-01-17", "lst11"));
 
-        return cont;
+        SimpleNode<?> lf111 = NodeFactory.createImmutableSimpleNode(
+                QName.create("augment:augment:module", "2014-01-17", "lf111"), null, instanceIdentifier);
+        lst11.add(lf111);
+        cont1.add(lst11.toInstance());
+        cont.add(cont1.toInstance());
+        return cont.toInstance();
     }
 
-    private InstanceIdentifier createInstanceIdentifier() throws URISyntaxException {
+    private YangInstanceIdentifier createInstanceIdentifier() throws URISyntaxException {
         List<PathArgument> pathArguments = new ArrayList<>();
         pathArguments.add(new NodeIdentifier(new QName(new URI("instance:identifier:module"), "cont")));
         pathArguments.add(new NodeIdentifier(new QName(new URI("instance:identifier:module"), "cont1")));
@@ -226,16 +221,16 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch
 
         pathArguments.add(new NodeIdentifier(new QName(new URI("augment:augment:module"), "lf112")));
 
-        return new InstanceIdentifier(pathArguments);
+        return YangInstanceIdentifier.create(pathArguments);
     }
 
-    private InstanceIdentifier createInstanceIdentifierWithLeafList() throws URISyntaxException {
+    private YangInstanceIdentifier createInstanceIdentifierWithLeafList() throws URISyntaxException {
         List<PathArgument> pathArguments = new ArrayList<>();
         pathArguments.add(new NodeIdentifier(new QName(new URI("instance:identifier:module"), "cont")));
         pathArguments.add(new NodeIdentifier(new QName(new URI("instance:identifier:module"), "cont1")));
         pathArguments.add(new NodeWithValue(new QName(new URI("augment:module:leaf:list"), "lflst11"), "lflst11_1"));
 
-        return new InstanceIdentifier(pathArguments);
+        return YangInstanceIdentifier.create(pathArguments);
     }
 
 }
index 307abebdd7b1a37ebfb3cc1d716048614c3e44cc..4ff4f707106a59058702166beb99a5cf8f506cb2 100644 (file)
@@ -3,12 +3,10 @@ package org.opendaylight.controller.sal.restconf.impl.test;
 import static org.junit.Assert.assertTrue;
 
 import java.io.FileNotFoundException;
-
 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;
@@ -47,7 +45,7 @@ public class CodecsExceptionsCatchingTest extends JerseyTest {
         resourceConfig = resourceConfig.registerInstances(restConf, StructuredDataToXmlProvider.INSTANCE,
                 StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
                 JsonToCompositeNodeProvider.INSTANCE);
-        resourceConfig.registerClasses( RestconfDocumentedExceptionMapper.class );
+        resourceConfig.registerClasses(RestconfDocumentedExceptionMapper.class);
         return resourceConfig;
     }
 
index 19a7eff480dece01d1e9ff5743b3ef9c5fa94c5e..8ae8d0bdac927415b7ebd514cf8c356a45a6b52e 100644 (file)
@@ -34,7 +34,6 @@ public class DummyFuture<T> implements Future<RpcResult<T>> {
         result = builder.result;
     }
 
-
     @Override
     public boolean cancel(final boolean mayInterruptIfRunning) {
         return cancel;
@@ -56,8 +55,8 @@ public class DummyFuture<T> implements Future<RpcResult<T>> {
     }
 
     @Override
-    public RpcResult<T> get(final long timeout, final TimeUnit unit) throws InterruptedException,
-    ExecutionException, TimeoutException {
+    public RpcResult<T> get(final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException,
+            TimeoutException {
         return result;
     }
 
index 16d14842db3c2cc02684e244a219f7d20da03daf..3c545c06e95054f70dd4ab21c42912179f37990d 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.sal.restconf.impl.test;
 
 import java.util.Collection;
-
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
index d90e9539c83cbbeeff51726967370dc1f6e53724..008fda4e0960b9e2ecd3b3c5518887dd03dba452 100644 (file)
@@ -8,7 +8,6 @@
 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.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.Status;
index 910ca8e20aab453d02b4e320b0493775666d3575..9aab841546016a5cb09f669c168307b2aaf0f725 100644 (file)
@@ -19,6 +19,9 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
 import java.io.FileNotFoundException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -27,12 +30,12 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.UriInfo;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.opendaylight.controller.sal.common.util.RpcErrors;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.api.mount.MountInstance;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
@@ -45,8 +48,8 @@ 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.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
 import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
@@ -56,45 +59,41 @@ 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 com.google.common.base.Optional;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
 public class InvokeRpcMethodTest {
 
     private RestconfImpl restconfImpl = null;
     private static ControllerContext controllerContext = null;
-
+    private static UriInfo uriInfo;
 
     @BeforeClass
     public static void init() throws FileNotFoundException {
-        Set<Module> allModules = new HashSet<Module>( TestUtils
-                .loadModulesFrom("/full-versions/yangs") );
-        allModules.addAll( TestUtils.loadModulesFrom("/invoke-rpc") );
+        Set<Module> allModules = new HashSet<Module>(TestUtils.loadModulesFrom("/full-versions/yangs"));
+        allModules.addAll(TestUtils.loadModulesFrom("/invoke-rpc"));
         assertNotNull(allModules);
         Module module = TestUtils.resolveModule("invoke-rpc-module", allModules);
         assertNotNull(module);
         SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
-        controllerContext = spy( ControllerContext.getInstance() );
+        controllerContext = spy(ControllerContext.getInstance());
         controllerContext.setSchemas(schemaContext);
-
+        uriInfo = mock(UriInfo.class);
+        MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
+        map.put("prettyPrint", Collections.singletonList("true"));
+        when(uriInfo.getQueryParameters(any(Boolean.class))).thenReturn(map);
     }
 
     @Before
-    public void initMethod()
-    {
+    public void initMethod() {
         restconfImpl = RestconfImpl.getInstance();
-        restconfImpl.setControllerContext( controllerContext );
+        restconfImpl.setControllerContext(controllerContext);
     }
 
     /**
-     * Test method invokeRpc in RestconfImpl class tests if composite node as
-     * input parameter of method invokeRpc (second argument) is wrapped to
-     * parent composite node which has QName equals to QName of rpc (resolved
-     * from string - first argument).
+     * Test method invokeRpc in RestconfImpl class tests if composite node as input parameter of method invokeRpc
+     * (second argument) is wrapped to parent composite node which has QName equals to QName of rpc (resolved from
+     * string - first argument).
      */
     @Test
-    public void invokeRpcMtethodTest() {
+    public void invokeRpcMethodTest() {
         ControllerContext contContext = controllerContext;
         try {
             contContext.findModuleNameByNamespace(new URI("invoke:rpc:module"));
@@ -110,11 +109,10 @@ public class InvokeRpcMethodTest {
 
         CompositeNode payload = preparePayload();
 
-        when(mockedBrokerFacade.invokeRpc(any(QName.class), any(CompositeNode.class)))
-            .thenReturn( Futures.<RpcResult<CompositeNode>>immediateFuture(
-                                               Rpcs.<CompositeNode>getRpcResult( true ) ) );
+        when(mockedBrokerFacade.invokeRpc(any(QName.class), any(CompositeNode.class))).thenReturn(
+                Futures.<RpcResult<CompositeNode>> immediateFuture(RpcResultBuilder.<CompositeNode>success().build()));
 
-        StructuredData structData = restconf.invokeRpc("invoke-rpc-module:rpc-test", payload);
+        StructuredData structData = restconf.invokeRpc("invoke-rpc-module:rpc-test", payload, uriInfo);
         assertTrue(structData == null);
 
     }
@@ -132,207 +130,224 @@ public class InvokeRpcMethodTest {
 
     @Test
     public void testInvokeRpcWithNoPayloadRpc_FailNoErrors() {
-        RpcResult<CompositeNode> rpcResult = Rpcs.<CompositeNode>getRpcResult( false );
+        RpcResult<CompositeNode> rpcResult = RpcResultBuilder.<CompositeNode>failed().build();
 
         BrokerFacade brokerFacade = mock(BrokerFacade.class);
-        when( brokerFacade.invokeRpc(
-                 eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast")),
-                 any(CompositeNode.class)))
-            .thenReturn( Futures.<RpcResult<CompositeNode>>immediateFuture( rpcResult ) );
+        when(
+                brokerFacade.invokeRpc(
+                        eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast")),
+                        any(CompositeNode.class))).thenReturn(
+                Futures.<RpcResult<CompositeNode>> immediateFuture(rpcResult));
 
         restconfImpl.setBroker(brokerFacade);
 
         try {
-            restconfImpl.invokeRpc("toaster:cancel-toast", "");
+            restconfImpl.invokeRpc("toaster:cancel-toast", "", uriInfo);
             fail("Expected an exception to be thrown.");
-        }
-        catch (RestconfDocumentedException e) {
-            verifyRestconfDocumentedException( e, 0, ErrorType.RPC, ErrorTag.OPERATION_FAILED,
-                                               Optional.<String>absent(), Optional.<String>absent() );
+        } catch (RestconfDocumentedException e) {
+            verifyRestconfDocumentedException(e, 0, ErrorType.RPC, ErrorTag.OPERATION_FAILED,
+                    Optional.<String> absent(), Optional.<String> absent());
         }
     }
 
-    void verifyRestconfDocumentedException( final RestconfDocumentedException e, final int index,
-                                            final ErrorType expErrorType, final ErrorTag expErrorTag,
-                                            final Optional<String> expErrorMsg,
-                                            final Optional<String> expAppTag ) {
+    void verifyRestconfDocumentedException(final RestconfDocumentedException e, final int index,
+            final ErrorType expErrorType, final ErrorTag expErrorTag, final Optional<String> expErrorMsg,
+            final Optional<String> expAppTag) {
         RestconfError actual = null;
         try {
-            actual = e.getErrors().get( index );
-        }
-        catch( ArrayIndexOutOfBoundsException ex ) {
-            fail( "RestconfError not found at index " + index );
+            actual = e.getErrors().get(index);
+        } catch (ArrayIndexOutOfBoundsException ex) {
+            fail("RestconfError not found at index " + index);
         }
 
-        assertEquals( "getErrorType", expErrorType, actual.getErrorType() );
-        assertEquals( "getErrorTag", expErrorTag, actual.getErrorTag() );
-        assertNotNull( "getErrorMessage is null", actual.getErrorMessage() );
+        assertEquals("getErrorType", expErrorType, actual.getErrorType());
+        assertEquals("getErrorTag", expErrorTag, actual.getErrorTag());
+        assertNotNull("getErrorMessage is null", actual.getErrorMessage());
 
-        if( expErrorMsg.isPresent() ) {
-            assertEquals( "getErrorMessage", expErrorMsg.get(), actual.getErrorMessage() );
+        if (expErrorMsg.isPresent()) {
+            assertEquals("getErrorMessage", expErrorMsg.get(), actual.getErrorMessage());
         }
 
-        if( expAppTag.isPresent() ) {
-            assertEquals( "getErrorAppTag", expAppTag.get(), actual.getErrorAppTag() );
+        if (expAppTag.isPresent()) {
+            assertEquals("getErrorAppTag", expAppTag.get(), actual.getErrorAppTag());
         }
     }
 
     @Test
     public void testInvokeRpcWithNoPayloadRpc_FailWithRpcError() {
         List<RpcError> rpcErrors = Arrays.asList(
-            RpcErrors.getRpcError( null, "bogusTag", null, ErrorSeverity.ERROR, "foo",
-                                   RpcError.ErrorType.TRANSPORT, null ),
-            RpcErrors.getRpcError( "app-tag", "in-use", null, ErrorSeverity.WARNING, "bar",
-                                   RpcError.ErrorType.RPC, null ));
+            RpcResultBuilder.newError( RpcError.ErrorType.TRANSPORT, "bogusTag", "foo" ),
+            RpcResultBuilder.newWarning( RpcError.ErrorType.RPC, "in-use", "bar",
+                                         "app-tag", null, null ) );
 
-        RpcResult<CompositeNode> rpcResult = Rpcs.<CompositeNode>getRpcResult( false, rpcErrors );
+        RpcResult<CompositeNode> rpcResult = RpcResultBuilder.<CompositeNode>failed()
+                                                              .withRpcErrors(rpcErrors).build();
 
         BrokerFacade brokerFacade = mock(BrokerFacade.class);
-        when( brokerFacade.invokeRpc(
-                 eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast")),
-                 any(CompositeNode.class)))
-            .thenReturn( Futures.<RpcResult<CompositeNode>>immediateFuture( rpcResult ) );
+        when(
+                brokerFacade.invokeRpc(
+                        eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast")),
+                        any(CompositeNode.class))).thenReturn(
+                Futures.<RpcResult<CompositeNode>> immediateFuture(rpcResult));
 
         restconfImpl.setBroker(brokerFacade);
 
         try {
-            restconfImpl.invokeRpc("toaster:cancel-toast", "");
+            restconfImpl.invokeRpc("toaster:cancel-toast", "", uriInfo);
             fail("Expected an exception to be thrown.");
-        }
-        catch (RestconfDocumentedException e) {
-            verifyRestconfDocumentedException( e, 0, ErrorType.TRANSPORT, ErrorTag.OPERATION_FAILED,
-                                               Optional.of( "foo" ), Optional.<String>absent() );
-            verifyRestconfDocumentedException( e, 1, ErrorType.RPC, ErrorTag.IN_USE,
-                                               Optional.of( "bar" ), Optional.of( "app-tag" ) );
+        } catch (RestconfDocumentedException e) {
+            verifyRestconfDocumentedException(e, 0, ErrorType.TRANSPORT, ErrorTag.OPERATION_FAILED, Optional.of("foo"),
+                    Optional.<String> absent());
+            verifyRestconfDocumentedException(e, 1, ErrorType.RPC, ErrorTag.IN_USE, Optional.of("bar"),
+                    Optional.of("app-tag"));
         }
     }
 
     @Test
     public void testInvokeRpcWithNoPayload_Success() {
-        RpcResult<CompositeNode> rpcResult = Rpcs.<CompositeNode>getRpcResult( true );
+        RpcResult<CompositeNode> rpcResult = RpcResultBuilder.<CompositeNode>success().build();
 
         BrokerFacade brokerFacade = mock(BrokerFacade.class);
-        when( brokerFacade.invokeRpc(
-                 eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast")),
-                 any( CompositeNode.class )))
-            .thenReturn( Futures.<RpcResult<CompositeNode>>immediateFuture( rpcResult ) );
+        when(
+                brokerFacade.invokeRpc(
+                        eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast")),
+                        any(CompositeNode.class))).thenReturn(
+                Futures.<RpcResult<CompositeNode>> immediateFuture(rpcResult));
 
         restconfImpl.setBroker(brokerFacade);
 
-        StructuredData output = restconfImpl.invokeRpc("toaster:cancel-toast",
-                "");
+        StructuredData output = restconfImpl.invokeRpc("toaster:cancel-toast", "", uriInfo);
         assertEquals(null, output);
-        //additional validation in the fact that the restconfImpl does not throw an exception.
+        // additional validation in the fact that the restconfImpl does not
+        // throw an exception.
     }
 
     @Test
     public void testInvokeRpcMethodExpectingNoPayloadButProvidePayload() {
         try {
-            restconfImpl.invokeRpc("toaster:cancel-toast", " a payload ");
+            restconfImpl.invokeRpc("toaster:cancel-toast", " a payload ", uriInfo);
             fail("Expected an exception");
         } catch (RestconfDocumentedException e) {
-            verifyRestconfDocumentedException( e, 0, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
-                                               Optional.<String>absent(), Optional.<String>absent() );
+            verifyRestconfDocumentedException(e, 0, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
+                    Optional.<String> absent(), Optional.<String> absent());
         }
     }
 
     @Test
     public void testInvokeRpcMethodWithBadMethodName() {
         try {
-            restconfImpl.invokeRpc("toaster:bad-method", "");
+            restconfImpl.invokeRpc("toaster:bad-method", "", uriInfo);
             fail("Expected an exception");
-        }
-        catch (RestconfDocumentedException e) {
-            verifyRestconfDocumentedException( e, 0, ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT,
-                                               Optional.<String>absent(), Optional.<String>absent() );
+        } catch (RestconfDocumentedException e) {
+            verifyRestconfDocumentedException(e, 0, ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT,
+                    Optional.<String> absent(), Optional.<String> absent());
         }
     }
 
     @Test
     public void testInvokeRpcMethodWithInput() {
-        RpcResult<CompositeNode> rpcResult = Rpcs.<CompositeNode>getRpcResult( true );
+        RpcResult<CompositeNode> rpcResult = RpcResultBuilder.<CompositeNode>success().build();
 
         CompositeNode payload = mock(CompositeNode.class);
 
         BrokerFacade brokerFacade = mock(BrokerFacade.class);
-        when( brokerFacade.invokeRpc(
-                 eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)make-toast")),
-                 any(CompositeNode.class)))
-            .thenReturn( Futures.<RpcResult<CompositeNode>>immediateFuture( rpcResult ) );
+        when(
+                brokerFacade.invokeRpc(
+                        eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)make-toast")),
+                        any(CompositeNode.class))).thenReturn(
+                Futures.<RpcResult<CompositeNode>> immediateFuture(rpcResult));
 
         restconfImpl.setBroker(brokerFacade);
 
-        StructuredData output = restconfImpl.invokeRpc("toaster:make-toast",
-                payload);
+        StructuredData output = restconfImpl.invokeRpc("toaster:make-toast", payload, uriInfo);
         assertEquals(null, output);
-        //additional validation in the fact that the restconfImpl does not throw an exception.
+        // additional validation in the fact that the restconfImpl does not
+        // throw an exception.
     }
 
     @Test
     public void testThrowExceptionWhenSlashInModuleName() {
         try {
-            restconfImpl.invokeRpc("toaster/slash", "");
+            restconfImpl.invokeRpc("toaster/slash", "", uriInfo);
             fail("Expected an exception.");
-        }
-        catch (RestconfDocumentedException e) {
-            verifyRestconfDocumentedException( e, 0, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
-                                               Optional.<String>absent(), Optional.<String>absent() );
+        } catch (RestconfDocumentedException e) {
+            verifyRestconfDocumentedException(e, 0, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
+                    Optional.<String> absent(), Optional.<String> absent());
         }
     }
 
     @Test
     public void testInvokeRpcWithNoPayloadWithOutput_Success() {
-        CompositeNode compositeNode = mock( CompositeNode.class );
-        RpcResult<CompositeNode> rpcResult = Rpcs.<CompositeNode>getRpcResult( true, compositeNode,
-                                                            Collections.<RpcError>emptyList() );
+        CompositeNode compositeNode = mock(CompositeNode.class);
+        RpcResult<CompositeNode> rpcResult =
+                                  RpcResultBuilder.<CompositeNode>success(compositeNode).build();
 
         BrokerFacade brokerFacade = mock(BrokerFacade.class);
-        when( brokerFacade.invokeRpc(
+        when(
+                brokerFacade.invokeRpc(
                         eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)testOutput")),
-                        any( CompositeNode.class )))
-            .thenReturn( Futures.<RpcResult<CompositeNode>>immediateFuture( rpcResult ) );
+                        any(CompositeNode.class))).thenReturn(
+                Futures.<RpcResult<CompositeNode>> immediateFuture(rpcResult));
 
         restconfImpl.setBroker(brokerFacade);
 
-        StructuredData output = restconfImpl.invokeRpc("toaster:testOutput", "");
-        assertNotNull( output );
-        assertSame( compositeNode, output.getData() );
-        assertNotNull( output.getSchema() );
+        StructuredData output = restconfImpl.invokeRpc("toaster:testOutput", "", uriInfo);
+        assertNotNull(output);
+        assertSame(compositeNode, output.getData());
+        assertNotNull(output.getSchema());
     }
 
+    /**
+     *
+     * Tests calling of RestConfImpl method invokeRpc. In the method there is searched rpc in remote schema context.
+     * This rpc is then executed.
+     *
+     * I wasn't able to simulate calling of rpc on remote device therefore this testing method raise method when rpc is
+     * invoked.
+     */
     @Test
-    public void testMountedRpcCallNoPayload_Success() throws Exception
-    {
-        RpcResult<CompositeNode> rpcResult = Rpcs.<CompositeNode>getRpcResult( true );
+    public void testMountedRpcCallNoPayload_Success() throws Exception {
+        RpcResult<CompositeNode> rpcResult = RpcResultBuilder.<CompositeNode>success().build();
 
-        ListenableFuture<RpcResult<CompositeNode>> mockListener = mock( ListenableFuture.class );
-        when( mockListener.get() ).thenReturn( rpcResult );
+        ListenableFuture<RpcResult<CompositeNode>> mockListener = mock(ListenableFuture.class);
+        when(mockListener.get()).thenReturn(rpcResult);
 
-        QName cancelToastQName = QName.create( "namespace", "2014-05-28", "cancelToast" );
+        QName cancelToastQName = QName.create("namespace", "2014-05-28", "cancelToast");
 
-        RpcDefinition mockRpc = mock( RpcDefinition.class );
-        when( mockRpc.getQName() ).thenReturn( cancelToastQName );
+        RpcDefinition mockRpc = mock(RpcDefinition.class);
+        when(mockRpc.getQName()).thenReturn(cancelToastQName);
 
-        MountInstance mockMountPoint = mock( MountInstance.class );
-        when( mockMountPoint.rpc( eq( cancelToastQName ), any( CompositeNode.class ) ) )
-        .thenReturn( mockListener );
+        MountInstance mockMountPoint = mock(MountInstance.class);
+        when(mockMountPoint.rpc(eq(cancelToastQName), any(CompositeNode.class))).thenReturn(mockListener);
 
-        InstanceIdWithSchemaNode mockedInstanceId = mock( InstanceIdWithSchemaNode.class );
-        when( mockedInstanceId.getMountPoint() ).thenReturn( mockMountPoint );
+        when(mockMountPoint.getSchemaContext()).thenReturn(TestUtils.loadSchemaContext("/invoke-rpc"));
 
-        ControllerContext mockedContext = mock( ControllerContext.class );
-        String cancelToastStr = "toaster:cancel-toast";
-        when( mockedContext.urlPathArgDecode( cancelToastStr ) ).thenReturn( cancelToastStr );
-        when( mockedContext.getRpcDefinition( cancelToastStr ) ).thenReturn( mockRpc );
-        when( mockedContext.toMountPointIdentifier(  "opendaylight-inventory:nodes/node/"
-                + "REMOTE_HOST/yang-ext:mount/toaster:cancel-toast" ) ).thenReturn( mockedInstanceId );
+        InstanceIdWithSchemaNode mockedInstanceId = mock(InstanceIdWithSchemaNode.class);
+        when(mockedInstanceId.getMountPoint()).thenReturn(mockMountPoint);
 
-        restconfImpl.setControllerContext( mockedContext );
-        StructuredData output = restconfImpl.invokeRpc(
-                "opendaylight-inventory:nodes/node/REMOTE_HOST/yang-ext:mount/toaster:cancel-toast",
-                "");
-        assertEquals(null, output);
+        ControllerContext mockedContext = mock(ControllerContext.class);
+        String rpcNoop = "invoke-rpc-module:rpc-noop";
+        when(mockedContext.urlPathArgDecode(rpcNoop)).thenReturn(rpcNoop);
+        when(mockedContext.getRpcDefinition(rpcNoop)).thenReturn(mockRpc);
+        when(
+                mockedContext.toMountPointIdentifier(eq("opendaylight-inventory:nodes/node/"
+                        + "REMOTE_HOST/yang-ext:mount/invoke-rpc-module:rpc-noop"))).thenReturn(mockedInstanceId);
+
+        restconfImpl.setControllerContext(mockedContext);
+        try {
+            restconfImpl.invokeRpc(
+                    "opendaylight-inventory:nodes/node/REMOTE_HOST/yang-ext:mount/invoke-rpc-module:rpc-noop", "",
+                    uriInfo);
+            fail("RestconfDocumentedException wasn't raised");
+        } catch (RestconfDocumentedException e) {
+            List<RestconfError> errors = e.getErrors();
+            assertNotNull(errors);
+            assertEquals(1, errors.size());
+            assertEquals(ErrorType.APPLICATION, errors.iterator().next().getErrorType());
+            assertEquals(ErrorTag.OPERATION_FAILED, errors.iterator().next().getErrorTag());
+        }
 
-        //additional validation in the fact that the restconfImpl does not throw an exception.
+        // additional validation in the fact that the restconfImpl does not
+        // throw an exception.
     }
 }
index 319603dfc14b1f6a4965d6de46e99bf1a6199f8f..3dd3101a2e2a325f8da94cdacef60dbaa0c0add0 100644 (file)
@@ -19,12 +19,10 @@ import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUt
 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 javax.ws.rs.core.UriInfo;
-
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
 import org.junit.BeforeClass;
@@ -55,10 +53,10 @@ public class MediaTypesTest extends JerseyTest {
     @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());
+        // 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,
@@ -66,31 +64,31 @@ public class MediaTypesTest extends JerseyTest {
         return resourceConfig;
     }
 
-  @Test
-  public void testPostOperationsWithInputDataMediaTypes() throws UnsupportedEncodingException {
-      String uriPrefix = "/operations/";
-      String uriPath = "ietf-interfaces:interfaces";
-      String uri = uriPrefix + uriPath;
-      when(restconfService.invokeRpc(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
-      post(uri, Draft02.MediaTypes.OPERATION+JSON, Draft02.MediaTypes.OPERATION+JSON, jsonData);
-      verify(restconfService, times(1)).invokeRpc(eq(uriPath), any(CompositeNode.class));
-      post(uri, Draft02.MediaTypes.OPERATION+XML, Draft02.MediaTypes.OPERATION+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 testPostOperationsWithInputDataMediaTypes() throws UnsupportedEncodingException {
+        String uriPrefix = "/operations/";
+        String uriPath = "ietf-interfaces:interfaces";
+        String uri = uriPrefix + uriPath;
+        when(restconfService.invokeRpc(eq(uriPath), any(CompositeNode.class), any(UriInfo.class))).thenReturn(null);
+        post(uri, Draft02.MediaTypes.OPERATION + JSON, Draft02.MediaTypes.OPERATION + JSON, jsonData);
+        verify(restconfService, times(1)).invokeRpc(eq(uriPath), any(CompositeNode.class), any(UriInfo.class));
+        post(uri, Draft02.MediaTypes.OPERATION + XML, Draft02.MediaTypes.OPERATION + XML, xmlData);
+        verify(restconfService, times(2)).invokeRpc(eq(uriPath), any(CompositeNode.class), any(UriInfo.class));
+        post(uri, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, jsonData);
+        verify(restconfService, times(3)).invokeRpc(eq(uriPath), any(CompositeNode.class), any(UriInfo.class));
+        post(uri, MediaType.APPLICATION_XML, MediaType.APPLICATION_XML, xmlData);
+        verify(restconfService, times(4)).invokeRpc(eq(uriPath), any(CompositeNode.class), any(UriInfo.class));
+        post(uri, MediaType.TEXT_XML, MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(5)).invokeRpc(eq(uriPath), any(CompositeNode.class), any(UriInfo.class));
+        post(uri, null, MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class), any(UriInfo.class));
+
+        // negative tests
+        post(uri, MediaType.TEXT_PLAIN, MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class), any(UriInfo.class));
+        post(uri, MediaType.TEXT_XML, MediaType.TEXT_PLAIN, xmlData);
+        verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class), any(UriInfo.class));
+    }
 
     @Test
     public void testGetConfigMediaTypes() throws UnsupportedEncodingException {
@@ -98,9 +96,9 @@ public class MediaTypesTest extends JerseyTest {
         String uriPath = "ietf-interfaces:interfaces";
         String uri = uriPrefix + uriPath;
         when(restconfService.readConfigurationData(eq(uriPath), any(UriInfo.class))).thenReturn(null);
-        get(uri, Draft02.MediaTypes.DATA+JSON);
+        get(uri, Draft02.MediaTypes.DATA + JSON);
         verify(restconfService, times(1)).readConfigurationData(eq(uriPath), any(UriInfo.class));
-        get(uri, Draft02.MediaTypes.DATA+XML);
+        get(uri, Draft02.MediaTypes.DATA + XML);
         verify(restconfService, times(2)).readConfigurationData(eq(uriPath), any(UriInfo.class));
         get(uri, MediaType.APPLICATION_JSON);
         verify(restconfService, times(3)).readConfigurationData(eq(uriPath), any(UriInfo.class));
@@ -120,9 +118,9 @@ public class MediaTypesTest extends JerseyTest {
         String uriPath = "ietf-interfaces:interfaces";
         String uri = uriPrefix + uriPath;
         when(restconfService.readOperationalData(eq(uriPath), any(UriInfo.class))).thenReturn(null);
-        get(uri, Draft02.MediaTypes.DATA+JSON);
+        get(uri, Draft02.MediaTypes.DATA + JSON);
         verify(restconfService, times(1)).readOperationalData(eq(uriPath), any(UriInfo.class));
-        get(uri, Draft02.MediaTypes.DATA+XML);
+        get(uri, Draft02.MediaTypes.DATA + XML);
         verify(restconfService, times(2)).readOperationalData(eq(uriPath), any(UriInfo.class));
         get(uri, MediaType.APPLICATION_JSON);
         verify(restconfService, times(3)).readOperationalData(eq(uriPath), any(UriInfo.class));
@@ -142,9 +140,9 @@ public class MediaTypesTest extends JerseyTest {
         String uriPath = "ietf-interfaces:interfaces";
         String uri = uriPrefix + uriPath;
         when(restconfService.updateConfigurationData(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
-        put(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+        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);
+        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));
@@ -162,9 +160,9 @@ public class MediaTypesTest extends JerseyTest {
         String uriPath = "ietf-interfaces:interfaces";
         String uri = uriPrefix + uriPath;
         when(restconfService.createConfigurationData(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
-        post(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+        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);
+        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));
@@ -181,9 +179,9 @@ public class MediaTypesTest extends JerseyTest {
         String uriPrefix = "/config/";
         String uri = uriPrefix;
         when(restconfService.createConfigurationData(any(CompositeNode.class))).thenReturn(null);
-        post(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+        post(uri, null, Draft02.MediaTypes.DATA + JSON, jsonData);
         verify(restconfService, times(1)).createConfigurationData(any(CompositeNode.class));
-        post(uri, null, Draft02.MediaTypes.DATA+XML, xmlData);
+        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));
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MultipleEqualNamesForDataNodesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MultipleEqualNamesForDataNodesTest.java
new file mode 100644 (file)
index 0000000..5fbfc45
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import java.util.Set;
+import javax.ws.rs.ext.MessageBodyReader;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+
+/**
+ * If more then one data element with equal name exists where container or leaf schema node should be present the
+ * RestconfDocumentedException has to be raised
+ *
+ * Tests for BUG 1204
+ */
+public class MultipleEqualNamesForDataNodesTest {
+
+    @Test
+    public void multipleEqualNameDataNodeTestForContainerJsonTest() {
+        multipleEqualNameDataNodeTest("/equal-data-node-names/equal-name-data-for-container.json",
+                ErrorType.APPLICATION, ErrorTag.BAD_ELEMENT, JsonToCompositeNodeProvider.INSTANCE);
+    }
+
+    @Test
+    public void multipleEqualNameDataNodeTestForLeafJsonTest() {
+        multipleEqualNameDataNodeTest("/equal-data-node-names/equal-name-data-for-leaf.json", ErrorType.PROTOCOL,
+                ErrorTag.MALFORMED_MESSAGE, JsonToCompositeNodeProvider.INSTANCE);
+    }
+
+    @Test
+    public void multipleEqualNameDataNodeTestForContainerXmlTest() {
+        multipleEqualNameDataNodeTest("/equal-data-node-names/equal-name-data-for-container.xml",
+                ErrorType.APPLICATION, ErrorTag.BAD_ELEMENT, XmlToCompositeNodeProvider.INSTANCE);
+    }
+
+    @Test
+    public void multipleEqualNameDataNodeTestForLeafXmlTest() {
+        multipleEqualNameDataNodeTest("/equal-data-node-names/equal-name-data-for-leaf.xml", ErrorType.APPLICATION,
+                ErrorTag.BAD_ELEMENT, XmlToCompositeNodeProvider.INSTANCE);
+    }
+
+    private void multipleEqualNameDataNodeTest(String path, ErrorType errorType, ErrorTag errorTag,
+            MessageBodyReader<CompositeNode> messageBodyReader) {
+        try {
+            CompositeNode compositeNode = TestUtils.readInputToCnSn(path, false, messageBodyReader);
+            assertNotNull(compositeNode);
+
+            Set<Module> modules = null;
+            modules = TestUtils.loadModulesFrom("/equal-data-node-names/yang");
+            assertNotNull(modules);
+
+            TestUtils.normalizeCompositeNode(compositeNode, modules, "equal-data-node-names" + ":" + "cont");
+            fail("Exception RestconfDocumentedException should be raised");
+        } catch (RestconfDocumentedException e) {
+            List<RestconfError> errors = e.getErrors();
+            assertNotNull(errors);
+
+            assertEquals(1, errors.size());
+
+            RestconfError restconfError = errors.get(0);
+
+            assertEquals(errorType, restconfError.getErrorType());
+            assertEquals(errorTag, restconfError.getErrorTag());
+        }
+    }
+
+}
index 158569af7386eb35081ba046af00d96b0de08d96..7c354acc4077a4c1d50ad9da0d27e3a009973127 100644 (file)
@@ -11,7 +11,6 @@ import static org.junit.Assert.assertNotNull;
 
 import java.net.URI;
 import java.net.URISyntaxException;
-
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
@@ -26,7 +25,7 @@ public class NormalizeNodeTest extends YangAndXmlAndDataSchemaLoader {
         dataLoad("/normalize-node/yang/");
     }
 
-    @Test(expected=RestconfDocumentedException.class)
+    @Test(expected = RestconfDocumentedException.class)
     public void namespaceNotNullAndInvalidNamespaceAndNoModuleNameTest() {
 
         TestUtils.normalizeCompositeNode(prepareCnSn("wrongnamespace"), modules, schemaNodePath);
index 024a93b78e7e2a52e76059b198363fec003ababd..4000c7cc807f7e62c3583649ee3d04e2acd32f53 100644 (file)
@@ -12,7 +12,6 @@ import static org.junit.Assert.assertNull;
 import static org.mockito.Mockito.mock;
 
 import java.util.Collections;
-
 import org.junit.Test;
 import org.opendaylight.controller.sal.restconf.impl.RestCodec;
 import org.opendaylight.yangtools.concepts.Codec;
@@ -28,7 +27,7 @@ public class RestCodecExceptionsTest {
 
     @Test
     public void serializeExceptionTest() {
-        Codec<Object, Object> codec = RestCodec.from(BitsType.create(PATH, Collections.<Bit>emptyList()), null);
+        Codec<Object, Object> codec = RestCodec.from(BitsType.create(PATH, Collections.<Bit> emptyList()), null);
         String serializedValue = (String) codec.serialize("incorrect value"); // set
                                                                               // expected
         assertEquals("incorrect value", serializedValue);
index e8cbf3140f35f9f750612ddc5c932a8763034a4b..66ced818175e2435cda90e41a854214277c6403b 100644 (file)
@@ -31,7 +31,7 @@ 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.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
@@ -57,10 +57,10 @@ public class RestDeleteOperationTest extends JerseyTest {
     @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());
+        // 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);
@@ -71,18 +71,19 @@ public class RestDeleteOperationTest extends JerseyTest {
     public void deleteConfigStatusCodes() throws UnsupportedEncodingException {
         String uri = "/config/test-interface:interfaces";
         Future<RpcResult<TransactionStatus>> dummyFuture = createFuture(TransactionStatus.COMMITED);
-        when(brokerFacade.commitConfigurationDataDelete(any(InstanceIdentifier.class))).thenReturn(dummyFuture);
+        when(brokerFacade.commitConfigurationDataDelete(any(YangInstanceIdentifier.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);
+        when(brokerFacade.commitConfigurationDataDelete(any(YangInstanceIdentifier.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();
+        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(statusName)
+                .build();
         return new DummyFuture.Builder<TransactionStatus>().rpcResult(rpcResult).build();
     }
 
index 53183c611cf54329d5555b2de8b56b01cedfdf0d..bab06e92451985b5a0d95032e99174adb91ba4b0 100644 (file)
@@ -12,7 +12,6 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.io.FileNotFoundException;
-
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
@@ -47,10 +46,9 @@ public class RestGetAugmentedElementWhenEqualNamesTest {
     public void nodeWithoutNamespaceHasMoreAugments() {
         try {
             controllerContext.toInstanceIdentifier("main:cont/cont1");
-            fail( "Expected exception" );
+            fail("Expected exception");
         } catch (RestconfDocumentedException e) {
-            assertTrue(e.getErrors().get( 0 ).getErrorMessage().contains(
-                                    "is added as augment from more than one module"));
+            assertTrue(e.getErrors().get(0).getErrorMessage().contains("is added as augment from more than one module"));
         }
     }
 }
index f0a232fba670539c5a872e5894a89bd7c214c778..ac660e32bce0f654e8801a56c723f6ec6736c80c 100644 (file)
@@ -7,8 +7,10 @@
  */
 package org.opendaylight.controller.sal.restconf.impl.test;
 
-import static org.junit.Assert.assertNotNull;
 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 static org.junit.Assert.fail;
 import static org.mockito.Matchers.any;
@@ -25,8 +27,10 @@ import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -58,11 +62,13 @@ import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
 import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
 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.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.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 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.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -77,7 +83,7 @@ public class RestGetOperationTest extends JerseyTest {
         Object key;
         Object data; // List for a CompositeNode, value Object for a SimpleNode
 
-        NodeData( Object key, Object data ) {
+        NodeData(final Object key, final Object data) {
             this.key = key;
             this.data = data;
         }
@@ -92,6 +98,8 @@ public class RestGetOperationTest extends JerseyTest {
     private static SchemaContext schemaContextModules;
     private static SchemaContext schemaContextBehindMountPoint;
 
+    private static final String RESTCONF_NS = "urn:ietf:params:xml:ns:yang:ietf-restconf";
+
     @BeforeClass
     public static void init() throws FileNotFoundException {
         schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
@@ -119,7 +127,7 @@ public class RestGetOperationTest extends JerseyTest {
         resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
                 StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
                 JsonToCompositeNodeProvider.INSTANCE);
-        resourceConfig.registerClasses( RestconfDocumentedExceptionMapper.class );
+        resourceConfig.registerClasses(RestconfDocumentedExceptionMapper.class);
         return resourceConfig;
     }
 
@@ -156,11 +164,11 @@ public class RestGetOperationTest extends JerseyTest {
     public void getDataWithUrlMountPoint() throws UnsupportedEncodingException, URISyntaxException {
         when(
                 brokerFacade.readConfigurationDataBehindMountPoint(any(MountInstance.class),
-                        any(InstanceIdentifier.class))).thenReturn(prepareCnDataForMountPointTest());
+                        any(YangInstanceIdentifier.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);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
 
         ControllerContext.getInstance().setMountService(mockMountService);
 
@@ -174,12 +182,11 @@ public class RestGetOperationTest extends JerseyTest {
     /**
      * MountPoint test. URI represents mount point.
      *
-     * Slashes in URI behind mount point. lst1 element with key
-     * GigabitEthernet0%2F0%2F0%2F0 (GigabitEthernet0/0/0/0) is requested via
-     * GET HTTP operation. It is tested whether %2F character is replaced with
-     * simple / in InstanceIdentifier parameter in method
-     * {@link BrokerFacade#readConfigurationDataBehindMountPoint(MountInstance, InstanceIdentifier)}
-     * which is called in method {@link RestconfImpl#readConfigurationData}
+     * Slashes in URI behind mount point. lst1 element with key GigabitEthernet0%2F0%2F0%2F0 (GigabitEthernet0/0/0/0) is
+     * requested via GET HTTP operation. It is tested whether %2F character is replaced with simple / in
+     * InstanceIdentifier parameter in method
+     * {@link BrokerFacade#readConfigurationDataBehindMountPoint(MountInstance, YangInstanceIdentifier)} which is called in
+     * method {@link RestconfImpl#readConfigurationData}
      *
      *
      * @throws ParseException
@@ -187,14 +194,14 @@ public class RestGetOperationTest extends JerseyTest {
     @Test
     public void getDataWithSlashesBehindMountPoint() throws UnsupportedEncodingException, URISyntaxException,
             ParseException {
-        InstanceIdentifier awaitedInstanceIdentifier = prepareInstanceIdentifierForList();
+        YangInstanceIdentifier awaitedInstanceIdentifier = prepareInstanceIdentifierForList();
         when(
                 brokerFacade.readConfigurationDataBehindMountPoint(any(MountInstance.class),
                         eq(awaitedInstanceIdentifier))).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);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
 
         ControllerContext.getInstance().setMountService(mockMountService);
 
@@ -202,7 +209,7 @@ public class RestGetOperationTest extends JerseyTest {
         assertEquals(200, get(uri, MediaType.APPLICATION_XML));
     }
 
-    private InstanceIdentifier prepareInstanceIdentifierForList() throws URISyntaxException, ParseException {
+    private YangInstanceIdentifier prepareInstanceIdentifierForList() throws URISyntaxException, ParseException {
         List<PathArgument> parameters = new ArrayList<>();
 
         Date revision = new SimpleDateFormat("yyyy-MM-dd").parse("2014-01-09");
@@ -211,21 +218,21 @@ public class RestGetOperationTest extends JerseyTest {
         QName qNameList = QName.create(uri, revision, "lst1");
         QName qNameKeyList = QName.create(uri, revision, "lf11");
 
-        parameters.add(new InstanceIdentifier.NodeIdentifier(qNameCont));
-        parameters.add(new InstanceIdentifier.NodeIdentifierWithPredicates(qNameList, qNameKeyList,
+        parameters.add(new YangInstanceIdentifier.NodeIdentifier(qNameCont));
+        parameters.add(new YangInstanceIdentifier.NodeIdentifierWithPredicates(qNameList, qNameKeyList,
                 "GigabitEthernet0/0/0/0"));
-        return new InstanceIdentifier(parameters);
+        return YangInstanceIdentifier.create(parameters);
     }
 
     @Test
     public void getDataMountPointIntoHighestElement() throws UnsupportedEncodingException, URISyntaxException {
         when(
                 brokerFacade.readConfigurationDataBehindMountPoint(any(MountInstance.class),
-                        any(InstanceIdentifier.class))).thenReturn(prepareCnDataForMountPointTest());
+                        any(YangInstanceIdentifier.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);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
 
         ControllerContext.getInstance().setMountService(mockMountService);
 
@@ -244,7 +251,7 @@ public class RestGetOperationTest extends JerseyTest {
         validateModulesResponseJson(response);
 
         response = target(uri).request("application/yang.api+xml").get();
-        validateModulesResponseXml(response);
+        validateModulesResponseXml(response,schemaContextModules);
     }
 
     // /streams/
@@ -260,9 +267,12 @@ public class RestGetOperationTest extends JerseyTest {
         assertTrue(responseBody.contains("streams"));
 
         response = target(uri).request("application/yang.api+xml").get();
-        responseBody = response.readEntity(String.class);
-        assertNotNull(responseBody);
-        assertTrue(responseBody.contains("<streams xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\""));
+        Document responseXmlBody = response.readEntity(Document.class);
+        assertNotNull(responseXmlBody);
+        Element rootNode = responseXmlBody.getDocumentElement();
+
+        assertEquals("streams", rootNode.getLocalName());
+        assertEquals(RESTCONF_NS, rootNode.getNamespaceURI());
     }
 
     // /modules/module
@@ -274,18 +284,23 @@ public class RestGetOperationTest extends JerseyTest {
 
         Response response = target(uri).request("application/yang.api+xml").get();
         assertEquals(200, response.getStatus());
-        String responseBody = response.readEntity(String.class);
-        assertTrue("Module2 in xml wasn't found", prepareXmlRegex("module2", "2014-01-02", "module:2", responseBody)
-                .find());
-        String[] split = responseBody.split("<module");
-        assertEquals("<module element is returned more then once", 2, split.length);
+        Document responseXml = response.readEntity(Document.class);
+
+
+
+        QName qname = assertedModuleXmlToModuleQName(responseXml.getDocumentElement());
+        assertNotNull(qname);
+
+        assertEquals("module2", qname.getLocalName());
+        assertEquals("module:2", qname.getNamespace().toString());
+        assertEquals("2014-01-02", qname.getFormattedRevision());
 
         response = target(uri).request("application/yang.api+json").get();
         assertEquals(200, response.getStatus());
-        responseBody = response.readEntity(String.class);
+        String responseBody = response.readEntity(String.class);
         assertTrue("Module2 in json wasn't found", prepareJsonRegex("module2", "2014-01-02", "module:2", responseBody)
                 .find());
-        split = responseBody.split("\"module\"");
+        String[] split = responseBody.split("\"module\"");
         assertEquals("\"module\" element is returned more then once", 2, split.length);
 
     }
@@ -299,19 +314,12 @@ public class RestGetOperationTest extends JerseyTest {
 
         Response response = target(uri).request("application/yang.api+xml").get();
         assertEquals(200, response.getStatus());
-        String responseBody = response.readEntity(String.class);
-        assertTrue("Xml response for /operations dummy-rpc1-module1 is incorrect",
-                validateOperationsResponseXml(responseBody, "dummy-rpc1-module1", "module:1").find());
-        assertTrue("Xml response for /operations dummy-rpc2-module1 is incorrect",
-                validateOperationsResponseXml(responseBody, "dummy-rpc2-module1", "module:1").find());
-        assertTrue("Xml response for /operations dummy-rpc1-module2 is incorrect",
-                validateOperationsResponseXml(responseBody, "dummy-rpc1-module2", "module:2").find());
-        assertTrue("Xml response for /operations dummy-rpc2-module2 is incorrect",
-                validateOperationsResponseXml(responseBody, "dummy-rpc2-module2", "module:2").find());
+        Document responseDoc = response.readEntity(Document.class);
+        validateOperationsResponseXml(responseDoc, schemaContextModules);
 
         response = target(uri).request("application/yang.api+json").get();
         assertEquals(200, response.getStatus());
-        responseBody = response.readEntity(String.class);
+        String responseBody = response.readEntity(String.class);
         assertTrue("Json response for /operations dummy-rpc1-module1 is incorrect",
                 validateOperationsResponseJson(responseBody, "dummy-rpc1-module1", "module1").find());
         assertTrue("Json response for /operations dummy-rpc2-module1 is incorrect",
@@ -323,6 +331,30 @@ public class RestGetOperationTest extends JerseyTest {
 
     }
 
+    private void validateOperationsResponseXml(final Document responseDoc, final SchemaContext schemaContext) {
+        Element operationsElem = responseDoc.getDocumentElement();
+        assertEquals(RESTCONF_NS, operationsElem.getNamespaceURI());
+        assertEquals("operations", operationsElem.getLocalName());
+
+
+        HashSet<QName> foundOperations = new HashSet<>();
+
+        NodeList operationsList = operationsElem.getChildNodes();
+        for(int i = 0;i < operationsList.getLength();i++) {
+            org.w3c.dom.Node operation = operationsList.item(i);
+
+            String namespace = operation.getNamespaceURI();
+            String name = operation.getLocalName();
+            QName opQName = QName.create(URI.create(namespace), null, name);
+            foundOperations.add(opQName);
+        }
+
+        for(RpcDefinition schemaOp : schemaContext.getOperations()) {
+            assertTrue(foundOperations.contains(schemaOp.getQName().withoutRevision()));
+        }
+
+    }
+
     // /operations/pathToMountPoint/yang-ext:mount
     @Test
     public void getOperationsBehindMountPointTest() throws FileNotFoundException, UnsupportedEncodingException {
@@ -332,7 +364,7 @@ public class RestGetOperationTest extends JerseyTest {
         MountInstance mountInstance = mock(MountInstance.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextBehindMountPoint);
         MountService mockMountService = mock(MountService.class);
-        when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
 
         controllerContext.setMountService(mockMountService);
 
@@ -340,15 +372,13 @@ public class RestGetOperationTest extends JerseyTest {
 
         Response response = target(uri).request("application/yang.api+xml").get();
         assertEquals(200, response.getStatus());
-        String responseBody = response.readEntity(String.class);
-        assertTrue("Xml response for /operations/mount_point rpc-behind-module1 is incorrect",
-                validateOperationsResponseXml(responseBody, "rpc-behind-module1", "module:1:behind:mount:point").find());
-        assertTrue("Xml response for /operations/mount_point rpc-behind-module2 is incorrect",
-                validateOperationsResponseXml(responseBody, "rpc-behind-module2", "module:2:behind:mount:point").find());
+
+        Document responseDoc = response.readEntity(Document.class);
+        validateOperationsResponseXml(responseDoc, schemaContextBehindMountPoint);
 
         response = target(uri).request("application/yang.api+json").get();
         assertEquals(200, response.getStatus());
-        responseBody = response.readEntity(String.class);
+        String responseBody = response.readEntity(String.class);
         assertTrue("Json response for /operations/mount_point rpc-behind-module1 is incorrect",
                 validateOperationsResponseJson(responseBody, "rpc-behind-module1", "module1-behind-mount-point").find());
         assertTrue("Json response for /operations/mount_point rpc-behind-module2 is incorrect",
@@ -356,7 +386,7 @@ public class RestGetOperationTest extends JerseyTest {
 
     }
 
-    private Matcher validateOperationsResponseJson(String searchIn, String rpcName, String moduleName) {
+    private Matcher validateOperationsResponseJson(final String searchIn, final String rpcName, final String moduleName) {
         StringBuilder regex = new StringBuilder();
         regex.append("^");
 
@@ -390,7 +420,7 @@ public class RestGetOperationTest extends JerseyTest {
 
     }
 
-    private Matcher validateOperationsResponseXml(String searchIn, String rpcName, String namespace) {
+    private Matcher validateOperationsResponseXml(final String searchIn, final String rpcName, final String namespace) {
         StringBuilder regex = new StringBuilder();
 
         regex.append("^");
@@ -423,7 +453,7 @@ public class RestGetOperationTest extends JerseyTest {
         MountInstance mountInstance = mock(MountInstance.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextBehindMountPoint);
         MountService mockMountService = mock(MountService.class);
-        when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
 
         controllerContext.setMountService(mockMountService);
 
@@ -444,15 +474,7 @@ public class RestGetOperationTest extends JerseyTest {
 
         response = target(uri).request("application/yang.api+xml").get();
         assertEquals(200, response.getStatus());
-        responseBody = response.readEntity(String.class);
-        assertTrue(
-                "module1-behind-mount-point in json wasn't found",
-                prepareXmlRegex("module1-behind-mount-point", "2014-02-03", "module:1:behind:mount:point", responseBody)
-                        .find());
-        assertTrue(
-                "module2-behind-mount-point in json wasn't found",
-                prepareXmlRegex("module2-behind-mount-point", "2014-02-04", "module:2:behind:mount:point", responseBody)
-                        .find());
+        validateModulesResponseXml(response, schemaContextBehindMountPoint);
 
     }
 
@@ -465,7 +487,7 @@ public class RestGetOperationTest extends JerseyTest {
         MountInstance mountInstance = mock(MountInstance.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextBehindMountPoint);
         MountService mockMountService = mock(MountService.class);
-        when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
 
         controllerContext.setMountService(mockMountService);
 
@@ -484,29 +506,86 @@ public class RestGetOperationTest extends JerseyTest {
 
         response = target(uri).request("application/yang.api+xml").get();
         assertEquals(200, response.getStatus());
-        responseBody = response.readEntity(String.class);
-        assertTrue(
-                "module1-behind-mount-point in json wasn't found",
-                prepareXmlRegex("module1-behind-mount-point", "2014-02-03", "module:1:behind:mount:point", responseBody)
-                        .find());
-        split = responseBody.split("<module");
-        assertEquals("<module element is returned more then once", 2, split.length);
+        Document responseXml = response.readEntity(Document.class);
+
+        QName module = assertedModuleXmlToModuleQName(responseXml.getDocumentElement());
+
+        assertEquals("module1-behind-mount-point", module.getLocalName());
+        assertEquals("2014-02-03", module.getFormattedRevision());
+        assertEquals("module:1:behind:mount:point", module.getNamespace().toString());
+
 
     }
 
-    private void validateModulesResponseXml(Response response) {
+    private void validateModulesResponseXml(final Response response, final SchemaContext schemaContext) {
         assertEquals(200, response.getStatus());
-        String responseBody = response.readEntity(String.class);
+        Document responseBody = response.readEntity(Document.class);
+        NodeList moduleNodes = responseBody.getDocumentElement().getElementsByTagNameNS(RESTCONF_NS, "module");
 
-        assertTrue("Module1 in xml wasn't found", prepareXmlRegex("module1", "2014-01-01", "module:1", responseBody)
-                .find());
-        assertTrue("Module2 in xml wasn't found", prepareXmlRegex("module2", "2014-01-02", "module:2", responseBody)
-                .find());
-        assertTrue("Module3 in xml wasn't found", prepareXmlRegex("module3", "2014-01-03", "module:3", responseBody)
-                .find());
+        assertTrue(moduleNodes.getLength() > 0);
+
+        HashSet<QName> foundModules = new HashSet<>();
+
+        for(int i=0;i < moduleNodes.getLength();i++) {
+            org.w3c.dom.Node module = moduleNodes.item(i);
+
+            QName name = assertedModuleXmlToModuleQName(module);
+            foundModules.add(name);
+        }
+
+        assertAllModules(foundModules,schemaContext);
+    }
+
+    private void assertAllModules(final Set<QName> foundModules, final SchemaContext schemaContext) {
+        for(Module module : schemaContext.getModules()) {
+            QName current = QName.create(module.getQNameModule(),module.getName());
+            assertTrue("Module not found in response.",foundModules.contains(current));
+        }
+
+    }
+
+    private QName assertedModuleXmlToModuleQName(final org.w3c.dom.Node module) {
+        assertEquals("module", module.getLocalName());
+        assertEquals(RESTCONF_NS, module.getNamespaceURI());
+        String revision = null;
+        String namespace = null;
+        String name = null;
+
+
+        NodeList childNodes = module.getChildNodes();
+
+        for(int i =0;i < childNodes.getLength(); i++) {
+            org.w3c.dom.Node child = childNodes.item(i);
+            assertEquals(RESTCONF_NS, child.getNamespaceURI());
+
+            switch(child.getLocalName()) {
+                case "name":
+                    assertNull("Name element appeared multiple times",name);
+                    name = child.getTextContent().trim();
+                    break;
+                case "revision":
+                    assertNull("Revision element appeared multiple times",revision);
+                    revision = child.getTextContent().trim();
+                    break;
+
+                case "namespace":
+                    assertNull("Namespace element appeared multiple times",namespace);
+                    namespace = child.getTextContent().trim();
+                    break;
+            }
+        }
+
+        assertNotNull("Revision was not part of xml",revision);
+        assertNotNull("Module namespace was not part of xml",namespace);
+        assertNotNull("Module identiffier was not part of xml",name);
+
+
+        // TODO Auto-generated method stub
+
+        return QName.create(namespace,revision,name);
     }
 
-    private void validateModulesResponseJson(Response response) {
+    private void validateModulesResponseJson(final Response response) {
         assertEquals(200, response.getStatus());
         String responseBody = response.readEntity(String.class);
 
@@ -518,7 +597,8 @@ public class RestGetOperationTest extends JerseyTest {
                 .find());
     }
 
-    private Matcher prepareJsonRegex(String module, String revision, String namespace, String searchIn) {
+    private Matcher prepareJsonRegex(final String module, final String revision, final String namespace,
+            final String searchIn) {
         StringBuilder regex = new StringBuilder();
         regex.append("^");
 
@@ -544,41 +624,15 @@ public class RestGetOperationTest extends JerseyTest {
 
     }
 
-    private Matcher prepareXmlRegex(String module, String revision, String namespace, String searchIn) {
-        StringBuilder regex = new StringBuilder();
-        regex.append("^");
-
-        regex.append(".*<module.*");
-        regex.append(".*>");
-
-        regex.append(".*<name>");
-        regex.append(".*" + module);
-        regex.append(".*<\\/name>");
-
-        regex.append(".*<revision>");
-        regex.append(".*" + revision);
-        regex.append(".*<\\/revision>");
-
-        regex.append(".*<namespace>");
-        regex.append(".*" + namespace);
-        regex.append(".*<\\/namespace>");
 
-        regex.append(".*<\\/module.*>");
-
-        regex.append(".*");
-        regex.append("$");
-
-        Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
-        return ptrn.matcher(searchIn);
-    }
-
-    private void prepareMockForModulesTest(ControllerContext mockedControllerContext) throws FileNotFoundException {
+    private void prepareMockForModulesTest(final ControllerContext mockedControllerContext)
+            throws FileNotFoundException {
         SchemaContext schemaContext = TestUtils.loadSchemaContext("/modules");
         mockedControllerContext.setGlobalSchema(schemaContext);
         // when(mockedControllerContext.getGlobalSchema()).thenReturn(schemaContext);
     }
 
-    private int get(String uri, String mediaType) {
+    private int get(final String uri, final String mediaType) {
         return target(uri).request(mediaType).get().getStatus();
     }
 
@@ -590,11 +644,11 @@ public class RestGetOperationTest extends JerseyTest {
     }
 
     private void mockReadOperationalDataMethod() {
-        when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(answerFromGet);
+        when(brokerFacade.readOperationalData(any(YangInstanceIdentifier.class))).thenReturn(answerFromGet);
     }
 
     private void mockReadConfigurationDataMethod() {
-        when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(answerFromGet);
+        when(brokerFacade.readConfigurationData(any(YangInstanceIdentifier.class))).thenReturn(answerFromGet);
     }
 
     private static CompositeNode prepareCompositeNodeWithIetfInterfacesInterfacesData() {
@@ -615,314 +669,325 @@ public class RestGetOperationTest extends JerseyTest {
         return null;
     }
 
+    /**
+     * If includeWhiteChars URI parameter is set to false then no white characters can be included in returned output
+     *
+     * @throws UnsupportedEncodingException
+     */
+    @Test
+    public void getDataWithUriIncludeWhiteCharsParameterTest() throws UnsupportedEncodingException {
+        getDataWithUriIncludeWhiteCharsParameter("config");
+        getDataWithUriIncludeWhiteCharsParameter("operational");
+    }
+
+    private void getDataWithUriIncludeWhiteCharsParameter(final String target) throws UnsupportedEncodingException {
+        mockReadConfigurationDataMethod();
+        String uri = "/" + target + "/ietf-interfaces:interfaces/interface/eth0";
+        Response response = target(uri).queryParam("prettyPrint", "false").request("application/xml").get();
+        String xmlData = response.readEntity(String.class);
+
+        Pattern pattern = Pattern.compile(".*(>\\s+|\\s+<).*", Pattern.DOTALL);
+        Matcher matcher = pattern.matcher(xmlData);
+        // XML element can't surrounded with white character (e.g ">    " or
+        // "    <")
+        assertFalse(matcher.matches());
+
+        response = target(uri).queryParam("prettyPrint", "false").request("application/json").get();
+        String jsonData = response.readEntity(String.class);
+        pattern = Pattern.compile(".*(\\}\\s+|\\s+\\{|\\]\\s+|\\s+\\[|\\s+:|:\\s+).*", Pattern.DOTALL);
+        matcher = pattern.matcher(jsonData);
+        // JSON element can't surrounded with white character (e.g "} ", " {",
+        // "] ", " [", " :" or ": ")
+        assertFalse(matcher.matches());
+    }
+
     @Test
     public void getDataWithUriDepthParameterTest() throws UnsupportedEncodingException {
 
-        ControllerContext.getInstance().setGlobalSchema( schemaContextModules );
-
-        CompositeNode depth1Cont = toCompositeNode(
-            toCompositeNodeData( toNestedQName( "depth1-cont" ),
-                toCompositeNodeData( toNestedQName( "depth2-cont1" ),
-                    toCompositeNodeData( toNestedQName( "depth3-cont1" ),
-                        toCompositeNodeData( toNestedQName( "depth4-cont1" ),
-                            toSimpleNodeData( toNestedQName( "depth5-leaf1" ), "depth5-leaf1-value" )
-                        ),
-                        toSimpleNodeData( toNestedQName( "depth4-leaf1" ), "depth4-leaf1-value" )
-                    ),
-                    toSimpleNodeData( toNestedQName( "depth3-leaf1" ), "depth3-leaf1-value" )
-                ),
-                toCompositeNodeData( toNestedQName( "depth2-cont2" ),
-                    toCompositeNodeData( toNestedQName( "depth3-cont2" ),
-                        toCompositeNodeData( toNestedQName( "depth4-cont2" ),
-                            toSimpleNodeData( toNestedQName( "depth5-leaf2" ), "depth5-leaf2-value" )
-                        ),
-                        toSimpleNodeData( toNestedQName( "depth4-leaf2" ), "depth4-leaf2-value" )
-                    ),
-                    toSimpleNodeData( toNestedQName( "depth3-leaf2" ), "depth3-leaf2-value" )
-                ),
-                toSimpleNodeData( toNestedQName( "depth2-leaf1" ), "depth2-leaf1-value" )
-            ) );
-
-        when( brokerFacade.readConfigurationData( any( InstanceIdentifier.class ) ) )
-            .thenReturn( depth1Cont );
+        ControllerContext.getInstance().setGlobalSchema(schemaContextModules);
+
+        CompositeNode depth1Cont = toCompositeNode(toCompositeNodeData(
+                toNestedQName("depth1-cont"),
+                toCompositeNodeData(
+                        toNestedQName("depth2-cont1"),
+                        toCompositeNodeData(
+                                toNestedQName("depth3-cont1"),
+                                toCompositeNodeData(toNestedQName("depth4-cont1"),
+                                        toSimpleNodeData(toNestedQName("depth5-leaf1"), "depth5-leaf1-value")),
+                                toSimpleNodeData(toNestedQName("depth4-leaf1"), "depth4-leaf1-value")),
+                        toSimpleNodeData(toNestedQName("depth3-leaf1"), "depth3-leaf1-value")),
+                toCompositeNodeData(
+                        toNestedQName("depth2-cont2"),
+                        toCompositeNodeData(
+                                toNestedQName("depth3-cont2"),
+                                toCompositeNodeData(toNestedQName("depth4-cont2"),
+                                        toSimpleNodeData(toNestedQName("depth5-leaf2"), "depth5-leaf2-value")),
+                                toSimpleNodeData(toNestedQName("depth4-leaf2"), "depth4-leaf2-value")),
+                        toSimpleNodeData(toNestedQName("depth3-leaf2"), "depth3-leaf2-value")),
+                toSimpleNodeData(toNestedQName("depth2-leaf1"), "depth2-leaf1-value")));
+
+        when(brokerFacade.readConfigurationData(any(YangInstanceIdentifier.class))).thenReturn(depth1Cont);
 
         // Test config with depth 1
 
-        Response response = target( "/config/nested-module:depth1-cont" ).queryParam( "depth", "1" )
-                                .request( "application/xml" ).get();
+        Response response = target("/config/nested-module:depth1-cont").queryParam("depth", "1")
+                .request("application/xml").get();
 
-        verifyXMLResponse( response, expectEmptyContainer( "depth1-cont" ) );
+        verifyXMLResponse(response, expectEmptyContainer("depth1-cont"));
 
         // Test config with depth 2
 
-        response = target( "/config/nested-module:depth1-cont" ).queryParam( "depth", "2" )
-                       .request( "application/xml" ).get();
+        response = target("/config/nested-module:depth1-cont").queryParam("depth", "2").request("application/xml")
+                .get();
 
-//        String xml="<depth1-cont><depth2-cont1/><depth2-cont2/><depth2-leaf1>depth2-leaf1-value</depth2-leaf1></depth1-cont>";
-//        Response mr=mock(Response.class);
-//        when(mr.getEntity()).thenReturn( new java.io.StringBufferInputStream(xml) );
+        // String
+        // xml="<depth1-cont><depth2-cont1/><depth2-cont2/><depth2-leaf1>depth2-leaf1-value</depth2-leaf1></depth1-cont>";
+        // Response mr=mock(Response.class);
+        // when(mr.getEntity()).thenReturn( new
+        // java.io.StringBufferInputStream(xml) );
 
-        verifyXMLResponse( response,
-            expectContainer( "depth1-cont",
-                expectEmptyContainer( "depth2-cont1" ),
-                expectEmptyContainer( "depth2-cont2" ),
-                expectLeaf( "depth2-leaf1", "depth2-leaf1-value" )
-            ) );
+        verifyXMLResponse(
+                response,
+                expectContainer("depth1-cont", expectEmptyContainer("depth2-cont1"),
+                        expectEmptyContainer("depth2-cont2"), expectLeaf("depth2-leaf1", "depth2-leaf1-value")));
 
         // Test config with depth 3
 
-        response = target( "/config/nested-module:depth1-cont" ).queryParam( "depth", "3" )
-                       .request( "application/xml" ).get();
-
-        verifyXMLResponse( response,
-            expectContainer( "depth1-cont",
-                expectContainer( "depth2-cont1",
-                    expectEmptyContainer( "depth3-cont1" ),
-                    expectLeaf( "depth3-leaf1", "depth3-leaf1-value" )
-                ),
-                expectContainer( "depth2-cont2",
-                    expectEmptyContainer( "depth3-cont2" ),
-                    expectLeaf( "depth3-leaf2", "depth3-leaf2-value" )
-                ),
-                expectLeaf( "depth2-leaf1", "depth2-leaf1-value" )
-           ) );
+        response = target("/config/nested-module:depth1-cont").queryParam("depth", "3").request("application/xml")
+                .get();
+
+        verifyXMLResponse(
+                response,
+                expectContainer(
+                        "depth1-cont",
+                        expectContainer("depth2-cont1", expectEmptyContainer("depth3-cont1"),
+                                expectLeaf("depth3-leaf1", "depth3-leaf1-value")),
+                        expectContainer("depth2-cont2", expectEmptyContainer("depth3-cont2"),
+                                expectLeaf("depth3-leaf2", "depth3-leaf2-value")),
+                        expectLeaf("depth2-leaf1", "depth2-leaf1-value")));
 
         // Test config with depth 4
 
-        response = target( "/config/nested-module:depth1-cont" ).queryParam( "depth", "4" )
-                      .request( "application/xml" ).get();
-
-        verifyXMLResponse( response,
-            expectContainer( "depth1-cont",
-                expectContainer( "depth2-cont1",
-                    expectContainer( "depth3-cont1",
-                        expectEmptyContainer( "depth4-cont1" ),
-                        expectLeaf( "depth4-leaf1", "depth4-leaf1-value" )
-                    ),
-                    expectLeaf( "depth3-leaf1", "depth3-leaf1-value" )
-                ),
-                expectContainer( "depth2-cont2",
-                    expectContainer( "depth3-cont2",
-                        expectEmptyContainer( "depth4-cont2" ),
-                        expectLeaf( "depth4-leaf2", "depth4-leaf2-value" )
-                    ),
-                    expectLeaf( "depth3-leaf2", "depth3-leaf2-value" )
-                ),
-                expectLeaf( "depth2-leaf1", "depth2-leaf1-value" )
-            ) );
+        response = target("/config/nested-module:depth1-cont").queryParam("depth", "4").request("application/xml")
+                .get();
+
+        verifyXMLResponse(
+                response,
+                expectContainer(
+                        "depth1-cont",
+                        expectContainer(
+                                "depth2-cont1",
+                                expectContainer("depth3-cont1", expectEmptyContainer("depth4-cont1"),
+                                        expectLeaf("depth4-leaf1", "depth4-leaf1-value")),
+                                expectLeaf("depth3-leaf1", "depth3-leaf1-value")),
+                        expectContainer(
+                                "depth2-cont2",
+                                expectContainer("depth3-cont2", expectEmptyContainer("depth4-cont2"),
+                                        expectLeaf("depth4-leaf2", "depth4-leaf2-value")),
+                                expectLeaf("depth3-leaf2", "depth3-leaf2-value")),
+                        expectLeaf("depth2-leaf1", "depth2-leaf1-value")));
 
         // Test config with depth 5
 
-        response = target( "/config/nested-module:depth1-cont" ).queryParam( "depth", "5" )
-                       .request( "application/xml" ).get();
-
-        verifyXMLResponse( response,
-            expectContainer( "depth1-cont",
-                expectContainer( "depth2-cont1",
-                    expectContainer( "depth3-cont1",
-                        expectContainer( "depth4-cont1",
-                            expectLeaf( "depth5-leaf1", "depth5-leaf1-value" )
-                        ),
-                        expectLeaf( "depth4-leaf1", "depth4-leaf1-value" )
-                    ),
-                    expectLeaf( "depth3-leaf1", "depth3-leaf1-value" )
-                ),
-                expectContainer( "depth2-cont2",
-                    expectContainer( "depth3-cont2",
-                        expectContainer( "depth4-cont2",
-                            expectLeaf( "depth5-leaf2", "depth5-leaf2-value" )
-                        ),
-                        expectLeaf( "depth4-leaf2", "depth4-leaf2-value" )
-                    ),
-                    expectLeaf( "depth3-leaf2", "depth3-leaf2-value" )
-                ),
-                expectLeaf( "depth2-leaf1", "depth2-leaf1-value" )
-            ) );
+        response = target("/config/nested-module:depth1-cont").queryParam("depth", "5").request("application/xml")
+                .get();
+
+        verifyXMLResponse(
+                response,
+                expectContainer(
+                        "depth1-cont",
+                        expectContainer(
+                                "depth2-cont1",
+                                expectContainer(
+                                        "depth3-cont1",
+                                        expectContainer("depth4-cont1",
+                                                expectLeaf("depth5-leaf1", "depth5-leaf1-value")),
+                                        expectLeaf("depth4-leaf1", "depth4-leaf1-value")),
+                                expectLeaf("depth3-leaf1", "depth3-leaf1-value")),
+                        expectContainer(
+                                "depth2-cont2",
+                                expectContainer(
+                                        "depth3-cont2",
+                                        expectContainer("depth4-cont2",
+                                                expectLeaf("depth5-leaf2", "depth5-leaf2-value")),
+                                        expectLeaf("depth4-leaf2", "depth4-leaf2-value")),
+                                expectLeaf("depth3-leaf2", "depth3-leaf2-value")),
+                        expectLeaf("depth2-leaf1", "depth2-leaf1-value")));
 
         // Test config with depth unbounded
 
-        response = target( "/config/nested-module:depth1-cont" ).queryParam( "depth", "unbounded" )
-                       .request( "application/xml" ).get();
-
-        verifyXMLResponse( response,
-            expectContainer( "depth1-cont",
-                expectContainer( "depth2-cont1",
-                    expectContainer( "depth3-cont1",
-                        expectContainer( "depth4-cont1",
-                            expectLeaf( "depth5-leaf1", "depth5-leaf1-value" )
-                        ),
-                        expectLeaf( "depth4-leaf1", "depth4-leaf1-value" )
-                    ),
-                    expectLeaf( "depth3-leaf1", "depth3-leaf1-value" )
-                ),
-                expectContainer( "depth2-cont2",
-                    expectContainer( "depth3-cont2",
-                        expectContainer( "depth4-cont2",
-                            expectLeaf( "depth5-leaf2", "depth5-leaf2-value" )
-                        ),
-                        expectLeaf( "depth4-leaf2", "depth4-leaf2-value" )
-                    ),
-                    expectLeaf( "depth3-leaf2", "depth3-leaf2-value" )
-                ),
-                expectLeaf( "depth2-leaf1", "depth2-leaf1-value" )
-            ) );
+        response = target("/config/nested-module:depth1-cont").queryParam("depth", "unbounded")
+                .request("application/xml").get();
+
+        verifyXMLResponse(
+                response,
+                expectContainer(
+                        "depth1-cont",
+                        expectContainer(
+                                "depth2-cont1",
+                                expectContainer(
+                                        "depth3-cont1",
+                                        expectContainer("depth4-cont1",
+                                                expectLeaf("depth5-leaf1", "depth5-leaf1-value")),
+                                        expectLeaf("depth4-leaf1", "depth4-leaf1-value")),
+                                expectLeaf("depth3-leaf1", "depth3-leaf1-value")),
+                        expectContainer(
+                                "depth2-cont2",
+                                expectContainer(
+                                        "depth3-cont2",
+                                        expectContainer("depth4-cont2",
+                                                expectLeaf("depth5-leaf2", "depth5-leaf2-value")),
+                                        expectLeaf("depth4-leaf2", "depth4-leaf2-value")),
+                                expectLeaf("depth3-leaf2", "depth3-leaf2-value")),
+                        expectLeaf("depth2-leaf1", "depth2-leaf1-value")));
 
         // Test operational
 
-        CompositeNode depth2Cont1 = toCompositeNode(
-            toCompositeNodeData( toNestedQName( "depth2-cont1" ),
-                toCompositeNodeData( toNestedQName( "depth3-cont1" ),
-                    toCompositeNodeData( toNestedQName( "depth4-cont1" ),
-                        toSimpleNodeData( toNestedQName( "depth5-leaf1" ), "depth5-leaf1-value" )
-                    ),
-                    toSimpleNodeData( toNestedQName( "depth4-leaf1" ), "depth4-leaf1-value" )
-                ),
-                toSimpleNodeData( toNestedQName( "depth3-leaf1" ), "depth3-leaf1-value" )
-            ) );
-
-        when( brokerFacade.readOperationalData( any( InstanceIdentifier.class ) ) )
-             .thenReturn( depth2Cont1 );
-
-        response = target( "/operational/nested-module:depth1-cont/depth2-cont1" )
-                       .queryParam( "depth", "3" ).request( "application/xml" ).get();
-
-        verifyXMLResponse( response,
-            expectContainer( "depth2-cont1",
-                expectContainer( "depth3-cont1",
-                    expectEmptyContainer( "depth4-cont1" ),
-                    expectLeaf( "depth4-leaf1", "depth4-leaf1-value" )
-                ),
-                expectLeaf( "depth3-leaf1", "depth3-leaf1-value" )
-            ) );
+        CompositeNode depth2Cont1 = toCompositeNode(toCompositeNodeData(
+                toNestedQName("depth2-cont1"),
+                toCompositeNodeData(
+                        toNestedQName("depth3-cont1"),
+                        toCompositeNodeData(toNestedQName("depth4-cont1"),
+                                toSimpleNodeData(toNestedQName("depth5-leaf1"), "depth5-leaf1-value")),
+                        toSimpleNodeData(toNestedQName("depth4-leaf1"), "depth4-leaf1-value")),
+                toSimpleNodeData(toNestedQName("depth3-leaf1"), "depth3-leaf1-value")));
+
+        when(brokerFacade.readOperationalData(any(YangInstanceIdentifier.class))).thenReturn(depth2Cont1);
+
+        response = target("/operational/nested-module:depth1-cont/depth2-cont1").queryParam("depth", "3")
+                .request("application/xml").get();
+
+        verifyXMLResponse(
+                response,
+                expectContainer(
+                        "depth2-cont1",
+                        expectContainer("depth3-cont1", expectEmptyContainer("depth4-cont1"),
+                                expectLeaf("depth4-leaf1", "depth4-leaf1-value")),
+                        expectLeaf("depth3-leaf1", "depth3-leaf1-value")));
     }
 
     @Test
     public void getDataWithInvalidDepthParameterTest() {
 
-        ControllerContext.getInstance().setGlobalSchema( schemaContextModules );
+        ControllerContext.getInstance().setGlobalSchema(schemaContextModules);
 
-        final MultivaluedMap<String,String> paramMap = new MultivaluedHashMap<>();
-        paramMap.putSingle( "depth", "1o" );
-        UriInfo mockInfo = mock( UriInfo.class );
-        when( mockInfo.getQueryParameters( false ) ).thenAnswer(
-            new Answer<MultivaluedMap<String,String>>() {
-                @Override
-                public MultivaluedMap<String, String> answer( InvocationOnMock invocation ) {
-                    return paramMap;
-                }
-            } );
+        final MultivaluedMap<String, String> paramMap = new MultivaluedHashMap<>();
+        paramMap.putSingle("depth", "1o");
+        UriInfo mockInfo = mock(UriInfo.class);
+        when(mockInfo.getQueryParameters(false)).thenAnswer(new Answer<MultivaluedMap<String, String>>() {
+            @Override
+            public MultivaluedMap<String, String> answer(final InvocationOnMock invocation) {
+                return paramMap;
+            }
+        });
 
-        getDataWithInvalidDepthParameterTest( mockInfo );
+        getDataWithInvalidDepthParameterTest(mockInfo);
 
-        paramMap.putSingle( "depth", "0" );
-        getDataWithInvalidDepthParameterTest( mockInfo );
+        paramMap.putSingle("depth", "0");
+        getDataWithInvalidDepthParameterTest(mockInfo);
 
-        paramMap.putSingle( "depth", "-1" );
-        getDataWithInvalidDepthParameterTest( mockInfo );
+        paramMap.putSingle("depth", "-1");
+        getDataWithInvalidDepthParameterTest(mockInfo);
     }
 
-    private void getDataWithInvalidDepthParameterTest( UriInfo uriInfo ) {
+    private void getDataWithInvalidDepthParameterTest(final UriInfo uriInfo) {
         try {
-            restconfImpl.readConfigurationData( "nested-module:depth1-cont", uriInfo );
-            fail( "Expected RestconfDocumentedException" );
-        }
-        catch( RestconfDocumentedException e ) {
-            assertTrue( "Unexpected error message: " + e.getErrors().get( 0 ).getErrorMessage(),
-                        e.getErrors().get( 0 ).getErrorMessage().contains( "depth" ) );
+            restconfImpl.readConfigurationData("nested-module:depth1-cont", uriInfo);
+            fail("Expected RestconfDocumentedException");
+        } catch (RestconfDocumentedException e) {
+            assertTrue("Unexpected error message: " + e.getErrors().get(0).getErrorMessage(), e.getErrors().get(0)
+                    .getErrorMessage().contains("depth"));
         }
     }
 
-    private void verifyXMLResponse( Response response, NodeData nodeData ) {
+    private void verifyXMLResponse(final Response response, final NodeData nodeData) {
 
-        Document doc = TestUtils.loadDocumentFrom( (InputStream) response.getEntity() );
-        assertNotNull( "Could not parse XML document", doc );
+        Document doc = TestUtils.loadDocumentFrom((InputStream) response.getEntity());
+        assertNotNull("Could not parse XML document", doc);
 
-        //System.out.println(TestUtils.getDocumentInPrintableForm( doc ));
+        // System.out.println(TestUtils.getDocumentInPrintableForm( doc ));
 
-        verifyContainerElement( doc.getDocumentElement(), nodeData );
+        verifyContainerElement(doc.getDocumentElement(), nodeData);
     }
 
     @SuppressWarnings("unchecked")
-    private void verifyContainerElement( Element element, NodeData nodeData ) {
+    private void verifyContainerElement(final Element element, final NodeData nodeData) {
 
-        assertEquals( "Element local name", nodeData.key, element.getNodeName() );
+        assertEquals("Element local name", nodeData.key, element.getNodeName());
 
         NodeList childNodes = element.getChildNodes();
-        if( nodeData.data == null ) { // empty container
-            assertTrue( "Expected no child elements for \"" + element.getNodeName() + "\"",
-                        childNodes.getLength() == 0 );
+        if (nodeData.data == null) { // empty container
+            assertTrue("Expected no child elements for \"" + element.getNodeName() + "\"", childNodes.getLength() == 0);
             return;
         }
 
-        Map<String,NodeData> expChildMap = Maps.newHashMap();
-        for( NodeData expChild: (List<NodeData>)nodeData.data ) {
-            expChildMap.put( expChild.key.toString(), expChild );
+        Map<String, NodeData> expChildMap = Maps.newHashMap();
+        for (NodeData expChild : (List<NodeData>) nodeData.data) {
+            expChildMap.put(expChild.key.toString(), expChild);
         }
 
-        for( int i = 0; i < childNodes.getLength(); i++ ) {
-            org.w3c.dom.Node actualChild = childNodes.item( i );
-            if( !( actualChild instanceof Element ) ) {
+        for (int i = 0; i < childNodes.getLength(); i++) {
+            org.w3c.dom.Node actualChild = childNodes.item(i);
+            if (!(actualChild instanceof Element)) {
                 continue;
             }
 
-            Element actualElement = (Element)actualChild;
-            NodeData expChild = expChildMap.remove( actualElement.getNodeName() );
-            assertNotNull( "Unexpected child element for parent \"" + element.getNodeName() +
-                           "\": " + actualElement.getNodeName(), expChild );
-
-            if( expChild.data == null || expChild.data instanceof List ) {
-                verifyContainerElement( actualElement, expChild );
-            }
-            else {
-                assertEquals( "Text content for element: " + actualElement.getNodeName(),
-                              expChild.data, actualElement.getTextContent() );
+            Element actualElement = (Element) actualChild;
+            NodeData expChild = expChildMap.remove(actualElement.getNodeName());
+            assertNotNull(
+                    "Unexpected child element for parent \"" + element.getNodeName() + "\": "
+                            + actualElement.getNodeName(), expChild);
+
+            if (expChild.data == null || expChild.data instanceof List) {
+                verifyContainerElement(actualElement, expChild);
+            else {
+                assertEquals("Text content for element: " + actualElement.getNodeName(), expChild.data,
+                        actualElement.getTextContent());
             }
         }
 
-        if( !expChildMap.isEmpty() ) {
-            fail( "Missing elements for parent \"" + element.getNodeName() +
-                  "\": " + expChildMap.keySet() );
+        if (!expChildMap.isEmpty()) {
+            fail("Missing elements for parent \"" + element.getNodeName() + "\": " + expChildMap.keySet());
         }
     }
 
-    private NodeData expectContainer( String name, NodeData... childData ) {
-        return new NodeData( name, Lists.newArrayList( childData ) );
+    private NodeData expectContainer(final String name, final NodeData... childData) {
+        return new NodeData(name, Lists.newArrayList(childData));
     }
 
-    private NodeData expectEmptyContainer( String name ) {
-        return new NodeData( name, null );
+    private NodeData expectEmptyContainer(final String name) {
+        return new NodeData(name, null);
     }
 
-    private NodeData expectLeaf( String name, Object value ) {
-        return new NodeData( name, value );
+    private NodeData expectLeaf(final String name, final Object value) {
+        return new NodeData(name, value);
     }
 
-    private QName toNestedQName( String localName ) {
-        return QName.create( "urn:nested:module", "2014-06-3", localName );
+    private QName toNestedQName(final String localName) {
+        return QName.create("urn:nested:module", "2014-06-3", localName);
     }
 
     @SuppressWarnings("unchecked")
-    private CompositeNode toCompositeNode( NodeData nodeData ) {
+    private CompositeNode toCompositeNode(final NodeData nodeData) {
         CompositeNodeBuilder<ImmutableCompositeNode> builder = ImmutableCompositeNode.builder();
-        builder.setQName( (QName) nodeData.key );
+        builder.setQName((QName) nodeData.key);
 
-        for( NodeData child: (List<NodeData>)nodeData.data ) {
-            if( child.data instanceof List ) {
-                builder.add( toCompositeNode( child ) );
-            }
-            else {
-                builder.addLeaf( (QName) child.key, child.data );
+        for (NodeData child : (List<NodeData>) nodeData.data) {
+            if (child.data instanceof List) {
+                builder.add(toCompositeNode(child));
+            } else {
+                builder.addLeaf((QName) child.key, child.data);
             }
         }
 
         return builder.toInstance();
     }
 
-    private NodeData toCompositeNodeData( QName key, NodeData... childData ) {
-        return new NodeData( key, Lists.newArrayList( childData ) );
+    private NodeData toCompositeNodeData(final QName key, final NodeData... childData) {
+        return new NodeData(key, Lists.newArrayList(childData));
     }
 
-    private NodeData toSimpleNodeData( QName key, Object value ) {
-        return new NodeData( key, value );
+    private NodeData toSimpleNodeData(final QName key, final Object value) {
+        return new NodeData(key, value);
     }
 }
index 5b36fd52f78c329649fb3d593034d6bf028031f0..979b58b78a184aacc28ceb82f7bd44f7f3315100 100644 (file)
@@ -37,7 +37,6 @@ 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.common.util.RpcErrors;
 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;
@@ -52,11 +51,11 @@ 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.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
 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.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
@@ -125,10 +124,12 @@ public class RestPostOperationTest extends JerseyTest {
         assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
 
         List<RpcError> rpcErrors = new ArrayList<>();
-        rpcErrors.add( RpcErrors.getRpcError("applicationTag1", "tag1", "info1", ErrorSeverity.ERROR, "message1", ErrorType.RPC, null));
-        rpcErrors.add( RpcErrors.getRpcError("applicationTag2", "tag2", "info2", ErrorSeverity.WARNING, "message2", ErrorType.PROTOCOL, null));
+        rpcErrors.add( RpcResultBuilder.newError( ErrorType.RPC, "tag1", "message1",
+                                                  "applicationTag1", "info1", null ) );
+        rpcErrors.add( RpcResultBuilder.newWarning( ErrorType.PROTOCOL, "tag2", "message2",
+                                                    "applicationTag2", "info2", null ) );
         mockInvokeRpc(null, false, rpcErrors);
-        assertEquals(500,post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
+        assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
 
         uri = "/operations/test-module:rpc-wrongtest";
         assertEquals(400, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
@@ -173,12 +174,12 @@ public class RestPostOperationTest extends JerseyTest {
                 rpcResult).build();
         when(
                 brokerFacade.commitConfigurationDataPostBehindMountPoint(any(MountInstance.class),
-                        any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
+                        any(YangInstanceIdentifier.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);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
 
         ControllerContext.getInstance().setMountService(mockMountService);
 
@@ -198,8 +199,8 @@ public class RestPostOperationTest extends JerseyTest {
             builder.errors(errors);
         }
         RpcResult<CompositeNode> rpcResult = builder.build();
-        when(brokerFacade.invokeRpc(any(QName.class), any(CompositeNode.class)))
-                .thenReturn(Futures.<RpcResult<CompositeNode>> immediateFuture(rpcResult));
+        when(brokerFacade.invokeRpc(any(QName.class), any(CompositeNode.class))).thenReturn(
+                Futures.<RpcResult<CompositeNode>> immediateFuture(rpcResult));
     }
 
     private void mockInvokeRpc(CompositeNode result, boolean sucessful) {
@@ -216,7 +217,7 @@ public class RestPostOperationTest extends JerseyTest {
             dummyFuture = new DummyFuture.Builder<TransactionStatus>().build();
         }
 
-        when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class)))
+        when(brokerFacade.commitConfigurationDataPost(any(YangInstanceIdentifier.class), any(CompositeNode.class)))
                 .thenReturn(dummyFuture);
     }
 
@@ -228,10 +229,10 @@ public class RestPostOperationTest extends JerseyTest {
         Future<RpcResult<TransactionStatus>> dummyFuture = new DummyFuture.Builder<TransactionStatus>().rpcResult(
                 rpcResult).build();
 
-        when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class)))
+        when(brokerFacade.commitConfigurationDataPost(any(YangInstanceIdentifier.class), any(CompositeNode.class)))
                 .thenReturn(dummyFuture);
 
-        ArgumentCaptor<InstanceIdentifier> instanceIdCaptor = ArgumentCaptor.forClass(InstanceIdentifier.class);
+        ArgumentCaptor<YangInstanceIdentifier> instanceIdCaptor = ArgumentCaptor.forClass(YangInstanceIdentifier.class);
         ArgumentCaptor<CompositeNode> compNodeCaptor = ArgumentCaptor.forClass(CompositeNode.class);
 
         String URI_1 = "/config";
@@ -252,7 +253,7 @@ public class RestPostOperationTest extends JerseyTest {
     public void createConfigurationDataNullTest() throws UnsupportedEncodingException {
         initMocking();
 
-        when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class)))
+        when(brokerFacade.commitConfigurationDataPost(any(YangInstanceIdentifier.class), any(CompositeNode.class)))
                 .thenReturn(null);
 
         String URI_1 = "/config";
index 44b5f491d66ff71f1ca2ea53196f5c4db7536f8c..5d837f42bd27dd58233aaed07546f1b2fb5e2f06 100644 (file)
@@ -39,7 +39,7 @@ 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.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public class RestPutOperationTest extends JerseyTest {
@@ -123,12 +123,12 @@ public class RestPutOperationTest extends JerseyTest {
                 rpcResult).build();
         when(
                 brokerFacade.commitConfigurationDataPutBehindMountPoint(any(MountInstance.class),
-                        any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
+                        any(YangInstanceIdentifier.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);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
 
         ControllerContext.getInstance().setMountService(mockMountService);
 
@@ -147,12 +147,12 @@ public class RestPutOperationTest extends JerseyTest {
                 rpcResult).build();
         when(
                 brokerFacade.commitConfigurationDataPutBehindMountPoint(any(MountInstance.class),
-                        any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
+                        any(YangInstanceIdentifier.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);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
 
         ControllerContext.getInstance().setMountService(mockMountService);
 
@@ -169,7 +169,7 @@ public class RestPutOperationTest extends JerseyTest {
                 .build();
         Future<RpcResult<TransactionStatus>> dummyFuture = new DummyFuture.Builder<TransactionStatus>().rpcResult(
                 rpcResult).build();
-        when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class)))
+        when(brokerFacade.commitConfigurationDataPut(any(YangInstanceIdentifier.class), any(CompositeNode.class)))
                 .thenReturn(dummyFuture);
     }
 
index c5c459618933af91bb272654d0b40b070fb7ffd3..b8c0270a61407a8358a741abe2515bc83395ef60 100644 (file)
@@ -78,63 +78,61 @@ import org.w3c.dom.NodeList;
 public class RestconfDocumentedExceptionMapperTest extends JerseyTest {
 
     interface ErrorInfoVerifier {
-        void verifyXML( Node errorInfoNode );
-        void verifyJson( JsonElement errorInfoElement );
+        void verifyXML(Node errorInfoNode);
+
+        void verifyJson(JsonElement errorInfoElement);
     }
 
     static class ComplexErrorInfoVerifier implements ErrorInfoVerifier {
 
         Map<String, String> expErrorInfo;
 
-        public ComplexErrorInfoVerifier( final Map<String, String> expErrorInfo ) {
+        public ComplexErrorInfoVerifier(final Map<String, String> expErrorInfo) {
             this.expErrorInfo = expErrorInfo;
         }
 
         @Override
-        public void verifyXML( final Node errorInfoNode ) {
+        public void verifyXML(final Node errorInfoNode) {
 
-            Map<String, String> mutableExpMap = Maps.newHashMap( expErrorInfo );
+            Map<String, String> mutableExpMap = Maps.newHashMap(expErrorInfo);
             NodeList childNodes = errorInfoNode.getChildNodes();
-            for( int i = 0; i < childNodes.getLength(); i++ ) {
-                Node child = childNodes.item( i );
-                if( child  instanceof Element ) {
-                    String expValue = mutableExpMap.remove( child.getNodeName() );
-                    assertNotNull( "Found unexpected \"error-info\" child node: " +
-                            child.getNodeName(), expValue );
-                    assertEquals( "Text content for \"error-info\" child node " +
-                            child.getNodeName(), expValue, child.getTextContent() );
+            for (int i = 0; i < childNodes.getLength(); i++) {
+                Node child = childNodes.item(i);
+                if (child instanceof Element) {
+                    String expValue = mutableExpMap.remove(child.getNodeName());
+                    assertNotNull("Found unexpected \"error-info\" child node: " + child.getNodeName(), expValue);
+                    assertEquals("Text content for \"error-info\" child node " + child.getNodeName(), expValue,
+                            child.getTextContent());
                 }
             }
 
-            if( !mutableExpMap.isEmpty() ) {
-                fail( "Missing \"error-info\" child nodes: " + mutableExpMap );
+            if (!mutableExpMap.isEmpty()) {
+                fail("Missing \"error-info\" child nodes: " + mutableExpMap);
             }
         }
 
         @Override
-        public void verifyJson( final JsonElement errorInfoElement ) {
+        public void verifyJson(final JsonElement errorInfoElement) {
 
-            assertTrue( "\"error-info\" Json element is not an Object",
-                    errorInfoElement.isJsonObject() );
+            assertTrue("\"error-info\" Json element is not an Object", errorInfoElement.isJsonObject());
 
             Map<String, String> actualErrorInfo = Maps.newHashMap();
-            for( Entry<String, JsonElement> entry: errorInfoElement.getAsJsonObject().entrySet() ) {
+            for (Entry<String, JsonElement> entry : errorInfoElement.getAsJsonObject().entrySet()) {
                 String leafName = entry.getKey();
                 JsonElement leafElement = entry.getValue();
-                actualErrorInfo.put( leafName, leafElement.getAsString() );
+                actualErrorInfo.put(leafName, leafElement.getAsString());
             }
 
-            Map<String, String> mutableExpMap = Maps.newHashMap( expErrorInfo );
-            for( Entry<String,String> actual: actualErrorInfo.entrySet() ) {
-                String expValue = mutableExpMap.remove( actual.getKey() );
-                assertNotNull( "Found unexpected \"error-info\" child node: " +
-                        actual.getKey(), expValue );
-                assertEquals( "Text content for \"error-info\" child node " +
-                        actual.getKey(), expValue, actual.getValue() );
+            Map<String, String> mutableExpMap = Maps.newHashMap(expErrorInfo);
+            for (Entry<String, String> actual : actualErrorInfo.entrySet()) {
+                String expValue = mutableExpMap.remove(actual.getKey());
+                assertNotNull("Found unexpected \"error-info\" child node: " + actual.getKey(), expValue);
+                assertEquals("Text content for \"error-info\" child node " + actual.getKey(), expValue,
+                        actual.getValue());
             }
 
-            if( !mutableExpMap.isEmpty() ) {
-                fail( "Missing \"error-info\" child nodes: " + mutableExpMap );
+            if (!mutableExpMap.isEmpty()) {
+                fail("Missing \"error-info\" child nodes: " + mutableExpMap);
             }
         }
     }
@@ -143,27 +141,27 @@ public class RestconfDocumentedExceptionMapperTest extends JerseyTest {
 
         String expTextContent;
 
-        public SimpleErrorInfoVerifier( final String expErrorInfo ) {
+        public SimpleErrorInfoVerifier(final String expErrorInfo) {
             this.expTextContent = expErrorInfo;
         }
 
-        void verifyContent( final String actualContent ) {
-            assertNotNull( "Actual \"error-info\" text content is null", actualContent );
-            assertTrue( "", actualContent.contains( expTextContent ) );
+        void verifyContent(final String actualContent) {
+            assertNotNull("Actual \"error-info\" text content is null", actualContent);
+            assertTrue("", actualContent.contains(expTextContent));
         }
 
         @Override
-        public void verifyXML( final Node errorInfoNode ) {
-            verifyContent( errorInfoNode.getTextContent() );
+        public void verifyXML(final Node errorInfoNode) {
+            verifyContent(errorInfoNode.getTextContent());
         }
 
         @Override
-        public void verifyJson( final JsonElement errorInfoElement ) {
-            verifyContent( errorInfoElement.getAsString() );
+        public void verifyJson(final JsonElement errorInfoElement) {
+            verifyContent(errorInfoElement.getAsString());
         }
     }
 
-    static RestconfService mockRestConf = mock( RestconfService.class );
+    static RestconfService mockRestConf = mock(RestconfService.class);
 
     static XPath XPATH = XPathFactory.newInstance().newXPath();
     static XPathExpression ERROR_LIST;
@@ -175,745 +173,650 @@ public class RestconfDocumentedExceptionMapperTest extends JerseyTest {
 
     @BeforeClass
     public static void init() throws Exception {
-        ControllerContext.getInstance().setGlobalSchema( TestUtils.loadSchemaContext("/modules") );
+        ControllerContext.getInstance().setGlobalSchema(TestUtils.loadSchemaContext("/modules"));
 
         NamespaceContext nsContext = new NamespaceContext() {
             @Override
-            public Iterator<?> getPrefixes( final String namespaceURI ) {
+            public Iterator<?> getPrefixes(final String namespaceURI) {
                 return null;
             }
 
             @Override
-            public String getPrefix( final String namespaceURI ) {
+            public String getPrefix(final String namespaceURI) {
                 return null;
             }
 
             @Override
-            public String getNamespaceURI( final String prefix ) {
-                return "ietf-restconf".equals( prefix ) ? Draft02.RestConfModule.NAMESPACE : null;
+            public String getNamespaceURI(final String prefix) {
+                return "ietf-restconf".equals(prefix) ? Draft02.RestConfModule.NAMESPACE : null;
             }
         };
 
-        XPATH.setNamespaceContext( nsContext );
-        ERROR_LIST = XPATH.compile( "ietf-restconf:errors/ietf-restconf:error" );
-        ERROR_TYPE = XPATH.compile( "ietf-restconf:error-type" );
-        ERROR_TAG = XPATH.compile( "ietf-restconf:error-tag" );
-        ERROR_MESSAGE = XPATH.compile( "ietf-restconf:error-message" );
-        ERROR_APP_TAG = XPATH.compile( "ietf-restconf:error-app-tag" );
-        ERROR_INFO = XPATH.compile( "ietf-restconf:error-info" );
+        XPATH.setNamespaceContext(nsContext);
+        ERROR_LIST = XPATH.compile("ietf-restconf:errors/ietf-restconf:error");
+        ERROR_TYPE = XPATH.compile("ietf-restconf:error-type");
+        ERROR_TAG = XPATH.compile("ietf-restconf:error-tag");
+        ERROR_MESSAGE = XPATH.compile("ietf-restconf:error-message");
+        ERROR_APP_TAG = XPATH.compile("ietf-restconf:error-app-tag");
+        ERROR_INFO = XPATH.compile("ietf-restconf:error-info");
     }
 
     @Override
     @Before
     public void setUp() throws Exception {
-        reset( mockRestConf );
+        reset(mockRestConf);
         super.setUp();
     }
 
     @Override
     protected Application configure() {
         ResourceConfig resourceConfig = new ResourceConfig();
-        resourceConfig = resourceConfig.registerInstances( mockRestConf, StructuredDataToXmlProvider.INSTANCE,
-                StructuredDataToJsonProvider.INSTANCE );
-        resourceConfig.registerClasses( RestconfDocumentedExceptionMapper.class );
+        resourceConfig = resourceConfig.registerInstances(mockRestConf, StructuredDataToXmlProvider.INSTANCE,
+                StructuredDataToJsonProvider.INSTANCE);
+        resourceConfig.registerClasses(RestconfDocumentedExceptionMapper.class);
         return resourceConfig;
     }
 
-    void stageMockEx( final RestconfDocumentedException ex ) {
-        reset( mockRestConf );
-        when( mockRestConf.readOperationalData( any( String.class ), any( UriInfo.class ) ) ).thenThrow( ex );
+    void stageMockEx(final RestconfDocumentedException ex) {
+        reset(mockRestConf);
+        when(mockRestConf.readOperationalData(any(String.class), any(UriInfo.class))).thenThrow(ex);
     }
 
-    void testJsonResponse( final RestconfDocumentedException ex, final Status expStatus, final ErrorType expErrorType,
+    void testJsonResponse(final RestconfDocumentedException ex, final Status expStatus, final ErrorType expErrorType,
             final ErrorTag expErrorTag, final String expErrorMessage, final String expErrorAppTag,
-            final ErrorInfoVerifier errorInfoVerifier ) throws Exception {
+            final ErrorInfoVerifier errorInfoVerifier) throws Exception {
 
-        stageMockEx( ex );
+        stageMockEx(ex);
 
-        Response resp = target("/operational/foo").request( MediaType.APPLICATION_JSON ).get();
+        Response resp = target("/operational/foo").request(MediaType.APPLICATION_JSON).get();
 
-        InputStream stream = verifyResponse( resp, MediaType.APPLICATION_JSON, expStatus );
+        InputStream stream = verifyResponse(resp, MediaType.APPLICATION_JSON, expStatus);
 
-        verifyJsonResponseBody( stream, expErrorType, expErrorTag, expErrorMessage,
-                expErrorAppTag, errorInfoVerifier );
+        verifyJsonResponseBody(stream, expErrorType, expErrorTag, expErrorMessage, expErrorAppTag, errorInfoVerifier);
     }
 
     @Test
     public void testToJsonResponseWithMessageOnly() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error" ), Status.INTERNAL_SERVER_ERROR,
-                ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error"), Status.INTERNAL_SERVER_ERROR,
+                ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error", null, null);
 
         // To test verification code
-        //        String json =
-        //            "{ errors: {" +
-        //            "    error: [{" +
-        //            "      error-tag : \"operation-failed\"" +
-        //            "      ,error-type : \"application\"" +
-        //            "      ,error-message : \"An error occurred\"" +
-        //            "      ,error-info : {" +
-        //            "        session-id: \"123\"" +
-        //            "        ,address: \"1.2.3.4\"" +
-        //            "      }" +
-        //            "    }]" +
-        //            "  }" +
-        //            "}";
+        // String json =
+        // "{ errors: {" +
+        // "    error: [{" +
+        // "      error-tag : \"operation-failed\"" +
+        // "      ,error-type : \"application\"" +
+        // "      ,error-message : \"An error occurred\"" +
+        // "      ,error-info : {" +
+        // "        session-id: \"123\"" +
+        // "        ,address: \"1.2.3.4\"" +
+        // "      }" +
+        // "    }]" +
+        // "  }" +
+        // "}";
         //
-        //        verifyJsonResponseBody( new java.io.StringBufferInputStream(json ), ErrorType.APPLICATION,
-        //            ErrorTag.OPERATION_FAILED, "An error occurred", null,
-        //            com.google.common.collect.ImmutableMap.of( "session-id", "123", "address", "1.2.3.4" ) );
+        // verifyJsonResponseBody( new java.io.StringBufferInputStream(json ),
+        // ErrorType.APPLICATION,
+        // ErrorTag.OPERATION_FAILED, "An error occurred", null,
+        // com.google.common.collect.ImmutableMap.of( "session-id", "123",
+        // "address", "1.2.3.4" ) );
     }
 
     @Test
     public void testToJsonResponseWithInUseErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.IN_USE ),
-                Status.CONFLICT, ErrorType.PROTOCOL,
-                ErrorTag.IN_USE, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.IN_USE),
+                Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.IN_USE, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithInvalidValueErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.RPC,
-                ErrorTag.INVALID_VALUE ),
-                Status.BAD_REQUEST, ErrorType.RPC,
-                ErrorTag.INVALID_VALUE, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.RPC, ErrorTag.INVALID_VALUE),
+                Status.BAD_REQUEST, ErrorType.RPC, ErrorTag.INVALID_VALUE, "mock error", null, null);
 
     }
 
     @Test
     public void testToJsonResponseWithTooBigErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.TRANSPORT,
-                ErrorTag.TOO_BIG ),
-                Status.REQUEST_ENTITY_TOO_LARGE, ErrorType.TRANSPORT,
-                ErrorTag.TOO_BIG, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.TRANSPORT, ErrorTag.TOO_BIG),
+                Status.REQUEST_ENTITY_TOO_LARGE, ErrorType.TRANSPORT, ErrorTag.TOO_BIG, "mock error", null, null);
 
     }
 
     @Test
     public void testToJsonResponseWithMissingAttributeErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.MISSING_ATTRIBUTE ),
-                Status.BAD_REQUEST, ErrorType.PROTOCOL,
-                ErrorTag.MISSING_ATTRIBUTE, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.MISSING_ATTRIBUTE),
+                Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.MISSING_ATTRIBUTE, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithBadAttributeErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.BAD_ATTRIBUTE ),
-                Status.BAD_REQUEST, ErrorType.PROTOCOL,
-                ErrorTag.BAD_ATTRIBUTE, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE),
+                Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE, "mock error", null, null);
     }
+
     @Test
     public void testToJsonResponseWithUnknownAttributeErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.UNKNOWN_ATTRIBUTE ),
-                Status.BAD_REQUEST, ErrorType.PROTOCOL,
-                ErrorTag.UNKNOWN_ATTRIBUTE, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ATTRIBUTE),
+                Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ATTRIBUTE, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithBadElementErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.BAD_ELEMENT ),
-                Status.BAD_REQUEST,
-                ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT),
+                Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithUnknownElementErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.UNKNOWN_ELEMENT ),
-                Status.BAD_REQUEST, ErrorType.PROTOCOL,
-                ErrorTag.UNKNOWN_ELEMENT, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT),
+                Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithUnknownNamespaceErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.UNKNOWN_NAMESPACE ),
-                Status.BAD_REQUEST, ErrorType.PROTOCOL,
-                ErrorTag.UNKNOWN_NAMESPACE, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE),
+                Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithMalformedMessageErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.MALFORMED_MESSAGE ),
-                Status.BAD_REQUEST, ErrorType.PROTOCOL,
-                ErrorTag.MALFORMED_MESSAGE, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE),
+                Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithAccessDeniedErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.ACCESS_DENIED ),
-                Status.FORBIDDEN, ErrorType.PROTOCOL,
-                ErrorTag.ACCESS_DENIED, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.ACCESS_DENIED),
+                Status.FORBIDDEN, ErrorType.PROTOCOL, ErrorTag.ACCESS_DENIED, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithLockDeniedErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.LOCK_DENIED ),
-                Status.CONFLICT, ErrorType.PROTOCOL,
-                ErrorTag.LOCK_DENIED, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.LOCK_DENIED),
+                Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.LOCK_DENIED, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithResourceDeniedErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.RESOURCE_DENIED ),
-                Status.CONFLICT, ErrorType.PROTOCOL,
-                ErrorTag.RESOURCE_DENIED, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.RESOURCE_DENIED),
+                Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.RESOURCE_DENIED, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithRollbackFailedErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.ROLLBACK_FAILED ),
-                Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL,
-                ErrorTag.ROLLBACK_FAILED, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.ROLLBACK_FAILED),
+                Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL, ErrorTag.ROLLBACK_FAILED, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithDataExistsErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.DATA_EXISTS ),
-                Status.CONFLICT, ErrorType.PROTOCOL,
-                ErrorTag.DATA_EXISTS, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS),
+                Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithDataMissingErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.DATA_MISSING ),
-                Status.CONFLICT, ErrorType.PROTOCOL,
-                ErrorTag.DATA_MISSING, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING),
+                Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithOperationNotSupportedErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.OPERATION_NOT_SUPPORTED ),
-                Status.NOT_IMPLEMENTED, ErrorType.PROTOCOL,
-                ErrorTag.OPERATION_NOT_SUPPORTED, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL,
+                ErrorTag.OPERATION_NOT_SUPPORTED), Status.NOT_IMPLEMENTED, ErrorType.PROTOCOL,
+                ErrorTag.OPERATION_NOT_SUPPORTED, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithOperationFailedErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.OPERATION_FAILED ),
-                Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL,
-                ErrorTag.OPERATION_FAILED, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.OPERATION_FAILED),
+                Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL, ErrorTag.OPERATION_FAILED, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithPartialOperationErrorTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.PARTIAL_OPERATION ),
-                Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL,
-                ErrorTag.PARTIAL_OPERATION, "mock error", null, null );
+        testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.PARTIAL_OPERATION),
+                Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL, ErrorTag.PARTIAL_OPERATION, "mock error", null, null);
     }
 
     @Test
     public void testToJsonResponseWithErrorAppTag() throws Exception {
 
-        testJsonResponse( new RestconfDocumentedException( new RestconfError(
-                ErrorType.APPLICATION, ErrorTag.INVALID_VALUE,
-                "mock error", "mock-app-tag" ) ),
-                Status.BAD_REQUEST, ErrorType.APPLICATION,
-                ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag", null );
+        testJsonResponse(new RestconfDocumentedException(new RestconfError(ErrorType.APPLICATION,
+                ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag")), Status.BAD_REQUEST, ErrorType.APPLICATION,
+                ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag", null);
     }
 
     @Test
     public void testToJsonResponseWithMultipleErrors() throws Exception {
 
-        List<RestconfError> errorList = Arrays.asList(
-                new RestconfError( ErrorType.APPLICATION, ErrorTag.LOCK_DENIED, "mock error1" ),
-                new RestconfError( ErrorType.RPC, ErrorTag.ROLLBACK_FAILED, "mock error2" ) );
-        stageMockEx( new RestconfDocumentedException( errorList ) );
+        List<RestconfError> errorList = Arrays.asList(new RestconfError(ErrorType.APPLICATION, ErrorTag.LOCK_DENIED,
+                "mock error1"), new RestconfError(ErrorType.RPC, ErrorTag.ROLLBACK_FAILED, "mock error2"));
+        stageMockEx(new RestconfDocumentedException(errorList));
 
-        Response resp = target("/operational/foo").request( MediaType.APPLICATION_JSON ).get();
+        Response resp = target("/operational/foo").request(MediaType.APPLICATION_JSON).get();
 
-        InputStream stream = verifyResponse( resp, MediaType.APPLICATION_JSON, Status.CONFLICT );
+        InputStream stream = verifyResponse(resp, MediaType.APPLICATION_JSON, Status.CONFLICT);
 
-        JsonArray arrayElement = parseJsonErrorArrayElement( stream );
+        JsonArray arrayElement = parseJsonErrorArrayElement(stream);
 
-        assertEquals( "\"error\" Json array element length", 2, arrayElement.size() );
+        assertEquals("\"error\" Json array element length", 2, arrayElement.size());
 
-        verifyJsonErrorNode( arrayElement.get( 0 ), ErrorType.APPLICATION, ErrorTag.LOCK_DENIED,
-                "mock error1", null, null );
+        verifyJsonErrorNode(arrayElement.get(0), ErrorType.APPLICATION, ErrorTag.LOCK_DENIED, "mock error1", null, null);
 
-        verifyJsonErrorNode( arrayElement.get( 1 ), ErrorType.RPC, ErrorTag.ROLLBACK_FAILED,
-                "mock error2", null, null );
+        verifyJsonErrorNode(arrayElement.get(1), ErrorType.RPC, ErrorTag.ROLLBACK_FAILED, "mock error2", null, null);
     }
 
     @Test
     public void testToJsonResponseWithErrorInfo() throws Exception {
 
         String errorInfo = "<address>1.2.3.4</address> <session-id>123</session-id>";
-        testJsonResponse( new RestconfDocumentedException( new RestconfError(
-                ErrorType.APPLICATION, ErrorTag.INVALID_VALUE,
-                "mock error", "mock-app-tag", errorInfo ) ),
-                Status.BAD_REQUEST, ErrorType.APPLICATION,
-                ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag",
-                new ComplexErrorInfoVerifier( ImmutableMap.of(
-                        "session-id", "123", "address", "1.2.3.4" ) ) );
+        testJsonResponse(new RestconfDocumentedException(new RestconfError(ErrorType.APPLICATION,
+                ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag", errorInfo)), Status.BAD_REQUEST,
+                ErrorType.APPLICATION, ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag",
+                new ComplexErrorInfoVerifier(ImmutableMap.of("session-id", "123", "address", "1.2.3.4")));
     }
 
     @Test
     public void testToJsonResponseWithExceptionCause() throws Exception {
 
-        Exception cause = new Exception( "mock exception cause" );
-        testJsonResponse( new RestconfDocumentedException( "mock error", cause ),
-                Status.INTERNAL_SERVER_ERROR, ErrorType.APPLICATION,
-                ErrorTag.OPERATION_FAILED, "mock error", null,
-                new SimpleErrorInfoVerifier( cause.getMessage() ) );
+        Exception cause = new Exception("mock exception cause");
+        testJsonResponse(new RestconfDocumentedException("mock error", cause), Status.INTERNAL_SERVER_ERROR,
+                ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error", null,
+                new SimpleErrorInfoVerifier(cause.getMessage()));
     }
 
-    void testXMLResponse( final RestconfDocumentedException ex, final Status expStatus, final ErrorType expErrorType,
-            final ErrorTag expErrorTag, final String expErrorMessage,
-            final String expErrorAppTag, final ErrorInfoVerifier errorInfoVerifier ) throws Exception
-    {
-        stageMockEx( ex );
+    void testXMLResponse(final RestconfDocumentedException ex, final Status expStatus, final ErrorType expErrorType,
+            final ErrorTag expErrorTag, final String expErrorMessage, final String expErrorAppTag,
+            final ErrorInfoVerifier errorInfoVerifier) throws Exception {
+        stageMockEx(ex);
 
-        Response resp = target("/operational/foo").request( MediaType.APPLICATION_XML ).get();
+        Response resp = target("/operational/foo").request(MediaType.APPLICATION_XML).get();
 
-        InputStream stream = verifyResponse( resp, MediaType.APPLICATION_XML, expStatus );
+        InputStream stream = verifyResponse(resp, MediaType.APPLICATION_XML, expStatus);
 
-        verifyXMLResponseBody( stream, expErrorType, expErrorTag, expErrorMessage,
-                expErrorAppTag, errorInfoVerifier );
+        verifyXMLResponseBody(stream, expErrorType, expErrorTag, expErrorMessage, expErrorAppTag, errorInfoVerifier);
     }
 
     @Test
     public void testToXMLResponseWithMessageOnly() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error" ), Status.INTERNAL_SERVER_ERROR,
-                ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error"), Status.INTERNAL_SERVER_ERROR,
+                ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error", null, null);
 
         // To test verification code
-        //        String xml =
-        //            "<errors xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\">"+
-        //            "  <error>" +
-        //            "    <error-type>application</error-type>"+
-        //            "    <error-tag>operation-failed</error-tag>"+
-        //            "    <error-message>An error occurred</error-message>"+
-        //            "    <error-info>" +
-        //            "      <session-id>123</session-id>" +
-        //            "      <address>1.2.3.4</address>" +
-        //            "    </error-info>" +
-        //            "  </error>" +
-        //            "</errors>";
+        // String xml =
+        // "<errors xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\">"+
+        // "  <error>" +
+        // "    <error-type>application</error-type>"+
+        // "    <error-tag>operation-failed</error-tag>"+
+        // "    <error-message>An error occurred</error-message>"+
+        // "    <error-info>" +
+        // "      <session-id>123</session-id>" +
+        // "      <address>1.2.3.4</address>" +
+        // "    </error-info>" +
+        // "  </error>" +
+        // "</errors>";
         //
-        //        verifyXMLResponseBody( new java.io.StringBufferInputStream(xml), ErrorType.APPLICATION,
-        //                ErrorTag.OPERATION_FAILED, "An error occurred", null,
-        //                com.google.common.collect.ImmutableMap.of( "session-id", "123", "address", "1.2.3.4" ) );
+        // verifyXMLResponseBody( new java.io.StringBufferInputStream(xml),
+        // ErrorType.APPLICATION,
+        // ErrorTag.OPERATION_FAILED, "An error occurred", null,
+        // com.google.common.collect.ImmutableMap.of( "session-id", "123",
+        // "address", "1.2.3.4" ) );
     }
 
     @Test
     public void testToXMLResponseWithInUseErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.IN_USE ),
-                Status.CONFLICT, ErrorType.PROTOCOL,
-                ErrorTag.IN_USE, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.IN_USE),
+                Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.IN_USE, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithInvalidValueErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.RPC,
-                ErrorTag.INVALID_VALUE ),
-                Status.BAD_REQUEST, ErrorType.RPC,
-                ErrorTag.INVALID_VALUE, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.RPC, ErrorTag.INVALID_VALUE),
+                Status.BAD_REQUEST, ErrorType.RPC, ErrorTag.INVALID_VALUE, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithTooBigErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.TRANSPORT,
-                ErrorTag.TOO_BIG ),
-                Status.REQUEST_ENTITY_TOO_LARGE, ErrorType.TRANSPORT,
-                ErrorTag.TOO_BIG, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.TRANSPORT, ErrorTag.TOO_BIG),
+                Status.REQUEST_ENTITY_TOO_LARGE, ErrorType.TRANSPORT, ErrorTag.TOO_BIG, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithMissingAttributeErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.MISSING_ATTRIBUTE ),
-                Status.BAD_REQUEST, ErrorType.PROTOCOL,
-                ErrorTag.MISSING_ATTRIBUTE, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.MISSING_ATTRIBUTE),
+                Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.MISSING_ATTRIBUTE, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithBadAttributeErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.BAD_ATTRIBUTE ),
-                Status.BAD_REQUEST, ErrorType.PROTOCOL,
-                ErrorTag.BAD_ATTRIBUTE, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE),
+                Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE, "mock error", null, null);
     }
+
     @Test
     public void testToXMLResponseWithUnknownAttributeErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.UNKNOWN_ATTRIBUTE ),
-                Status.BAD_REQUEST, ErrorType.PROTOCOL,
-                ErrorTag.UNKNOWN_ATTRIBUTE, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ATTRIBUTE),
+                Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ATTRIBUTE, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithBadElementErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.BAD_ELEMENT ),
-                Status.BAD_REQUEST, ErrorType.PROTOCOL,
-                ErrorTag.BAD_ELEMENT, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT),
+                Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithUnknownElementErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.UNKNOWN_ELEMENT ),
-                Status.BAD_REQUEST, ErrorType.PROTOCOL,
-                ErrorTag.UNKNOWN_ELEMENT, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT),
+                Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithUnknownNamespaceErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.UNKNOWN_NAMESPACE ),
-                Status.BAD_REQUEST, ErrorType.PROTOCOL,
-                ErrorTag.UNKNOWN_NAMESPACE, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE),
+                Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithMalformedMessageErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.MALFORMED_MESSAGE ),
-                Status.BAD_REQUEST, ErrorType.PROTOCOL,
-                ErrorTag.MALFORMED_MESSAGE, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE),
+                Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithAccessDeniedErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.ACCESS_DENIED ),
-                Status.FORBIDDEN, ErrorType.PROTOCOL,
-                ErrorTag.ACCESS_DENIED, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.ACCESS_DENIED),
+                Status.FORBIDDEN, ErrorType.PROTOCOL, ErrorTag.ACCESS_DENIED, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithLockDeniedErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.LOCK_DENIED ),
-                Status.CONFLICT, ErrorType.PROTOCOL,
-                ErrorTag.LOCK_DENIED, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.LOCK_DENIED),
+                Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.LOCK_DENIED, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithResourceDeniedErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.RESOURCE_DENIED ),
-                Status.CONFLICT, ErrorType.PROTOCOL,
-                ErrorTag.RESOURCE_DENIED, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.RESOURCE_DENIED),
+                Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.RESOURCE_DENIED, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithRollbackFailedErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.ROLLBACK_FAILED ),
-                Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL,
-                ErrorTag.ROLLBACK_FAILED, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.ROLLBACK_FAILED),
+                Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL, ErrorTag.ROLLBACK_FAILED, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithDataExistsErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.DATA_EXISTS ),
-                Status.CONFLICT, ErrorType.PROTOCOL,
-                ErrorTag.DATA_EXISTS, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS),
+                Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithDataMissingErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.DATA_MISSING ),
-                Status.CONFLICT, ErrorType.PROTOCOL,
-                ErrorTag.DATA_MISSING, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING),
+                Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithOperationNotSupportedErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.OPERATION_NOT_SUPPORTED ),
-                Status.NOT_IMPLEMENTED, ErrorType.PROTOCOL,
-                ErrorTag.OPERATION_NOT_SUPPORTED, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL,
+                ErrorTag.OPERATION_NOT_SUPPORTED), Status.NOT_IMPLEMENTED, ErrorType.PROTOCOL,
+                ErrorTag.OPERATION_NOT_SUPPORTED, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithOperationFailedErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.OPERATION_FAILED ),
-                Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL,
-                ErrorTag.OPERATION_FAILED, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.OPERATION_FAILED),
+                Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL, ErrorTag.OPERATION_FAILED, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithPartialOperationErrorTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( "mock error", ErrorType.PROTOCOL,
-                ErrorTag.PARTIAL_OPERATION ),
-                Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL,
-                ErrorTag.PARTIAL_OPERATION, "mock error", null, null );
+        testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.PARTIAL_OPERATION),
+                Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL, ErrorTag.PARTIAL_OPERATION, "mock error", null, null);
     }
 
     @Test
     public void testToXMLResponseWithErrorAppTag() throws Exception {
 
-        testXMLResponse( new RestconfDocumentedException( new RestconfError(
-                ErrorType.APPLICATION, ErrorTag.INVALID_VALUE,
-                "mock error", "mock-app-tag" ) ),
-                Status.BAD_REQUEST, ErrorType.APPLICATION,
-                ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag", null );
+        testXMLResponse(new RestconfDocumentedException(new RestconfError(ErrorType.APPLICATION,
+                ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag")), Status.BAD_REQUEST, ErrorType.APPLICATION,
+                ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag", null);
     }
 
     @Test
     public void testToXMLResponseWithErrorInfo() throws Exception {
 
         String errorInfo = "<address>1.2.3.4</address> <session-id>123</session-id>";
-        testXMLResponse( new RestconfDocumentedException( new RestconfError(
-                ErrorType.APPLICATION, ErrorTag.INVALID_VALUE,
-                "mock error", "mock-app-tag", errorInfo ) ),
-                Status.BAD_REQUEST, ErrorType.APPLICATION,
-                ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag",
-                new ComplexErrorInfoVerifier( ImmutableMap.of(
-                        "session-id", "123", "address", "1.2.3.4" ) ) );
+        testXMLResponse(new RestconfDocumentedException(new RestconfError(ErrorType.APPLICATION,
+                ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag", errorInfo)), Status.BAD_REQUEST,
+                ErrorType.APPLICATION, ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag",
+                new ComplexErrorInfoVerifier(ImmutableMap.of("session-id", "123", "address", "1.2.3.4")));
     }
 
     @Test
     public void testToXMLResponseWithExceptionCause() throws Exception {
 
-        Exception cause = new Exception( "mock exception cause" );
-        testXMLResponse( new RestconfDocumentedException( "mock error", cause ),
-                Status.INTERNAL_SERVER_ERROR, ErrorType.APPLICATION,
-                ErrorTag.OPERATION_FAILED, "mock error", null,
-                new SimpleErrorInfoVerifier( cause.getMessage() ) );
+        Exception cause = new Exception("mock exception cause");
+        testXMLResponse(new RestconfDocumentedException("mock error", cause), Status.INTERNAL_SERVER_ERROR,
+                ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error", null,
+                new SimpleErrorInfoVerifier(cause.getMessage()));
     }
 
     @Test
     public void testToXMLResponseWithMultipleErrors() throws Exception {
 
-        List<RestconfError> errorList = Arrays.asList(
-                new RestconfError( ErrorType.APPLICATION, ErrorTag.LOCK_DENIED, "mock error1" ),
-                new RestconfError( ErrorType.RPC, ErrorTag.ROLLBACK_FAILED, "mock error2" ) );
-        stageMockEx( new RestconfDocumentedException( errorList ) );
+        List<RestconfError> errorList = Arrays.asList(new RestconfError(ErrorType.APPLICATION, ErrorTag.LOCK_DENIED,
+                "mock error1"), new RestconfError(ErrorType.RPC, ErrorTag.ROLLBACK_FAILED, "mock error2"));
+        stageMockEx(new RestconfDocumentedException(errorList));
 
-        Response resp = target("/operational/foo").request( MediaType.APPLICATION_XML ).get();
+        Response resp = target("/operational/foo").request(MediaType.APPLICATION_XML).get();
 
-        InputStream stream = verifyResponse( resp, MediaType.APPLICATION_XML, Status.CONFLICT );
+        InputStream stream = verifyResponse(resp, MediaType.APPLICATION_XML, Status.CONFLICT);
 
-        Document doc = parseXMLDocument( stream );
+        Document doc = parseXMLDocument(stream);
 
-        NodeList children = getXMLErrorList( doc, 2 );
+        NodeList children = getXMLErrorList(doc, 2);
 
-        verifyXMLErrorNode( children.item( 0 ), ErrorType.APPLICATION, ErrorTag.LOCK_DENIED,
-                "mock error1", null, null );
+        verifyXMLErrorNode(children.item(0), ErrorType.APPLICATION, ErrorTag.LOCK_DENIED, "mock error1", null, null);
 
-        verifyXMLErrorNode( children.item( 1 ), ErrorType.RPC, ErrorTag.ROLLBACK_FAILED,
-                "mock error2", null, null );
+        verifyXMLErrorNode(children.item(1), ErrorType.RPC, ErrorTag.ROLLBACK_FAILED, "mock error2", null, null);
     }
 
     @Test
     public void testToResponseWithAcceptHeader() throws Exception {
 
-        stageMockEx( new RestconfDocumentedException( "mock error" ) );
+        stageMockEx(new RestconfDocumentedException("mock error"));
 
-        Response resp = target("/operational/foo")
-                .request().header( "Accept", MediaType.APPLICATION_JSON ).get();
+        Response resp = target("/operational/foo").request().header("Accept", MediaType.APPLICATION_JSON).get();
 
-        InputStream stream = verifyResponse( resp, MediaType.APPLICATION_JSON,
-                Status.INTERNAL_SERVER_ERROR );
+        InputStream stream = verifyResponse(resp, MediaType.APPLICATION_JSON, Status.INTERNAL_SERVER_ERROR);
 
-        verifyJsonResponseBody( stream, ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error",
-                null, null );
+        verifyJsonResponseBody(stream, ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error", null, null);
     }
 
     @Test
     public void testToResponseWithStatusOnly() throws Exception {
 
-        // The StructuredDataToJsonProvider should throw a RestconfDocumentedException with no data
+        // The StructuredDataToJsonProvider should throw a
+        // RestconfDocumentedException with no data
 
-        when( mockRestConf.readOperationalData( any( String.class ), any( UriInfo.class ) ) )
-            .thenReturn( new StructuredData( null, null, null ) );
+        when(mockRestConf.readOperationalData(any(String.class), any(UriInfo.class))).thenReturn(
+                new StructuredData(null, null, null));
 
-        Response resp = target("/operational/foo").request( MediaType.APPLICATION_JSON ).get();
+        Response resp = target("/operational/foo").request(MediaType.APPLICATION_JSON).get();
 
-        verifyResponse( resp, MediaType.TEXT_PLAIN, Status.NOT_FOUND );
+        verifyResponse(resp, MediaType.TEXT_PLAIN, Status.NOT_FOUND);
     }
 
-    InputStream verifyResponse( final Response resp, final String expMediaType, final Status expStatus ) {
-        assertEquals( "getMediaType", MediaType.valueOf( expMediaType ), resp.getMediaType() );
-        assertEquals( "getStatus", expStatus.getStatusCode(), resp.getStatus() );
+    InputStream verifyResponse(final Response resp, final String expMediaType, final Status expStatus) {
+        assertEquals("getMediaType", MediaType.valueOf(expMediaType), resp.getMediaType());
+        assertEquals("getStatus", expStatus.getStatusCode(), resp.getStatus());
 
         Object entity = resp.getEntity();
-        assertEquals( "Response entity", true, entity instanceof InputStream );
-        InputStream stream = (InputStream)entity;
+        assertEquals("Response entity", true, entity instanceof InputStream);
+        InputStream stream = (InputStream) entity;
         return stream;
     }
 
-    void verifyJsonResponseBody( final InputStream stream, final ErrorType expErrorType, final ErrorTag expErrorTag,
-            final String expErrorMessage, final String expErrorAppTag,
-            final ErrorInfoVerifier errorInfoVerifier ) throws Exception {
+    void verifyJsonResponseBody(final InputStream stream, final ErrorType expErrorType, final ErrorTag expErrorTag,
+            final String expErrorMessage, final String expErrorAppTag, final ErrorInfoVerifier errorInfoVerifier)
+            throws Exception {
 
-        JsonArray arrayElement = parseJsonErrorArrayElement( stream );
+        JsonArray arrayElement = parseJsonErrorArrayElement(stream);
 
-        assertEquals( "\"error\" Json array element length", 1, arrayElement.size() );
+        assertEquals("\"error\" Json array element length", 1, arrayElement.size());
 
-        verifyJsonErrorNode( arrayElement.get( 0 ),  expErrorType, expErrorTag, expErrorMessage,
-                expErrorAppTag, errorInfoVerifier );
+        verifyJsonErrorNode(arrayElement.get(0), expErrorType, expErrorTag, expErrorMessage, expErrorAppTag,
+                errorInfoVerifier);
     }
 
-    private JsonArray parseJsonErrorArrayElement( final InputStream stream ) throws IOException {
+    private JsonArray parseJsonErrorArrayElement(final InputStream stream) throws IOException {
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        ByteStreams.copy( stream, bos );
+        ByteStreams.copy(stream, bos);
 
-        System.out.println("JSON: "+bos.toString());
+        System.out.println("JSON: " + bos.toString());
 
         JsonParser parser = new JsonParser();
         JsonElement rootElement;
 
         try {
-            rootElement = parser.parse(
-                    new InputStreamReader( new ByteArrayInputStream( bos.toByteArray() ) ) );
-        }
-        catch( Exception e ) {
-            throw new IllegalArgumentException( "Invalid JSON response:\n" + bos.toString(), e );
+            rootElement = parser.parse(new InputStreamReader(new ByteArrayInputStream(bos.toByteArray())));
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Invalid JSON response:\n" + bos.toString(), e);
         }
 
-        assertTrue( "Root element of Json is not an Object", rootElement.isJsonObject() );
+        assertTrue("Root element of Json is not an Object", rootElement.isJsonObject());
 
         Set<Entry<String, JsonElement>> errorsEntrySet = rootElement.getAsJsonObject().entrySet();
-        assertEquals( "Json Object element set count", 1, errorsEntrySet.size() );
+        assertEquals("Json Object element set count", 1, errorsEntrySet.size());
 
         Entry<String, JsonElement> errorsEntry = errorsEntrySet.iterator().next();
         JsonElement errorsElement = errorsEntry.getValue();
-        assertEquals( "First Json element name", "errors", errorsEntry.getKey() );
-        assertTrue( "\"errors\" Json element is not an Object", errorsElement.isJsonObject() );
+        assertEquals("First Json element name", "errors", errorsEntry.getKey());
+        assertTrue("\"errors\" Json element is not an Object", errorsElement.isJsonObject());
 
         Set<Entry<String, JsonElement>> errorListEntrySet = errorsElement.getAsJsonObject().entrySet();
-        assertEquals( "Root \"errors\" element child count", 1, errorListEntrySet.size() );
+        assertEquals("Root \"errors\" element child count", 1, errorListEntrySet.size());
 
         JsonElement errorListElement = errorListEntrySet.iterator().next().getValue();
-        assertEquals( "\"errors\" child Json element name", "error",
-                errorListEntrySet.iterator().next().getKey() );
-        assertTrue( "\"error\" Json element is not an Array", errorListElement.isJsonArray() );
+        assertEquals("\"errors\" child Json element name", "error", errorListEntrySet.iterator().next().getKey());
+        assertTrue("\"error\" Json element is not an Array", errorListElement.isJsonArray());
 
-        // As a final check, make sure there aren't multiple "error" array elements. Unfortunately,
-        // the call above to getAsJsonObject().entrySet() will out duplicate "error" elements. So
+        // As a final check, make sure there aren't multiple "error" array
+        // elements. Unfortunately,
+        // the call above to getAsJsonObject().entrySet() will out duplicate
+        // "error" elements. So
         // we'll use regex on the json string to verify this.
 
-        Matcher matcher = Pattern.compile( "\"error\"[ ]*:[ ]*\\[", Pattern.DOTALL ).matcher( bos.toString() );
-        assertTrue( "Expected 1 \"error\" element", matcher.find() );
-        assertFalse( "Found multiple \"error\" elements", matcher.find() );
+        Matcher matcher = Pattern.compile("\"error\"[ ]*:[ ]*\\[", Pattern.DOTALL).matcher(bos.toString());
+        assertTrue("Expected 1 \"error\" element", matcher.find());
+        assertFalse("Found multiple \"error\" elements", matcher.find());
 
         return errorListElement.getAsJsonArray();
     }
 
-    void verifyJsonErrorNode( final JsonElement errorEntryElement, final ErrorType expErrorType, final ErrorTag expErrorTag,
-            final String expErrorMessage, final String expErrorAppTag,
-            final ErrorInfoVerifier errorInfoVerifier ) {
+    void verifyJsonErrorNode(final JsonElement errorEntryElement, final ErrorType expErrorType,
+            final ErrorTag expErrorTag, final String expErrorMessage, final String expErrorAppTag,
+            final ErrorInfoVerifier errorInfoVerifier) {
 
         JsonElement errorInfoElement = null;
         Map<String, String> leafMap = Maps.newHashMap();
-        for( Entry<String, JsonElement> entry: errorEntryElement.getAsJsonObject().entrySet() ) {
+        for (Entry<String, JsonElement> entry : errorEntryElement.getAsJsonObject().entrySet()) {
             String leafName = entry.getKey();
             JsonElement leafElement = entry.getValue();
 
-            if( "error-info".equals( leafName ) ) {
-                assertNotNull( "Found unexpected \"error-info\" element", errorInfoVerifier );
+            if ("error-info".equals(leafName)) {
+                assertNotNull("Found unexpected \"error-info\" element", errorInfoVerifier);
                 errorInfoElement = leafElement;
-            }
-            else {
-                assertTrue( "\"error\" leaf Json element " + leafName +
-                        " is not a Primitive", leafElement.isJsonPrimitive() );
+            } else {
+                assertTrue("\"error\" leaf Json element " + leafName + " is not a Primitive",
+                        leafElement.isJsonPrimitive());
 
-                leafMap.put( leafName, leafElement.getAsString() );
+                leafMap.put(leafName, leafElement.getAsString());
             }
         }
 
-        assertEquals( "error-type", expErrorType.getErrorTypeTag(), leafMap.remove( "error-type" ) );
-        assertEquals( "error-tag", expErrorTag.getTagValue(), leafMap.remove( "error-tag" ) );
+        assertEquals("error-type", expErrorType.getErrorTypeTag(), leafMap.remove("error-type"));
+        assertEquals("error-tag", expErrorTag.getTagValue(), leafMap.remove("error-tag"));
 
-        verifyOptionalJsonLeaf( leafMap.remove( "error-message" ), expErrorMessage, "error-message" );
-        verifyOptionalJsonLeaf( leafMap.remove( "error-app-tag" ), expErrorAppTag, "error-app-tag" );
+        verifyOptionalJsonLeaf(leafMap.remove("error-message"), expErrorMessage, "error-message");
+        verifyOptionalJsonLeaf(leafMap.remove("error-app-tag"), expErrorAppTag, "error-app-tag");
 
-        if( !leafMap.isEmpty() ) {
-            fail( "Found unexpected Json leaf elements for \"error\" element: " + leafMap );
+        if (!leafMap.isEmpty()) {
+            fail("Found unexpected Json leaf elements for \"error\" element: " + leafMap);
         }
 
-        if( errorInfoVerifier != null ) {
-            assertNotNull( "Missing \"error-info\" element", errorInfoElement );
-            errorInfoVerifier.verifyJson( errorInfoElement );
+        if (errorInfoVerifier != null) {
+            assertNotNull("Missing \"error-info\" element", errorInfoElement);
+            errorInfoVerifier.verifyJson(errorInfoElement);
         }
     }
 
-    void verifyOptionalJsonLeaf( final String actualValue, final String expValue, final String tagName ) {
-        if( expValue != null ) {
-            assertEquals( tagName, expValue, actualValue );
-        }
-        else {
-            assertNull( "Found unexpected \"error\" leaf entry for: " + tagName, actualValue );
+    void verifyOptionalJsonLeaf(final String actualValue, final String expValue, final String tagName) {
+        if (expValue != null) {
+            assertEquals(tagName, expValue, actualValue);
+        } else {
+            assertNull("Found unexpected \"error\" leaf entry for: " + tagName, actualValue);
         }
     }
 
-    void verifyXMLResponseBody( final InputStream stream, final ErrorType expErrorType, final ErrorTag expErrorTag,
-            final String expErrorMessage, final String expErrorAppTag,
-            final ErrorInfoVerifier errorInfoVerifier )
-                    throws Exception {
+    void verifyXMLResponseBody(final InputStream stream, final ErrorType expErrorType, final ErrorTag expErrorTag,
+            final String expErrorMessage, final String expErrorAppTag, final ErrorInfoVerifier errorInfoVerifier)
+            throws Exception {
 
-        Document doc = parseXMLDocument( stream );
+        Document doc = parseXMLDocument(stream);
 
-        NodeList children = getXMLErrorList( doc, 1 );
+        NodeList children = getXMLErrorList(doc, 1);
 
-        verifyXMLErrorNode( children.item( 0 ), expErrorType, expErrorTag, expErrorMessage,
-                expErrorAppTag, errorInfoVerifier );
+        verifyXMLErrorNode(children.item(0), expErrorType, expErrorTag, expErrorMessage, expErrorAppTag,
+                errorInfoVerifier);
     }
 
-    private Document parseXMLDocument( final InputStream stream ) throws IOException {
+    private Document parseXMLDocument(final InputStream stream) throws IOException {
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
         factory.setNamespaceAware(true);
         factory.setCoalescing(true);
@@ -921,60 +824,57 @@ public class RestconfDocumentedExceptionMapperTest extends JerseyTest {
         factory.setIgnoringComments(true);
 
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        ByteStreams.copy( stream, bos );
+        ByteStreams.copy(stream, bos);
 
-        System.out.println("XML: "+bos.toString());
+        System.out.println("XML: " + bos.toString());
 
         Document doc = null;
         try {
-            doc = factory.newDocumentBuilder().parse( new ByteArrayInputStream( bos.toByteArray() ) );
-        }
-        catch( Exception e ) {
-            throw new IllegalArgumentException( "Invalid XML response:\n" + bos.toString(), e );
+            doc = factory.newDocumentBuilder().parse(new ByteArrayInputStream(bos.toByteArray()));
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Invalid XML response:\n" + bos.toString(), e);
         }
         return doc;
     }
 
-    void verifyXMLErrorNode( final Node errorNode, final ErrorType expErrorType, final ErrorTag expErrorTag,
-            final String expErrorMessage, final String expErrorAppTag,
-            final ErrorInfoVerifier errorInfoVerifier ) throws Exception {
+    void verifyXMLErrorNode(final Node errorNode, final ErrorType expErrorType, final ErrorTag expErrorTag,
+            final String expErrorMessage, final String expErrorAppTag, final ErrorInfoVerifier errorInfoVerifier)
+            throws Exception {
 
-        String errorType = (String)ERROR_TYPE.evaluate( errorNode, XPathConstants.STRING );
-        assertEquals( "error-type", expErrorType.getErrorTypeTag(), errorType );
+        String errorType = (String) ERROR_TYPE.evaluate(errorNode, XPathConstants.STRING);
+        assertEquals("error-type", expErrorType.getErrorTypeTag(), errorType);
 
-        String errorTag = (String)ERROR_TAG.evaluate( errorNode, XPathConstants.STRING );
-        assertEquals( "error-tag", expErrorTag.getTagValue(), errorTag );
+        String errorTag = (String) ERROR_TAG.evaluate(errorNode, XPathConstants.STRING);
+        assertEquals("error-tag", expErrorTag.getTagValue(), errorTag);
 
-        verifyOptionalXMLLeaf( errorNode, ERROR_MESSAGE, expErrorMessage, "error-message" );
-        verifyOptionalXMLLeaf( errorNode, ERROR_APP_TAG, expErrorAppTag, "error-app-tag" );
+        verifyOptionalXMLLeaf(errorNode, ERROR_MESSAGE, expErrorMessage, "error-message");
+        verifyOptionalXMLLeaf(errorNode, ERROR_APP_TAG, expErrorAppTag, "error-app-tag");
 
-        Node errorInfoNode = (Node)ERROR_INFO.evaluate( errorNode, XPathConstants.NODE );
-        if( errorInfoVerifier != null ) {
-            assertNotNull( "Missing \"error-info\" node", errorInfoNode );
+        Node errorInfoNode = (Node) ERROR_INFO.evaluate(errorNode, XPathConstants.NODE);
+        if (errorInfoVerifier != null) {
+            assertNotNull("Missing \"error-info\" node", errorInfoNode);
 
-            errorInfoVerifier.verifyXML( errorInfoNode );
-        }
-        else {
-            assertNull( "Found unexpected \"error-info\" node", errorInfoNode );
+            errorInfoVerifier.verifyXML(errorInfoNode);
+        } else {
+            assertNull("Found unexpected \"error-info\" node", errorInfoNode);
         }
     }
 
-    void verifyOptionalXMLLeaf( final Node fromNode, final XPathExpression xpath, final String expValue,
-            final String tagName ) throws Exception {
-        if( expValue != null ) {
-            String actual = (String)xpath.evaluate( fromNode, XPathConstants.STRING );
-            assertEquals( tagName, expValue, actual );
-        }
-        else {
-            assertNull( "Found unexpected \"error\" leaf entry for: " + tagName,
-                    xpath.evaluate( fromNode, XPathConstants.NODE ) );
+    void verifyOptionalXMLLeaf(final Node fromNode, final XPathExpression xpath, final String expValue,
+            final String tagName) throws Exception {
+        if (expValue != null) {
+            String actual = (String) xpath.evaluate(fromNode, XPathConstants.STRING);
+            assertEquals(tagName, expValue, actual);
+        } else {
+            assertNull("Found unexpected \"error\" leaf entry for: " + tagName,
+                    xpath.evaluate(fromNode, XPathConstants.NODE));
         }
     }
 
-    NodeList getXMLErrorList( final Node fromNode, final int count ) throws Exception {
-        NodeList errorList = (NodeList)ERROR_LIST.evaluate( fromNode, XPathConstants.NODESET );
-        assertNotNull( "Root errors node is empty", errorList );
-        assertEquals( "Root errors node child count", count, errorList.getLength() );
+    NodeList getXMLErrorList(final Node fromNode, final int count) throws Exception {
+        NodeList errorList = (NodeList) ERROR_LIST.evaluate(fromNode, XPathConstants.NODESET);
+        assertNotNull("Root errors node is empty", errorList);
+        assertEquals("Root errors node child count", count, errorList.getLength());
         return errorList;
     }
 }
index a1b87325540e51a65b5918a9674148e9e2cbea26..18311104a41f9761dd5bede15965df9625ea061b 100644 (file)
@@ -1,10 +1,10 @@
 /*
-* Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
-*
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v1.0 which accompanies this distribution,
-* and is available at http://www.eclipse.org/legal/epl-v10.html
-*/
+ * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.sal.restconf.impl.test;
 
 import static org.hamcrest.CoreMatchers.equalTo;
@@ -14,18 +14,15 @@ import static org.junit.Assert.assertThat;
 
 import java.util.HashMap;
 import java.util.Map;
-
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.junit.Test;
-
-import static org.opendaylight.controller.sal.common.util.RpcErrors.getRpcError;
-
 import org.opendaylight.controller.sal.restconf.impl.RestconfError;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
 import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 
 /**
  * Unit tests for RestconfError.
@@ -40,196 +37,166 @@ public class RestconfErrorTest {
 
         private final String text;
 
-        public Contains( String text ) {
+        public Contains(String text) {
             this.text = text;
         }
 
         @Override
-        public void describeTo( Description desc ) {
-            desc.appendText( "contains " ).appendValue( text );
+        public void describeTo(Description desc) {
+            desc.appendText("contains ").appendValue(text);
         }
 
         @Override
-        public boolean matches( Object arg ) {
-            return arg != null && arg.toString().contains( text );
+        public boolean matches(Object arg) {
+            return arg != null && arg.toString().contains(text);
         }
     }
 
     @Test
-    public void testErrorTagValueOf()
-    {
-        assertEquals( ErrorTag.IN_USE,
-                ErrorTag.valueOfCaseInsensitive( ErrorTag.IN_USE.getTagValue() ) );
+    public void testErrorTagValueOf() {
+        assertEquals(ErrorTag.IN_USE, ErrorTag.valueOfCaseInsensitive(ErrorTag.IN_USE.getTagValue()));
     }
 
     @Test
-    public void testErrorTagValueOfIsLowercase()
-    {
-        assertEquals( "in-use",
-                ErrorTag.IN_USE.getTagValue() );
+    public void testErrorTagValueOfIsLowercase() {
+        assertEquals("in-use", ErrorTag.IN_USE.getTagValue());
     }
 
     @Test
-    public void testErrorTypeGetErrorTypeTagIsLowerCase()
-    {
-       assertEquals( ErrorType.APPLICATION.name().toLowerCase(),
-               ErrorType.APPLICATION.getErrorTypeTag() );
+    public void testErrorTypeGetErrorTypeTagIsLowerCase() {
+        assertEquals(ErrorType.APPLICATION.name().toLowerCase(), ErrorType.APPLICATION.getErrorTypeTag());
     }
 
     @Test
-    public void testErrorTypeValueOf()
-    {
-       assertEquals( ErrorType.APPLICATION,
-                     ErrorType.valueOfCaseInsensitive( ErrorType.APPLICATION.getErrorTypeTag() ) );
+    public void testErrorTypeValueOf() {
+        assertEquals(ErrorType.APPLICATION, ErrorType.valueOfCaseInsensitive(ErrorType.APPLICATION.getErrorTypeTag()));
     }
 
     @Test
-    public void testErrorTagStatusCodes()
-    {
-        Map<String,Integer> lookUpMap = new HashMap<String,Integer>();
-
-        lookUpMap.put( "in-use", 409);
-        lookUpMap.put( "invalid-value", 400);
-        lookUpMap.put( "too-big", 413);
-        lookUpMap.put( "missing-attribute", 400);
-        lookUpMap.put( "bad-attribute", 400);
-        lookUpMap.put( "unknown-attribute", 400);
-        lookUpMap.put( "bad-element", 400);
-        lookUpMap.put( "unknown-element", 400);
-        lookUpMap.put( "unknown-namespace", 400);
-        lookUpMap.put( "access-denied", 403);
-        lookUpMap.put( "lock-denied", 409);
-        lookUpMap.put( "resource-denied", 409);
-        lookUpMap.put( "rollback-failed", 500);
-        lookUpMap.put( "data-exists", 409);
-        lookUpMap.put( "data-missing", 409);
-        lookUpMap.put( "operation-not-supported", 501);
-        lookUpMap.put( "operation-failed", 500);
-        lookUpMap.put( "partial-operation", 500);
-        lookUpMap.put( "malformed-message", 400);
-
-        for( ErrorTag tag : ErrorTag.values() )
-        {
-            Integer expectedStatusCode = lookUpMap.get( tag.getTagValue() );
-            assertNotNull( "Failed to find " + tag.getTagValue(), expectedStatusCode );
-            assertEquals( "Status Code does not match", expectedStatusCode,
-                          Integer.valueOf( tag.getStatusCode() ) );
+    public void testErrorTagStatusCodes() {
+        Map<String, Integer> lookUpMap = new HashMap<String, Integer>();
+
+        lookUpMap.put("in-use", 409);
+        lookUpMap.put("invalid-value", 400);
+        lookUpMap.put("too-big", 413);
+        lookUpMap.put("missing-attribute", 400);
+        lookUpMap.put("bad-attribute", 400);
+        lookUpMap.put("unknown-attribute", 400);
+        lookUpMap.put("bad-element", 400);
+        lookUpMap.put("unknown-element", 400);
+        lookUpMap.put("unknown-namespace", 400);
+        lookUpMap.put("access-denied", 403);
+        lookUpMap.put("lock-denied", 409);
+        lookUpMap.put("resource-denied", 409);
+        lookUpMap.put("rollback-failed", 500);
+        lookUpMap.put("data-exists", 409);
+        lookUpMap.put("data-missing", 409);
+        lookUpMap.put("operation-not-supported", 501);
+        lookUpMap.put("operation-failed", 500);
+        lookUpMap.put("partial-operation", 500);
+        lookUpMap.put("malformed-message", 400);
+
+        for (ErrorTag tag : ErrorTag.values()) {
+            Integer expectedStatusCode = lookUpMap.get(tag.getTagValue());
+            assertNotNull("Failed to find " + tag.getTagValue(), expectedStatusCode);
+            assertEquals("Status Code does not match", expectedStatusCode, Integer.valueOf(tag.getStatusCode()));
         }
     }
 
     @Test
-    public void testRestConfDocumentedException_NoCause()
-    {
+    public void testRestConfDocumentedException_NoCause() {
         String expectedMessage = "Message";
         ErrorType expectedErrorType = ErrorType.RPC;
         ErrorTag expectedErrorTag = ErrorTag.IN_USE;
-        RestconfError e =
-                new RestconfError( expectedErrorType,
-                                                 expectedErrorTag, expectedMessage );
+        RestconfError e = new RestconfError(expectedErrorType, expectedErrorTag, expectedMessage);
 
-        validateRestConfError(expectedMessage, expectedErrorType, expectedErrorTag,
-                              null, (String)null, e);
+        validateRestConfError(expectedMessage, expectedErrorType, expectedErrorTag, null, (String) null, e);
     }
 
     @Test
-    public void testRestConfDocumentedException_WithAppTag()
-    {
+    public void testRestConfDocumentedException_WithAppTag() {
         String expectedMessage = "Message";
         ErrorType expectedErrorType = ErrorType.RPC;
         ErrorTag expectedErrorTag = ErrorTag.IN_USE;
         String expectedErrorAppTag = "application.tag";
 
-        RestconfError e =
-                new RestconfError( expectedErrorType,
-                                                 expectedErrorTag, expectedMessage, expectedErrorAppTag );
+        RestconfError e = new RestconfError(expectedErrorType, expectedErrorTag, expectedMessage, expectedErrorAppTag);
 
-        validateRestConfError(expectedMessage, expectedErrorType, expectedErrorTag,
-                              expectedErrorAppTag, (String)null, e);
+        validateRestConfError(expectedMessage, expectedErrorType, expectedErrorTag, expectedErrorAppTag, (String) null,
+                e);
     }
 
     @Test
-    public void testRestConfDocumentedException_WithAppTagErrorInfo()
-    {
+    public void testRestConfDocumentedException_WithAppTagErrorInfo() {
         String expectedMessage = "Message";
         ErrorType expectedErrorType = ErrorType.RPC;
         ErrorTag expectedErrorTag = ErrorTag.IN_USE;
         String expectedErrorAppTag = "application.tag";
         String errorInfo = "<extra><sessionid>session.id</sessionid></extra>";
 
-        RestconfError e = new RestconfError( expectedErrorType,
-                                             expectedErrorTag,
-                                             expectedMessage,
-                                             expectedErrorAppTag,
-                                             errorInfo );
+        RestconfError e = new RestconfError(expectedErrorType, expectedErrorTag, expectedMessage, expectedErrorAppTag,
+                errorInfo);
 
-        validateRestConfError(expectedMessage, expectedErrorType, expectedErrorTag,
-                expectedErrorAppTag, errorInfo, e);
+        validateRestConfError(expectedMessage, expectedErrorType, expectedErrorTag, expectedErrorAppTag, errorInfo, e);
     }
 
     @Test
     public void testRestConfErrorWithRpcError() {
 
         // All fields set
-        RpcError rpcError = getRpcError( "mock app-tag", ErrorTag.BAD_ATTRIBUTE.getTagValue(),
-                                         "mock error-info", RpcError.ErrorSeverity.ERROR,
-                                         "mock error-message", RpcError.ErrorType.PROTOCOL,
-                                         new Exception( "mock cause" ) );
+        RpcError rpcError = RpcResultBuilder.newError(
+                RpcError.ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE.getTagValue(), "mock error-message",
+                "mock app-tag", "mock error-info", new Exception( "mock cause" ) );
 
-        validateRestConfError( "mock error-message", ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE,
-                               "mock app-tag", "mock error-info",
-                               new RestconfError( rpcError ) );
+        validateRestConfError("mock error-message", ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE, "mock app-tag",
+                "mock error-info", new RestconfError(rpcError));
 
         // All fields set except 'info' - expect error-info set to 'cause'
-        rpcError = getRpcError( "mock app-tag", ErrorTag.BAD_ATTRIBUTE.getTagValue(),
-                                null, RpcError.ErrorSeverity.ERROR,
-                                "mock error-message", RpcError.ErrorType.PROTOCOL,
-                                new Exception( "mock cause" ) );
+        rpcError = RpcResultBuilder.newError(
+                RpcError.ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE.getTagValue(), "mock error-message",
+                "mock app-tag", null, new Exception( "mock cause" ) );
 
-        validateRestConfError( "mock error-message", ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE,
-                               "mock app-tag", new Contains( "mock cause" ),
-                               new RestconfError( rpcError ) );
+        validateRestConfError("mock error-message", ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE, "mock app-tag",
+                new Contains("mock cause"), new RestconfError(rpcError));
 
         // Some fields set - expect error-info set to ErrorSeverity
-        rpcError = getRpcError( null, ErrorTag.ACCESS_DENIED.getTagValue(),
-                                null, RpcError.ErrorSeverity.ERROR,
-                                null, RpcError.ErrorType.RPC, null );
+        rpcError = RpcResultBuilder.newError(
+                RpcError.ErrorType.RPC, ErrorTag.ACCESS_DENIED.getTagValue(), null, null, null, null );
 
-        validateRestConfError( null, ErrorType.RPC, ErrorTag.ACCESS_DENIED,
-                               null, "<severity>error</severity>",
-                               new RestconfError( rpcError ) );
+        validateRestConfError(null, ErrorType.RPC, ErrorTag.ACCESS_DENIED, null, "<severity>error</severity>",
+                new RestconfError(rpcError));
 
-        // 'tag' field not mapped to ErrorTag - expect error-tag set to OPERATION_FAILED
-        rpcError = getRpcError( null, "not mapped",
-                                null, RpcError.ErrorSeverity.WARNING,
-                                null, RpcError.ErrorType.TRANSPORT, null );
+        // 'tag' field not mapped to ErrorTag - expect error-tag set to
+        // OPERATION_FAILED
+        rpcError = RpcResultBuilder.newWarning(
+                RpcError.ErrorType.TRANSPORT, "not mapped", null, null, null, null );
 
-        validateRestConfError( null, ErrorType.TRANSPORT, ErrorTag.OPERATION_FAILED,
-                               null, "<severity>warning</severity>",
-                               new RestconfError( rpcError ) );
+        validateRestConfError(null, ErrorType.TRANSPORT, ErrorTag.OPERATION_FAILED, null,
+                "<severity>warning</severity>", new RestconfError(rpcError));
 
         // No fields set - edge case
-        rpcError = getRpcError( null, null, null, null, null, null, null );
+        rpcError = RpcResultBuilder.newError( null, null, null, null, null, null );
 
         validateRestConfError( null, ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED,
-                               null, (String)null, new RestconfError( rpcError ) );
+                               null, "<severity>error</severity>", new RestconfError( rpcError ) );
     }
 
-    private void validateRestConfError(String expectedMessage, ErrorType expectedErrorType,
-            ErrorTag expectedErrorTag, String expectedErrorAppTag, String errorInfo, RestconfError e) {
+    private void validateRestConfError(String expectedMessage, ErrorType expectedErrorType, ErrorTag expectedErrorTag,
+            String expectedErrorAppTag, String errorInfo, RestconfError e) {
 
-        validateRestConfError( expectedMessage, expectedErrorType, expectedErrorTag,
-                               expectedErrorAppTag, equalTo( errorInfo ), e );
+        validateRestConfError(expectedMessage, expectedErrorType, expectedErrorTag, expectedErrorAppTag,
+                equalTo(errorInfo), e);
     }
 
-    private void validateRestConfError(String expectedMessage, ErrorType expectedErrorType,
-            ErrorTag expectedErrorTag, String expectedErrorAppTag,
-            Matcher<String> errorInfoMatcher, RestconfError e) {
+    private void validateRestConfError(String expectedMessage, ErrorType expectedErrorType, ErrorTag expectedErrorTag,
+            String expectedErrorAppTag, Matcher<String> errorInfoMatcher, RestconfError e) {
 
-        assertEquals( "getErrorMessage", expectedMessage, e.getErrorMessage() );
-        assertEquals( "getErrorType", expectedErrorType, e.getErrorType() );
-        assertEquals( "getErrorTag", expectedErrorTag, e.getErrorTag() );
-        assertEquals( "getErrorAppTag", expectedErrorAppTag, e.getErrorAppTag() );
-        assertThat( "getErrorInfo", e.getErrorInfo(), errorInfoMatcher );
-        e.toString(); // really just checking for NPE etc. Don't care about contents.
+        assertEquals("getErrorMessage", expectedMessage, e.getErrorMessage());
+        assertEquals("getErrorType", expectedErrorType, e.getErrorType());
+        assertEquals("getErrorTag", expectedErrorTag, e.getErrorTag());
+        assertEquals("getErrorAppTag", expectedErrorAppTag, e.getErrorAppTag());
+        assertThat("getErrorInfo", e.getErrorInfo(), errorInfoMatcher);
+        e.toString(); // really just checking for NPE etc. Don't care about
+                      // contents.
     }
 }
index e2559f4b70ab27e2e6d990996e84bd8fbfb47045..236712b45499a70df1b1e69b7c19e3d094dc561b 100644 (file)
@@ -16,7 +16,6 @@ import static org.mockito.Mockito.when;
 
 import java.io.FileNotFoundException;
 import java.util.Set;
-
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -25,7 +24,7 @@ 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.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
@@ -40,33 +39,27 @@ public class RestconfImplTest {
 
     @BeforeClass
     public static void init() throws FileNotFoundException {
-        Set<Module> allModules = TestUtils
-                .loadModulesFrom("/full-versions/yangs");
+        Set<Module> allModules = TestUtils.loadModulesFrom("/full-versions/yangs");
         assertNotNull(allModules);
         SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
-        controllerContext = spy( ControllerContext.getInstance() );
+        controllerContext = spy(ControllerContext.getInstance());
         controllerContext.setSchemas(schemaContext);
 
     }
 
     @Before
-    public void initMethod()
-    {
+    public void initMethod() {
         restconfImpl = RestconfImpl.getInstance();
-        restconfImpl.setControllerContext( controllerContext );
+        restconfImpl.setControllerContext(controllerContext);
     }
 
     @Test
     public void testExample() throws FileNotFoundException {
-        CompositeNode loadedCompositeNode = TestUtils.readInputToCnSn(
-                "/parts/ietf-interfaces_interfaces.xml",
+        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));
+        when(brokerFacade.readOperationalData(any(YangInstanceIdentifier.class))).thenReturn(loadedCompositeNode);
+        assertEquals(loadedCompositeNode, brokerFacade.readOperationalData(null));
     }
 
-
 }
index 853c19f93530c16449840b1043ac07d30edaab4f..67d98f6b558db0a0915928ff869d2a0f123a5b45 100644 (file)
@@ -13,6 +13,7 @@ import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import com.google.common.base.Preconditions;
 import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -27,7 +28,8 @@ import java.sql.Date;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
-
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.MessageBodyWriter;
@@ -40,7 +42,6 @@ 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.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
@@ -50,7 +51,7 @@ 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.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -61,8 +62,6 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 
-import com.google.common.base.Preconditions;
-
 public final class TestUtils {
 
     private static final Logger LOG = LoggerFactory.getLogger(TestUtils.class);
@@ -148,10 +147,9 @@ public final class TestUtils {
 
     /**
      *
-     * 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}
+     * 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();
@@ -162,9 +160,8 @@ public final class TestUtils {
     }
 
     /**
-     * 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.
+     * 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) {
@@ -232,7 +229,7 @@ public final class TestUtils {
 
         controllerContext.setSchemas(TestUtils.loadSchemaContext(modules));
 
-        when(mockedBrokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class)))
+        when(mockedBrokerFacade.commitConfigurationDataPut(any(YangInstanceIdentifier.class), any(CompositeNode.class)))
                 .thenReturn(
                         new DummyFuture.Builder().rpcResult(
                                 new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
@@ -280,8 +277,8 @@ public final class TestUtils {
 
         ControllerContext.getInstance().setSchemas(loadSchemaContext(modules));
 
-        messageBodyWriter.writeTo(new StructuredData(compositeNode, dataSchemaNode, null), null, null, null, null, null,
-                byteArrayOS);
+        messageBodyWriter.writeTo(new StructuredData(compositeNode, dataSchemaNode, null), null, null, null, null,
+                null, byteArrayOS);
 
         return byteArrayOS.toString();
     }
@@ -297,6 +294,22 @@ public final class TestUtils {
         }
         bufReader.close();
         return result.toString();
+    }
+
+    private static Pattern patternForStringsSeparatedByWhiteChars(String... substrings) {
+        StringBuilder pattern = new StringBuilder();
+        pattern.append(".*");
+        for (String substring : substrings) {
+            pattern.append(substring);
+            pattern.append("\\s*");
+        }
+        pattern.append(".*");
+        return Pattern.compile(pattern.toString(), Pattern.DOTALL);
+    }
 
+    public static boolean containsStringData(String jsonOutput, String... substrings) {
+        Pattern pattern = patternForStringsSeparatedByWhiteChars(substrings);
+        Matcher matcher = pattern.matcher(jsonOutput);
+        return matcher.matches();
     }
 }
index 33d4b325bef2c6abc6424c044e8a572acb619ac2..655aba267fb5574a94e352fcedd3e4727c923a73 100644 (file)
@@ -14,9 +14,9 @@ import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import com.google.common.collect.Iterables;
 import java.io.FileNotFoundException;
 import java.util.Set;
-
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
@@ -28,7 +28,7 @@ import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode;
 import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -131,7 +131,7 @@ public class URITest {
         initMountService(true);
         InstanceIdWithSchemaNode instanceIdentifier = controllerContext
                 .toInstanceIdentifier("simple-nodes:users/yang-ext:mount/");
-        assertEquals(true, instanceIdentifier.getInstanceIdentifier().getPath().isEmpty());
+        assertTrue(Iterables.isEmpty(instanceIdentifier.getInstanceIdentifier().getPathArguments()));
     }
 
     @Test
@@ -152,7 +152,7 @@ public class URITest {
                 .toInstanceIdentifier("simple-nodes:users/yang-ext:mount/test-interface2:class");
     }
 
-    public void initMountService(boolean withSchema) {
+    public void initMountService(final boolean withSchema) {
         MountService mountService = mock(MountService.class);
         controllerContext.setMountService(mountService);
         BrokerFacade brokerFacade = mock(BrokerFacade.class);
@@ -163,10 +163,11 @@ public class URITest {
         Set<Module> modules2 = TestUtils.loadModulesFrom("/test-config-data/yang2");
         SchemaContext schemaContext2 = TestUtils.loadSchemaContext(modules2);
         MountInstance mountInstance = mock(MountInstance.class);
-        if (withSchema)
+        if (withSchema) {
             when(mountInstance.getSchemaContext()).thenReturn(schemaContext2);
-        else
+        } else {
             when(mountInstance.getSchemaContext()).thenReturn(null);
-        when(mountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
+        }
+        when(mountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
     }
 }
index 5476d71320e9ae7a3a0fce6a9ec87f8dfe80088f..f4e869f99f49ebf42e482ca0c67f88dff0a6c285 100644 (file)
@@ -15,19 +15,17 @@ import java.io.IOException;
 import java.net.URISyntaxException;
 import java.util.List;
 import java.util.Map;
-
 import javax.ws.rs.WebApplicationException;
-
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.yangtools.yang.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.InstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 
 public class XmlAndJsonToCnSnInstanceIdentifierTest extends YangAndXmlAndDataSchemaLoader {
@@ -72,9 +70,9 @@ public class XmlAndJsonToCnSnInstanceIdentifierTest extends YangAndXmlAndDataSch
     private void verifyLeafListPredicate(CompositeNode cnSn) throws URISyntaxException {
         SimpleNode<?> lf11 = getSnWithInstanceIdentifierWhenLeafList(cnSn);
         Object value = lf11.getValue();
-        assertTrue(value instanceof InstanceIdentifier);
+        assertTrue(value instanceof YangInstanceIdentifier);
 
-        InstanceIdentifier instanceIdentifier = (InstanceIdentifier) value;
+        YangInstanceIdentifier instanceIdentifier = (YangInstanceIdentifier) value;
         List<PathArgument> pathArguments = instanceIdentifier.getPath();
         assertEquals(3, pathArguments.size());
         String revisionDate = "2014-01-17";
@@ -93,9 +91,9 @@ public class XmlAndJsonToCnSnInstanceIdentifierTest extends YangAndXmlAndDataSch
     private void verifyListPredicate(CompositeNode cnSn) throws URISyntaxException {
         SimpleNode<?> lf111 = getSnWithInstanceIdentifierWhenList(cnSn);
         Object value = lf111.getValue();
-        assertTrue(value instanceof InstanceIdentifier);
+        assertTrue(value instanceof YangInstanceIdentifier);
 
-        InstanceIdentifier instanceIdentifier = (InstanceIdentifier) value;
+        YangInstanceIdentifier instanceIdentifier = (YangInstanceIdentifier) value;
         List<PathArgument> pathArguments = instanceIdentifier.getPath();
         assertEquals(4, pathArguments.size());
         String revisionDate = "2014-01-17";
index e5a737e6d5d868be87fad55215d9be8b952bd0fd..483d90da0d220fc1054929d01008afabb5871175 100644 (file)
@@ -11,9 +11,7 @@ import static org.junit.Assert.assertEquals;
 
 import java.io.IOException;
 import java.net.URISyntaxException;
-
 import javax.ws.rs.WebApplicationException;
-
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
index d5759bedb11342ae08eb5bb057ab13ee0a84813f..efcc3743c6938907e25d8dbd6af9e500e3549780 100644 (file)
@@ -11,7 +11,6 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
 import java.util.Set;
-
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 
index 3617ed9fb0d897adaf654ed96f0f98967811d7d2..ae07571ad93efc192cb0c395420048e8a437631e 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.sal.restconf.impl.test.structures;
 
 import static org.junit.Assert.assertFalse;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -57,14 +58,12 @@ public class LstItem {
     }
 
     public void addLfLst(LfLst lfLst) {
-        assertFalse( "Found multiple leaf list elements for " + lfLst.getName(),
-                    lfLsts.containsKey( lfLst.getName() ) );
+        assertFalse("Found multiple leaf list elements for " + lfLst.getName(), lfLsts.containsKey(lfLst.getName()));
         lfLsts.put(lfLst.getName(), lfLst);
     }
 
     public void addLst(Lst lst) {
-        assertFalse( "Found multiple list elements for " + lst.getName(),
-                     lsts.containsKey( lst.getName() ) );
+        assertFalse("Found multiple list elements for " + lst.getName(), lsts.containsKey(lst.getName()));
         lsts.put(lst.getName(), lst);
     }
 
index 845d54ea1f568388ff6c7ba1400f0e76cac9ccf5..664aad6578c84fab98a3e569d00fa93dd3a1ee8d 100644 (file)
@@ -23,15 +23,13 @@ import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
 import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
 import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
 import io.netty.handler.codec.http.websocketx.WebSocketVersion;
-
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
 import java.net.URI;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class WebSocketClient  {
+public class WebSocketClient {
 
     private final URI uri;
     private Bootstrap bootstrap = new Bootstrap();;
@@ -40,51 +38,57 @@ public class WebSocketClient  {
     private Channel clientChannel;
     private final EventLoopGroup group = new NioEventLoopGroup();
 
-    public WebSocketClient(URI uri,IClientMessageCallback clientMessageCallback) {
+    public WebSocketClient(URI uri, IClientMessageCallback clientMessageCallback) {
         this.uri = uri;
-        clientHandler = new WebSocketClientHandler(
-                WebSocketClientHandshakerFactory.newHandshaker(
-                        uri, WebSocketVersion.V13, null, false,null),clientMessageCallback); // last null could be replaced with DefaultHttpHeaders
+        clientHandler = new WebSocketClientHandler(WebSocketClientHandshakerFactory.newHandshaker(uri,
+                WebSocketVersion.V13, null, false, null), clientMessageCallback); // last
+                                                                                  // null
+                                                                                  // could
+                                                                                  // be
+                                                                                  // replaced
+                                                                                  // with
+                                                                                  // DefaultHttpHeaders
         initialize();
     }
-    private void initialize(){
+
+    private void initialize() {
 
         String protocol = uri.getScheme();
         if (!"http".equals(protocol)) {
             throw new IllegalArgumentException("Unsupported protocol: " + protocol);
         }
 
-        bootstrap.group(group)
-                .channel(NioSocketChannel.class)
-                .handler(new ChannelInitializer<SocketChannel>() {
-                    @Override
-                    public void initChannel(SocketChannel ch) throws Exception {
-                        ChannelPipeline pipeline = ch.pipeline();
-                        pipeline.addLast("http-codec", new HttpClientCodec());
-                        pipeline.addLast("aggregator", new HttpObjectAggregator(8192));
-                        pipeline.addLast("ws-handler", clientHandler);
-                    }
-                });
+        bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {
+            @Override
+            public void initChannel(SocketChannel ch) throws Exception {
+                ChannelPipeline pipeline = ch.pipeline();
+                pipeline.addLast("http-codec", new HttpClientCodec());
+                pipeline.addLast("aggregator", new HttpObjectAggregator(8192));
+                pipeline.addLast("ws-handler", clientHandler);
+            }
+        });
     }
-    public void connect() throws InterruptedException{
+
+    public void connect() throws InterruptedException {
         System.out.println("WebSocket Client connecting");
-        clientChannel  = bootstrap.connect(uri.getHost(), uri.getPort()).sync().channel();
+        clientChannel = bootstrap.connect(uri.getHost(), uri.getPort()).sync().channel();
         clientHandler.handshakeFuture().sync();
     }
 
-    public void writeAndFlush(String message){
+    public void writeAndFlush(String message) {
         clientChannel.writeAndFlush(new TextWebSocketFrame(message));
     }
-    public void writeAndFlush(Object message){
+
+    public void writeAndFlush(Object message) {
         clientChannel.writeAndFlush(message);
     }
 
-    public void ping(){
-        clientChannel.writeAndFlush(new PingWebSocketFrame(Unpooled.copiedBuffer(new byte[]{1, 2, 3, 4, 5, 6})));
+    public void ping() {
+        clientChannel.writeAndFlush(new PingWebSocketFrame(Unpooled.copiedBuffer(new byte[] { 1, 2, 3, 4, 5, 6 })));
     }
 
     public void close(String reasonText) throws InterruptedException {
-        CloseWebSocketFrame closeWebSocketFrame = new CloseWebSocketFrame(1000,reasonText);
+        CloseWebSocketFrame closeWebSocketFrame = new CloseWebSocketFrame(1000, reasonText);
         clientChannel.writeAndFlush(closeWebSocketFrame);
 
         // WebSocketClientHandler will close the connection when the server
@@ -122,7 +126,7 @@ public class WebSocketClient  {
         @Override
         public void onMessageReceived(Object message) {
             if (message instanceof TextWebSocketFrame) {
-                logger.info("received message {}"+ ((TextWebSocketFrame)message).text());
+                logger.info("received message {}" + ((TextWebSocketFrame) message).text());
             }
         }
     }
index 0a16e254ccc6cd6c1a2f838cb04917477ce7869d..e07d8c48f0f2c9ba253a1282f4bf0e453ae19e3f 100644 (file)
@@ -18,7 +18,6 @@ import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
 import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
 import io.netty.handler.codec.http.websocketx.WebSocketFrame;
 import io.netty.util.CharsetUtil;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -29,8 +28,7 @@ public class WebSocketClientHandler extends SimpleChannelInboundHandler<Object>
     private ChannelPromise handshakeFuture;
     private final IClientMessageCallback messageListener;
 
-
-    public WebSocketClientHandler(WebSocketClientHandshaker handshaker,IClientMessageCallback listener) {
+    public WebSocketClientHandler(WebSocketClientHandshaker handshaker, IClientMessageCallback listener) {
         this.handshaker = handshaker;
         this.messageListener = listener;
     }
@@ -92,4 +90,3 @@ public class WebSocketClientHandler extends SimpleChannelInboundHandler<Object>
         ctx.close();
     }
 }
-
index d9ef2ef243986bb63960f8212f4ab2bbf81346f6..70f0f050dc9fdea84f186537eafbcad6779d7e53 100644 (file)
@@ -15,12 +15,10 @@ import static org.mockito.Mockito.mock;
 import java.io.FileNotFoundException;
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
-
 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;
@@ -55,10 +53,10 @@ public class RestStream extends JerseyTest {
     @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());
+        // 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,
@@ -72,13 +70,15 @@ public class RestStream extends JerseyTest {
         Response responseWithStreamName = post(uri, MediaType.APPLICATION_XML, getRpcInput());
         String xmlResponse = responseWithStreamName.readEntity(String.class);
         assertNotNull(xmlResponse);
-        assertTrue(xmlResponse.contains("<stream-name>ietf-interfaces:interfaces/ietf-interfaces:interface/eth0</stream-name>"));
+        assertTrue(xmlResponse
+                .contains("<stream-name>ietf-interfaces:interfaces/ietf-interfaces:interface/eth0</stream-name>"));
 
         uri = "/streams/stream/ietf-interfaces:interfaces/ietf-interfaces:interface/eth0";
         Response responseWithRedirectionUri = get(uri, MediaType.APPLICATION_XML);
         final URI websocketServerUri = responseWithRedirectionUri.getLocation();
         assertNotNull(websocketServerUri);
-        assertEquals(websocketServerUri.toString(), "http://localhost:8181/ietf-interfaces:interfaces/ietf-interfaces:interface/eth0");
+        assertEquals(websocketServerUri.toString(),
+                "http://localhost:8181/ietf-interfaces:interfaces/ietf-interfaces:interface/eth0");
     }
 
     private Response post(String uri, String mediaType, String data) {
index 62159ccad6c0edf76e4e8ac75282935e80c06450..5a5a621d930b68fc240140f76b086a0d57bc0a3c 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test;
 import static org.junit.Assert.assertNotNull;
 
 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;
@@ -21,13 +20,12 @@ public class XmlAugmentedElementToCnSnTest {
 
     @Test
     public void loadDataAugmentedSchemaMoreEqualNamesTest() {
-        loadAndNormalizeData("/common/augment/xml/dataa.xml", "/common/augment/yang", "main","cont");
-        loadAndNormalizeData("/common/augment/xml/datab.xml", "/common/augment/yang", "main","cont");
+        loadAndNormalizeData("/common/augment/xml/dataa.xml", "/common/augment/yang", "main", "cont");
+        loadAndNormalizeData("/common/augment/xml/datab.xml", "/common/augment/yang", "main", "cont");
     }
 
     private void loadAndNormalizeData(String xmlPath, String yangPath, String topLevelElementName, String moduleName) {
-        CompositeNode compNode = TestUtils.readInputToCnSn(xmlPath, false,
-                XmlToCompositeNodeProvider.INSTANCE);
+        CompositeNode compNode = TestUtils.readInputToCnSn(xmlPath, false, XmlToCompositeNodeProvider.INSTANCE);
         assertNotNull(compNode);
         Set<Module> modules = TestUtils.loadModulesFrom(yangPath);
 
@@ -35,5 +33,4 @@ public class XmlAugmentedElementToCnSnTest {
         TestUtils.normalizeCompositeNode(compNode, modules, topLevelElementName + ":" + moduleName);
     }
 
-
 }
index e5b0bf507d03212bf2efedaaa18cc2f28f734567..6c11bc1861995879818ce31b3d6d75696c2decf7 100644 (file)
@@ -13,7 +13,6 @@ import static org.junit.Assert.assertTrue;
 
 import java.util.List;
 import java.util.Set;
-
 import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
@@ -30,8 +29,7 @@ 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.
+     * top level element represents container. second level element is list with two elements.
      */
     @Test
     public void testXmlDataContainer() {
@@ -202,8 +200,7 @@ public class XmlLeafrefToCnSnTest {
 
     /**
      *
-     * Test case like <lf11 xmlns="namespace1"
-     * xmlns:x="namespace">identity</lf11>
+     * Test case like <lf11 xmlns="namespace1" xmlns:x="namespace">identity</lf11>
      */
 
     @Test
@@ -214,8 +211,7 @@ public class XmlLeafrefToCnSnTest {
 
     /**
      *
-     * Test case like <cont1 xmlns="namespace1"> <lf11
-     * xmlns:x="namespace">identity</lf11> </cont1>
+     * Test case like <cont1 xmlns="namespace1"> <lf11 xmlns:x="namespace">identity</lf11> </cont1>
      */
     @Test
     public void testIdentityrefDefaultNmspcInParrentElement() {
@@ -225,8 +221,7 @@ public class XmlLeafrefToCnSnTest {
 
     /**
      *
-     * Test case like <cont1 xmlns="namespace1" xmlns:x="namespace">
-     * <lf11>x:identity</lf11> </cont1>
+     * Test case like <cont1 xmlns="namespace1" xmlns:x="namespace"> <lf11>x:identity</lf11> </cont1>
      */
     @Ignore
     @Test
@@ -237,8 +232,7 @@ public class XmlLeafrefToCnSnTest {
 
     /**
      *
-     * Test case like (without namespace in xml) <cont1> <lf11>x:identity</lf11>
-     * </cont1>
+     * Test case like (without namespace in xml) <cont1> <lf11>x:identity</lf11> </cont1>
      */
     @Test
     public void testIdentityrefNoNmspcValueWithPrefix() {
@@ -248,8 +242,7 @@ public class XmlLeafrefToCnSnTest {
 
     /**
      *
-     * Test case like (without namespace in xml) <cont1> <lf11>identity</lf11>
-     * </cont1>
+     * Test case like (without namespace in xml) <cont1> <lf11>identity</lf11> </cont1>
      */
     @Test
     public void testIdentityrefNoNmspcValueWithoutPrefix() {
@@ -322,8 +315,8 @@ public class XmlLeafrefToCnSnTest {
         assertEquals((short) 100, cont1_lf11.getValue());
     }
 
-    private void testIdentityrefToCnSn(final String xmlPath, final String yangPath, final String moduleName, final String schemaName,
-            final int moduleCount, final String resultLocalName, final String resultNamespace) {
+    private void testIdentityrefToCnSn(final String xmlPath, final String yangPath, final String moduleName,
+            final String schemaName, final int moduleCount, final String resultLocalName, final String resultNamespace) {
         CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlPath, false, XmlToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
 
index 5cda4a7f52014dc4a9ab3572d9073877ec12e74e..e2621d635bc3dab04629beffcb15c3d111b9eb21 100644 (file)
@@ -14,7 +14,6 @@ import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
-
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
@@ -57,26 +56,26 @@ public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader {
     }
 
     @Test
-    public void testXmlBlankInput() throws Exception{
-        InputStream inputStream = new ByteArrayInputStream( "".getBytes() );
-        CompositeNode compositeNode =
-                XmlToCompositeNodeProvider.INSTANCE.readFrom(null, null, null, null, null, inputStream);
+    public void testXmlBlankInput() throws Exception {
+        InputStream inputStream = new ByteArrayInputStream("".getBytes());
+        CompositeNode compositeNode = XmlToCompositeNodeProvider.INSTANCE.readFrom(null, null, null, null, null,
+                inputStream);
 
-        assertNull( compositeNode );
+        assertNull(compositeNode);
     }
 
     @Test
-    public void testXmlBlankInputUnmarkableStream() throws Exception{
-        InputStream inputStream = new ByteArrayInputStream( "".getBytes() ){
+    public void testXmlBlankInputUnmarkableStream() throws Exception {
+        InputStream inputStream = new ByteArrayInputStream("".getBytes()) {
             @Override
             public boolean markSupported() {
                 return false;
             }
         };
-        CompositeNode compositeNode =
-                XmlToCompositeNodeProvider.INSTANCE.readFrom(null, null, null, null, null, inputStream);
+        CompositeNode compositeNode = XmlToCompositeNodeProvider.INSTANCE.readFrom(null, null, null, null, null,
+                inputStream);
 
-        assertNull( compositeNode );
+        assertNull(compositeNode);
     }
 
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/equal-data-node-names/equal-name-data-for-container.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/equal-data-node-names/equal-name-data-for-container.json
new file mode 100644 (file)
index 0000000..78b097d
--- /dev/null
@@ -0,0 +1,16 @@
+{
+    "cont":{
+        "cont1":[
+            {
+                "lst11":{
+                    "lf111":"value1"
+                }
+            },
+            {
+                "lst11":{
+                    "lf111":"value2"
+                }
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/equal-data-node-names/equal-name-data-for-container.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/equal-data-node-names/equal-name-data-for-container.xml
new file mode 100644 (file)
index 0000000..26a1f5f
--- /dev/null
@@ -0,0 +1,12 @@
+<cont>
+    <cont1>
+        <lst11>
+            <lf111>value1</lf111>
+        </lst11>
+    </cont1>
+    <cont1>
+        <lst11>
+            <lf111>value1</lf111>
+        </lst11>
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/equal-data-node-names/equal-name-data-for-leaf.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/equal-data-node-names/equal-name-data-for-leaf.json
new file mode 100644 (file)
index 0000000..d0a9fd4
--- /dev/null
@@ -0,0 +1,15 @@
+{
+    "cont":{
+        "cont1":{
+            "lst11":[
+             {
+                "lf111":"value1",
+                "lf111":"value2"
+             },
+             {
+                "lf111":"value3"
+             }
+             ]
+         }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/equal-data-node-names/equal-name-data-for-leaf.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/equal-data-node-names/equal-name-data-for-leaf.xml
new file mode 100644 (file)
index 0000000..4221c2d
--- /dev/null
@@ -0,0 +1,11 @@
+<cont>
+    <cont1>
+        <lst11>
+          <lf111>value1</lf111>,
+          <lf111>value2</lf111>,
+        </lst11>
+        <lst11>
+          <lf111>value3</lf111>,
+        </lst11>
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/equal-data-node-names/yang/equal-data-node-names.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/equal-data-node-names/yang/equal-data-node-names.yang
new file mode 100644 (file)
index 0000000..3a3653a
--- /dev/null
@@ -0,0 +1,18 @@
+/* bug 1204 */
+module equal-data-node-names {
+  namespace "ns:equal:data:node:names";
+
+  prefix "eqdanona";
+  revision 2014-06-26 {
+  }
+
+  container cont {
+    container cont1 {
+        list lst11 {
+            leaf lf111 {
+                type string;
+            }
+        }
+    }
+  }
+}
\ No newline at end of file
index 2e533e720e0760f6abca5b84663c52ce170a4899..baf7d1e9ae7a9f61ccdf8b33cdefe728e4c16cee 100644 (file)
@@ -4,7 +4,7 @@ module test-module {
 
   revision 2014-01-09 {
   }
-  
+
   container interfaces {
     container class {
         leaf name {
@@ -18,7 +18,7 @@ module test-module {
         }
     }
   }
-  
+
   container cont {
     container cont1 {
         leaf lf11 {
@@ -34,9 +34,18 @@ module test-module {
             type string;
         }
     }
-  }   
-  
+  }
   
+  list lst-with-composite-key {
+    key "key1 key2";
+    leaf key1 {
+        type string;
+    }
+    leaf key2 {
+        type uint8;
+    }
+  }
+
   rpc rpc-test {
     input {
       container cont {
@@ -48,16 +57,11 @@ module test-module {
                 type string;
             }
         }
-      }    
+      }
     }
     output {
         container cont-output {
         }
-    } 
-  
+    }
   }
-  
-  
-
 }
\ No newline at end of file
index ba06645354fb67ec215db9c67914a9367a7be43c..208c2164d506530f00b0cfd0a000325da447390e 100644 (file)
@@ -16,5 +16,8 @@ module invoke-rpc-module {
         }
     }
   }  
-  
+
+  rpc rpc-noop {
+  }
+
 }
\ No newline at end of file
index 10d964d6449595e13971a80428046ac6508871a2..b886fc9da9621459dc12531c22ea1d6ac9d360e2 100644 (file)
@@ -1,5 +1,5 @@
 {
-       "cont": {       
-               "lf":                           
-       }
+    "cont": {
+        "lf":
+    }
 }
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/multiple-nodes/multiple-nodes.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/multiple-nodes/multiple-nodes.yang
new file mode 100644 (file)
index 0000000..22a1dae
--- /dev/null
@@ -0,0 +1,17 @@
+module multiple-nodes {
+    namespace "multiple:nodes";
+    prefix "mod1";
+    revision "2014-06-23";
+
+    container cont {
+        container cont1 {
+            leaf lf11 {
+                type string;
+            }
+        }
+
+        leaf lf1 {
+            type string;
+        }
+    }
+}
\ No newline at end of file
index 31f4253318f146e95c2a0923f3f08d3e14cc4a2d..9a1816b90e88f333417a6c62d335c67b7f04739f 100644 (file)
@@ -16,7 +16,7 @@ import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionListener;
 import org.opendaylight.controller.sal.rest.doc.impl.ApiDocGenerator;
 import org.opendaylight.controller.sal.rest.doc.mountpoints.MountPointSwagger;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
index 68d31de8da35688737e927689d5f55a9085de2e9..5ba8b26bc1eb6bb69ac0d5e3564dbbfe5f8c27cf 100644 (file)
@@ -14,6 +14,7 @@ import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
@@ -161,7 +162,7 @@ public class BaseYangSwaggerGenerator {
 
         List<Api> apis = new ArrayList<Api>();
 
-        Set<DataSchemaNode> dataSchemaNodes = m.getChildNodes();
+        Collection<DataSchemaNode> dataSchemaNodes = m.getChildNodes();
         _logger.debug("child nodes size [{}]", dataSchemaNodes.size());
         for (DataSchemaNode node : dataSchemaNodes) {
             if ((node instanceof ListSchemaNode) || (node instanceof ContainerSchemaNode)) {
@@ -240,9 +241,8 @@ public class BaseYangSwaggerGenerator {
         apis.add(api);
         if ((node instanceof ListSchemaNode) || (node instanceof ContainerSchemaNode)) {
             DataNodeContainer schemaNode = (DataNodeContainer) node;
-            Set<DataSchemaNode> dataSchemaNodes = schemaNode.getChildNodes();
 
-            for (DataSchemaNode childNode : dataSchemaNodes) {
+            for (DataSchemaNode childNode : schemaNode.getChildNodes()) {
                 // We don't support going to leaf nodes today. Only lists and
                 // containers.
                 if (childNode instanceof ListSchemaNode || childNode instanceof ContainerSchemaNode) {
index 0e929afc8461c5da04bafa6dc44e7c782f83417d..95bb1a094371db4f17d38c310c0043b07006c5c3 100644 (file)
@@ -14,7 +14,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
+import org.apache.commons.lang3.BooleanUtils;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -25,6 +25,7 @@ import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
@@ -85,6 +86,8 @@ public class ModelGenerator {
     private static final String NUMBER = "number";
     private static final String BOOLEAN = "boolean";
     private static final String STRING = "string";
+  private static final String ID_KEY = "id";
+  private static final String SUB_TYPES_KEY = "subTypes";
 
     private static final Map<Class<? extends TypeDefinition<?>>, String> YANG_TYPE_TO_JSON_TYPE_MAPPING;
 
@@ -115,6 +118,7 @@ public class ModelGenerator {
         JSONObject models = new JSONObject();
         processContainers(module, models);
         processRPCs(module, models);
+    processIdentities(module, models);
         return models;
     }
 
@@ -122,9 +126,8 @@ public class ModelGenerator {
             JSONException {
 
         String moduleName = module.getName();
-        Set<DataSchemaNode> childNodes = module.getChildNodes();
 
-        for (DataSchemaNode childNode : childNodes) {
+        for (DataSchemaNode childNode : module.getChildNodes()) {
             JSONObject configModuleJSON = null;
             JSONObject operationalModuleJSON = null;
 
@@ -187,6 +190,58 @@ public class ModelGenerator {
         }
     }
 
+  /**
+   * Processes the 'identity' statement in a yang model
+   * and maps it to a 'model' in the Swagger JSON spec.
+   *
+   * @param module The module from which the identity stmt will be processed
+   * @param models The JSONObject in which the parsed identity will be put as a 'model' obj
+   * @throws JSONException
+   */
+  private void processIdentities(Module module, JSONObject models) throws JSONException {
+
+    String moduleName = module.getName();
+    Set<IdentitySchemaNode> idNodes =  module.getIdentities();
+    _logger.debug("Processing Identities for module {} . Found {} identity statements", moduleName, idNodes.size());
+
+    for(IdentitySchemaNode idNode : idNodes){
+      JSONObject identityObj=new JSONObject();
+      String identityName = idNode.getQName().getLocalName();
+      _logger.debug("Processing Identity: {}", identityName);
+
+      identityObj.put(ID_KEY, identityName);
+      identityObj.put(DESCRIPTION_KEY, idNode.getDescription());
+
+      JSONObject props = new JSONObject();
+      IdentitySchemaNode baseId = idNode.getBaseIdentity();
+
+
+      if(baseId==null) {
+        /**
+         * This is a base identity. So lets see if
+         * it has sub types. If it does, then add them to the model definition.
+         */
+        Set<IdentitySchemaNode> derivedIds = idNode.getDerivedIdentities();
+
+        if(derivedIds != null) {
+          JSONArray subTypes = new JSONArray();
+          for(IdentitySchemaNode derivedId : derivedIds){
+            subTypes.put(derivedId.getQName().getLocalName());
+          }
+          identityObj.put(SUB_TYPES_KEY, subTypes);
+        }
+      } else {
+        /**
+         * This is a derived entity. Add it's base type & move on.
+         */
+        props.put(TYPE_KEY, baseId.getQName().getLocalName());
+      }
+
+      //Add the properties. For a base type, this will be an empty object as required by the Swagger spec.
+      identityObj.put(PROPERTIES_KEY, props);
+      models.put(identityName, identityObj);
+    }
+  }
     /**
      * Processes the container node and populates the moduleJSON
      *
@@ -215,13 +270,12 @@ public class ModelGenerator {
         String containerDescription = container.getDescription();
         moduleJSON.put(DESCRIPTION_KEY, containerDescription);
 
-        Set<DataSchemaNode> containerChildren = container.getChildNodes();
-        JSONObject properties = processChildren(containerChildren, moduleName, models, isConfig);
+        JSONObject properties = processChildren(container.getChildNodes(), moduleName, models, isConfig);
         moduleJSON.put(PROPERTIES_KEY, properties);
         return moduleJSON;
     }
 
-    private JSONObject processChildren(Set<DataSchemaNode> nodes, String moduleName,
+    private JSONObject processChildren(Iterable<DataSchemaNode> nodes, String moduleName,
             JSONObject models) throws JSONException, IOException {
         return processChildren(nodes, moduleName, models, null);
     }
@@ -236,7 +290,7 @@ public class ModelGenerator {
      * @throws JSONException
      * @throws IOException
      */
-    private JSONObject processChildren(Set<DataSchemaNode> nodes, String moduleName,
+    private JSONObject processChildren(Iterable<DataSchemaNode> nodes, String moduleName,
             JSONObject models, Boolean isConfig) throws JSONException, IOException {
 
         JSONObject properties = new JSONObject();
@@ -249,7 +303,7 @@ public class ModelGenerator {
                 if (node instanceof LeafSchemaNode) {
                     property = processLeafNode((LeafSchemaNode) node);
                 } else if (node instanceof ListSchemaNode) {
-                    property = processListSchemaNode((ListSchemaNode) node, moduleName, models);
+                    property = processListSchemaNode((ListSchemaNode) node, moduleName, models, isConfig);
 
                 } else if (node instanceof LeafListSchemaNode) {
                     property = processLeafListNode((LeafListSchemaNode) node);
@@ -354,17 +408,18 @@ public class ModelGenerator {
      *
      * @param listNode
      * @param moduleName
+     * @param isConfig
      * @return
      * @throws JSONException
      * @throws IOException
      */
     private JSONObject processListSchemaNode(ListSchemaNode listNode, String moduleName,
-            JSONObject models) throws JSONException, IOException {
+            JSONObject models, Boolean isConfig) throws JSONException, IOException {
 
-        Set<DataSchemaNode> listChildren = listNode.getChildNodes();
-        String fileName = listNode.getQName().getLocalName();
+        String fileName = (BooleanUtils.isNotFalse(isConfig)?OperationBuilder.CONFIG:OperationBuilder.OPERATIONAL) +
+                                                                listNode.getQName().getLocalName();
 
-        JSONObject childSchemaProperties = processChildren(listChildren, moduleName, models);
+        JSONObject childSchemaProperties = processChildren(listNode.getChildNodes(), moduleName, models);
         JSONObject childSchema = getSchemaTemplate();
         childSchema.put(TYPE_KEY, OBJECT_TYPE);
         childSchema.put(PROPERTIES_KEY, childSchemaProperties);
@@ -443,7 +498,7 @@ public class ModelGenerator {
             processUnionType((UnionTypeDefinition) leafTypeDef, property);
 
         } else if (leafTypeDef instanceof IdentityrefTypeDefinition) {
-            property.putOpt(TYPE_KEY, "object");
+      property.putOpt(TYPE_KEY, ((IdentityrefTypeDefinition) leafTypeDef).getIdentity().getQName().getLocalName());
         } else if (leafTypeDef instanceof BinaryTypeDefinition) {
             processBinaryType((BinaryTypeDefinition) leafTypeDef, property);
         } else {
@@ -541,12 +596,15 @@ public class ModelGenerator {
     private void processUnionType(UnionTypeDefinition unionType, JSONObject property)
             throws JSONException {
 
-        List<TypeDefinition<?>> unionTypes = unionType.getTypes();
-        JSONArray unionArray = new JSONArray();
-        for (TypeDefinition<?> typeDef : unionTypes) {
-            unionArray.put(YANG_TYPE_TO_JSON_TYPE_MAPPING.get(typeDef.getClass()));
+        StringBuilder type = new StringBuilder();
+        for (TypeDefinition<?> typeDef : unionType.getTypes() ) {
+            if( type.length() > 0 ){
+                type.append( " or " );
+            }
+            type.append(YANG_TYPE_TO_JSON_TYPE_MAPPING.get(typeDef.getClass()));
         }
-        property.put(TYPE_KEY, unionArray);
+
+        property.put(TYPE_KEY, type );
     }
 
     /**
index b996bf12348ccc89088b1426c269049a9cf98928..29ada12c6f8737a3d61fc5e68abde7cece17fad1 100644 (file)
@@ -23,7 +23,7 @@ import javax.ws.rs.core.UriInfo;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 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.controller.sal.core.api.mount.MountProvisionListener;
 import org.opendaylight.controller.sal.rest.doc.impl.BaseYangSwaggerGenerator;
 import org.opendaylight.controller.sal.rest.doc.swagger.Api;
 import org.opendaylight.controller.sal.rest.doc.swagger.ApiDeclaration;
@@ -31,9 +31,9 @@ import org.opendaylight.controller.sal.rest.doc.swagger.Operation;
 import org.opendaylight.controller.sal.rest.doc.swagger.Resource;
 import org.opendaylight.controller.sal.rest.doc.swagger.ResourceList;
 import org.opendaylight.yangtools.yang.common.QName;
-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.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
@@ -43,14 +43,14 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
     private static final String DATASTORES_LABEL = "Datastores";
 
     private MountProvisionService mountService;
-    private final Map<InstanceIdentifier, Long> instanceIdToLongId = new TreeMap<>(
-            new Comparator<InstanceIdentifier>() {
+    private final Map<YangInstanceIdentifier, Long> instanceIdToLongId = new TreeMap<>(
+            new Comparator<YangInstanceIdentifier>() {
                 @Override
-                public int compare(InstanceIdentifier o1, InstanceIdentifier o2) {
+                public int compare(final YangInstanceIdentifier o1, final YangInstanceIdentifier o2) {
                     return o1.toString().compareToIgnoreCase(o2.toString());
                 }
             });
-    private final Map<Long, InstanceIdentifier> longIdToInstanceId = new HashMap<>();
+    private final Map<Long, YangInstanceIdentifier> longIdToInstanceId = new HashMap<>();
     private final Object lock = new Object();
 
     private final AtomicLong idKey = new AtomicLong(0);
@@ -62,7 +62,7 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
         Map<String, Long> urlToId = new HashMap<>();
         synchronized (lock) {
             SchemaContext context = globalSchema.getGlobalContext();
-            for (Entry<InstanceIdentifier, Long> entry : instanceIdToLongId.entrySet()) {
+            for (Entry<YangInstanceIdentifier, Long> entry : instanceIdToLongId.entrySet()) {
                 String modName = findModuleName(entry.getKey(), context);
                 urlToId.put(generateUrlPrefixFromInstanceID(entry.getKey(), modName),
                         entry.getValue());
@@ -71,12 +71,12 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
         return urlToId;
     }
 
-    public void setGlobalSchema(SchemaService globalSchema) {
+    public void setGlobalSchema(final SchemaService globalSchema) {
         this.globalSchema = globalSchema;
     }
 
-    private String findModuleName(InstanceIdentifier id, SchemaContext context) {
-        PathArgument rootQName = id.getPath().get(0);
+    private String findModuleName(final YangInstanceIdentifier id, final SchemaContext context) {
+        PathArgument rootQName = id.getPathArguments().iterator().next();
         for (Module mod : context.getModules()) {
             if (mod.getDataChildByName(rootQName.getNodeType()) != null) {
                 return mod.getName();
@@ -85,41 +85,40 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
         return null;
     }
 
-    private String generateUrlPrefixFromInstanceID(InstanceIdentifier key, String moduleName) {
-        List<PathArgument> path = key.getPath();
+    private String generateUrlPrefixFromInstanceID(final YangInstanceIdentifier key, final String moduleName) {
         StringBuilder builder = new StringBuilder();
         if (moduleName != null) {
             builder.append(moduleName);
-            builder.append(":");
+            builder.append(':');
         }
         boolean first = true;
-        for (PathArgument arg : path) {
+        for (PathArgument arg : key.getPathArguments()) {
 
             String name = arg.getNodeType().getLocalName();
             if (first) {
                 first = false;
             } else {
-                builder.append("/");
+                builder.append('/');
             }
             builder.append(name);
-            if (arg instanceof InstanceIdentifier.NodeIdentifierWithPredicates) {
+            if (arg instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) {
                 NodeIdentifierWithPredicates nodeId = (NodeIdentifierWithPredicates) arg;
                 for (Entry<QName, Object> entry : nodeId.getKeyValues().entrySet()) {
-                    builder.append("/").append(entry.getValue());
+                    builder.append('/').append(entry.getValue());
                 }
             }
         }
 
-        return builder.append("/").toString();
+        return builder.append('/').toString();
     }
 
-    private String getYangMountUrl(InstanceIdentifier key) {
+    private String getYangMountUrl(final YangInstanceIdentifier key) {
         String modName = findModuleName(key, globalSchema.getGlobalContext());
         return generateUrlPrefixFromInstanceID(key, modName) + "yang-ext:mount/";
     }
 
-    public ResourceList getResourceList(UriInfo uriInfo, Long id) {
-        InstanceIdentifier iid = getInstanceId(id);
+    public ResourceList getResourceList(final UriInfo uriInfo, final Long id) {
+        YangInstanceIdentifier iid = getInstanceId(id);
         if (iid == null) {
             return null; // indicating not found.
         }
@@ -139,15 +138,15 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
         return list;
     }
 
-    private InstanceIdentifier getInstanceId(Long id) {
-        InstanceIdentifier instanceId;
+    private YangInstanceIdentifier getInstanceId(final Long id) {
+        YangInstanceIdentifier instanceId;
         synchronized (lock) {
             instanceId = longIdToInstanceId.get(id);
         }
         return instanceId;
     }
 
-    private SchemaContext getSchemaContext(InstanceIdentifier id) {
+    private SchemaContext getSchemaContext(final YangInstanceIdentifier id) {
 
         if (id == null) {
             return null;
@@ -165,8 +164,8 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
         return context;
     }
 
-    public ApiDeclaration getMountPointApi(UriInfo uriInfo, Long id, String module, String revision) {
-        InstanceIdentifier iid = getInstanceId(id);
+    public ApiDeclaration getMountPointApi(final UriInfo uriInfo, final Long id, final String module, final String revision) {
+        YangInstanceIdentifier iid = getInstanceId(id);
         SchemaContext context = getSchemaContext(iid);
         String urlPrefix = getYangMountUrl(iid);
         if (context == null) {
@@ -179,7 +178,7 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
         return super.getApiDeclaration(module, revision, uriInfo, context, urlPrefix);
     }
 
-    private ApiDeclaration generateDataStoreApiDoc(UriInfo uriInfo, String context) {
+    private ApiDeclaration generateDataStoreApiDoc(final UriInfo uriInfo, final String context) {
 
         ApiDeclaration declaration = super.createApiDeclaration(createBasePathFromUriInfo(uriInfo));
         List<Api> apis = new LinkedList<>();
@@ -194,7 +193,7 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
 
     }
 
-    private Api createGetApi(String datastore, String note, String context) {
+    private Api createGetApi(final String datastore, final String note, final String context) {
         Operation getConfig = new Operation();
         getConfig.setMethod("GET");
         getConfig.setNickname("GET " + datastore);
@@ -207,12 +206,12 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
         return api;
     }
 
-    public void setMountService(MountProvisionService mountService) {
+    public void setMountService(final MountProvisionService mountService) {
         this.mountService = mountService;
     }
 
     @Override
-    public void onMountPointCreated(InstanceIdentifier path) {
+    public void onMountPointCreated(final YangInstanceIdentifier path) {
         synchronized (lock) {
             Long idLong = idKey.incrementAndGet();
             instanceIdToLongId.put(path, idLong);
@@ -221,7 +220,7 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
     }
 
     @Override
-    public void onMountPointRemoved(InstanceIdentifier path) {
+    public void onMountPointRemoved(final YangInstanceIdentifier path) {
         synchronized (lock) {
             Long id = instanceIdToLongId.remove(path);
             longIdToInstanceId.remove(id);
index 2816f79e2413a90afc4125346a1a64804658a548..05a76a4cb7ca0551d0bb55322b4603f78eb7fd4b 100644 (file)
@@ -24,7 +24,6 @@
 <script src='swagger-ui.js' type='text/javascript'></script>\r
 <script src='lib/odl/list_mounts.js' type='text/javascript'></script>\r
 <script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>\r
-<script src='lib/odl/rest-tree.js' type='text/javascript'></script>\r
 <script src='lib/odl/swagger.js' type='text/javascript'></script>\r
 \r
 <script type="text/javascript">\r
index 8390a385e6a136a29d79e64376a0fadf8fa03757..07c9378439d2f66551672d8a08ec20785a0a074b 100644 (file)
@@ -2,6 +2,7 @@ package org.opendaylight.controller.sal.rest.doc.impl;
 
 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 java.io.File;
@@ -65,6 +66,24 @@ public class ApiDocGeneratorTest {
         }
     }
 
+    @Test
+    public void testEdgeCases() throws Exception {
+        Preconditions.checkArgument(helper.getModules() != null, "No modules found");
+
+        for (Entry<File, Module> m : helper.getModules().entrySet()) {
+            if (m.getKey().getAbsolutePath().endsWith("toaster.yang")) {
+                ApiDeclaration doc = generator.getSwaggerDocSpec(m.getValue(),
+                        "http://localhost:8080/restconf", "");
+                Assert.assertNotNull(doc);
+
+                //testing bugs.opendaylight.org bug 1290. UnionType model type.
+                String jsonString = doc.getModels().toString();
+                assertTrue(
+                        jsonString.contains( "testUnion\":{\"type\":\"integer or string\",\"required\":false}" ) );
+            }
+        }
+    }
+
     private void validateToaster(ApiDeclaration doc) throws Exception {
         Set<String> expectedUrls = new TreeSet<>(Arrays.asList(new String[] {
                 "/config/toaster2:toaster/", "/operational/toaster2:toaster/",
@@ -99,6 +118,7 @@ public class ApiDocGeneratorTest {
             expectedConfigMethods.removeAll(actualConfigMethods);
             fail("Missing expected method on config API: " + expectedConfigMethods);
         }
+
         // TODO: we should really do some more validation of the
         // documentation...
         /**
index a2e29398a3a68ffe0723b8c8fbfa96d8acb5e84b..bba8ed9ca6fcf557bb972af2d3c55c68bf1f3f13 100644 (file)
@@ -32,13 +32,13 @@ import org.opendaylight.controller.sal.rest.doc.swagger.Operation;
 import org.opendaylight.controller.sal.rest.doc.swagger.Resource;
 import org.opendaylight.controller.sal.rest.doc.swagger.ResourceList;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public class MountPointSwaggerTest {
 
     private static final String HTTP_URL = "http://localhost/path";
-    private static final InstanceIdentifier instanceId = InstanceIdentifier.builder()
+    private static final YangInstanceIdentifier instanceId = YangInstanceIdentifier.builder()
             .node(QName.create("nodes"))
             .nodeWithKey(QName.create("node"), QName.create("id"), "123").build();
     private static final String INSTANCE_URL = "nodes/node/123/";
diff --git a/opendaylight/md-sal/sal-test-model/pom.xml b/opendaylight/md-sal/sal-test-model/pom.xml
new file mode 100644 (file)
index 0000000..11a0ef2
--- /dev/null
@@ -0,0 +1,81 @@
+<?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>sal-parent</artifactId>
+        <groupId>org.opendaylight.controller</groupId>
+        <version>1.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-binding</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools.model</groupId>
+            <artifactId>yang-ext</artifactId>
+        </dependency>
+    </dependencies>
+
+    <artifactId>sal-test-model</artifactId>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <configuration>
+                    <includes>
+                        <include>org.opendaylight.controller.*</include>
+                    </includes>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>pre-test</id>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>post-test</id>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                        <phase>test</phase>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate-sources</goal>
+                        </goals>
+                        <configuration>
+                            <codeGenerators>
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+                                    </codeGeneratorClass>
+                                    <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+                                </generator>
+                            </codeGenerators>
+                            <inspectDependencies>true</inspectDependencies>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <scm>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+        <tag>HEAD</tag>
+        <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+    </scm>
+
+</project>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-test-model/src/main/java/org/opendaylight/controller/md/sal/test/model/util/ListsBindingUtils.java b/opendaylight/md-sal/sal-test-model/src/main/java/org/opendaylight/controller/md/sal/test/model/util/ListsBindingUtils.java
new file mode 100644 (file)
index 0000000..a0c23ae
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.test.model.util;
+
+import java.util.Arrays;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.TreeComplexUsesAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.TreeComplexUsesAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.complex.from.grouping.ListViaUses;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.complex.from.grouping.ListViaUsesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.complex.from.grouping.ListViaUsesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.Top;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.TopBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelListKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.top.level.list.NestedList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.top.level.list.NestedListKey;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.collect.ImmutableList;
+
+public class ListsBindingUtils {
+
+    private static final InstanceIdentifier<Top> TOP_PATH = InstanceIdentifier.create(Top.class);
+
+    private ListsBindingUtils() {
+        throw new UnsupportedOperationException();
+    }
+
+    public static final TopLevelListKey TOP_FOO_KEY = new TopLevelListKey("foo");
+    public static final TopLevelListKey TOP_BAR_KEY = new TopLevelListKey("bar");
+    public static final ListViaUsesKey USES_ONE_KEY = new ListViaUsesKey("one");
+    public static final ListViaUsesKey USES_TWO_KEY = new ListViaUsesKey("two");
+
+
+    public static InstanceIdentifier<TopLevelList> path(final TopLevelListKey key) {
+        return TOP_PATH.child(TopLevelList.class, key);
+    }
+
+    public static InstanceIdentifier<NestedList> path(final TopLevelListKey top,final NestedListKey nested) {
+        return path(top).child(NestedList.class, nested);
+    }
+
+    public static InstanceIdentifier<ListViaUses> path(final TopLevelListKey top,final ListViaUsesKey uses) {
+        return path(top).augmentation(TreeComplexUsesAugment.class).child(ListViaUses.class, uses);
+    }
+
+    public static <T extends DataObject & Augmentation<TopLevelList>> InstanceIdentifier<T> path(final TopLevelListKey key, final Class<T> augmentation) {
+        return path(key).augmentation(augmentation);
+    }
+
+    public static Top top(final TopLevelList... listItems) {
+        return new TopBuilder().setTopLevelList(Arrays.asList(listItems)).build();
+    }
+
+    public static TopLevelList topLevelList(final TopLevelListKey key) {
+        return new TopLevelListBuilder().setKey(key).build();
+    }
+
+    public static TopLevelList topLevelList(final TopLevelListKey key, final TreeComplexUsesAugment augment) {
+        TopLevelListBuilder builder = new TopLevelListBuilder().setKey(key);
+        builder.addAugmentation(TreeComplexUsesAugment.class, augment);
+        return builder.build();
+    }
+
+    public static TreeComplexUsesAugment complexUsesAugment(final ListViaUsesKey... keys) {
+        ImmutableList.Builder<ListViaUses> listViaUses = ImmutableList.<ListViaUses> builder();
+        for (ListViaUsesKey key : keys) {
+            listViaUses.add(new ListViaUsesBuilder().setKey(key).build());
+        }
+        return new TreeComplexUsesAugmentBuilder().setListViaUses(listViaUses.build()).build();
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-test-model/src/main/yang/opendaylight-mdsal-augment-test.yang b/opendaylight/md-sal/sal-test-model/src/main/yang/opendaylight-mdsal-augment-test.yang
new file mode 100644 (file)
index 0000000..ddd7687
--- /dev/null
@@ -0,0 +1,93 @@
+module opendaylight-mdsal-augment-test {
+
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:augment";
+    prefix aug-test;
+
+    import opendaylight-mdsal-list-test {
+        prefix test;
+    }
+    import yang-ext {
+        prefix ext;
+    }
+
+    description
+        "This module contains a collection of YANG augmentations used for
+        some test cases.";
+
+    revision 2014-07-09 {
+        description
+        "Test model for testing data broker with nested lists.";
+    }
+
+    grouping leaf-from-grouping {
+        leaf leaf-from-grouping {
+            type string;
+        }
+    }
+
+    grouping complex-from-grouping {
+        container container-with-uses {
+            uses leaf-from-grouping;
+        }
+        list list-via-uses {
+            key "name";
+            leaf name {
+                type string;
+            }
+        }
+    
+    }
+
+    augment "/test:top/test:top-level-list" {
+        ext:augment-identifier tree-leaf-only-uses-augment;
+        uses leaf-from-grouping;
+    }
+
+    augment "/test:put-top/test:input/test:top-level-list" {
+        ext:augment-identifier rpc-leaf-only-uses-augment;
+        uses leaf-from-grouping;
+    }
+
+    augment "/test:top/test:top-level-list" {
+        ext:augment-identifier tree-complex-uses-augment;
+        uses complex-from-grouping;
+    }
+
+    augment "/test:put-top/test:input/test:top-level-list" {
+        ext:augment-identifier rpc-complex-uses-augment;
+        uses complex-from-grouping;
+    }
+
+    augment "/test:top/test:top-level-list" {
+        ext:augment-identifier tree-leaf-only-augment;
+
+        leaf simple-value {
+            type string;
+        }
+    }
+    
+    augment "/test:top/test:top-level-list" {
+        ext:augment-identifier tree-second-leaf-only-augment;
+
+        leaf second-simple-value {
+            type string;
+        }
+    }
+
+    augment "/test:put-top/test:input/test:top-level-list" {
+        ext:augment-identifier rpc-leaf-only-augment;
+
+        leaf simple-value {
+            type string;
+        }
+    }
+
+    augment "/test:put-top/test:input/test:top-level-list" {
+        ext:augment-identifier rpc-second-leaf-only-augment;
+
+        leaf second-simple-value {
+            type string;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-test-model/src/main/yang/opendaylight-mdsal-list-test.yang b/opendaylight/md-sal/sal-test-model/src/main/yang/opendaylight-mdsal-list-test.yang
new file mode 100644 (file)
index 0000000..48666e1
--- /dev/null
@@ -0,0 +1,51 @@
+module opendaylight-mdsal-list-test {
+
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:list";
+    prefix list-test;
+
+
+    description
+        "This module contains a collection of YANG definitions used for
+        some test cases.";
+
+    revision 2014-07-01 {
+        description
+        "Test model for testing data broker with nested lists.";
+    }
+
+    grouping two-level-list {
+        list top-level-list {
+            description
+                "Top Level List";
+            key "name";
+            leaf name {
+                type string;
+            }
+            list nested-list {
+                key "name";
+                leaf name {
+                    type string;
+                }
+                leaf type {
+                    type string;
+                    mandatory true;
+                    description
+                        "Mandatory type of list.";
+                }
+                ordered-by user;
+                description
+                    "A list of service functions that compose the service chain";
+            }
+        }
+    }
+
+    container top {
+        uses two-level-list;
+    }
+
+    rpc put-top {
+        input {
+            uses two-level-list;
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-test-model/src/main/yang/opendaylight-test-routed-rpc.yang b/opendaylight/md-sal/sal-test-model/src/main/yang/opendaylight-test-routed-rpc.yang
new file mode 100644 (file)
index 0000000..c3a9824
--- /dev/null
@@ -0,0 +1,46 @@
+module opendaylight-test-routed-rpc {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:rpc:routing";
+    prefix "rpc";
+    import yang-ext { prefix ext; }
+
+    description
+        "Test model for testing of registering rpc service on binding independent mount point 
+        and retrieving rpc service via binding aware mount point.";
+
+    revision "2014-07-01" {
+        description
+            "Initial revision";
+    }
+
+    identity test-context {
+        description "Test Context";
+    }
+    
+    typedef encapsulated-route {
+        type instance-identifier;
+    }
+    
+    grouping route-in-grouping {
+        leaf route {
+            type instance-identifier;
+            ext:context-reference test-context;
+        }
+    }
+    
+    grouping encapsulated-route-in-grouping {
+        leaf route {
+            type encapsulated-route;
+            ext:context-reference test-context;
+        }
+    }
+
+    rpc routed-simple-route {
+        input {
+            leaf route {
+                type instance-identifier;
+                ext:context-reference test-context;
+            }
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-test-model/src/main/yang/opendaylight-test-rpc-service.yang b/opendaylight/md-sal/sal-test-model/src/main/yang/opendaylight-test-rpc-service.yang
new file mode 100644 (file)
index 0000000..3412eb5
--- /dev/null
@@ -0,0 +1,22 @@
+module opendaylight-test-rpc-service {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:bi:ba:rpcservice";
+    prefix "rpc";
+
+    description
+        "Test model for testing of registering rpc service on binding independent mount point 
+        and retrieving rpc service via binding aware mount point.";
+
+    revision "2014-07-01" {
+        description
+            "Initial revision";
+    }
+
+    rpc rock-the-house {
+        input {
+            leaf zip-code {
+                type string;
+            }
+        }
+    }
+}
\ No newline at end of file
index 6f31a7ec76ac6e365429faefbf035b93764731cc..d123456262a2c7359aa052599e9fd98b6c78a265 100644 (file)
@@ -20,7 +20,7 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 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.packet.service.rev130709.PacketProcessingService;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,7 +33,7 @@ public class L2SwitchProvider extends AbstractBindingAwareConsumer
 
   private final static Logger _logger = LoggerFactory.getLogger(L2SwitchProvider.class);
 
-  private Registration<NotificationListener> listenerRegistration;
+  private ListenerRegistration<NotificationListener> listenerRegistration;
   private AddressTracker addressTracker;
   private TopologyLinkDataChangeHandler topologyLinkDataChangeHandler;
 
index f6a8306a98b6a71650ffcbc7b06a331a184dbd32..6e720299d8364e21d058e9603f86e33544697b1d 100644 (file)
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>config-api</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-common-util</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-binding-api</artifactId>
index a23def6262a0af8e6938f59c4f7a92e3c14b0eb7..8d67fb4ed09371394dc10cc9b9d8105f860d16db 100644 (file)
@@ -9,13 +9,16 @@
  */
 package org.opendaylight.controller.config.yang.config.kitchen_service.impl;
 
+import java.util.concurrent.Future;
+
 import org.opendaylight.controller.sample.kitchen.api.EggsType;
 import org.opendaylight.controller.sample.kitchen.api.KitchenService;
 import org.opendaylight.controller.sample.kitchen.impl.KitchenServiceImpl;
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToastType;
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterService;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -47,7 +50,7 @@ public final class KitchenServiceModule extends AbstractKitchenServiceModule {
 
         final KitchenServiceImpl kitchenService = new KitchenServiceImpl(toasterService);
 
-        final Registration<NotificationListener> toasterListenerReg =
+        final ListenerRegistration<NotificationListener> toasterListenerReg =
                 getNotificationServiceDependency().registerNotificationListener( kitchenService );
 
         final KitchenServiceRuntimeRegistration runtimeReg =
@@ -63,7 +66,9 @@ public final class KitchenServiceModule extends AbstractKitchenServiceModule {
             }
 
             @Override
-            public boolean makeBreakfast( final EggsType eggs, final Class<? extends ToastType> toast, final int toastDoneness ) {
+            public Future<RpcResult<Void>> makeBreakfast( final EggsType eggs,
+                                                          final Class<? extends ToastType> toast,
+                                                          final int toastDoneness ) {
                 return kitchenService.makeBreakfast( eggs, toast, toastDoneness );
             }
         }
index ef9c122ec1fb314a32d16e5566ca2275db7b5cd9..7e7f342962cba09a7204aa046b9126b77d46d33a 100644 (file)
@@ -1,7 +1,11 @@
 package org.opendaylight.controller.sample.kitchen.api;
 
+import java.util.concurrent.Future;
+
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToastType;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 
 public interface KitchenService {
-    boolean makeBreakfast( EggsType eggs, Class<? extends ToastType> toast, int toastDoneness );
+    Future<RpcResult<Void>> makeBreakfast( EggsType eggs, Class<? extends ToastType> toast,
+                                           int toastDoneness );
 }
index 911a8c87d7166edc38c7faa2597678c8f55c611a..c6aa545935af5e2ae9771343706ac24a0518a363 100644 (file)
@@ -1,10 +1,15 @@
 package org.opendaylight.controller.sample.kitchen.impl;
 
+import java.util.List;
+import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
 
 import org.opendaylight.controller.config.yang.config.kitchen_service.impl.KitchenServiceRuntimeMXBean;
 import org.opendaylight.controller.sample.kitchen.api.EggsType;
 import org.opendaylight.controller.sample.kitchen.api.KitchenService;
+import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastInput;
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastInputBuilder;
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToastType;
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterListener;
@@ -12,16 +17,31 @@ import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterRestocked;
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterService;
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.WheatBread;
+import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.JdkFutureAdapters;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
 public class KitchenServiceImpl implements KitchenService, KitchenServiceRuntimeMXBean, ToasterListener {
 
     private static final Logger log = LoggerFactory.getLogger( KitchenServiceImpl.class );
 
     private final ToasterService toaster;
 
+    private final ListeningExecutorService executor =
+                                   MoreExecutors.listeningDecorator( Executors.newCachedThreadPool() );
+
     private volatile boolean toasterOutOfBread;
 
     public KitchenServiceImpl(ToasterService toaster) {
@@ -29,39 +49,101 @@ public class KitchenServiceImpl implements KitchenService, KitchenServiceRuntime
     }
 
     @Override
-    public boolean makeBreakfast( EggsType eggs, Class<? extends ToastType> toast, int toastDoneness ) {
+    public Future<RpcResult<Void>> makeBreakfast( EggsType eggsType, Class<? extends ToastType> toastType,
+                                                  int toastDoneness ) {
+
+        // Call makeToast and use JdkFutureAdapters to convert the Future to a ListenableFuture,
+        // The OpendaylightToaster impl already returns a ListenableFuture so the conversion is
+        // actually a no-op.
+
+        ListenableFuture<RpcResult<Void>> makeToastFuture = JdkFutureAdapters.listenInPoolThread(
+                makeToast( toastType, toastDoneness ), executor );
+
+        ListenableFuture<RpcResult<Void>> makeEggsFuture = makeEggs( eggsType );
+
+        // Combine the 2 ListenableFutures into 1 containing a list of RpcResults.
+
+        ListenableFuture<List<RpcResult<Void>>> combinedFutures =
+                Futures.allAsList( ImmutableList.of( makeToastFuture, makeEggsFuture ) );
+
+        // Then transform the RpcResults into 1.
+
+        return Futures.transform( combinedFutures,
+            new AsyncFunction<List<RpcResult<Void>>,RpcResult<Void>>() {
+                @Override
+                public ListenableFuture<RpcResult<Void>> apply( List<RpcResult<Void>> results )
+                                                                                 throws Exception {
+                    boolean atLeastOneSucceeded = false;
+                    Builder<RpcError> errorList = ImmutableList.builder();
+                    for( RpcResult<Void> result: results ) {
+                        if( result.isSuccessful() ) {
+                            atLeastOneSucceeded = true;
+                        }
+
+                        if( result.getErrors() != null ) {
+                            errorList.addAll( result.getErrors() );
+                        }
+                    }
+
+                    return Futures.immediateFuture(
+                              RpcResultBuilder.<Void> status( atLeastOneSucceeded )
+                                              .withRpcErrors( errorList.build() ).build() );
+                }
+        } );
+    }
+
+    private ListenableFuture<RpcResult<Void>> makeEggs( EggsType eggsType ) {
+
+        return executor.submit( new Callable<RpcResult<Void>>() {
+
+            @Override
+            public RpcResult<Void> call() throws Exception {
+
+                // We don't actually do anything here - just return a successful result.
+                return RpcResultBuilder.<Void> success().build();
+            }
+        } );
+    }
+
+    private Future<RpcResult<Void>> makeToast( Class<? extends ToastType> toastType,
+                                               int toastDoneness ) {
 
         if( toasterOutOfBread )
         {
             log.info( "We're out of toast but we can make eggs" );
-            return true;
+            return Futures.immediateFuture( RpcResultBuilder.<Void> success()
+                     .withWarning( ErrorType.APPLICATION, "partial-operation",
+                                      "Toaster is out of bread but we can make you eggs" ).build() );
         }
 
         // Access the ToasterService to make the toast.
-        // We don't actually make the eggs for this example - sorry.
-        MakeToastInputBuilder toastInput = new MakeToastInputBuilder();
-        toastInput.setToasterDoneness( (long) toastDoneness);
-        toastInput.setToasterToastType( toast );
 
-        try {
-            RpcResult<Void> result = toaster.makeToast( toastInput.build() ).get();
+        MakeToastInput toastInput = new MakeToastInputBuilder()
+            .setToasterDoneness( (long) toastDoneness )
+            .setToasterToastType( toastType )
+            .build();
+
+        return toaster.makeToast( toastInput );
+    }
 
+    @Override
+    public Boolean makeScrambledWithWheat() {
+        try {
+            // This call has to block since we must return a result to the JMX client.
+            RpcResult<Void> result = makeBreakfast( EggsType.SCRAMBLED, WheatBread.class, 2 ).get();
             if( result.isSuccessful() ) {
-                log.info( "makeToast succeeded" );
+                log.info( "makeBreakfast succeeded" );
             } else {
-                log.warn( "makeToast failed: " + result.getErrors() );
+                log.warn( "makeBreakfast failed: " + result.getErrors() );
             }
 
             return result.isSuccessful();
+
         } catch( InterruptedException | ExecutionException e ) {
-            log.warn( "Error occurred during toast creation" );
+            log.warn( "An error occurred while maing breakfast: " + e );
         }
-        return false;
-    }
 
-    @Override
-    public Boolean makeScrambledWithWheat() {
-        return makeBreakfast( EggsType.SCRAMBLED, WheatBread.class, 2 );
+        return Boolean.FALSE;
     }
 
     /**
index 907b35475f80f3565e18d2965885ff505bb55d6e..30f1762197ecf58a35c8828775dfb009742a7025 100644 (file)
@@ -93,13 +93,13 @@ public class ToasterTest {
         long toastsMade = (long) platformMBeanServer.getAttribute(providerOn, "ToastsMade");
         assertEquals(0, toastsMade);
 
-        boolean toasts = true;
+        boolean success = true;
 
         // Make toasts using OSGi service
-        toasts &= kitchenService.makeBreakfast( EggsType.SCRAMBLED, HashBrown.class, 4);
-        toasts &= kitchenService.makeBreakfast( EggsType.POACHED, WhiteBread.class, 8 );
+        success &= kitchenService.makeBreakfast( EggsType.SCRAMBLED, HashBrown.class, 4).get().isSuccessful();
+        success &= kitchenService.makeBreakfast( EggsType.POACHED, WhiteBread.class, 8 ).get().isSuccessful();
 
-        Assert.assertTrue("Not all toasts done by " + kitchenService, toasts);
+        Assert.assertTrue("Not all breakfasts succeeded", success);
 
         // Verify toasts made count on provider via JMX/config-subsystem
         toastsMade = (long) platformMBeanServer.getAttribute(providerOn, "ToastsMade");
index f904f9726efce6c236526f318654fab49a81f49a..d76c2d3c22a415628beccef2eb9af4c36035840d 100644 (file)
@@ -10,7 +10,9 @@
 
   <logger name="org.opendaylight.yangtools.yang.parser" level="ERROR"/>
 
-  <root level="debug">
+  <logger name="org.opendaylight.controller.sample.toaster.provider" level="DEBUG"/>
+
+  <root level="error">
     <appender-ref ref="STDOUT" />
   </root>
 </configuration>
index ec352e8f510dad03911be2ad2eeb0ec6a5c44542..b7518e094d0e61594a391c2fc4a78b181294e00a 100644 (file)
@@ -7,24 +7,24 @@
  */
 package org.opendaylight.controller.sample.toaster.provider;
 
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
 
 import org.opendaylight.controller.config.yang.config.toaster_provider.impl.ToasterProviderRuntimeMXBean;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.common.util.RpcErrors;
-import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.DisplayString;
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastInput;
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.RestockToasterInput;
@@ -38,13 +38,19 @@ import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
 
 public class OpendaylightToaster implements ToasterService, ToasterProviderRuntimeMXBean,
                                             DataChangeListener, AutoCloseable {
@@ -61,10 +67,9 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti
 
     private final ExecutorService executor;
 
-    // As you will see we are using multiple threads here. Therefore we need to be careful about concurrency.
-    // In this case we use the taskLock to provide synchronization for the current task.
-    private volatile Future<RpcResult<Void>> currentTask;
-    private final Object taskLock = new Object();
+    // The following holds the Future for the current make toast task.
+    // This is used to cancel the current toast.
+    private final AtomicReference<Future<?>> currentMakeToastTask = new AtomicReference<>();
 
     private final AtomicLong amountOfBreadInStock = new AtomicLong( 100 );
 
@@ -83,7 +88,7 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti
 
     public void setDataProvider(final DataBroker salDataProvider) {
         this.dataProvider = salDataProvider;
-        updateStatus();
+        setToasterStatusUp( null );
     }
 
     /**
@@ -95,24 +100,31 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti
         executor.shutdown();
 
         if (dataProvider != null) {
-            WriteTransaction t = dataProvider.newWriteOnlyTransaction();
-            t.delete(LogicalDatastoreType.OPERATIONAL,TOASTER_IID);
-            t.commit().get(); // FIXME: This call should not be blocking.
+            WriteTransaction tx = dataProvider.newWriteOnlyTransaction();
+            tx.delete(LogicalDatastoreType.OPERATIONAL,TOASTER_IID);
+            Futures.addCallback( tx.submit(), new FutureCallback<Void>() {
+                @Override
+                public void onSuccess( final Void result ) {
+                    LOG.debug( "Delete Toaster commit result: " + result );
+                }
+
+                @Override
+                public void onFailure( final Throwable t ) {
+                    LOG.error( "Delete of Toaster failed", t );
+                }
+            } );
         }
     }
 
-    private Toaster buildToaster() {
-        // We don't need to synchronize on currentTask here b/c it's declared volatile and
-        // we're just doing a read.
-        boolean isUp = currentTask == null;
+    private Toaster buildToaster( final ToasterStatus status ) {
 
         // note - we are simulating a device whose manufacture and model are
         // fixed (embedded) into the hardware.
         // This is why the manufacture and model number are hardcoded.
-        ToasterBuilder tb = new ToasterBuilder();
-        tb.setToasterManufacturer(TOASTER_MANUFACTURER).setToasterModelNumber(TOASTER_MODEL_NUMBER)
-                .setToasterStatus(isUp ? ToasterStatus.Up : ToasterStatus.Down);
-        return tb.build();
+        return new ToasterBuilder().setToasterManufacturer( TOASTER_MANUFACTURER )
+                                   .setToasterModelNumber( TOASTER_MODEL_NUMBER )
+                                   .setToasterStatus( status )
+                                   .build();
     }
 
     /**
@@ -133,57 +145,136 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti
     }
 
     /**
-     * RestConf RPC call implemented from the ToasterService interface.
+     * RPC call implemented from the ToasterService interface that cancels the current
+     * toast, if any.
      */
     @Override
     public Future<RpcResult<Void>> cancelToast() {
-        synchronized (taskLock) {
-            if (currentTask != null) {
-                currentTask.cancel(true);
-                currentTask = null;
-            }
+
+        Future<?> current = currentMakeToastTask.getAndSet( null );
+        if( current != null ) {
+            current.cancel( true );
         }
+
         // Always return success from the cancel toast call.
-        return Futures.immediateFuture(Rpcs.<Void> getRpcResult(true, Collections.<RpcError> emptySet()));
+        return Futures.immediateFuture( RpcResultBuilder.<Void> success().build() );
     }
 
     /**
-     * RestConf RPC call implemented from the ToasterService interface.
+     * RPC call implemented from the ToasterService interface that attempts to make toast.
      */
     @Override
     public Future<RpcResult<Void>> makeToast(final MakeToastInput input) {
         LOG.info("makeToast: " + input);
 
-        synchronized (taskLock) {
-            if (currentTask != null) {
-                // return an error since we are already toasting some toast.
-                LOG.info( "Toaster is already making toast" );
+        final SettableFuture<RpcResult<Void>> futureResult = SettableFuture.create();
 
-                RpcResult<Void> result = Rpcs.<Void> getRpcResult(false, null, Arrays.asList(
-                        RpcErrors.getRpcError( "", "in-use", null, ErrorSeverity.WARNING,
-                                               "Toaster is busy", ErrorType.APPLICATION, null ) ) );
-                return Futures.immediateFuture(result);
-            }
-            else if( outOfBread() ) {
-                RpcResult<Void> result = Rpcs.<Void> getRpcResult(false, null, Arrays.asList(
-                        RpcErrors.getRpcError( "out-of-stock", "resource-denied", null, null,
-                                               "Toaster is out of bread",
-                                               ErrorType.APPLICATION, null ) ) );
-                return Futures.immediateFuture(result);
-            }
-            else {
-                // Notice that we are moving the actual call to another thread,
-                // allowing this thread to return immediately.
-                // The MD-SAL design encourages asynchronus programming. If the
-                // caller needs to block until the call is
-                // complete then they can leverage the blocking methods on the
-                // Future interface.
-                currentTask = executor.submit(new MakeToastTask(input));
+        checkStatusAndMakeToast( input, futureResult, 2 );
+
+        return futureResult;
+    }
+
+    private RpcError makeToasterOutOfBreadError() {
+        return RpcResultBuilder.newError( ErrorType.APPLICATION, "resource-denied",
+                "Toaster is out of bread", "out-of-stock", null, null );
+    }
+
+    private RpcError makeToasterInUseError() {
+        return RpcResultBuilder.newWarning( ErrorType.APPLICATION, "in-use",
+                "Toaster is busy", null, null, null );
+    }
+
+    private void checkStatusAndMakeToast( final MakeToastInput input,
+                                          final SettableFuture<RpcResult<Void>> futureResult,
+                                          final int tries ) {
+
+        // Read the ToasterStatus and, if currently Up, try to write the status to Down.
+        // If that succeeds, then we essentially have an exclusive lock and can proceed
+        // to make toast.
+
+        final ReadWriteTransaction tx = dataProvider.newReadWriteTransaction();
+        ListenableFuture<Optional<Toaster>> readFuture =
+                                          tx.read( LogicalDatastoreType.OPERATIONAL, TOASTER_IID );
+
+        final ListenableFuture<Void> commitFuture =
+            Futures.transform( readFuture, new AsyncFunction<Optional<Toaster>,Void>() {
+
+                @Override
+                public ListenableFuture<Void> apply(
+                        final Optional<Toaster> toasterData ) throws Exception {
+
+                    ToasterStatus toasterStatus = ToasterStatus.Up;
+                    if( toasterData.isPresent() ) {
+                        toasterStatus = toasterData.get().getToasterStatus();
+                    }
+
+                    LOG.debug( "Read toaster status: {}", toasterStatus );
+
+                    if( toasterStatus == ToasterStatus.Up ) {
+
+                        if( outOfBread() ) {
+                            LOG.debug( "Toaster is out of bread" );
+
+                            return Futures.immediateFailedCheckedFuture(
+                                    new TransactionCommitFailedException( "", makeToasterOutOfBreadError() ) );
+                        }
+
+                        LOG.debug( "Setting Toaster status to Down" );
+
+                        // We're not currently making toast - try to update the status to Down
+                        // to indicate we're going to make toast. This acts as a lock to prevent
+                        // concurrent toasting.
+                        tx.put( LogicalDatastoreType.OPERATIONAL, TOASTER_IID,
+                                buildToaster( ToasterStatus.Down ) );
+                        return tx.submit();
+                    }
+
+                    LOG.debug( "Oops - already making toast!" );
+
+                    // Return an error since we are already making toast. This will get
+                    // propagated to the commitFuture below which will interpret the null
+                    // TransactionStatus in the RpcResult as an error condition.
+                    return Futures.immediateFailedCheckedFuture(
+                            new TransactionCommitFailedException( "", makeToasterInUseError() ) );
+                }
+        } );
+
+        Futures.addCallback( commitFuture, new FutureCallback<Void>() {
+            @Override
+            public void onSuccess( final Void result ) {
+                // OK to make toast
+                currentMakeToastTask.set( executor.submit( new MakeToastTask( input, futureResult ) ) );
             }
-        }
 
-        updateStatus();
-        return currentTask;
+            @Override
+            public void onFailure( final Throwable ex ) {
+                if( ex instanceof OptimisticLockFailedException ) {
+
+                    // Another thread is likely trying to make toast simultaneously and updated the
+                    // status before us. Try reading the status again - if another make toast is
+                    // now in progress, we should get ToasterStatus.Down and fail.
+
+                    if( ( tries - 1 ) > 0 ) {
+                        LOG.debug( "Got OptimisticLockFailedException - trying again" );
+
+                        checkStatusAndMakeToast( input, futureResult, tries - 1 );
+                    }
+                    else {
+                        futureResult.set( RpcResultBuilder.<Void> failed()
+                                .withError( ErrorType.APPLICATION, ex.getMessage() ).build() );
+                    }
+
+                } else {
+
+                    LOG.debug( "Failed to commit Toaster status", ex );
+
+                    // Probably already making toast.
+                    futureResult.set( RpcResultBuilder.<Void> failed()
+                            .withRpcErrors( ((TransactionCommitFailedException)ex).getErrorList() )
+                            .build() );
+                }
+            }
+        } );
     }
 
     /**
@@ -195,17 +286,15 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti
     public Future<RpcResult<java.lang.Void>> restockToaster(final RestockToasterInput input) {
         LOG.info( "restockToaster: " + input );
 
-        synchronized( taskLock ) {
-            amountOfBreadInStock.set( input.getAmountOfBreadToStock() );
+        amountOfBreadInStock.set( input.getAmountOfBreadToStock() );
 
-            if( amountOfBreadInStock.get() > 0 ) {
-                ToasterRestocked reStockedNotification =
-                    new ToasterRestockedBuilder().setAmountOfBread( input.getAmountOfBreadToStock() ).build();
-                notificationProvider.publish( reStockedNotification );
-            }
+        if( amountOfBreadInStock.get() > 0 ) {
+            ToasterRestocked reStockedNotification = new ToasterRestockedBuilder()
+                .setAmountOfBread( input.getAmountOfBreadToStock() ).build();
+            notificationProvider.publish( reStockedNotification );
         }
 
-        return Futures.immediateFuture(Rpcs.<Void> getRpcResult(true, Collections.<RpcError> emptySet()));
+        return Futures.immediateFuture( RpcResultBuilder.<Void> success().build() );
     }
 
     /**
@@ -225,19 +314,32 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti
         return toastsMade.get();
     }
 
-    private void updateStatus() {
-        if (dataProvider != null) {
-            WriteTransaction tx = dataProvider.newWriteOnlyTransaction();
-            tx.put(LogicalDatastoreType.OPERATIONAL,TOASTER_IID, buildToaster());
+    private void setToasterStatusUp( final Function<Boolean,Void> resultCallback ) {
+
+        WriteTransaction tx = dataProvider.newWriteOnlyTransaction();
+        tx.put( LogicalDatastoreType.OPERATIONAL,TOASTER_IID, buildToaster( ToasterStatus.Up ) );
 
-            try {
-                tx.commit().get();
-            } catch (InterruptedException | ExecutionException e) {
-                LOG.warn("Failed to update toaster status, operational otherwise", e);
+        Futures.addCallback( tx.submit(), new FutureCallback<Void>() {
+            @Override
+            public void onSuccess( final Void result ) {
+                notifyCallback( true );
             }
-        } else {
-            LOG.trace("No data provider configured, not updating status");
-        }
+
+            @Override
+            public void onFailure( final Throwable t ) {
+                // We shouldn't get an OptimisticLockFailedException (or any ex) as no
+                // other component should be updating the operational state.
+                LOG.error( "Failed to update toaster status", t );
+
+                notifyCallback( false );
+            }
+
+            void notifyCallback( final boolean result ) {
+                if( resultCallback != null ) {
+                    resultCallback.apply( result );
+                }
+            }
+        } );
     }
 
     private boolean outOfBread()
@@ -245,19 +347,22 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti
         return amountOfBreadInStock.get() == 0;
     }
 
-    private class MakeToastTask implements Callable<RpcResult<Void>> {
+    private class MakeToastTask implements Callable<Void> {
 
         final MakeToastInput toastRequest;
+        final SettableFuture<RpcResult<Void>> futureResult;
 
-        public MakeToastTask(final MakeToastInput toast) {
-            toastRequest = toast;
+        public MakeToastTask( final MakeToastInput toastRequest,
+                              final SettableFuture<RpcResult<Void>> futureResult ) {
+            this.toastRequest = toastRequest;
+            this.futureResult = futureResult;
         }
 
         @Override
-        public RpcResult<Void> call() {
+        public Void call() {
             try
             {
-                // make toast just sleeps for n secondn per doneness level.
+                // make toast just sleeps for n seconds per doneness level.
                 long darknessFactor = OpendaylightToaster.this.darknessFactor.get();
                 Thread.sleep(darknessFactor * toastRequest.getToasterDoneness());
 
@@ -275,15 +380,25 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti
                 notificationProvider.publish( new ToasterOutOfBreadBuilder().build() );
             }
 
-            synchronized (taskLock) {
-                currentTask = null;
-            }
+            // Set the Toaster status back to up - this essentially releases the toasting lock.
+            // We can't clear the current toast task nor set the Future result until the
+            // update has been committed so we pass a callback to be notified on completion.
+
+            setToasterStatusUp( new Function<Boolean,Void>() {
+                @Override
+                public Void apply( final Boolean result ) {
+
+                    currentMakeToastTask.set( null );
+
+                    LOG.debug("Toast done");
 
-            updateStatus();
+                    futureResult.set( RpcResultBuilder.<Void>success().build() );
 
-            LOG.debug("Toast done");
+                    return null;
+                }
+            } );
 
-            return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+            return null;
         }
     }
 }
index af61db1a8096874945fe92f7fc5478c948b0f5da..b1db280c2472802aed2e97ce525422308eca3b12 100644 (file)
@@ -95,6 +95,8 @@ final class FlowComparator {
         if (statsFlow == storedFlow) {
             return true;
         }
+        if (storedFlow == null && statsFlow != null) return false;
+        if (statsFlow == null && storedFlow != null) return false;
         if (storedFlow.getClass() != statsFlow.getClass()) {
             return false;
         }
index add46bd162fc5644a0f4a5bf13fed72e5ad0a6d2..edf7388a769a662a0ea7848694501c08a864ac0a 100644 (file)
@@ -64,31 +64,15 @@ final class FlowStatsTracker extends AbstractListeningStatsTracker<FlowAndStatis
     protected FlowStatsEntry updateSingleStat(final DataModificationTransaction trans, final FlowAndStatisticsMapList map) {
         short tableId = map.getTableId();
 
-        FlowBuilder flowBuilder = new FlowBuilder();
-
         FlowStatisticsDataBuilder flowStatisticsData = new FlowStatisticsDataBuilder();
 
-        FlowBuilder flow = new FlowBuilder();
-        flow.setContainerName(map.getContainerName());
-        flow.setBufferId(map.getBufferId());
-        flow.setCookie(map.getCookie());
-        flow.setCookieMask(map.getCookieMask());
-        flow.setFlags(map.getFlags());
-        flow.setFlowName(map.getFlowName());
-        flow.setHardTimeout(map.getHardTimeout());
-        if(map.getFlowId() != null)
+        FlowBuilder flow = new FlowBuilder(map);
+        if(map.getFlowId() != null) {
             flow.setId(new FlowId(map.getFlowId().getValue()));
-        flow.setIdleTimeout(map.getIdleTimeout());
-        flow.setInstallHw(map.isInstallHw());
-        flow.setInstructions(map.getInstructions());
-        if(map.getFlowId()!= null)
+        }
+        if(map.getFlowId()!= null) {
             flow.setKey(new FlowKey(new FlowId(map.getKey().getFlowId().getValue())));
-        flow.setMatch(map.getMatch());
-        flow.setOutGroup(map.getOutGroup());
-        flow.setOutPort(map.getOutPort());
-        flow.setPriority(map.getPriority());
-        flow.setStrict(map.isStrict());
-        flow.setTableId(tableId);
+        }
 
         Flow flowRule = flow.build();
 
@@ -105,22 +89,6 @@ final class FlowStatsTracker extends AbstractListeningStatsTracker<FlowAndStatis
         flowStatistics.setByteCount(flowStats.getByteCount());
         flowStatistics.setPacketCount(flowStats.getPacketCount());
         flowStatistics.setDuration(flowStats.getDuration());
-        flowStatistics.setContainerName(map.getContainerName());
-        flowStatistics.setBufferId(map.getBufferId());
-        flowStatistics.setCookie(map.getCookie());
-        flowStatistics.setCookieMask(map.getCookieMask());
-        flowStatistics.setFlags(map.getFlags());
-        flowStatistics.setFlowName(map.getFlowName());
-        flowStatistics.setHardTimeout(map.getHardTimeout());
-        flowStatistics.setIdleTimeout(map.getIdleTimeout());
-        flowStatistics.setInstallHw(map.isInstallHw());
-        flowStatistics.setInstructions(map.getInstructions());
-        flowStatistics.setMatch(map.getMatch());
-        flowStatistics.setOutGroup(map.getOutGroup());
-        flowStatistics.setOutPort(map.getOutPort());
-        flowStatistics.setPriority(map.getPriority());
-        flowStatistics.setStrict(map.isStrict());
-        flowStatistics.setTableId(tableId);
 
         flowStatisticsData.setFlowStatistics(flowStatistics.build());
 
@@ -143,13 +111,12 @@ final class FlowStatsTracker extends AbstractListeningStatsTracker<FlowAndStatis
                             .augmentation(FlowCapableNode.class)
                             .child(Table.class, new TableKey(tableId))
                             .child(Flow.class,existingFlow.getKey()).toInstance();
-                    flowBuilder.setKey(existingFlow.getKey());
-                    flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
+                    flow.setKey(existingFlow.getKey());
+                    flow.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
                     logger.debug("Found matching flow in the datastore, augmenting statistics");
                     // Update entry with timestamp of latest response
-                    flow.setKey(existingFlow.getKey());
                     FlowStatsEntry flowStatsEntry = new FlowStatsEntry(tableId,flow.build());
-                    trans.putOperationalData(flowRef, flowBuilder.build());
+                    trans.putOperationalData(flowRef, flow.build());
                     return flowStatsEntry;
                 }
             }
@@ -168,13 +135,12 @@ final class FlowStatsTracker extends AbstractListeningStatsTracker<FlowAndStatis
                                 .augmentation(FlowCapableNode.class)
                                 .child(Table.class, new TableKey(tableId))
                                 .child(Flow.class,existingFlow.getKey()).toInstance();
-                        flowBuilder.setKey(existingFlow.getKey());
-                        flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
+                        flow.setKey(existingFlow.getKey());
+                        flow.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
                         logger.debug("Found matching unaccounted flow in the operational datastore, augmenting statistics");
                         // Update entry with timestamp of latest response
-                        flow.setKey(existingFlow.getKey());
                         FlowStatsEntry flowStatsEntry = new FlowStatsEntry(tableId,flow.build());
-                        trans.putOperationalData(flowRef, flowBuilder.build());
+                        trans.putOperationalData(flowRef, flow.build());
                         return flowStatsEntry;
                     }
                 }
@@ -187,15 +153,15 @@ final class FlowStatsTracker extends AbstractListeningStatsTracker<FlowAndStatis
         InstanceIdentifier<Flow> flowRef = getNodeIdentifierBuilder().augmentation(FlowCapableNode.class)
                     .child(Table.class, new TableKey(tableId))
                     .child(Flow.class,newFlowKey).toInstance();
-        flowBuilder.setKey(newFlowKey);
-        flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
+        flow.setKey(newFlowKey);
+        flow.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
         logger.debug("Flow {} is not present in config data store, augmenting statistics as an unaccounted flow",
-                    flowBuilder.build());
+                    flow.build());
 
         // Update entry with timestamp of latest response
         flow.setKey(newFlowKey);
         FlowStatsEntry flowStatsEntry = new FlowStatsEntry(tableId,flow.build());
-        trans.putOperationalData(flowRef, flowBuilder.build());
+        trans.putOperationalData(flowRef, flow.build());
         return flowStatsEntry;
     }
 
index b96d2be47e11b5f66fda9bc2d4df156e1b08c421..8c9b60e43f0b7dc373b3365039ab950f86df6bfc 100644 (file)
@@ -28,7 +28,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.slf4j.Logger;
@@ -76,7 +75,7 @@ public class StatisticsProvider implements AutoCloseable {
 
     private final StatisticsListener updateCommiter = new StatisticsListener(StatisticsProvider.this);
 
-    private Registration<NotificationListener> listenerRegistration;
+    private ListenerRegistration<NotificationListener> listenerRegistration;
 
     private ListenerRegistration<DataChangeListener> flowCapableTrackerRegistration;
 
index 0ae33b8c71fa93add1914d79c595c14538b0737f..29a27e2bb2a2cdfc85c7b49eada243bdc9f8a531 100644 (file)
@@ -48,9 +48,13 @@ public class StatisticsRequestScheduler implements DataTransactionListener {
     private final TimerTask task = new TimerTask() {
         @Override
         public void run() {
-            long now = System.nanoTime();
-            if(now > lastRequestTime+TimeUnit.MILLISECONDS.toNanos(REQUEST_MONITOR_INTERVAL)){
-                requestStatistics();
+            try{
+                long now = System.nanoTime();
+                if(now > lastRequestTime+TimeUnit.MILLISECONDS.toNanos(REQUEST_MONITOR_INTERVAL)){
+                    requestStatistics();
+                }
+            }catch (IllegalArgumentException | IllegalStateException | NullPointerException e){
+                srsLogger.warn("Exception occured while sending statistics request : {}",e);
             }
         }
     };
index b219722ba864eb6a5b306171038112e5a2f2ebf9..91db6e264b63518f48f9326882ea994ebb9a3bd4 100644 (file)
@@ -9,7 +9,7 @@ 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.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -19,7 +19,7 @@ public class LLDPDiscoveryProvider implements AutoCloseable {
     private DataProviderService dataService;
     private NotificationProviderService notificationService;
     private final LLDPDiscoveryListener commiter = new LLDPDiscoveryListener(LLDPDiscoveryProvider.this);
-    private Registration<NotificationListener> listenerRegistration;
+    private ListenerRegistration<NotificationListener> listenerRegistration;
 
     public DataProviderService getDataService() {
         return this.dataService;
@@ -38,7 +38,7 @@ public class LLDPDiscoveryProvider implements AutoCloseable {
     }
 
     public void start() {
-        Registration<NotificationListener> registerNotificationListener = this.getNotificationService().registerNotificationListener(this.commiter);
+        ListenerRegistration<NotificationListener> registerNotificationListener = this.getNotificationService().registerNotificationListener(this.commiter);
         this.listenerRegistration = registerNotificationListener;
         LLDPLinkAger.getInstance().setManager(this);
         LOG.info("LLDPDiscoveryListener Started.");
index d656bda932f2251e18ea7f71f6c19500115456d3..a87971bc6bc0e1d6a294c30a08dfb73cf81484be 100644 (file)
@@ -19,7 +19,7 @@ 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.rev131021.network.topology.Topology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.osgi.framework.BundleContext;
@@ -28,7 +28,7 @@ import org.slf4j.LoggerFactory;
 
 public class FlowCapableTopologyProvider extends AbstractBindingAwareProvider implements AutoCloseable {
     private final static Logger LOG = LoggerFactory.getLogger(FlowCapableTopologyProvider.class);
-    private Registration<NotificationListener> listenerRegistration;
+    private ListenerRegistration<NotificationListener> listenerRegistration;
     private Thread thread;
 
     /**
index c10f0a9089ed5341550d21a62ea68c3ac67c9a02..8a29139854c3f801cc372c7c7ac94a1995c20ce4 100644 (file)
                             org.opendaylight.controller.netconf.confignetconfconnector.transactions,
                             org.opendaylight.controller.netconf.confignetconfconnector.util,
                             org.opendaylight.controller.netconf.confignetconfconnector.osgi,
-                            org.opendaylight.controller.config.util,
                             org.opendaylight.controller.netconf.confignetconfconnector.exception,</Private-Package>
             <Import-Package>com.google.common.base,
                             com.google.common.collect,
                             com.google.common.io,
                             org.opendaylight.yangtools.yang.model.api.type,
                             org.opendaylight.yangtools.sal.binding.generator.spi,
-                            org.opendaylight.yangtools.sal.binding.yang.types,</Import-Package>
+                            org.opendaylight.yangtools.sal.binding.yang.types,
+                            org.opendaylight.controller.config.util
+              </Import-Package>
             <Export-Package></Export-Package>
           </instructions>
         </configuration>
index a2b8e0bfdf6b97a5cc4cdf1e361084e6be0d1078..104bf4df94c86dfe8b5bb44674020feb0f1c5ecb 100644 (file)
@@ -45,6 +45,6 @@ public class SimpleIdentityRefAttributeWritingStrategy extends SimpleAttributeWr
         QName qName = QName.create(value);
         String identityValue = qName.getLocalName();
         String identityNamespace = qName.getNamespace().toString();
-        return XmlUtil.createTextElementWithNamespacedContent(doc, key, PREFIX, identityNamespace, identityValue);
+        return XmlUtil.createTextElementWithNamespacedContent(doc, key, PREFIX, identityNamespace, identityValue, namespace);
     }
 }
index f86d641112585515198e9cbad18cce3c62a89389..2b363ea153960eeb98754855ffa54473e43fad14 100644 (file)
@@ -13,11 +13,12 @@ import java.util.Map;
 import javax.management.InstanceNotFoundException;
 import javax.management.ObjectName;
 import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.yangtools.yang.common.QName;
 
 public class ServiceRegistryWrapper {
 
-    private ServiceReferenceReadableRegistry configServiceRefRegistry;
+    private final ServiceReferenceReadableRegistry configServiceRefRegistry;
 
     public ServiceRegistryWrapper(ServiceReferenceReadableRegistry configServiceRefRegistry) {
         this.configServiceRefRegistry = configServiceRefRegistry;
@@ -43,7 +44,12 @@ public class ServiceRegistryWrapper {
 
         String qNameOfService = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName);
         try {
-            return configServiceRefRegistry.getServiceReference(qNameOfService, refName);
+            /*
+             Remove transaction name as this is redundant - will be stripped in DynamicWritableWrapper,
+             and makes it hard to compare with service references got from MXBean attributes
+            */
+            return ObjectNameUtil.withoutTransactionName(
+                    configServiceRefRegistry.getServiceReference(qNameOfService, refName));
         } catch (InstanceNotFoundException e) {
             throw new IllegalArgumentException("No serviceInstance mapped to " + refName
                     + " under service name " + serviceName + " , " + refNameToInstance.keySet(), e);
index 37ad2bb22260ab45027b635d5671da8077d823b7..59a1d4fe7141bbe54a2dc770a4d2c789819bf52d 100644 (file)
@@ -104,8 +104,11 @@ public final class Services {
 
             String serviceName =  ObjectNameAttributeReadingStrategy.checkPrefixAndExtractServiceName(typeElement, prefixNamespace);
 
-            Map<String, String> innerMap = Maps.newHashMap();
-            namespaceToServices.put(serviceName, innerMap);
+            Map<String, String> innerMap = namespaceToServices.get(serviceName);
+            if (innerMap == null) {
+                innerMap = Maps.newHashMap();
+                namespaceToServices.put(serviceName, innerMap);
+            }
 
             List<XmlElement> instances = service.getChildElements(XmlNetconfConstants.INSTANCE_KEY);
             service.checkUnrecognisedElements(instances, typeElement);
index 6ebeeaa07ba86034991ffd584448135bd2ec5b13..d8ceb311038e6f0602832448a32de27db6d3e664 100644 (file)
@@ -8,6 +8,10 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
 
+import static java.util.Arrays.asList;
+
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import javax.management.Attribute;
@@ -30,7 +34,7 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy {
 
     @Override
     void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-            String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
+                               String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
         throw new NetconfConfigHandlingException(
                 String.format("Unable to handle missing instance, no missing instances should appear at this point, missing: %s : %s ",
                         module,
@@ -39,6 +43,7 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy {
                 NetconfDocumentedException.ErrorTag.operation_failed,
                 NetconfDocumentedException.ErrorSeverity.error);
     }
+
     @Override
     void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
 
@@ -51,10 +56,16 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy {
                     continue;
                 }
 
-                Object value = ace.getResolvedValue().get();
-                ta.setAttribute(on, ace.getJmxName(), new Attribute(ace.getJmxName(), value));
-                logger.debug("Attribute {} set to {} for {}", configAttributeEntry.getKey(), value, on);
+                Object toBeMergedIn = ace.getResolvedValue().get();
+                // Get the existing values so we can merge the new values with them.
+                Attribute currentAttribute = ta.getAttribute(on, ace.getJmxName());
+                Object oldValue = (currentAttribute != null ? currentAttribute.getValue() : null);
+                // Merge value with currentValue
+                toBeMergedIn = merge(oldValue, toBeMergedIn);
+                ta.setAttribute(on, ace.getJmxName(), new Attribute(ace.getJmxName(), toBeMergedIn));
+                logger.debug("Attribute {} set to {} for {}", configAttributeEntry.getKey(), toBeMergedIn, on);
             } catch (Exception e) {
+                logger.error("Error while merging objectnames of {}", on, e);
                 throw new NetconfConfigHandlingException(String.format("Unable to set attributes for %s, Error with attribute %s : %s ",
                         on,
                         configAttributeEntry.getKey(),
@@ -65,4 +76,44 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy {
             }
         }
     }
+
+    /**
+     * Merge value into current value
+     * Currently, this is only implemented for arrays of ObjectNames, but that is the
+     * most common case for which it is needed.
+     */
+    protected Object merge(Object oldValue, Object toBeMergedIn) {
+        if (oldValue instanceof ObjectName[] && toBeMergedIn instanceof ObjectName[]) {
+            toBeMergedIn = mergeObjectNameArrays((ObjectName[]) oldValue, (ObjectName[]) toBeMergedIn);
+        }
+        return toBeMergedIn;
+    }
+
+    /**
+     * Merge value into current values
+     * This implements for arrays of ObjectNames, but that is the
+     * most common case for which it is needed.
+     *
+     * @param oldValue - the new values to be merged into existing values
+     * @param toBeMergedIn - the existing values
+     *
+     * @return an ObjectName[] consisting the elements of currentValue with an elements from values not already present in currentValue added
+     *
+     */
+    protected ObjectName[] mergeObjectNameArrays(ObjectName[] oldValue, ObjectName[] toBeMergedIn) {
+        List<ObjectName> newValueList = new ArrayList<>();
+        newValueList.addAll(asList(oldValue));
+        /*
+         It is guaranteed that old values do not contain transaction name.
+         Since toBeMergedIn is filled using service references translated by ServiceRegistryWrapper, it
+         is also guaranteed that this list will not contain transaction names.
+         Run through the list of values to be merged.  If we don't have them already, add them to the list.
+         */
+        for (ObjectName objName : toBeMergedIn) {
+            if (!newValueList.contains(objName)) {
+                newValueList.add(objName);
+            }
+        }
+        return newValueList.toArray(new ObjectName[newValueList.size()]);
+    }
 }
index 5840c9dbd14d1aa3b3fe050d079e426d8ec21f20..85cdf0335fecc793fc29e0c357f41cf4ee41c1e6 100644 (file)
@@ -9,33 +9,65 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 
 import java.lang.ref.SoftReference;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+import java.util.concurrent.atomic.AtomicReference;
 
-import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class YangStoreServiceImpl implements YangStoreService {
+    private static final Logger LOG = LoggerFactory.getLogger(YangStoreServiceImpl.class);
+
+    /**
+     * This is a rather interesting locking model. We need to guard against both the
+     * cache expiring from GC and being invalidated by schema context change. The
+     * context can change while we are doing processing, so we do not want to block
+     * it, so no synchronization can happen on the methods.
+     *
+     * So what we are doing is the following:
+     *
+     * We synchronize with GC as usual, using a SoftReference.
+     *
+     * The atomic reference is used to synchronize with {@link #refresh()}, e.g. when
+     * refresh happens, it will push a SoftReference(null), e.g. simulate the GC. Now
+     * that may happen while the getter is already busy acting on the old schema context,
+     * so it needs to understand that a refresh has happened and retry. To do that, it
+     * attempts a CAS operation -- if it fails, in knows that the SoftReference has
+     * been replaced and thus it needs to retry.
+     *
+     * Note that {@link #getYangStoreSnapshot()} will still use synchronize() internally
+     * to stop multiple threads doing the same work.
+     */
+    private final AtomicReference<SoftReference<YangStoreSnapshotImpl>> ref = new AtomicReference<>(new SoftReference<YangStoreSnapshotImpl>(null));
     private final SchemaContextProvider service;
-    @GuardedBy("this")
-    private SoftReference<YangStoreSnapshotImpl> cache = new SoftReference<>(null);
 
-    public YangStoreServiceImpl(SchemaContextProvider service) {
+    public YangStoreServiceImpl(final SchemaContextProvider service) {
         this.service = service;
     }
 
     @Override
     public synchronized YangStoreSnapshotImpl getYangStoreSnapshot() throws YangStoreException {
-        YangStoreSnapshotImpl yangStoreSnapshot = cache.get();
-        if (yangStoreSnapshot == null) {
-            yangStoreSnapshot = new YangStoreSnapshotImpl(service.getSchemaContext());
-            cache = new SoftReference<>(yangStoreSnapshot);
+        SoftReference<YangStoreSnapshotImpl> r = ref.get();
+        YangStoreSnapshotImpl ret = r.get();
+
+        while (ret == null) {
+            // We need to be compute a new value
+            ret = new YangStoreSnapshotImpl(service.getSchemaContext());
+
+            if (!ref.compareAndSet(r, new SoftReference<>(ret))) {
+                LOG.debug("Concurrent refresh detected, recomputing snapshot");
+                r = ref.get();
+                ret = null;
+            }
         }
-        return yangStoreSnapshot;
+
+        return ret;
     }
 
     /**
      * Called when schema context changes, invalidates cache.
      */
-    public synchronized void refresh() {
-        cache.clear();
+    public void refresh() {
+        ref.set(new SoftReference<YangStoreSnapshotImpl>(null));
     }
 }
index 782998067f80d5fc35a1249dedbaa8e0dcf4e37b..827708f31ceb52fbc39bd8c202fa630cf698d225 100644 (file)
@@ -9,6 +9,13 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 
 import com.google.common.collect.Maps;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.PackageTranslator;
 import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
@@ -21,18 +28,12 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
 public class YangStoreSnapshotImpl implements YangStoreSnapshot {
     private static final Logger logger = LoggerFactory.getLogger(YangStoreSnapshotImpl.class);
 
 
     private final Map<String /* Namespace from yang file */,
-            Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> moduleMXBeanEntryMap;
+    Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> moduleMXBeanEntryMap;
 
 
     private final Map<QName, Map<String, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries;
@@ -40,7 +41,7 @@ public class YangStoreSnapshotImpl implements YangStoreSnapshot {
     private final SchemaContext schemaContext;
 
 
-    public YangStoreSnapshotImpl(SchemaContext resolveSchemaContext) {
+    public YangStoreSnapshotImpl(final SchemaContext resolveSchemaContext) {
         logger.trace("Resolved modules:{}", resolveSchemaContext.getModules());
         this.schemaContext = resolveSchemaContext;
         // JMX generator
@@ -60,7 +61,7 @@ public class YangStoreSnapshotImpl implements YangStoreSnapshot {
                     qNamesToSIEs.put(sieEntry.getKey(), sieEntry.getValue());
                 } else {
                     throw new IllegalStateException("Cannot add two SIE with same qname "
-                                    + sieEntry.getValue());
+                            + sieEntry.getValue());
                 }
             }
         }
@@ -75,7 +76,7 @@ public class YangStoreSnapshotImpl implements YangStoreSnapshot {
             TypeProviderWrapper typeProviderWrapper = new TypeProviderWrapper(
                     new TypeProviderImpl(resolveSchemaContext));
 
-            QName qName = new QName(module.getNamespace(), module.getRevision(), module.getName());
+            QName qName = QName.create(module.getNamespace(), module.getRevision(), module.getName());
 
             Map<String /* MB identity local name */, ModuleMXBeanEntry> namesToMBEs =
                     Collections.unmodifiableMap(ModuleMXBeanEntry.create(module, qNamesToSIEs, resolveSchemaContext,
@@ -105,7 +106,7 @@ public class YangStoreSnapshotImpl implements YangStoreSnapshot {
     }
 
     @Override
-    public String getModuleSource(org.opendaylight.yangtools.yang.model.api.ModuleIdentifier moduleIdentifier) {
+    public String getModuleSource(final org.opendaylight.yangtools.yang.model.api.ModuleIdentifier moduleIdentifier) {
         return schemaContext.getModuleSource(moduleIdentifier).get();
     }
 
diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategyTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategyTest.java
new file mode 100644 (file)
index 0000000..b187749
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
+
+import static java.util.Arrays.asList;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.opendaylight.controller.config.api.jmx.ObjectNameUtil.createReadOnlyModuleON;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+import java.util.List;
+import java.util.Map;
+import javax.management.ObjectName;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModule;
+import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleFactory;
+import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleMXBean;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
+
+public class MergeEditConfigStrategyTest extends AbstractConfigTest {
+    private static final MultipleDependenciesModuleFactory factory = new MultipleDependenciesModuleFactory();
+    public static final String PARENT = "parent";
+    public static final String D1 = "d1";
+    public static final String D2 = "d2";
+    public static final String D3 = "d3";
+
+    private static final String factoryName = factory.getImplementationName();
+
+    @Before
+    public void setUp() throws Exception {
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory));
+
+        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+        ObjectName d1 = transaction.createModule(factoryName, D1);
+        ObjectName d2 = transaction.createModule(factoryName, D2);
+        ObjectName parent = transaction.createModule(factoryName, PARENT);
+        MultipleDependenciesModuleMXBean multipleDependenciesModuleMXBean = transaction.newMXBeanProxy(parent,
+                MultipleDependenciesModuleMXBean.class);
+        multipleDependenciesModuleMXBean.setTestingDeps(asList(d1, d2));
+        transaction.createModule(factoryName, D3);
+        transaction.commit();
+    }
+
+    @Test
+    public void testMergingOfObjectNames() throws Exception {
+        MergeEditConfigStrategy strategy = new MergeEditConfigStrategy();
+        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+
+        // add D3
+
+        AttributeConfigElement attributeConfigElement = mock(AttributeConfigElement.class);
+        doReturn(Optional.of(new ObjectName[] {createReadOnlyModuleON(factoryName, D3)})).when(attributeConfigElement).getResolvedValue();
+        doReturn("mocked").when(attributeConfigElement).toString();
+        String attributeName = MultipleDependenciesModule.testingDepsJmxAttribute.getAttributeName();
+        doReturn(attributeName).when(attributeConfigElement).getJmxName();
+        Map<String, AttributeConfigElement> configuration = ImmutableMap.of(
+                attributeName,
+                attributeConfigElement);
+
+        strategy.executeConfiguration(factoryName, PARENT, configuration, transaction,
+                mock(ServiceRegistryWrapper.class));
+        transaction.commit();
+
+        // parent's attribute should contain d1,d2,d3
+        MultipleDependenciesModuleMXBean proxy = configRegistryClient.newMXBeanProxy(
+                createReadOnlyModuleON(factoryName, PARENT),
+                MultipleDependenciesModuleMXBean.class);
+        List<ObjectName> testingDeps = proxy.getTestingDeps();
+        List<ObjectName> expected = asList(createReadOnlyModuleON(factoryName, D1),
+                createReadOnlyModuleON(factoryName, D2),
+                createReadOnlyModuleON(factoryName, D3));
+        assertEquals(expected, testingDeps);
+    }
+}
index a063f5786a8f4796d95023849fbc6243e873fa01..1e650c08b124a460c7d19f65200c1b0868ccee17 100644 (file)
@@ -8,14 +8,12 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.matchers.JUnitMatchers;
-import org.opendaylight.controller.config.api.LookupRegistry;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.yangtools.yang.common.QName;
 
 import java.net.URI;
 import java.text.ParseException;
@@ -24,9 +22,12 @@ import java.util.Date;
 import java.util.Map;
 import java.util.Set;
 
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.matchers.JUnitMatchers;
+import org.opendaylight.controller.config.api.LookupRegistry;
+import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
+import org.opendaylight.yangtools.yang.common.QName;
 
 public class NetconfOperationServiceImplTest {
 
@@ -72,15 +73,15 @@ public class NetconfOperationServiceImplTest {
             Assert.assertThat(
                     message,
                     JUnitMatchers
-                            .containsString("missing from config subsystem but present in yangstore: [(namespace?revision=1970-01-01)qname2]"));
+                    .containsString("missing from config subsystem but present in yangstore: [(namespace?revision=1970-01-01)qname2]"));
             Assert.assertThat(
                     message,
                     JUnitMatchers
-                            .containsString("All modules present in config: [(namespace?revision=1970-01-01)qname1]"));
+                    .containsString("All modules present in config: [(namespace?revision=1970-01-01)qname1]"));
         }
     }
 
-    private YangStoreSnapshot mockYangStoreSnapshot(String... qnames) {
+    private YangStoreSnapshot mockYangStoreSnapshot(final String... qnames) {
         YangStoreSnapshot mock = mock(YangStoreSnapshot.class);
 
         Map<String, Map<String, ModuleMXBeanEntry>> map = Maps.newHashMap();
@@ -99,18 +100,18 @@ public class NetconfOperationServiceImplTest {
         return mock;
     }
 
-    private ModuleMXBeanEntry mockMBeanEntry(String qname) {
+    private ModuleMXBeanEntry mockMBeanEntry(final String qname) {
         ModuleMXBeanEntry mock = mock(ModuleMXBeanEntry.class);
         QName q = getQName(qname);
         doReturn(q).when(mock).getYangModuleQName();
         return mock;
     }
 
-    private QName getQName(String qname) {
-        return new QName(URI.create("namespace"), date1970_01_01, qname);
+    private QName getQName(final String qname) {
+        return QName.create(URI.create("namespace"), date1970_01_01, qname);
     }
 
-    private LookupRegistry mockJmxClient(String... visibleQNames) {
+    private LookupRegistry mockJmxClient(final String... visibleQNames) {
         LookupRegistry mock = mock(LookupRegistry.class);
         Set<String> qnames = Sets.newHashSet();
         for (String visibleQName : visibleQNames) {
index 6fb231d847f2c5ae8c2022a7951460e19199ff70..3f04010015e8291d8dbeb6e47415d6ab8a12ad3f 100644 (file)
@@ -7,20 +7,25 @@
  */
 package org.opendaylight.controller.netconf.persist.impl.osgi;
 
-import org.junit.matchers.JUnitMatchers;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.fail;
 
+import org.junit.matchers.JUnitMatchers;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 final class TestingExceptionHandler implements Thread.UncaughtExceptionHandler {
 
+    private static final Logger logger = LoggerFactory.getLogger(ConfigPersisterTest.class);
+
     private Throwable t;
 
     @Override
     public void uncaughtException(Thread t, Throwable e) {
+        logger.debug("Uncaught exception in thread {}", t, e);
         this.t = e;
     }
 
diff --git a/opendaylight/netconf/netconf-cli/.gitignore b/opendaylight/netconf/netconf-cli/.gitignore
new file mode 100644 (file)
index 0000000..d5de9f2
--- /dev/null
@@ -0,0 +1,2 @@
+*.log
+cache
diff --git a/opendaylight/netconf/netconf-cli/README b/opendaylight/netconf/netconf-cli/README
new file mode 100644 (file)
index 0000000..c6a0af4
--- /dev/null
@@ -0,0 +1,113 @@
+usage: 
+Submit address + port for initial TCP connection (PURE TCP CONNECTIONS ARE NOT SUPPORTED YET)
+Submit username + password in addition to address + port for initial SSH connection
+If no arguments(or unexpected combination) is submitted, cli will be started without initial connection
+To use with ODL controller, run with: java -jar netconf-cli-0.2.5-SNAPSHOT-executable.jar  --server localhost --port 1830 --username admin --password admin
+
+Generic cli for netconf devices
+
+optional arguments:
+  -h, --help             show this help message and exit
+
+TCP:
+  Base arguments to initiate TCP connection right away
+
+  --server SERVER        Netconf device ip-address/domain name
+  --port PORT            Netconf device port
+
+SSH:
+  SSH credentials, if provided, initial connection will be attempted using SSH
+
+  --username USERNAME    Username for SSH connection
+  --password PASSWORD    Password for SSH connection
+------------------------------------------------------------------------
+
+To run the cli execute:
+
+java -jar netconf-cli-0.2.5-SNAPSHOT-executable.jar --username user --password password --server serverIP --port optionalPort
+
+The cli will connect to the remote device automatically.
+The initialization may take a few moments depending on the size of schemas provided by the device.
+To view the progress, one can take a look inside netconfcli.log file (All logs are in this file starting with level TRACE).
+Cli does not print any logging messages to the console, only to the file.
+
+------------------------------------------------------------------------
+
+Correct initialization + connection should display following output:
+
+[maros@localhost target]$ java -jar netconf-cli-0.2.5-SNAPSHOT-executable.jar  --server localhost --port 1830 --username admin --password admin
+Connecting to localhost via SSH. Please wait.
+Cli is up, available commands:
+
+add-flow(sal-flow)                                                                            add-group(sal-group)                                                                          
+add-meter(sal-meter)                                                                          begin-transaction(sal-remote)                                                                 
+cancel-commit(ietf-netconf)                                                                   cancel-toast(toaster)                                                                         
+clear-toasts-made(toaster-provider-impl)                                                      close(netconf-cli)                                                                            
+close-session(ietf-netconf)                                                                   commit(ietf-netconf)                                                                          
+connect(netconf-cli)                                                                          copy-config(ietf-netconf)                                                                     
+create-data-change-event-subscription(sal-remote)                                             create-notification-stream(sal-remote)                                                        
+delete-config(ietf-netconf)                                                                   discard-changes(ietf-netconf)                                                                 
+disconnect(netconf-cli)                                                                       edit-config(ietf-netconf)                                                                     
+finish-transaction(flow-capable-transaction)                                                  get(ietf-netconf)                                                                             
+get-aggregate-flow-statistics-from-flow-table-for-all-flows(opendaylight-flow-statistics)     get-aggregate-flow-statistics-from-flow-table-for-given-match(opendaylight-flow-statistics)   
+get-all-flow-statistics-from-flow-table(opendaylight-flow-statistics)                         get-all-flows-statistics-from-all-flow-tables(opendaylight-flow-statistics)                   
+get-all-group-statistics(opendaylight-group-statistics)                                       get-all-meter-config-statistics(opendaylight-meter-statistics)                                
+get-all-meter-statistics(opendaylight-meter-statistics)                                       get-all-node-connectors-statistics(opendaylight-port-statistics)                              
+get-all-queues-statistics-from-all-ports(opendaylight-queue-statistics)                       get-all-queues-statistics-from-given-port(opendaylight-queue-statistics)                      
+get-config(ietf-netconf)                                                                      get-dead-events-count(threadpool-impl)                                                        
+get-flow-statistics-from-flow-table(opendaylight-flow-statistics)                             get-flow-tables-statistics(opendaylight-flow-table-statistics)                                
+get-group-description(opendaylight-group-statistics)                                          get-group-features(opendaylight-group-statistics)                                             
+get-group-statistics(opendaylight-group-statistics)                                           get-meter-features(opendaylight-meter-statistics)                                             
+get-meter-statistics(opendaylight-meter-statistics)                                           get-next-transaction-id(flow-capable-transaction)                                             
+get-node-connector-statistics(opendaylight-port-statistics)                                   get-queue(sal-queue)                                                                          
+get-queue-statistics-from-given-port(opendaylight-queue-statistics)                           get-schema(ietf-netconf-monitoring)                                                           
+help(netconf-cli)                                                                             kill-session(ietf-netconf)                                                                    
+lock(ietf-netconf)                                                                            make-scrambled-with-wheat(kitchen-service-impl)                                               
+make-toast(toaster)                                                                           remove-flow(sal-flow)                                                                         
+remove-group(sal-group)                                                                       remove-meter(sal-meter)                                                                       
+reset(config-logging)                                                                         restock-toaster(toaster)                                                                      
+shutdown(shutdown-impl)                                                                       solicit-refresh(flow-topology-discovery)                                                      
+transmit-packet(packet-processing)                                                            unlock(ietf-netconf)                                                                          
+update-flow(sal-flow)                                                                         update-group(sal-group)                                                                       
+update-meter(sal-meter)                                                                       update-port(sal-port)                                                                         
+update-table(sal-table)                                                                       validate(ietf-netconf)                                                                        
+
+netconf()>
+
+
+------------------------------------------------------------------------
+
+At this stage, any supported rpc can be invoked. To see all possible rpcs press TAB (serves as autocomplete). The output contains all the commands reported after at start-up
+
+------------------------------------------------------------------------
+
+Example step-by-step execution of get-config rpc:
+
+1. Type get-config, hit TAB, hit enter
+2. Cli will now walk all the input arguments of get-config rpc and ask for value
+3. Cli asks for filter value
+4. Submit filter (using TAB autocomplete) as a schema path or type "skip" (to not add any filter) and hit enter
+5. Cli asks for config source (e.g. which data-store to query)
+6. Use TAB to view options and submit either running or candidate data-store
+7. Cli will display configuration of the remote device e.g. :
+
+data {
+  a {
+    address {
+      last-name a
+      first-name o
+      street aaaaa
+    }
+    address {
+      last-name a
+      first-name t
+    }
+    address {
+      last-name a
+      first-name y
+    }
+  }
+}
+
+
+------------------------------------------------------------------------
diff --git a/opendaylight/netconf/netconf-cli/README_ODL b/opendaylight/netconf/netconf-cli/README_ODL
new file mode 100644 (file)
index 0000000..3a15454
--- /dev/null
@@ -0,0 +1,154 @@
+This file contains ODL controller specific examples:
+
+1A. Connecting to ODL controller automatically:
+    a. Make sure ODL controller is running on your or any other accessible device
+    b. Start the cli using this command (in folder controller/opendaylight/netconf/netconf-cli/target/):
+        java -jar netconf-cli-0.2.5-SNAPSHOT-executable.jar  --server localhost --port 1830 --username admin --password admin
+    c. The cli will start up in aprox. 20 seconds (Schema download might take some time on the first connection, subsequent attempts should take less time)
+    d. You should see the list of commands avaliable in the controller e.g.:
+        add-flow(sal-flow)                                                                            add-group(sal-group)                                                                          
+        add-meter(sal-meter)                                                                          begin-transaction(sal-remote)                                                                 
+        cancel-commit(ietf-netconf)                                                                   cancel-toast(toaster)                                                                         
+        clear-toasts-made(toaster-provider-impl)                                                      close(netconf-cli)                                                                            
+        close-session(ietf-netconf)                                                                   commit(ietf-netconf)                                                                          
+        connect(netconf-cli)                                                                          copy-config(ietf-netconf)                                                                     
+        create-data-change-event-subscription(sal-remote)                                             ....
+
+
+1B. Connecting to ODL from the CLI:
+    a. Make sure ODL controller is running on your or any other accessible device
+    b. Start the cli using this command (in folder controller/opendaylight/netconf/netconf-cli/target/):
+        java -jar netconf-cli-0.2.5-SNAPSHOT-executable.jar
+    c. The cli will start app right away (few seconds)
+    d. You should see only the basic commands e.g. connect, close, help, disconnect 
+    e. Type connect, hit TAB, hit ENTER
+    f. Cli will ask for connect arguments: [address-name, address-port, user-name, user-password]
+    g. Address-name
+        The cli will ask what type of address you want to provide (domain-name or ip-address). This is caused by the yang model for connect command, the address-name is of type ietf-inet-types:host, which is a union of domain-name and ip-address.
+        Submit "domain-name" (TAB can be used for autocompete)
+        Now you need to provide value, submit "localhost" (TAB can be used for autocomplete, as "localhost" is the default value)
+    h. Address-port
+        Submit 1830 (default port for netconf SSH server in ODL)
+    i. User-name
+        Submit "admin"
+    j. User-password
+        Submit "admin"
+    k. The connection will be up in aprox. 20 seconds (Schema download might take some time on the first connection, subsequent attempts should take less time)
+    l. You should see the list of commands available in the controller
+
+
+2.  Disconnecting from ODL in the CLI
+    a. Execute scenario 1A or 1B
+    b. Type "disconn", hit TAB, hit Enter
+    c. You should see the following output:
+        status Connection disconnected
+    d. Use TAB to see available commands, only local commands are present now
+    e. Now you can use the connect command(as in 1B) to connect again
+
+
+3.  Using help command
+    a. Help command can be executed in connected as well as disconnected state
+    b. Type "help", hit TAB, hit Enter
+    c. You should see the help conent containing the list of all available commands with description for each of them e.g.
+        commands  {
+          commands [id=close(netconf-cli)] {
+            id close(netconf-cli)
+            description Close the whole cli
+          }
+          commands [id=help(netconf-cli)] {
+            id help(netconf-cli)
+            description Display help
+          }
+          commands [id=disconnect(netconf-cli)] {
+            id disconnect(netconf-cli)
+            description Disconnect from a netconf device that is currently connected
+          }
+          commands [id=connect(netconf-cli)] {
+            id connect(netconf-cli)
+            description Connect to a remote netconf device, if not connected yet. Connection initialization is blocking and might take some time, depending on amount of yang schemas in remote device.
+          }
+        }
+
+
+4.  Executing get-config command (get-config(ietf-netconf))
+    a. Execute scenario 1A or 1B
+    b. Type "get-config", hit TAB, hit Enter
+    c. Cli will ask for get-config arguments: [filter, source]
+    d. Filter
+        Submit "skip" (This will ignore the filter attribute, ODL does not support filtering at this moment, but will be supported in near future)
+    e. Source
+        You have to choose from candidate, running, startup. Submit running.
+    f. You should see the whole configuration of the ODL e.g.:
+        data {
+          modules {
+            module  {
+              module [name=toaster-provider-impl] {
+                name toaster-provider-impl
+                type (urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl?revision=2014-01-31)toaster-provider-impl
+                choice configuration (toaster-provider-impl)  {
+                    ...
+
+
+5.  Executing get command (get(ietf-netconf))
+    a. Execute scenario 1A or 1B
+    b. Type "get(", hit TAB, hit Enter
+    c. Cli will ask for get arguments: [filter]
+    d. Filter
+        Submit "skip" (This will ignore the filter attribute, ODL does not support filtering at this moment, but will be supported in near future)
+    f. You should see the whole data-tree of the ODL
+
+
+6.  Executing edit-config command (edit-config(ietf-netconf))
+    a. Execute scenario 1A or 1B
+    b. Type "edit", hit TAB, hit Enter
+    c. Cli will ask for edit-config arguments: [default-operation, edit-content, error-option, target, test-option]
+    d. Config
+        Config contains the data to be edited
+        1. First you have to specify a path pointing to a concrete data node. Use TAB to help with autocomplete.
+        Submit "modules(config)/module(config)/"
+        Module node is of type list and now you have to construct a whole new list entry for the module list.
+        2. The cli will ask for these nodes: [configuration, name, type]
+            Name - Submit any name e.g. newModule
+            Type - For Type you have to pick from available module types in the ODL, hit TAB for hints
+               Submit "threadfactory-naming(threadpool-impl)" to create a new instance of threadfactory in the ODL.
+            Configuration - For configuration you have to pick from available module types again
+               Submit "threadfactory-naming" to match previous module type
+               The cli will now ask for threadfactory-naming specific configuration: [prefix]
+                    Prefix - Submit any string
+        
+        The cli will now if you want to create another module entry.
+        Submit "N".
+    e. Default-operation
+        Submit "skip" to skip or pick from available e.g. merge, replace etc.
+    f. Error-option
+        Submit "skip" to skip option.
+    g. Config-target
+        This is a choice between running and candidate. Submit candidate to edit configuration only in the candidate datastore.
+    h. Test-option
+        Submit "skip" to skip option.
+    i. You should see OK response
+    j. You can check the candidate datastore change by executing get-config command as in scenario 4, but pick candidate as the source.
+    k. You should see this module in the output:
+        module [name=newModule] {
+            name newModule
+            type (urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?revision=2013-04-05)threadfactory-naming
+            choice configuration (threadfactory-naming)  {
+              name-prefix prefix
+            }
+          }
+
+
+7. Commiting changes from candidate to running datastore
+    a. Execute scenario 6.
+    b. Type commit, hit TAB, hit Enter
+    c. Cli will ask for commit arguments: [confirm-timeout, confirmed, persist, persist-id]. We will skip all these arguments since they are not supported in ODL. Cli should be able to detect this and not ask for them. This is a TODO, by supporting feature/if-feature detection in the CLI.
+    d. Confirm-timeout
+        Skip
+    e. Confirmed
+        N
+    f. Persist
+        Skip
+    g. Persist-id
+        Skip
+    h. You should see OK response
+    i. You can check the candidate datastore change by executing get-config command as in scenario 4.
diff --git a/opendaylight/netconf/netconf-cli/pom.xml b/opendaylight/netconf/netconf-cli/pom.xml
new file mode 100644 (file)
index 0000000..cd7a1aa
--- /dev/null
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!-- Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+  This program and the accompanying materials are made available under the
+  terms of the Eclipse Public License v1.0 which accompanies this distribution,
+  and is available at http://www.eclipse.org/legal/epl-v10.html -->
+<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>netconf-subsystem</artifactId>
+    <version>0.2.5-SNAPSHOT</version>
+  </parent>
+  <artifactId>netconf-cli</artifactId>
+  <packaging>jar</packaging>
+  <name>${project.artifactId}</name>
+
+  <!--
+  <properties>
+    <checkstyle.skip>true</checkstyle.skip>
+  </properties> -->
+
+  <dependencies>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <!--TODO configure properly -->
+    </dependency>
+    <dependency>
+      <groupId>jline</groupId>
+      <artifactId>jline</artifactId>
+      <version>2.11</version>
+    </dependency>
+    <dependency>
+      <groupId>net.sourceforge.argparse4j</groupId>
+      <artifactId>argparse4j</artifactId>
+      <version>0.4.3</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-core-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-netconf-connector</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>mockito-configuration</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-data-impl</artifactId>
+      <!--        <version>0.6.2-SNAPSHOT</version>-->
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-data-json</artifactId>
+      <version>0.6.2-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-model-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-parser-impl</artifactId>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifest>
+              <mainClass>org.opendaylight.controller.netconf.cli.Main</mainClass>
+            </manifest>
+          </archive>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-shade-plugin</artifactId>
+        <configuration></configuration>
+        <executions>
+          <execution>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+            <phase>package</phase>
+            <configuration>
+              <transformers>
+                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                  <mainClass>org.opendaylight.controller.netconf.cli.Main</mainClass>
+                </transformer>
+              </transformers>
+              <shadedArtifactAttached>true</shadedArtifactAttached>
+              <shadedClassifierName>executable</shadedClassifierName>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Cli.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Cli.java
new file mode 100644 (file)
index 0000000..a49c7b9
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import jline.console.UserInterruptException;
+import jline.console.completer.Completer;
+import jline.console.completer.StringsCompleter;
+import org.opendaylight.controller.netconf.cli.commands.Command;
+import org.opendaylight.controller.netconf.cli.commands.CommandConstants;
+import org.opendaylight.controller.netconf.cli.commands.CommandDispatcher;
+import org.opendaylight.controller.netconf.cli.commands.CommandInvocationException;
+import org.opendaylight.controller.netconf.cli.commands.input.Input;
+import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
+import org.opendaylight.controller.netconf.cli.commands.output.Output;
+import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.controller.netconf.cli.writer.WriteException;
+import org.opendaylight.controller.netconf.cli.writer.Writer;
+import org.opendaylight.controller.netconf.cli.writer.impl.CompositeNodeWriter;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+
+/**
+ * The top level cli state that dispatches command executions
+ */
+public class Cli implements Runnable {
+    private final CommandDispatcher commandRegistry;
+    private final CommandArgHandlerRegistry argumentHandlerRegistry;
+    private final SchemaContextRegistry schemaContextRegistry;
+    private final ConsoleIO consoleIO;
+
+    public Cli(final ConsoleIO consoleIO, final CommandDispatcher commandRegistry,
+            final CommandArgHandlerRegistry argumentHandlerRegistry, final SchemaContextRegistry schemaContextRegistry) {
+        this.consoleIO = consoleIO;
+        this.commandRegistry = commandRegistry;
+        this.argumentHandlerRegistry = argumentHandlerRegistry;
+        this.schemaContextRegistry = schemaContextRegistry;
+    }
+
+    @Override
+    public void run() {
+        try {
+            consoleIO.writeLn("Cli is up, available commands:");
+            final RootConsoleContext consoleContext = new RootConsoleContext(commandRegistry);
+            consoleIO.enterContext(consoleContext);
+            consoleIO.complete();
+            consoleIO.writeLn("");
+
+            while (true) {
+                final String commandName = consoleIO.read();
+                final Optional<Command> commandOpt = commandRegistry.getCommand(commandName);
+
+                if (commandOpt.isPresent() == false) {
+                    continue;
+                }
+
+                final Command command = commandOpt.get();
+                try {
+                    consoleIO.enterContext(command.getConsoleContext());
+                    final Output response = command.invoke(handleInput(command.getInputDefinition()));
+                    handleOutput(command, response);
+                } catch (final CommandInvocationException e) {
+                    consoleIO.write(e.getMessage());
+                } catch (final UserInterruptException e) {
+                    consoleIO.writeLn("Command " + command.getCommandId() + " was terminated.");
+                } finally {
+                    consoleIO.leaveContext();
+                }
+
+            }
+        } catch (final IOException e) {
+            throw new RuntimeException("IO failure", e);
+        }
+    }
+
+    private void handleOutput(final Command command, final Output response) {
+        final OutputDefinition outputDefinition = command.getOutputDefinition();
+
+        final Writer<DataSchemaNode> outHandler = argumentHandlerRegistry.getGenericWriter();
+        if (outputDefinition.isEmpty()) {
+            handleEmptyOutput(command, response);
+        } else {
+            handleRegularOutput(response, outputDefinition, outHandler);
+        }
+    }
+
+    private void handleRegularOutput(final Output response, final OutputDefinition outputDefinition,
+            final Writer<DataSchemaNode> outHandler) {
+        final Map<DataSchemaNode, List<Node<?>>> unwrap = response.unwrap(outputDefinition);
+
+        for (final DataSchemaNode schemaNode : unwrap.keySet()) {
+            Preconditions.checkNotNull(schemaNode);
+
+            try {
+
+                // FIXME move custom writer to GenericWriter/Serializers ...
+                // this checks only first level
+                final Optional<Class<? extends Writer<DataSchemaNode>>> customReaderClassOpt = tryGetCustomHandler(schemaNode);
+
+                if (customReaderClassOpt.isPresent()) {
+                    final Writer<DataSchemaNode> customReaderInstance = argumentHandlerRegistry
+                            .getCustomWriter(customReaderClassOpt.get());
+                    Preconditions.checkNotNull(customReaderInstance, "Unknown custom writer: %s",
+                            customReaderClassOpt.get());
+                    customReaderInstance.write(schemaNode, unwrap.get(schemaNode));
+                } else {
+                    outHandler.write(schemaNode, unwrap.get(schemaNode));
+                }
+
+            } catch (final WriteException e) {
+                throw new IllegalStateException("Unable to write value for: " + schemaNode.getQName() + " from: "
+                        + unwrap.get(schemaNode), e);
+            }
+        }
+    }
+
+    private void handleEmptyOutput(final Command command, final Output response) {
+        try {
+            new CompositeNodeWriter(consoleIO, new OutFormatter()).write(null,
+                    Collections.<Node<?>> singletonList(response.getOutput()));
+        } catch (final WriteException e) {
+            throw new IllegalStateException("Unable to write value for: " + response.getOutput().getNodeType()
+                    + " from: " + command.getCommandId(), e);
+        }
+    }
+
+    private Input handleInput(final InputDefinition inputDefinition) {
+        List<Node<?>> allArgs = Collections.emptyList();
+        try {
+            if (!inputDefinition.isEmpty()) {
+                allArgs = argumentHandlerRegistry.getGenericReader(schemaContextRegistry.getLocalSchemaContext()).read(
+                        inputDefinition.getInput());
+            }
+        } catch (final ReadingException e) {
+            throw new IllegalStateException("Unable to read value for: " + inputDefinition.getInput().getQName(), e);
+        }
+
+        return new Input(allArgs);
+    }
+
+    // TODO move tryGet to GenericWriter, GenericReader has the same code
+    private <T> Optional<Class<? extends T>> tryGetCustomHandler(final DataSchemaNode dataSchemaNode) {
+
+        for (final UnknownSchemaNode unknownSchemaNode : dataSchemaNode.getUnknownSchemaNodes()) {
+
+            if (isExtenstionForCustomHandler(unknownSchemaNode)) {
+                final String argumentHandlerClassName = unknownSchemaNode.getNodeParameter();
+                try {
+                    final Class<?> argumentClass = Class.forName(argumentHandlerClassName);
+                    // TODO add check before cast
+                    return Optional.<Class<? extends T>> of((Class<? extends T>) argumentClass);
+                } catch (final ClassNotFoundException e) {
+                    throw new IllegalArgumentException("Unknown custom reader class " + argumentHandlerClassName
+                            + " for: " + dataSchemaNode.getQName());
+                }
+            }
+        }
+
+        return Optional.absent();
+    }
+
+    private boolean isExtenstionForCustomHandler(final UnknownSchemaNode unknownSchemaNode) {
+        final QName qName = unknownSchemaNode.getExtensionDefinition().getQName();
+        return qName.equals(CommandConstants.ARG_HANDLER_EXT_QNAME);
+    }
+
+    private static final class RootConsoleContext implements ConsoleContext {
+
+        private final Completer completer;
+
+        public RootConsoleContext(final CommandDispatcher commandRegistry) {
+            completer = new CommandCompleter(commandRegistry);
+        }
+
+        @Override
+        public Completer getCompleter() {
+            return completer;
+        }
+
+        @Override
+        public Optional<String> getPrompt() {
+            return Optional.absent();
+        }
+
+        private class CommandCompleter extends StringsCompleter {
+
+            private final CommandDispatcher commandRegistry;
+
+            public CommandCompleter(final CommandDispatcher commandRegistry) {
+                this.commandRegistry = commandRegistry;
+            }
+
+            @Override
+            public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
+                getStrings().clear();
+                getStrings().addAll(commandRegistry.getCommandIds());
+                return super.complete(buffer, cursor, candidates);
+            }
+        }
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/CommandArgHandlerRegistry.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/CommandArgHandlerRegistry.java
new file mode 100644 (file)
index 0000000..2eab22a
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import java.util.Map;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.reader.Reader;
+import org.opendaylight.controller.netconf.cli.reader.custom.ConfigReader;
+import org.opendaylight.controller.netconf.cli.reader.custom.EditContentReader;
+import org.opendaylight.controller.netconf.cli.reader.custom.FilterReader;
+import org.opendaylight.controller.netconf.cli.reader.custom.PasswordReader;
+import org.opendaylight.controller.netconf.cli.reader.impl.GenericReader;
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.controller.netconf.cli.writer.Writer;
+import org.opendaylight.controller.netconf.cli.writer.custom.DataWriter;
+import org.opendaylight.controller.netconf.cli.writer.impl.NormalizedNodeWriter;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * Keeps custom and generic input/output arguments handlers. Custom handlers are
+ * constructed lazily, due to remote schema context acquisition.
+ */
+public class CommandArgHandlerRegistry {
+
+    private final ConsoleIO consoleIO;
+    private final SchemaContextRegistry schemaContextRegistry;
+
+    private final Map<Class<? extends Reader<? extends DataSchemaNode>>, ReaderProvider> customReaders = Maps
+            .newHashMap();
+    private final Map<Class<? extends Writer<DataSchemaNode>>, WriterProvider> customWriters = Maps.newHashMap();
+
+    public CommandArgHandlerRegistry(final ConsoleIO consoleIO, final SchemaContextRegistry schemaContextRegistry) {
+        this.consoleIO = consoleIO;
+        this.schemaContextRegistry = schemaContextRegistry;
+
+        setUpReaders();
+        setUpWriters();
+    }
+
+    private void setUpWriters() {
+        customWriters.put(DataWriter.class, new DataWriterProvider());
+    }
+
+    private void setUpReaders() {
+        customReaders.put(PasswordReader.class, new PasswordReaderProvider());
+        customReaders.put(FilterReader.class, new FilterReaderProvider());
+        customReaders.put(ConfigReader.class, new ConfigReaderProvider());
+        customReaders.put(EditContentReader.class, new EditContentReaderProvider());
+    }
+
+    public synchronized Reader<? extends DataSchemaNode> getCustomReader(
+            final Class<? extends Reader<DataSchemaNode>> readerType) {
+        return customReaders.get(readerType).provide(consoleIO, this, schemaContextRegistry);
+    }
+
+    private static SchemaContext getRemoteSchema(final Class<?> handlerType,
+            final SchemaContextRegistry schemaContextRegistry) {
+        final Optional<SchemaContext> remoteSchemaContext = schemaContextRegistry.getRemoteSchemaContext();
+        Preconditions.checkState(remoteSchemaContext.isPresent(),
+                "Remote schema context not acquired yet, cannot get handler %s", handlerType);
+        return remoteSchemaContext.get();
+    }
+
+    public synchronized Reader<DataSchemaNode> getGenericReader(final SchemaContext schemaContext) {
+        return new GenericReader(consoleIO, this, schemaContext);
+    }
+
+    public synchronized Reader<DataSchemaNode> getGenericReader(final SchemaContext schemaContext,
+            final boolean readConfigNode) {
+        return new GenericReader(consoleIO, this, schemaContext, readConfigNode);
+    }
+
+    public synchronized Writer<DataSchemaNode> getCustomWriter(final Class<? extends Writer<DataSchemaNode>> writerType) {
+        return customWriters.get(writerType).provide(consoleIO, getRemoteSchema(writerType, schemaContextRegistry),
+                this);
+    }
+
+    public synchronized Writer<DataSchemaNode> getGenericWriter() {
+        return new NormalizedNodeWriter(consoleIO, new OutFormatter());
+    }
+
+    /**
+     * Reader providers, in order to construct readers lazily
+     */
+    private static interface ReaderProvider {
+        Reader<? extends DataSchemaNode> provide(ConsoleIO consoleIO,
+                final CommandArgHandlerRegistry commandArgHandlerRegistry,
+                final SchemaContextRegistry schemaContextRegistry);
+    }
+
+    private static final class FilterReaderProvider implements ReaderProvider {
+        @Override
+        public Reader<? extends DataSchemaNode> provide(final ConsoleIO consoleIO,
+                final CommandArgHandlerRegistry commandArgHandlerRegistry,
+                final SchemaContextRegistry schemaContextRegistry) {
+            return new FilterReader(consoleIO, getRemoteSchema(FilterReader.class, schemaContextRegistry));
+        }
+    }
+
+    private static final class ConfigReaderProvider implements ReaderProvider {
+        @Override
+        public Reader<? extends DataSchemaNode> provide(final ConsoleIO consoleIO,
+                final CommandArgHandlerRegistry commandArgHandlerRegistry,
+                final SchemaContextRegistry schemaContextRegistry) {
+            return new ConfigReader(consoleIO, getRemoteSchema(ConfigReader.class, schemaContextRegistry),
+                    commandArgHandlerRegistry);
+        }
+    }
+
+    private static final class EditContentReaderProvider implements ReaderProvider {
+        @Override
+        public Reader<? extends DataSchemaNode> provide(final ConsoleIO consoleIO,
+                final CommandArgHandlerRegistry commandArgHandlerRegistry,
+                final SchemaContextRegistry schemaContextRegistry) {
+            return new EditContentReader(consoleIO, commandArgHandlerRegistry, getRemoteSchema(EditContentReader.class,
+                    schemaContextRegistry));
+        }
+    }
+
+    private static final class PasswordReaderProvider implements ReaderProvider {
+        @Override
+        public Reader<? extends DataSchemaNode> provide(final ConsoleIO consoleIO,
+                final CommandArgHandlerRegistry commandArgHandlerRegistry,
+                final SchemaContextRegistry schemaContextRegistry) {
+            return new PasswordReader(consoleIO, schemaContextRegistry.getLocalSchemaContext());
+        }
+    }
+
+    /**
+     * Writer providers, in order to construct readers lazily
+     */
+    private static interface WriterProvider {
+        Writer<DataSchemaNode> provide(ConsoleIO consoleIO, SchemaContext schema,
+                final CommandArgHandlerRegistry commandArgHandlerRegistry);
+    }
+
+    private class DataWriterProvider implements WriterProvider {
+        @Override
+        public Writer<DataSchemaNode> provide(final ConsoleIO consoleIO, final SchemaContext schema,
+                final CommandArgHandlerRegistry commandArgHandlerRegistry) {
+            return new DataWriter(consoleIO, new OutFormatter(), schema);
+        }
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Main.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Main.java
new file mode 100644 (file)
index 0000000..8605501
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli;
+
+import com.google.common.base.Preconditions;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import net.sourceforge.argparse4j.ArgumentParsers;
+import net.sourceforge.argparse4j.inf.ArgumentGroup;
+import net.sourceforge.argparse4j.inf.ArgumentParser;
+import net.sourceforge.argparse4j.inf.ArgumentParserException;
+import net.sourceforge.argparse4j.inf.Namespace;
+import org.opendaylight.controller.netconf.cli.commands.CommandDispatcher;
+import org.opendaylight.controller.netconf.cli.commands.local.Connect;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIOImpl;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * Parse arguments, start remote device connection and start CLI after the
+ * connection is fully up
+ */
+public class Main {
+
+    public static void main(final String[] args) {
+        final CliArgumentParser cliArgs = new CliArgumentParser();
+        try {
+            cliArgs.parse(args);
+        } catch (final ArgumentParserException e) {
+            // Just end the cli, exception was handled by the CliArgumentParser
+            return;
+        }
+
+        final ConsoleIO consoleIO;
+        try {
+            consoleIO = new ConsoleIOImpl();
+        } catch (final IOException e) {
+            handleStartupException(e);
+            return;
+        }
+
+        final SchemaContext localSchema = CommandDispatcher.parseSchema(CommandDispatcher.LOCAL_SCHEMA_PATHS);
+        final SchemaContextRegistry schemaContextRegistry = new SchemaContextRegistry(localSchema);
+
+        final CommandDispatcher commandDispatcher = new CommandDispatcher();
+        final CommandArgHandlerRegistry argumentHandlerRegistry = new CommandArgHandlerRegistry(consoleIO,
+                schemaContextRegistry);
+        final NetconfDeviceConnectionManager connectionManager = new NetconfDeviceConnectionManager(commandDispatcher,
+                argumentHandlerRegistry, schemaContextRegistry, consoleIO);
+
+        commandDispatcher.addLocalCommands(connectionManager, localSchema, cliArgs.getConnectionTimeoutMs());
+
+        switch (cliArgs.connectionArgsPresent()) {
+        case TCP: {
+            // FIXME support pure TCP
+            handleRunningException(new UnsupportedOperationException("PURE TCP CONNECTIONS ARE NOT SUPPORTED YET, USE SSH INSTEAD BY PROVIDING USERNAME AND PASSWORD AS WELL"));
+            return;
+        }
+        case SSH: {
+            writeStatus(consoleIO, "Connecting to %s via SSH. Please wait.", cliArgs.getAddress());
+            connectionManager.connectBlocking(cliArgs.getAddress(), getClientSshConfig(cliArgs));
+            break;
+        }
+        case NONE: {/* Do not connect initially */
+            writeStatus(consoleIO, "No initial connection. To connect use the connect command");
+        }
+        }
+
+        try {
+            new Cli(consoleIO, commandDispatcher, argumentHandlerRegistry, schemaContextRegistry).run();
+        } catch (final Exception e) {
+            // TODO Running exceptions have to be handled properly
+            handleRunningException(e);
+            System.exit(0);
+        }
+    }
+
+    private static NetconfClientConfigurationBuilder getClientConfig(final CliArgumentParser cliArgs) {
+        return NetconfClientConfigurationBuilder.create().withAddress(cliArgs.getServerAddress())
+                .withConnectionTimeoutMillis(cliArgs.getConnectionTimeoutMs())
+                .withReconnectStrategy(Connect.getReconnectStrategy())
+                .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.TCP);
+    }
+
+    private static NetconfClientConfigurationBuilder getClientSshConfig(final CliArgumentParser cliArgs) {
+        return NetconfClientConfigurationBuilder.create().withAddress(cliArgs.getServerAddress())
+                .withConnectionTimeoutMillis(cliArgs.getConnectionTimeoutMs())
+                .withReconnectStrategy(Connect.getReconnectStrategy())
+                .withAuthHandler(cliArgs.getCredentials())
+                .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH);
+    }
+
+    private static void handleStartupException(final IOException e) {
+        handleException(e, "Unable to initialize CLI");
+    }
+
+    private static void handleException(final Exception e, final String message) {
+        System.err.println(message);
+        e.printStackTrace(System.err);
+    }
+
+    private static void writeStatus(final ConsoleIO io, final String blueprint, final Object... args) {
+        try {
+            io.formatLn(blueprint, args);
+        } catch (final IOException e) {
+            handleStartupException(e);
+        }
+    }
+
+    private static void handleRunningException(final Exception e) {
+        handleException(e, "Unexpected CLI runtime exception");
+    }
+
+    private static final class CliArgumentParser {
+
+        public static final String USERNAME = "username";
+        public static final String PASSWORD = "password";
+        public static final String SERVER = "server";
+        public static final String PORT = "port";
+
+        public static final String CONNECT_TIMEOUT = "connectionTimeout";
+        public static final int DEFAULT_CONNECTION_TIMEOUT_MS = 50000;
+
+        private final ArgumentParser parser;
+        private Namespace parsed;
+
+        private CliArgumentParser() {
+            parser = ArgumentParsers.newArgumentParser("Netconf cli").defaultHelp(true)
+                    .description("Generic cli for netconf devices")
+                    .usage("Submit address + port for initial TCP connection (PURE TCP CONNECTIONS ARE NOT SUPPORTED YET)\n" +
+                            "Submit username + password in addition to address + port for initial SSH connection\n" +
+                            "If no arguments(or unexpected combination) is submitted, cli will be started without initial connection\n" +
+                            "To use with ODL controller, run with: java -jar netconf-cli-0.2.5-SNAPSHOT-executable.jar  --server localhost --port 1830 --username admin --password admin");
+
+            final ArgumentGroup tcpGroup = parser.addArgumentGroup("TCP")
+                    .description("Base arguments to initiate TCP connection right away");
+
+            tcpGroup.addArgument("--" + SERVER).help("Netconf device ip-address/domain name");
+            tcpGroup.addArgument("--" + PORT).type(Integer.class).help("Netconf device port");
+            tcpGroup.addArgument("--" + CONNECT_TIMEOUT)
+                    .type(Integer.class)
+                    .setDefault(DEFAULT_CONNECTION_TIMEOUT_MS)
+                    .help("Timeout(in ms) for connection to succeed, if the connection is not fully established by the time is up, " +
+                            "connection attempt is considered a failure. This attribute is not working as expected yet");
+
+            final ArgumentGroup sshGroup = parser.addArgumentGroup("SSH")
+                    .description("SSH credentials, if provided, initial connection will be attempted using SSH");
+
+            sshGroup.addArgument("--" + USERNAME).help("Username for SSH connection");
+            sshGroup.addArgument("--" + PASSWORD).help("Password for SSH connection");
+        }
+
+        public void parse(final String[] args) throws ArgumentParserException {
+            try {
+                this.parsed = parser.parseArgs(args);
+            } catch (final ArgumentParserException e) {
+                parser.handleError(e);
+                throw e;
+            }
+        }
+
+        public InetSocketAddress getServerAddress() {
+            try {
+                return new InetSocketAddress(InetAddress.getByName(getAddress()), getPort());
+            } catch (final UnknownHostException e) {
+                throw new IllegalArgumentException(e);
+            }
+        }
+
+        private Integer getPort() {
+            checkParsed();
+            return parsed.getInt(PORT);
+        }
+
+        private String getAddress() {
+            checkParsed();
+            return getString(SERVER);
+        }
+
+        private Integer getConnectionTimeoutMs() {
+            checkParsed();
+            return parsed.getInt(CONNECT_TIMEOUT);
+        }
+
+        private void checkParsed() {
+            Preconditions.checkState(parsed != null, "No arguments were parsed yet");
+        }
+
+        public String getUsername() {
+            checkParsed();
+            return getString(USERNAME);
+        }
+
+        private String getString(final String key) {
+            return parsed.getString(key);
+        }
+
+        public LoginPassword getCredentials() {
+            return new LoginPassword(getUsername(), getPassword());
+        }
+
+        public String getPassword() {
+            checkParsed();
+            return getString(PASSWORD);
+        }
+
+        public InitialConnectionType connectionArgsPresent() {
+            if(getAddress() != null && getPort() != null) {
+                if(getUsername() != null && getPassword() != null) {
+                    return InitialConnectionType.SSH;
+                }
+                return InitialConnectionType.TCP;
+            }
+            return InitialConnectionType.NONE;
+        }
+
+        enum InitialConnectionType {
+            TCP, SSH, NONE
+        }
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionHandler.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionHandler.java
new file mode 100644 (file)
index 0000000..bd092bc
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli;
+
+import com.google.common.base.Optional;
+import jline.console.completer.Completer;
+import jline.console.completer.NullCompleter;
+import org.opendaylight.controller.netconf.cli.commands.CommandDispatcher;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionCapabilities;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+
+/**
+ * Implementation of RemoteDeviceHandler. Integrates cli with
+ * sal-netconf-connector.
+ */
+public class NetconfDeviceConnectionHandler implements RemoteDeviceHandler<NetconfSessionCapabilities> {
+
+    private final CommandDispatcher commandDispatcher;
+    private final SchemaContextRegistry schemaContextRegistry;
+    private final ConsoleIO console;
+    private final String deviceId;
+
+    private boolean up = false;
+
+    public NetconfDeviceConnectionHandler(final CommandDispatcher commandDispatcher,
+            final SchemaContextRegistry schemaContextRegistry, final ConsoleIO console, final String deviceId) {
+        this.commandDispatcher = commandDispatcher;
+        this.schemaContextRegistry = schemaContextRegistry;
+        this.console = console;
+        this.deviceId = deviceId;
+    }
+
+    @Override
+    public synchronized void onDeviceConnected(final SchemaContextProvider contextProvider,
+            final NetconfSessionCapabilities capabilities, final RpcImplementation rpcImplementation) {
+        console.enterRootContext(new ConsoleContext() {
+
+            @Override
+            public Optional<String> getPrompt() {
+                return Optional.of(deviceId);
+            }
+
+            @Override
+            public Completer getCompleter() {
+                return new NullCompleter();
+            }
+        });
+
+        // TODO Load schemas for base netconf + inet types from remote device if
+        // possible
+        // TODO detect netconf base version
+        // TODO detect inet types version
+        commandDispatcher.addRemoteCommands(rpcImplementation, contextProvider.getSchemaContext());
+        schemaContextRegistry.setRemoteSchemaContext(contextProvider.getSchemaContext());
+        up = true;
+        this.notify();
+    }
+
+    /**
+     * @return true if connection was fully established
+     */
+    public synchronized boolean isUp() {
+        return up;
+    }
+
+    @Override
+    public synchronized void onDeviceDisconnected() {
+        console.leaveRootContext();
+        commandDispatcher.removeRemoteCommands();
+        schemaContextRegistry.setRemoteSchemaContext(null);
+        up = false;
+    }
+
+    @Override
+    public void onNotification(final CompositeNode compositeNode) {
+        // FIXME
+    }
+
+    @Override
+    public void close() {
+        // FIXME
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionManager.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionManager.java
new file mode 100644 (file)
index 0000000..3dd892e
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli;
+
+import com.google.common.base.Preconditions;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import org.opendaylight.controller.netconf.cli.commands.CommandDispatcher;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+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;
+
+/**
+ * Manages connect/disconnect to 1 remote device
+ */
+public class NetconfDeviceConnectionManager implements Closeable {
+
+    private final CommandDispatcher commandDispatcher;
+    private final SchemaContextRegistry schemaContextRegistry;
+    private final ConsoleIO console;
+
+    private final ExecutorService executor;
+    private final NioEventLoopGroup nettyThreadGroup;
+    private final NetconfClientDispatcherImpl netconfClientDispatcher;
+
+    // Connection
+    private NetconfDeviceConnectionHandler handler;
+    private NetconfDevice device;
+    private NetconfDeviceCommunicator listener;
+
+    public NetconfDeviceConnectionManager(final CommandDispatcher commandDispatcher,
+            final CommandArgHandlerRegistry argumentHandlerRegistry, final SchemaContextRegistry schemaContextRegistry,
+            final ConsoleIO consoleIO) {
+        this.commandDispatcher = commandDispatcher;
+        this.schemaContextRegistry = schemaContextRegistry;
+        this.console = consoleIO;
+
+        executor = Executors.newSingleThreadExecutor();
+        nettyThreadGroup = new NioEventLoopGroup();
+        netconfClientDispatcher = new NetconfClientDispatcherImpl(nettyThreadGroup, nettyThreadGroup,
+                new HashedWheelTimer());
+    }
+
+    // TODO we receive configBuilder in order to add SessionListener, Session
+    // Listener should not be part of config
+    public synchronized void connect(final String name, final NetconfClientConfigurationBuilder configBuilder) {
+        // TODO change IllegalState exceptions to custom ConnectionException
+        Preconditions.checkState(listener == null, "Already connected");
+
+        final RemoteDeviceId deviceId = new RemoteDeviceId(name);
+
+        handler = new NetconfDeviceConnectionHandler(commandDispatcher, schemaContextRegistry,
+                console, name);
+        device = NetconfDevice.createNetconfDevice(deviceId, getGlobalNetconfSchemaProvider(), executor, handler);
+        listener = new NetconfDeviceCommunicator(deviceId, device);
+        configBuilder.withSessionListener(listener);
+        listener.initializeRemoteConnection(netconfClientDispatcher, configBuilder.build());
+    }
+
+    /**
+     * Blocks thread until connection is fully established
+     */
+    public synchronized Set<String> connectBlocking(final String name, final NetconfClientConfigurationBuilder configBuilder) {
+        this.connect(name, configBuilder);
+        synchronized (handler) {
+            while (handler.isUp() == false) {
+                try {
+                    // TODO implement Timeout for unsuccessful connection
+                    handler.wait();
+                } catch (final InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                    throw new IllegalArgumentException(e);
+                }
+            }
+        }
+
+        return commandDispatcher.getRemoteCommandIds();
+    }
+
+    public synchronized void disconnect() {
+        Preconditions.checkState(listener != null, "Not connected yet");
+        Preconditions.checkState(handler.isUp(), "Not connected yet");
+        listener.close();
+        listener = null;
+        device = null;
+        handler.close();
+        handler = null;
+    }
+
+    private static AbstractCachingSchemaSourceProvider<String, InputStream> getGlobalNetconfSchemaProvider() {
+        // FIXME move to args
+        final String storageFile = "cache/schema";
+        final File directory = new File(storageFile);
+        final SchemaSourceProvider<String> defaultProvider = SchemaSourceProviders.noopProvider();
+        return FilesystemSchemaCachingProvider.createFromStringSourceProvider(defaultProvider, directory);
+    }
+
+    @Override
+    public void close() throws IOException {
+        executor.shutdownNow();
+        nettyThreadGroup.shutdownGracefully();
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/SchemaContextRegistry.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/SchemaContextRegistry.java
new file mode 100644 (file)
index 0000000..5c3cfe7
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli;
+
+import com.google.common.base.Optional;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * Contains the local schema context (containing local commands) and remote schema context (remote commands)
+ *
+ * Remote commands are set only after the connection is fully established. So classes using the remote schema context
+ */
+public class SchemaContextRegistry {
+
+    private final SchemaContext localSchemaContext;
+    private SchemaContext remoteSchemaContext;
+
+    public SchemaContextRegistry(final SchemaContext localSchemaContext) {
+        this.localSchemaContext = localSchemaContext;
+    }
+
+    public synchronized Optional<SchemaContext> getRemoteSchemaContext() {
+        return Optional.fromNullable(remoteSchemaContext);
+    }
+
+    public SchemaContext getLocalSchemaContext() {
+        return localSchemaContext;
+    }
+
+    public synchronized void setRemoteSchemaContext(final SchemaContext remoteSchemaContext) {
+        this.remoteSchemaContext = remoteSchemaContext;
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/AbstractCommand.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/AbstractCommand.java
new file mode 100644 (file)
index 0000000..f02ce74
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.commands;
+
+import com.google.common.base.Optional;
+import jline.console.completer.Completer;
+import jline.console.completer.NullCompleter;
+import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
+import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+
+public abstract class AbstractCommand implements Command {
+
+    private final QName qName;
+    private final InputDefinition args;
+    private final OutputDefinition output;
+    private final String description;
+
+    public AbstractCommand(final QName qName, final InputDefinition args, final OutputDefinition output,
+            final String description) {
+        this.qName = qName;
+        this.args = args;
+        this.output = output;
+        this.description = description;
+    }
+
+    protected static OutputDefinition getOutputDefinition(final RpcDefinition rpcDefinition) {
+        final ContainerSchemaNode output = rpcDefinition.getOutput();
+        return output != null ? OutputDefinition.fromOutput(output) : OutputDefinition.empty();
+    }
+
+    protected static InputDefinition getInputDefinition(final RpcDefinition rpcDefinition) {
+        final ContainerSchemaNode input = rpcDefinition.getInput();
+        return InputDefinition.fromInput(input);
+    }
+
+    @Override
+    public InputDefinition getInputDefinition() {
+        return args;
+    }
+
+    @Override
+    public OutputDefinition getOutputDefinition() {
+        return output;
+    }
+
+    @Override
+    public QName getCommandId() {
+        return qName;
+    }
+
+    @Override
+    public ConsoleContext getConsoleContext() {
+        return new ConsoleContext() {
+
+            @Override
+            public Completer getCompleter() {
+                return new NullCompleter();
+            }
+
+            @Override
+            public Optional<String> getPrompt() {
+                return Optional.of(qName.getLocalName());
+            }
+        };
+    }
+
+    @Override
+    public Optional<String> getCommandDescription() {
+        return Optional.fromNullable(description);
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/Command.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/Command.java
new file mode 100644 (file)
index 0000000..1435abd
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.commands;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.netconf.cli.commands.input.Input;
+import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
+import org.opendaylight.controller.netconf.cli.commands.output.Output;
+import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.yangtools.yang.common.QName;
+
+/**
+ * Local command e.g. help or remote rpc e.g. get-config must conform to this interface
+ */
+public interface Command {
+
+    Output invoke(Input inputArgs) throws CommandInvocationException;
+
+    InputDefinition getInputDefinition();
+
+    OutputDefinition getOutputDefinition();
+
+    QName getCommandId();
+
+    Optional<String> getCommandDescription();
+
+    ConsoleContext getConsoleContext();
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandConstants.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandConstants.java
new file mode 100644 (file)
index 0000000..7159af5
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.commands;
+
+import java.net.URI;
+import org.opendaylight.controller.netconf.cli.io.IOUtil;
+import org.opendaylight.yangtools.yang.common.QName;
+
+public class CommandConstants {
+
+    // Local command ids are defined here, this links the implementation to the rpc definition in yang
+    // Better way needs to be found to provide this link instead of hardcoded QNames (e.g. yang extension)
+    public static final QName HELP_QNAME = QName.create(URI.create("netconf:cli"), IOUtil.parseDate("2014-05-22"), "help");
+    public static final QName CLOSE_QNAME = QName.create(HELP_QNAME, "close");
+    public static final QName CONNECT_QNAME = QName.create(HELP_QNAME, "connect");
+    public static final QName DISCONNECT_QNAME = QName.create(CONNECT_QNAME, "disconnect");
+
+    public static final QName ARG_HANDLER_EXT_QNAME = QName.create(
+            URI.create("urn:ietf:params:xml:ns:netconf:base:1.0:cli"), IOUtil.parseDate("2014-05-26"),
+            "argument-handler");
+
+    public static final QName NETCONF_BASE_QNAME = QName.create("urn:ietf:params:xml:ns:netconf:base:1.0", "2011-06-01",
+            "netconf");
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandDispatcher.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandDispatcher.java
new file mode 100644 (file)
index 0000000..ec7b5b4
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.commands;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.controller.netconf.cli.NetconfDeviceConnectionHandler;
+import org.opendaylight.controller.netconf.cli.NetconfDeviceConnectionManager;
+import org.opendaylight.controller.netconf.cli.commands.local.Close;
+import org.opendaylight.controller.netconf.cli.commands.local.Connect;
+import org.opendaylight.controller.netconf.cli.commands.local.Disconnect;
+import org.opendaylight.controller.netconf.cli.commands.local.Help;
+import org.opendaylight.controller.netconf.cli.commands.remote.RemoteCommand;
+import org.opendaylight.controller.netconf.cli.io.IOUtil;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.yangtools.yang.common.QName;
+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.parser.impl.YangParserImpl;
+
+/**
+ * The registry of available commands local + remote. Created from schema contexts.
+ */
+public class CommandDispatcher {
+
+    // TODO extract interface
+
+    private final Map<QName, Command> localCommands = Maps.newHashMap();
+    private final Map<String, QName> nameToQNameLocal = Maps.newHashMap();
+
+    private final Map<QName, Command> remoteCommands = Maps.newHashMap();
+    private final Map<String, QName> nameToQNameRemote = Maps.newHashMap();
+
+    public synchronized Map<QName, Command> getCommands() {
+        return Collections.unmodifiableMap(mergeCommands());
+    }
+
+    private Map<QName, Command> mergeCommands() {
+        // TODO cache this merged map
+        return mergeMaps(remoteCommands, localCommands);
+    }
+
+    private Map<String, QName> mergeCommandIds() {
+        // TODO cache this merged map
+        return mergeMaps(nameToQNameRemote, nameToQNameLocal);
+    }
+
+    private <K, V> Map<K, V> mergeMaps(final Map<K, V> remoteMap, final Map<K, V> localMap) {
+        final Map<K, V> mergedCommands = Maps.newHashMap();
+        mergedCommands.putAll(remoteMap);
+        mergedCommands.putAll(localMap);
+        return mergedCommands;
+    }
+
+    public synchronized Set<String> getCommandIds() {
+        return mergeCommandIds().keySet();
+    }
+
+    public synchronized Set<String> getRemoteCommandIds() {
+        return nameToQNameRemote.keySet();
+    }
+
+    public synchronized Optional<Command> getCommand(final String nameWithModule) {
+        final QName commandQName = mergeCommandIds().get(nameWithModule);
+        final Map<QName, Command> qNameCommandMap = mergeCommands();
+        if(commandQName == null || qNameCommandMap.containsKey(commandQName) == false) {
+            return Optional.absent();
+        }
+
+        return Optional.of(qNameCommandMap.get(commandQName));
+    }
+
+    public synchronized Optional<Command> getCommand(final QName qName) {
+        return Optional.fromNullable(mergeCommands().get(qName));
+    }
+
+    private static Optional<Command> getCommand(final Map<String, QName> commandNameMap, final Map<QName, Command> commands, final String nameWithModule) {
+        final QName qName = commandNameMap.get(nameWithModule);
+        if(qName == null)
+            return Optional.absent();
+
+        final Command command = commands.get(qName);
+        if(command == null) {
+            return Optional.absent();
+        }
+
+        return Optional.of(command);
+    }
+
+    public static final Collection<String> BASE_NETCONF_SCHEMA_PATHS = Lists.newArrayList("/schema/remote/ietf-netconf.yang",
+            "/schema/common/netconf-cli-ext.yang", "/schema/common/ietf-inet-types.yang");
+
+    public synchronized void addRemoteCommands(final RpcImplementation rpcInvoker, final SchemaContext remoteSchema) {
+        this.addRemoteCommands(rpcInvoker, remoteSchema, parseSchema(BASE_NETCONF_SCHEMA_PATHS));
+    }
+
+    public synchronized void addRemoteCommands(final RpcImplementation rpcInvoker, final SchemaContext remoteSchema, final SchemaContext baseNetconfSchema) {
+        for (final SchemaContext context : Lists.newArrayList(remoteSchema, baseNetconfSchema)) {
+            for (final Module module : context.getModules()) {
+                for (final RpcDefinition rpcDefinition : module.getRpcs()) {
+                    final Command command = RemoteCommand.fromRpc(rpcDefinition, rpcInvoker);
+                    remoteCommands.put(rpcDefinition.getQName(), command);
+                    nameToQNameRemote.put(getCommandName(rpcDefinition, module), rpcDefinition.getQName());
+                }
+            }
+        }
+    }
+
+    public synchronized void removeRemoteCommands() {
+        remoteCommands.clear();
+        nameToQNameRemote.clear();
+    }
+
+    public static final Collection<String> LOCAL_SCHEMA_PATHS = Lists.newArrayList("/schema/local/netconf-cli.yang", "/schema/common/netconf-cli-ext.yang",
+            "/schema/common/ietf-inet-types.yang");
+
+    public synchronized void addLocalCommands(final NetconfDeviceConnectionManager connectionManager, final SchemaContext localSchema, final Integer connectionTimeout) {
+        for (final Module module : localSchema.getModules()) {
+            for (final RpcDefinition rpcDefinition : module.getRpcs()) {
+
+                // FIXME make local commands extensible
+                // e.g. by yang extension defining java class to be instantiated
+                // problem is with command specific resources
+                // e.g. Help would need command registry
+                final Command localCommand;
+                if (rpcDefinition.getQName().equals(CommandConstants.HELP_QNAME)) {
+                    localCommand = Help.create(rpcDefinition, this);
+                } else if (rpcDefinition.getQName().equals(CommandConstants.CLOSE_QNAME)) {
+                    localCommand = Close.create(rpcDefinition);
+                } else if (rpcDefinition.getQName().equals(CommandConstants.CONNECT_QNAME)) {
+                    localCommand = Connect.create(rpcDefinition, connectionManager, connectionTimeout);
+                } else if (rpcDefinition.getQName().equals(CommandConstants.DISCONNECT_QNAME)) {
+                    localCommand = Disconnect.create(rpcDefinition, connectionManager);
+                } else {
+                    throw new IllegalStateException("No command implementation available for local command: " + rpcDefinition.getQName());
+                }
+
+                localCommands.put(localCommand.getCommandId(), localCommand);
+                nameToQNameLocal.put(getCommandName(rpcDefinition, module), localCommand.getCommandId());
+            }
+        }
+    }
+
+    private static String getCommandName(final RpcDefinition rpcDefinition, final Module module) {
+        return IOUtil.qNameToKeyString(rpcDefinition.getQName(), module.getName());
+    }
+
+    public static SchemaContext parseSchema(final Collection<String> yangPath) {
+        final YangParserImpl yangParserImpl = new YangParserImpl();
+        // TODO change deprecated method
+        final Set<Module> modules = yangParserImpl.parseYangModelsFromStreams(loadYangs(yangPath));
+        return yangParserImpl.resolveSchemaContext(modules);
+    }
+
+    private static List<InputStream> loadYangs(final Collection<String> yangPaths) {
+
+        return Lists.newArrayList(Collections2.transform(Lists.newArrayList(yangPaths),
+                new Function<String, InputStream>() {
+                    @Override
+                    public InputStream apply(final String input) {
+                        final InputStream resourceAsStream = NetconfDeviceConnectionHandler.class.getResourceAsStream(input);
+                        Preconditions.checkNotNull(resourceAsStream, "File %s was null", input);
+                        return resourceAsStream;
+                    }
+                }));
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandInvocationException.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandInvocationException.java
new file mode 100644 (file)
index 0000000..e38f45f
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.commands;
+
+import org.opendaylight.yangtools.yang.common.QName;
+
+public class CommandInvocationException extends Exception {
+
+    public CommandInvocationException(final QName qName, final Throwable cause) {
+        this("Command " + qName + " invocation failed: " + cause.getMessage(), cause);
+    }
+
+    protected CommandInvocationException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+
+    public static class CommandTimeoutException extends CommandInvocationException {
+
+        public CommandTimeoutException(final QName qName, final Throwable e) {
+            super("Command " + qName + " timed out: " + e.getMessage(), e);
+        }
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/Input.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/Input.java
new file mode 100644 (file)
index 0000000..02173ac
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.commands.input;
+
+import com.google.common.base.Preconditions;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+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;
+
+/**
+ * Input arguments for and rpc/command execution
+ */
+public class Input {
+
+    private final List<Node<?>> args;
+
+    private final Map<String, Node<?>> nameToArg = new HashMap<String, Node<?>>();
+
+    public Input(final List<Node<?>> args) {
+        // FIXME empty Input should be constructed from static factory method
+        if(args.isEmpty()) {
+            this.args = Collections.emptyList();
+            return;
+        }
+
+        final Node<?> input = args.iterator().next();
+        Preconditions
+                .checkArgument(input instanceof CompositeNode, "Input container has to be of type composite node.");
+        this.args = ((CompositeNode) input).getValue();
+
+        for (final Node<?> arg : this.args) {
+            nameToArg.put(arg.getNodeType().getLocalName(), arg);
+        }
+    }
+
+    public Node<?> getArg(final String name) {
+        return nameToArg.get(name);
+    }
+
+    public CompositeNode wrap(final QName rpcQName) {
+        return new CompositeNodeTOImpl(rpcQName, null, args);
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/InputDefinition.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/InputDefinition.java
new file mode 100644 (file)
index 0000000..83e1b19
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.commands.input;
+
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+
+/**
+ * The definition of input arguments represented by schema nodes parsed from
+ * yang rpc definition
+ */
+public class InputDefinition {
+
+    private final ContainerSchemaNode inputContainer;
+
+    public InputDefinition(final ContainerSchemaNode inputContainer) {
+        this.inputContainer = inputContainer;
+    }
+
+    public static InputDefinition fromInput(final ContainerSchemaNode input) {
+        return new InputDefinition(input);
+    }
+
+    public ContainerSchemaNode getInput() {
+        return inputContainer;
+    }
+
+    // FIXME add empty as in output
+    public boolean isEmpty() {
+        return inputContainer == null;
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Close.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Close.java
new file mode 100644 (file)
index 0000000..c43432d
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.commands.local;
+
+import org.opendaylight.controller.netconf.cli.commands.AbstractCommand;
+import org.opendaylight.controller.netconf.cli.commands.Command;
+import org.opendaylight.controller.netconf.cli.commands.CommandInvocationException;
+import org.opendaylight.controller.netconf.cli.commands.input.Input;
+import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
+import org.opendaylight.controller.netconf.cli.commands.output.Output;
+import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+
+/**
+ * Local command to shut down the cli
+ */
+public class Close extends AbstractCommand {
+
+    public Close(final QName qName, final InputDefinition args, final OutputDefinition output, final String description) {
+        super(qName, args, output, description);
+    }
+
+    @Override
+    public Output invoke(final Input inputArgs) throws CommandInvocationException {
+        // FIXME clean up, close session and then close
+        System.exit(0);
+        return null;
+    }
+
+    public static Command create(final RpcDefinition rpcDefinition) {
+        return new Close(rpcDefinition.getQName(), getInputDefinition(rpcDefinition),
+                getOutputDefinition(rpcDefinition), rpcDefinition.getDescription());
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Connect.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Connect.java
new file mode 100644 (file)
index 0000000..f702aa3
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.commands.local;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import io.netty.util.concurrent.GlobalEventExecutor;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Set;
+import org.opendaylight.controller.netconf.cli.NetconfDeviceConnectionManager;
+import org.opendaylight.controller.netconf.cli.commands.AbstractCommand;
+import org.opendaylight.controller.netconf.cli.commands.Command;
+import org.opendaylight.controller.netconf.cli.commands.input.Input;
+import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
+import org.opendaylight.controller.netconf.cli.commands.output.Output;
+import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
+import org.opendaylight.protocol.framework.NeverReconnectStrategy;
+import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.yangtools.yang.common.QName;
+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.SimpleNodeTOImpl;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+
+/**
+ * Local command to connect to a remote device
+ */
+public class Connect extends AbstractCommand {
+
+    private final NetconfDeviceConnectionManager connectManager;
+    private final Integer connectionTimeout;
+
+    private Connect(final QName qName, final InputDefinition args, final OutputDefinition output,
+                    final NetconfDeviceConnectionManager connectManager, final String description, final Integer connectionTimeout) {
+        super(qName, args, output, description);
+        this.connectManager = connectManager;
+        this.connectionTimeout = connectionTimeout;
+    }
+
+    @Override
+    public Output invoke(final Input inputArgs) {
+        final NetconfClientConfigurationBuilder config = getConfig(inputArgs);
+        return invoke(config, getArgument(inputArgs, "address-name", String.class));
+    }
+
+    private Output invoke(final NetconfClientConfigurationBuilder config, final String addressName) {
+        final Set<String> remoteCmds = connectManager.connectBlocking(addressName, config);
+
+        final ArrayList<Node<?>> output = Lists.newArrayList();
+        output.add(new SimpleNodeTOImpl<>(QName.create(getCommandId(), "status"), null, "Connection initiated"));
+
+        for (final String cmdId : remoteCmds) {
+            output.add(new SimpleNodeTOImpl<>(QName.create(getCommandId(), "remote-commands"), null, cmdId));
+        }
+
+        return new Output(new CompositeNodeTOImpl(getCommandId(), null, output));
+    }
+
+    private NetconfClientConfigurationBuilder getConfig(final Input inputArgs) {
+
+        final ReconnectStrategy strategy = getReconnectStrategy();
+
+        final String address = getArgument(inputArgs, "address-name", String.class);
+        final Integer port = getArgument(inputArgs, "address-port", Integer.class);
+        final String username = getArgument(inputArgs, "user-name", String.class);
+        final String passwd = getArgument(inputArgs, "user-password", String.class);
+
+        final InetSocketAddress inetAddress;
+        try {
+            inetAddress = new InetSocketAddress(InetAddress.getByName(address), port);
+        } catch (final UnknownHostException e) {
+            throw new IllegalArgumentException("Unable to use address: " + address, e);
+        }
+
+        return NetconfClientConfigurationBuilder.create().withAddress(inetAddress)
+                .withConnectionTimeoutMillis(connectionTimeout)
+                .withReconnectStrategy(strategy)
+                .withAuthHandler(new LoginPassword(username, passwd))
+                .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH);
+    }
+
+    private <T> Optional<T> getArgumentOpt(final Input inputArgs, final String argName, final Class<T> type) {
+        final QName argQName = QName.create(getCommandId(), argName);
+        final Node<?> argumentNode = inputArgs.getArg(argName);
+        if (argumentNode == null) {
+            return Optional.absent();
+        }
+        Preconditions.checkArgument(argumentNode instanceof SimpleNode, "Only simple type argument supported, %s",
+                argQName);
+
+        final Object value = argumentNode.getValue();
+        Preconditions.checkArgument(type.isInstance(value), "Unexpected instance type: %s for argument: %s",
+                value.getClass(), argQName);
+        return Optional.of(type.cast(value));
+    }
+
+    private <T> T getArgument(final Input inputArgs, final String argName, final Class<T> type) {
+        final Optional<T> argumentOpt = getArgumentOpt(inputArgs, argName, type);
+        Preconditions.checkState(argumentOpt.isPresent(), "Argument: %s is missing but is required", argName);
+        return argumentOpt.get();
+    }
+
+    public static ReconnectStrategy getReconnectStrategy() {
+        // FIXME move to args either start-up args or input nodes for connect or both
+        return new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 1000);
+    }
+
+    public static Command create(final RpcDefinition rpcDefinition, final NetconfDeviceConnectionManager connectManager, final Integer connectionTimeout) {
+        return new Connect(rpcDefinition.getQName(), getInputDefinition(rpcDefinition),
+                getOutputDefinition(rpcDefinition), connectManager, rpcDefinition.getDescription(), connectionTimeout);
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Disconnect.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Disconnect.java
new file mode 100644 (file)
index 0000000..e938388
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.commands.local;
+
+import org.opendaylight.controller.netconf.cli.NetconfDeviceConnectionManager;
+import org.opendaylight.controller.netconf.cli.commands.AbstractCommand;
+import org.opendaylight.controller.netconf.cli.commands.Command;
+import org.opendaylight.controller.netconf.cli.commands.input.Input;
+import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
+import org.opendaylight.controller.netconf.cli.commands.output.Output;
+import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Local disconnect command
+ */
+public class Disconnect extends AbstractCommand {
+
+    private final NetconfDeviceConnectionManager connectionManager;
+
+    public Disconnect(final QName qName, final InputDefinition inputDefinition,
+            final OutputDefinition outputDefinition, final NetconfDeviceConnectionManager connectionManager,
+            final String description) {
+        super(qName, inputDefinition, outputDefinition, description);
+        this.connectionManager = connectionManager;
+    }
+
+    @Override
+    public Output invoke(final Input inputArgs) {
+        connectionManager.disconnect();
+
+        return new Output(new CompositeNodeTOImpl(getCommandId(), null,
+                Lists.<Node<?>> newArrayList(new SimpleNodeTOImpl<>(QName.create(getCommandId(), "status"), null,
+                        "Connection disconnected"))));
+    }
+
+    public static Command create(final RpcDefinition rpcDefinition,
+            final NetconfDeviceConnectionManager commandDispatcher) {
+        return new Disconnect(rpcDefinition.getQName(), getInputDefinition(rpcDefinition),
+                getOutputDefinition(rpcDefinition), commandDispatcher, rpcDefinition.getDescription());
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Help.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Help.java
new file mode 100644 (file)
index 0000000..1816469
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.commands.local;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.controller.netconf.cli.commands.AbstractCommand;
+import org.opendaylight.controller.netconf.cli.commands.Command;
+import org.opendaylight.controller.netconf.cli.commands.CommandDispatcher;
+import org.opendaylight.controller.netconf.cli.commands.input.Input;
+import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
+import org.opendaylight.controller.netconf.cli.commands.output.Output;
+import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+
+/**
+ * Local Help command. Displays all commands with description.
+ */
+public class Help extends AbstractCommand {
+
+    private final CommandDispatcher commandDispatcher;
+
+    public Help(final QName qName, final InputDefinition argsDefinition, final OutputDefinition output, final String description, final CommandDispatcher commandDispatcher) {
+        super(qName, argsDefinition, output, description);
+        this.commandDispatcher = commandDispatcher;
+    }
+
+    @Override
+    public Output invoke(final Input inputArgs) {
+        final ArrayList<Node<?>> value = Lists.newArrayList();
+
+        for (final String id : commandDispatcher.getCommandIds()) {
+            final Optional<Command> cmd = commandDispatcher.getCommand(id);
+            Preconditions.checkState(cmd.isPresent(), "Command %s has to be present in command dispatcher", id);
+            final Optional<String> description = cmd.get().getCommandDescription();
+            final List<Node<?>> nameAndDescription = Lists.newArrayList();
+            nameAndDescription.add(NodeFactory.createImmutableSimpleNode(QName.create(getCommandId(), "id"), null, id));
+            if(description.isPresent()) {
+                nameAndDescription.add(NodeFactory.createImmutableSimpleNode(QName.create(getCommandId(), "description"), null, description.get()));
+            }
+            value.add(ImmutableCompositeNode.create(QName.create(getCommandId(), "commands"), nameAndDescription));
+        }
+
+        return new Output(new CompositeNodeTOImpl(getCommandId(), null, value));
+    }
+
+    public static Command create(final RpcDefinition rpcDefinition, final CommandDispatcher commandDispatcher) {
+        return new Help(rpcDefinition.getQName(), getInputDefinition(rpcDefinition), getOutputDefinition(rpcDefinition), rpcDefinition.getDescription(), commandDispatcher);
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/Output.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/Output.java
new file mode 100644 (file)
index 0000000..c366c89
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.commands.output;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.util.List;
+import java.util.Map;
+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.model.api.DataSchemaNode;
+
+/**
+ * Output values for and rpc/command execution
+ */
+public class Output {
+
+    private final CompositeNode output;
+
+    public Output(final CompositeNode output) {
+        this.output = output;
+    }
+
+    public Map<DataSchemaNode, List<Node<?>>> unwrap(final OutputDefinition outputDefinition) {
+        Preconditions.checkArgument(outputDefinition.isEmpty() == false);
+
+        final Map<QName, DataSchemaNode> mappedSchemaNodes = mapOutput(outputDefinition);
+        final Map<DataSchemaNode, List<Node<?>>> mappedNodesToSchema = Maps.newHashMap();
+
+        for (final Node<?> node : output.getValue()) {
+            final DataSchemaNode schemaNode = mappedSchemaNodes.get(node.getKey().withoutRevision());
+            final List<Node<?>> list = mappedNodesToSchema.get(schemaNode) == null ? Lists.<Node<?>> newArrayList()
+                    : mappedNodesToSchema.get(schemaNode);
+            list.add(node);
+            mappedNodesToSchema.put(schemaNode, list);
+        }
+
+        return mappedNodesToSchema;
+    }
+
+    public CompositeNode getOutput() {
+        return output;
+    }
+
+    private Map<QName, DataSchemaNode> mapOutput(final OutputDefinition outputDefinition) {
+        final Map<QName, DataSchemaNode> mapped = Maps.newHashMap();
+        for (final DataSchemaNode dataSchemaNode : outputDefinition) {
+            // without revision since data QNames come without revision
+            mapped.put(dataSchemaNode.getQName().withoutRevision(), dataSchemaNode);
+        }
+
+        return mapped;
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/OutputDefinition.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/OutputDefinition.java
new file mode 100644 (file)
index 0000000..42afb16
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.commands.output;
+
+import com.google.common.base.Preconditions;
+import java.util.Collections;
+import java.util.Iterator;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+/**
+ * The definition of output elements represented by schema nodes parsed from yang rpc definition
+ */
+public class OutputDefinition implements Iterable<DataSchemaNode> {
+
+    public static final OutputDefinition EMPTY_OUTPUT = new OutputDefinition(Collections.<DataSchemaNode>emptySet());
+    private final Iterable<DataSchemaNode> childNodes;
+
+    public OutputDefinition(final Iterable<DataSchemaNode> childNodes) {
+        this.childNodes = childNodes;
+    }
+
+    @Override
+    public Iterator<DataSchemaNode> iterator() {
+        return childNodes.iterator();
+    }
+
+    public static OutputDefinition fromOutput(final ContainerSchemaNode output) {
+        Preconditions.checkNotNull(output);
+        return new OutputDefinition(output.getChildNodes());
+    }
+
+    public static OutputDefinition empty() {
+        return EMPTY_OUTPUT;
+    }
+
+    public boolean isEmpty() {
+        return this == EMPTY_OUTPUT;
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/remote/RemoteCommand.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/remote/RemoteCommand.java
new file mode 100644 (file)
index 0000000..05b9e85
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.commands.remote;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import org.opendaylight.controller.netconf.cli.commands.AbstractCommand;
+import org.opendaylight.controller.netconf.cli.commands.Command;
+import org.opendaylight.controller.netconf.cli.commands.CommandInvocationException;
+import org.opendaylight.controller.netconf.cli.commands.input.Input;
+import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
+import org.opendaylight.controller.netconf.cli.commands.output.Output;
+import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+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.RpcDefinition;
+
+/**
+ * Generic remote command implementation that sends the rpc xml to the remote device and waits for response
+ * Waiting is limited with TIMEOUT
+ */
+public class RemoteCommand extends AbstractCommand {
+
+    // TODO make this configurable
+    private static final long DEFAULT_TIMEOUT = 10000;
+    private static final TimeUnit DEFAULT_TIMEOUT_UNIT = TimeUnit.MILLISECONDS;
+    private final RpcImplementation rpc;
+
+    public RemoteCommand(final QName qName, final InputDefinition args, final OutputDefinition output, final String description, final RpcImplementation rpc) {
+        super(qName, args, output, description);
+        this.rpc = rpc;
+    }
+
+    @Override
+    public Output invoke(final Input inputArgs) throws CommandInvocationException {
+        final ListenableFuture<RpcResult<CompositeNode>> invokeRpc = rpc.invokeRpc(getCommandId(), inputArgs.wrap(getCommandId()));
+        try {
+            return new Output(invokeRpc.get(DEFAULT_TIMEOUT, DEFAULT_TIMEOUT_UNIT).getResult());
+        } catch (final ExecutionException e) {
+            throw new CommandInvocationException(getCommandId(), e);
+        } catch (final TimeoutException e) {
+            // Request timed out, cancel request
+            invokeRpc.cancel(true);
+            throw new CommandInvocationException.CommandTimeoutException(getCommandId(), e);
+        } catch (final InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static Command fromRpc(final RpcDefinition rpcDefinition, final RpcImplementation rpcInvoker) {
+        final InputDefinition args = getInputDefinition(rpcDefinition);
+        final OutputDefinition retVal = getOutputDefinition(rpcDefinition);
+
+        return new RemoteCommand(rpcDefinition.getQName(), args, retVal, rpcDefinition.getDescription(), rpcInvoker);
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/BaseConsoleContext.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/BaseConsoleContext.java
new file mode 100644 (file)
index 0000000..26e46d3
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.io;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import jline.console.completer.AggregateCompleter;
+import jline.console.completer.Completer;
+import jline.console.completer.StringsCompleter;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+public class BaseConsoleContext<T extends DataSchemaNode> implements ConsoleContext {
+
+    private static final Completer SKIP_COMPLETER = new StringsCompleter(IOUtil.SKIP);
+
+    private final T dataSchemaNode;
+
+    public BaseConsoleContext(final T dataSchemaNode) {
+        Preconditions.checkNotNull(dataSchemaNode);
+        this.dataSchemaNode = dataSchemaNode;
+    }
+
+    @Override
+    public Completer getCompleter() {
+        final ArrayList<Completer> completers = Lists.newArrayList(SKIP_COMPLETER);
+        completers.addAll(getAdditionalCompleters());
+        return new AggregateCompleter(completers);
+    }
+
+    protected List<Completer> getAdditionalCompleters() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public Optional<String> getPrompt() {
+        return Optional.of(dataSchemaNode.getQName().getLocalName());
+    }
+
+    protected T getDataSchemaNode() {
+        return dataSchemaNode;
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleContext.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleContext.java
new file mode 100644 (file)
index 0000000..f4ebfca
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.io;
+
+import com.google.common.base.Optional;
+import jline.console.completer.Completer;
+
+/**
+ * Context to be set in the IO. Different prompts + completers are required in different contexts of the CLI.
+ */
+public interface ConsoleContext {
+
+    Completer getCompleter();
+
+    Optional<String> getPrompt();
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIO.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIO.java
new file mode 100644 (file)
index 0000000..6bffeac
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.io;
+
+import java.io.IOException;
+
+/**
+ * Definition of IO interface
+ */
+public interface ConsoleIO {
+
+    String read() throws IOException;
+
+    String read(Character mask) throws IOException;
+
+    void write(CharSequence data) throws IOException;
+
+    void writeLn(CharSequence data) throws IOException;
+
+    void formatLn(String format, Object... args) throws IOException;
+
+    void enterContext(ConsoleContext consoleContext);
+
+    void enterRootContext(ConsoleContext consoleContext);
+
+    void leaveContext();
+
+    void leaveRootContext();
+
+    void complete();
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIOImpl.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIOImpl.java
new file mode 100644 (file)
index 0000000..5b7374a
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.io;
+
+import static org.opendaylight.controller.netconf.cli.io.IOUtil.PATH_SEPARATOR;
+import static org.opendaylight.controller.netconf.cli.io.IOUtil.PROMPT_SUFIX;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.Iterator;
+import jline.console.ConsoleReader;
+import jline.console.completer.Completer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Jline based IO implementation
+ */
+public class ConsoleIOImpl implements ConsoleIO {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ConsoleIOImpl.class);
+
+    private final ConsoleReader console;
+    private final Deque<ConsoleContext> contexts = new ArrayDeque<>();
+
+    public ConsoleIOImpl() throws IOException {
+        console = new ConsoleReader();
+        console.setHandleUserInterrupt(true);
+        console.setPaginationEnabled(true);
+        console.setHistoryEnabled(true);
+
+        // TODO trifferedActions not supported by jline in current version
+        // https://github.com/jline/jline2/issues/149
+        console.addTriggeredAction('?', new QuestionMarkActionListener());
+    }
+
+    @Override
+    public String read() throws IOException {
+        return console.readLine().trim();
+    }
+
+    @Override
+    public String read(final Character mask) throws IOException {
+        return console.readLine(mask).trim();
+    }
+
+    @Override
+    public void write(final CharSequence data) throws IOException {
+        console.print(data);
+        console.flush();
+    }
+
+    @Override
+    public void writeLn(final CharSequence data) throws IOException {
+        console.println(data);
+        console.flush();
+    }
+
+    @Override
+    public void formatLn(final String format, final Object... args) throws IOException {
+        console.println(String.format(format, args));
+        console.flush();
+    }
+
+    @Override
+    public void enterContext(final ConsoleContext consoleContext) {
+        contexts.push(consoleContext);
+        enterCtx(consoleContext);
+    }
+
+
+    @Override
+    public void enterRootContext(final ConsoleContext consoleContext) {
+        contexts.addLast(consoleContext);
+        enterCtx(consoleContext);
+    }
+
+    private void enterCtx(final ConsoleContext consoleContext) {
+        setCompleter(consoleContext.getCompleter());
+        console.setPrompt(buildPrompt());
+    }
+
+    @Override
+    public void leaveContext() {
+        contexts.pollFirst();
+        leaveCtx();
+    }
+
+    @Override
+    public void leaveRootContext() {
+        contexts.pollLast();
+        leaveCtx();
+    }
+
+    private void leaveCtx() {
+        console.setPrompt(buildPrompt());
+        if (contexts.peek() != null) {
+            setCompleter(contexts.peek().getCompleter());
+        }
+    }
+
+    protected String buildPrompt() {
+        final StringBuilder newPrompt = new StringBuilder();
+
+        final Iterator<ConsoleContext> descendingIterator = contexts.descendingIterator();
+        while (descendingIterator.hasNext()) {
+            final ConsoleContext consoleContext = descendingIterator.next();
+            final Optional<String> promptPart = consoleContext.getPrompt();
+            if (promptPart.isPresent()) {
+                newPrompt.append(PATH_SEPARATOR);
+                newPrompt.append(promptPart.get());
+            }
+        }
+        if (newPrompt.length() ==0) {
+            newPrompt.append(PATH_SEPARATOR);
+        }
+
+        newPrompt.append(PROMPT_SUFIX);
+
+        return newPrompt.toString();
+    }
+
+    private void setCompleter(final Completer newCompleter) {
+        for (final Completer concreteCompleter : console.getCompleters()) {
+            console.removeCompleter(concreteCompleter);
+        }
+        console.addCompleter(newCompleter);
+    }
+
+    private class QuestionMarkActionListener implements ActionListener {
+        @Override
+        public void actionPerformed(final ActionEvent e) {
+            ConsoleIOImpl.this.complete();
+        }
+    }
+
+    public void complete() {
+        final ArrayList<CharSequence> candidates = Lists.newArrayList();
+        contexts.peek().getCompleter().complete("", 0, candidates);
+        try {
+            console.getCompletionHandler().complete(console, candidates, 0);
+        } catch (final IOException ex) {
+            throw new IllegalStateException("Unable to write to output", ex);
+        }
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/IOUtil.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/IOUtil.java
new file mode 100644 (file)
index 0000000..1817cdd
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.io;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+import org.opendaylight.yangtools.yang.common.QName;
+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.SchemaNode;
+
+public class IOUtil {
+
+    public static final String SKIP = "skip";
+    public static final String PROMPT_SUFIX = ">";
+    public static final String PATH_SEPARATOR = "/";
+
+    private IOUtil() {
+    }
+
+    public static boolean isQName(final String qName) {
+        final Matcher matcher = patternNew.matcher(qName);
+        return matcher.matches();
+    }
+
+    public static Date parseDate(final String revision) {
+        final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+        try {
+            return formatter.parse(revision);
+        } catch (final ParseException e) {
+            throw new IllegalArgumentException("Date not valid", e);
+        }
+    }
+
+    public static String listType(final SchemaNode schemaNode) {
+        if (schemaNode instanceof LeafListSchemaNode) {
+            return "Leaf-list";
+        } else if (schemaNode instanceof ListSchemaNode) {
+            return "List";
+        } else if (schemaNode instanceof LeafSchemaNode) {
+            return "Leaf";
+        }
+        // FIXME throw exception on unexpected state, not null/emptyString
+        return "";
+    }
+
+    public static String qNameToKeyString(final QName qName, final String moduleName) {
+        return String.format("%s(%s)", qName.getLocalName(), moduleName);
+    }
+
+    // TODO test and check regex + review format of string for QName
+    final static Pattern patternNew = Pattern.compile("([^\\)]+)\\(([^\\)]+)\\)");
+
+    public static QName qNameFromKeyString(final String qName, final Map<String, QName> mappedModules)
+            throws ReadingException {
+        final Matcher matcher = patternNew.matcher(qName);
+        if (!matcher.matches()) {
+            final String message = String.format("QName in wrong format: %s should be: %s", qName, patternNew);
+            throw new ReadingException(message);
+        }
+        final QName base = mappedModules.get(matcher.group(2));
+        if (base == null) {
+            final String message = String.format("Module %s cannot be found", matcher.group(2));
+            throw new ReadingException(message);
+        }
+        return QName.create(base, matcher.group(1));
+    }
+
+    public static boolean isSkipInput(final String rawValue) {
+        return rawValue.equals(SKIP);
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/AbstractReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/AbstractReader.java
new file mode 100644 (file)
index 0000000..6131eef
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Strings;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import jline.console.completer.Completer;
+import jline.console.completer.NullCompleter;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
+
+public abstract class AbstractReader<T extends DataSchemaNode> implements Reader<T> {
+
+    public static final NullContext NULL_CONTEXT = new NullContext();
+
+    // TODO make console private add protected getter
+    protected ConsoleIO console;
+    private final SchemaContext context;
+    private boolean readConfigNode = false;
+
+    public AbstractReader(final ConsoleIO console, final SchemaContext context) {
+        this.console = console;
+        this.context = context;
+    }
+
+    public AbstractReader(final ConsoleIO console, final SchemaContext context, final boolean readConfigNode) {
+        this(console, context);
+        this.readConfigNode = readConfigNode;
+    }
+
+    protected SchemaContext getSchemaContext() {
+        return context;
+    }
+
+    protected ConsoleIO getConsole() {
+        return console;
+    }
+
+    protected boolean getReadConfigNode() {
+        return readConfigNode;
+    }
+
+    @Override
+    public List<Node<?>> read(final T schemaNode) throws ReadingException {
+        if (isReadingWanted(schemaNode)) {
+            final ConsoleContext ctx = getContext(schemaNode);
+            console.enterContext(ctx);
+            try {
+                return readWithContext(schemaNode);
+            } catch (final IOException e) {
+                throw new ReadingException("Unable to read data from input for " + schemaNode.getQName(), e);
+            } finally {
+                console.leaveContext();
+            }
+        }
+        return Collections.emptyList();
+    }
+
+    private boolean isReadingWanted(final DataSchemaNode node) {
+        if (readConfigNode && !node.isConfiguration()) {
+            return false;
+        }
+        return true;
+    }
+
+    // TODO javadoc
+
+    protected abstract List<Node<?>> readWithContext(T schemaNode) throws IOException, ReadingException;
+
+    protected abstract ConsoleContext getContext(T schemaNode);
+
+    protected Optional<String> getDefaultValue(final T schemaNode) {
+        String defaultValue = null;
+        if (schemaNode instanceof LeafSchemaNode) {
+            defaultValue = ((LeafSchemaNode) schemaNode).getDefault();
+        } else if (schemaNode instanceof ChoiceNode) {
+            defaultValue = ((ChoiceNode) schemaNode).getDefaultCase();
+        }
+
+        return Optional.fromNullable(defaultValue);
+    }
+
+    protected boolean isEmptyInput(final String rawValue) {
+        return Strings.isNullOrEmpty(rawValue);
+    }
+
+    protected static boolean isEmptyType(final TypeDefinition<?> type) {
+        return type instanceof EmptyTypeDefinition;
+    }
+
+    private static class NullContext implements ConsoleContext {
+        @Override
+        public Completer getCompleter() {
+            return new NullCompleter();
+        }
+
+        @Override
+        public Optional<String> getPrompt() {
+            return Optional.absent();
+        }
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/GenericListEntryReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/GenericListEntryReader.java
new file mode 100644 (file)
index 0000000..a30b182
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader;
+
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+/**
+ * marker interface to mark reader which can be used with GenericListReader
+ */
+public interface GenericListEntryReader<T extends DataSchemaNode> extends Reader<T> {
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/Reader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/Reader.java
new file mode 100644 (file)
index 0000000..9f27b8f
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+/**
+ * Generic provider(reader) of input arguments for commands
+ */
+public interface Reader<T extends DataSchemaNode> {
+
+    List<Node<?>> read(T schemaNode) throws ReadingException;
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/ReadingException.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/ReadingException.java
new file mode 100644 (file)
index 0000000..81915fc
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader;
+
+public class ReadingException extends Exception {
+
+    private static final long serialVersionUID = -298382323286156591L;
+
+    public ReadingException(final String msg, final Exception e) {
+        super(msg, e);
+    }
+
+    public ReadingException(final String msg) {
+        super(msg);
+    }
+
+    public static class IncorrectValueException extends ReadingException {
+
+        private static final long serialVersionUID = 164168437058431592L;
+
+        public IncorrectValueException(final String msg) {
+            super(msg);
+        }
+
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/ConfigReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/ConfigReader.java
new file mode 100644 (file)
index 0000000..95fc098
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.custom;
+
+import static org.opendaylight.controller.netconf.cli.io.IOUtil.isSkipInput;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import jline.console.completer.Completer;
+import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
+import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.io.IOUtil;
+import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * Custom reader implementation for filter elements in get/get-config rpcs. This
+ * reader overrides the default anyxml reader and reads filter as a schema path.
+ */
+public class ConfigReader extends AbstractReader<DataSchemaNode> {
+
+    public static final String SEPARATOR = "/";
+
+    private final CommandArgHandlerRegistry commandArgHandlerRegistry;
+    private final Map<String, QName> mappedModules;
+    private final Map<URI, QName> mappedModulesNamespace;
+
+    public ConfigReader(final ConsoleIO console, final SchemaContext remoteSchemaContext,
+            final CommandArgHandlerRegistry commandArgHandlerRegistry) {
+        super(console, remoteSchemaContext);
+        this.commandArgHandlerRegistry = commandArgHandlerRegistry;
+
+        mappedModules = Maps.newHashMap();
+        mappedModulesNamespace = Maps.newHashMap();
+        for (final Module module : remoteSchemaContext.getModules()) {
+            final QName moduleQName = QName.create(module.getNamespace(), module.getRevision(), module.getName());
+            mappedModules.put(moduleQName.getLocalName(), moduleQName);
+            mappedModulesNamespace.put(moduleQName.getNamespace(), moduleQName);
+        }
+    }
+
+    // FIXME refactor + unite common code with FilterReader
+
+    @Override
+    protected List<Node<?>> readWithContext(final DataSchemaNode schemaNode) throws IOException, ReadingException {
+        console.writeLn("Config " + schemaNode.getQName().getLocalName());
+        console.writeLn("Submit path of the data to edit. Use TAB for autocomplete");
+
+        final String rawValue = console.read();
+
+        // FIXME isSkip check should be somewhere in abstractReader
+        if (isSkipInput(rawValue) || Strings.isNullOrEmpty(rawValue)) {
+            return Collections.emptyList();
+        }
+
+        final List<QName> filterPartsQNames = Lists.newArrayList();
+
+        for (final String part : rawValue.split(SEPARATOR)) {
+            final QName qName = IOUtil.qNameFromKeyString(part, mappedModules);
+            filterPartsQNames.add(qName);
+        }
+
+        List<Node<?>> previous = readInnerNode(rawValue);
+
+        for (final QName qName : Lists.reverse(filterPartsQNames).subList(1, filterPartsQNames.size())) {
+            previous = Collections.<Node<?>> singletonList(new CompositeNodeTOImpl(qName, null,
+                    previous == null ? Collections.<Node<?>> emptyList() : previous));
+        }
+
+        final Node<?> newNode = previous == null ? null
+                : new CompositeNodeTOImpl(schemaNode.getQName(), null, previous);
+
+        return Collections.<Node<?>> singletonList(newNode);
+    }
+
+    private List<Node<?>> readInnerNode(final String pathString) throws ReadingException {
+        final Optional<DataSchemaNode> schema = getCurrentNode(getSchemaContext(), pathString);
+        Preconditions.checkState(schema.isPresent(), "Unable to find schema for %s", pathString);
+        return commandArgHandlerRegistry.getGenericReader(getSchemaContext(), true).read(schema.get());
+    }
+
+    @Override
+    protected ConsoleContext getContext(final DataSchemaNode schemaNode) {
+        return new FilterConsoleContext(schemaNode, getSchemaContext());
+    }
+
+    private final class FilterConsoleContext extends BaseConsoleContext<DataSchemaNode> {
+
+        private final SchemaContext remoteSchemaContext;
+
+        public FilterConsoleContext(final DataSchemaNode schemaNode, final SchemaContext remoteSchemaContext) {
+            super(schemaNode);
+            this.remoteSchemaContext = remoteSchemaContext;
+        }
+
+        @Override
+        protected List<Completer> getAdditionalCompleters() {
+            return Collections.<Completer> singletonList(new FilterCompleter(remoteSchemaContext));
+        }
+    }
+
+    private final class FilterCompleter implements Completer {
+
+        private final SchemaContext remoteSchemaContext;
+
+        public FilterCompleter(final SchemaContext remoteSchemaContext) {
+            this.remoteSchemaContext = remoteSchemaContext;
+        }
+
+        @Override
+        public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
+            final int idx = buffer.lastIndexOf(SEPARATOR);
+
+            final Optional<DataSchemaNode> currentNode = getCurrentNode(remoteSchemaContext, buffer);
+            if (currentNode.isPresent() && currentNode.get() instanceof DataNodeContainer) {
+                final Collection<DataSchemaNode> childNodes = ((DataNodeContainer) currentNode.get()).getChildNodes();
+                final Collection<String> transformed = Collections2.transform(childNodes,
+                        new Function<DataSchemaNode, String>() {
+                            @Override
+                            public String apply(final DataSchemaNode input) {
+                                return IOUtil.qNameToKeyString(input.getQName(),
+                                        mappedModulesNamespace.get(input.getQName().getNamespace()).getLocalName());
+                            }
+                        });
+
+                fillCandidates(buffer.substring(idx + 1), candidates, transformed);
+            }
+
+            return idx == -1 ? 0 : idx + 1;
+        }
+
+        private void fillCandidates(final String buffer, final List<CharSequence> candidates,
+                final Collection<String> transformed) {
+            final SortedSet<String> strings = new TreeSet<>(transformed);
+
+            if (buffer == null) {
+                candidates.addAll(strings);
+            } else {
+                for (final String match : strings.tailSet(buffer)) {
+                    if (!match.startsWith(buffer)) {
+                        break;
+                    }
+                    candidates.add(match);
+                }
+            }
+
+            if (candidates.size() == 1) {
+                candidates.set(0, candidates.get(0) + SEPARATOR);
+            }
+        }
+
+    }
+
+    private Optional<DataSchemaNode> getCurrentNode(DataSchemaNode parent, final String buffer) {
+        for (final String part : buffer.split(SEPARATOR)) {
+            if (IOUtil.isQName(part) == false) {
+                return Optional.of(parent);
+            }
+
+            final QName qName;
+            try {
+                qName = IOUtil.qNameFromKeyString(part, mappedModules);
+            } catch (final ReadingException e) {
+                return Optional.of(parent);
+            }
+            if (parent instanceof DataNodeContainer) {
+                parent = ((DataNodeContainer) parent).getDataChildByName(qName);
+            } else {
+                // This should check if we are at the end of buffer ?
+                return Optional.of(parent);
+            }
+        }
+        return Optional.of(parent);
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/EditContentReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/EditContentReader.java
new file mode 100644 (file)
index 0000000..af43d37
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.custom;
+
+import com.google.common.base.Preconditions;
+import java.io.IOException;
+import java.util.List;
+import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
+import org.opendaylight.controller.netconf.cli.commands.CommandConstants;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+import org.opendaylight.controller.netconf.cli.reader.impl.ChoiceReader;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class EditContentReader extends ChoiceReader {
+
+    public static final QName EDIT_CONTENT_QNAME = QName.create(CommandConstants.NETCONF_BASE_QNAME, "edit-content");
+    public static final QName CONFIG_QNAME = QName.create(EDIT_CONTENT_QNAME, "config");
+
+    // FIXME this could be removed if feature/if-feature are supported
+
+    public EditContentReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry, final SchemaContext schemaContext) {
+        super(console, argumentHandlerRegistry, schemaContext);
+    }
+
+    @Override
+    public List<Node<?>> readWithContext(final ChoiceNode choiceNode) throws IOException, ReadingException {
+        Preconditions.checkState(choiceNode.getQName().equals(EDIT_CONTENT_QNAME), "Unexpected choice %s, expected %s", choiceNode, EDIT_CONTENT_QNAME);
+        final ChoiceCaseNode selectedCase = choiceNode.getCaseNodeByName(CONFIG_QNAME);
+        Preconditions.checkNotNull(selectedCase, "Unexpected choice %s, expected %s that contains %s", choiceNode, EDIT_CONTENT_QNAME, CONFIG_QNAME);
+        return readSelectedCase(selectedCase);
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/FilterReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/FilterReader.java
new file mode 100644 (file)
index 0000000..7b37f69
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.custom;
+
+import static org.opendaylight.controller.netconf.cli.io.IOUtil.isSkipInput;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Strings;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import jline.console.completer.Completer;
+import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.io.IOUtil;
+import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Custom reader implementation for filter elements in get/get-config rpcs. This
+ * reader overrides the default anyxml reader and reads filter as a schema path.
+ */
+public class FilterReader extends AbstractReader<DataSchemaNode> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(FilterReader.class);
+
+    public static final String SEPARATOR = "/";
+
+    private final Map<String, QName> mappedModules;
+    private final Map<URI, QName> mappedModulesNamespace;
+
+    public FilterReader(final ConsoleIO console, final SchemaContext remoteSchemaContext) {
+        super(console, remoteSchemaContext);
+
+        mappedModules = Maps.newHashMap();
+        mappedModulesNamespace = Maps.newHashMap();
+        for (final Module module : remoteSchemaContext.getModules()) {
+            final QName moduleQName = QName.create(module.getNamespace(), module.getRevision(), module.getName());
+            mappedModules.put(moduleQName.getLocalName(), moduleQName);
+            mappedModulesNamespace.put(moduleQName.getNamespace(), moduleQName);
+        }
+    }
+
+    // FIXME refactor
+
+    public static final QName FILTER_TYPE_QNAME = QName.create("urn:ietf:params:xml:ns:netconf:base:1.0", "2011-06-01",
+            "type");
+    public static final String FILTER_TYPE_VALUE_DEFAULT = "subtree";
+
+    @Override
+    protected List<Node<?>> readWithContext(final DataSchemaNode schemaNode) throws IOException, ReadingException {
+        boolean redSuccessfuly = false;
+        Node<?> newNode = null;
+        do {
+            console.writeLn("Filter " + schemaNode.getQName().getLocalName());
+            console.writeLn("Submit path of the data to retrieve. Use TAB for autocomplete");
+
+            final String rawValue = console.read();
+
+            // FIXME skip should be somewhere in abstractReader
+            if (isSkipInput(rawValue) || Strings.isNullOrEmpty(rawValue)) {
+                return Collections.emptyList();
+            }
+
+            final List<QName> filterPartsQNames = Lists.newArrayList();
+
+            try {
+                for (final String part : rawValue.split(SEPARATOR)) {
+                    final QName qName = IOUtil.qNameFromKeyString(part, mappedModules);
+                    filterPartsQNames.add(qName);
+                }
+
+                Node<?> previous = null;
+
+                for (final QName qName : Lists.reverse(filterPartsQNames)) {
+                    previous = new CompositeNodeTOImpl(qName, null,
+                            previous == null ? Collections.<Node<?>> emptyList()
+                                    : Collections.<Node<?>> singletonList(previous));
+                }
+
+                final Map<QName, String> attributes = Collections.singletonMap(FILTER_TYPE_QNAME,
+                        FILTER_TYPE_VALUE_DEFAULT);
+                newNode = previous == null ? null : ImmutableCompositeNode.create(schemaNode.getQName(), attributes,
+                        Collections.<Node<?>> singletonList(previous));
+                redSuccessfuly = true;
+            } catch (final ReadingException e) {
+                final String message = "Specified filter path isn't correct.";
+                LOG.error(message, e);
+                console.writeLn(message);
+            }
+        } while (!redSuccessfuly);
+        return Collections.<Node<?>> singletonList(newNode);
+    }
+
+    @Override
+    protected ConsoleContext getContext(final DataSchemaNode schemaNode) {
+        return new FilterConsoleContext(schemaNode, getSchemaContext());
+    }
+
+    private final class FilterConsoleContext extends BaseConsoleContext<DataSchemaNode> {
+
+        private final SchemaContext remoteSchemaContext;
+
+        public FilterConsoleContext(final DataSchemaNode schemaNode, final SchemaContext remoteSchemaContext) {
+            super(schemaNode);
+            this.remoteSchemaContext = remoteSchemaContext;
+        }
+
+        @Override
+        protected List<Completer> getAdditionalCompleters() {
+            return Collections.<Completer> singletonList(new FilterCompleter(remoteSchemaContext));
+        }
+
+    }
+
+    private final class FilterCompleter implements Completer {
+
+        private final SchemaContext remoteSchemaContext;
+
+        // TODO add skip to filter completer, better soulution would be to add
+        // SKIP completer before context completer if possible
+
+        public FilterCompleter(final SchemaContext remoteSchemaContext) {
+            this.remoteSchemaContext = remoteSchemaContext;
+        }
+
+        @Override
+        public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
+            final int idx = buffer.lastIndexOf(SEPARATOR);
+
+            final Optional<DataNodeContainer> currentNode = getCurrentNode(remoteSchemaContext, buffer);
+            if (currentNode.isPresent()) {
+
+                final Collection<String> transformed = Collections2.transform(currentNode.get().getChildNodes(),
+                        new Function<DataSchemaNode, String>() {
+                            @Override
+                            public String apply(final DataSchemaNode input) {
+                                return IOUtil.qNameToKeyString(input.getQName(),
+                                        mappedModulesNamespace.get(input.getQName().getNamespace()).getLocalName());
+                            }
+                        });
+
+                fillCandidates(buffer.substring(idx + 1), candidates, transformed);
+            }
+
+            return idx == -1 ? 0 : idx + 1;
+        }
+
+        private void fillCandidates(final String buffer, final List<CharSequence> candidates,
+                final Collection<String> transformed) {
+            final SortedSet<String> strings = new TreeSet<>(transformed);
+
+            if (buffer == null) {
+                candidates.addAll(strings);
+            } else {
+                for (final String match : strings.tailSet(buffer)) {
+                    if (!match.startsWith(buffer)) {
+                        break;
+                    }
+                    candidates.add(match);
+                }
+            }
+
+            if (candidates.size() == 1) {
+                candidates.set(0, candidates.get(0) + SEPARATOR);
+            }
+        }
+
+        private Optional<DataNodeContainer> getCurrentNode(DataNodeContainer parent, final String buffer) {
+            for (final String part : buffer.split(SEPARATOR)) {
+                if (!IOUtil.isQName(part)) {
+                    return Optional.of(parent);
+                }
+
+                QName qName;
+                try {
+                    qName = IOUtil.qNameFromKeyString(part, mappedModules);
+                } catch (final ReadingException e) {
+                    return Optional.of(parent);
+                }
+
+                final DataSchemaNode dataChildByName = parent.getDataChildByName(qName);
+                if (dataChildByName instanceof DataNodeContainer) {
+                    parent = (DataNodeContainer) dataChildByName;
+                } else {
+                    return Optional.absent();
+                }
+            }
+            return Optional.of(parent);
+        }
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/PasswordReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/PasswordReader.java
new file mode 100644 (file)
index 0000000..4804455
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.custom;
+
+import com.google.common.base.Preconditions;
+import java.io.IOException;
+import jline.console.completer.Completer;
+import jline.console.completer.NullCompleter;
+import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.reader.impl.BasicDataHolderReader;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+
+public class PasswordReader extends BasicDataHolderReader<DataSchemaNode> {
+
+    private static final char PASSWORD_MASK = '*';
+
+    public PasswordReader(final ConsoleIO console, final SchemaContext schemaContext) {
+        super(console, schemaContext);
+    }
+
+    @Override
+    protected ConsoleContext getContext(final DataSchemaNode schemaNode) {
+        return new BaseConsoleContext<DataSchemaNode>(schemaNode) {
+            @Override
+            public Completer getCompleter() {
+                return new NullCompleter();
+            }
+        };
+    }
+
+    @Override
+    protected TypeDefinition<?> getType(final DataSchemaNode schemaNode) {
+        Preconditions.checkArgument(schemaNode instanceof LeafSchemaNode);
+        return ((LeafSchemaNode)schemaNode).getType();
+    }
+
+    @Override
+    protected String readValue() throws IOException {
+        return console.read(PASSWORD_MASK);
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/AnyXmlReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/AnyXmlReader.java
new file mode 100644 (file)
index 0000000..2ce2f64
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.impl;
+
+import static org.opendaylight.controller.netconf.cli.io.IOUtil.isSkipInput;
+import static org.opendaylight.controller.netconf.cli.io.IOUtil.listType;
+
+import com.google.common.base.Optional;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+public class AnyXmlReader extends AbstractReader<AnyXmlSchemaNode> {
+
+    public AnyXmlReader(final ConsoleIO console, final SchemaContext schemaContext) {
+        super(console, schemaContext);
+    }
+
+    public AnyXmlReader(final ConsoleIO console, final SchemaContext schemaContext, final boolean readConfigNode) {
+        super(console, schemaContext, readConfigNode);
+    }
+
+    @Override
+    protected List<Node<?>> readWithContext(final AnyXmlSchemaNode schemaNode) throws IOException, ReadingException {
+        console.writeLn(listType(schemaNode) + " " + schemaNode.getQName().getLocalName());
+
+        final String rawValue = console.read();
+
+        Node<?> newNode = null;
+        if (!isSkipInput(rawValue)) {
+            final Optional<Node<?>> value = tryParse(rawValue);
+
+            if (value.isPresent()) {
+                newNode = NodeFactory.createImmutableCompositeNode(schemaNode.getQName(), null,
+                        Collections.<Node<?>> singletonList(value.get()));
+            } else {
+                newNode = NodeFactory.createImmutableSimpleNode(schemaNode.getQName(), null, rawValue);
+            }
+        }
+
+        final List<Node<?>> newNodes = new ArrayList<>();
+        newNodes.add(newNode);
+        return newNodes;
+    }
+
+    private Optional<Node<?>> tryParse(final String rawValue) {
+        try {
+            final Document dom = XmlUtil.readXmlToDocument(rawValue);
+            return Optional.<Node<?>> of(XmlDocumentUtils.toDomNode(dom));
+        } catch (SAXException | IOException e) {
+            // TODO log
+            return Optional.absent();
+        }
+    }
+
+    @Override
+    protected ConsoleContext getContext(final AnyXmlSchemaNode schemaNode) {
+        return new BaseConsoleContext<>(schemaNode);
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/BasicDataHolderReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/BasicDataHolderReader.java
new file mode 100644 (file)
index 0000000..ef41e7f
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.impl;
+
+import static org.opendaylight.controller.netconf.cli.io.IOUtil.isSkipInput;
+import static org.opendaylight.controller.netconf.cli.io.IOUtil.listType;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.HashBiMap;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import jline.console.completer.Completer;
+import jline.console.completer.StringsCompleter;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.io.IOUtil;
+import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+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.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class BasicDataHolderReader<T extends DataSchemaNode> extends AbstractReader<T> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(BasicDataHolderReader.class);
+    private DataHolderCompleter currentCompleter;
+
+    public BasicDataHolderReader(final ConsoleIO console, final SchemaContext schemaContext,
+            final boolean readConfigNode) {
+        super(console, schemaContext, readConfigNode);
+    }
+
+    public BasicDataHolderReader(final ConsoleIO console, final SchemaContext schemaContext) {
+        super(console, schemaContext);
+    }
+
+    @Override
+    public List<Node<?>> readWithContext(final T schemaNode) throws IOException, ReadingException {
+        TypeDefinition<?> type = getType(schemaNode);
+        console.formatLn("Submit %s %s(%s)", listType(schemaNode), schemaNode.getQName().getLocalName(), type.getQName().getLocalName());
+
+        while (baseTypeFor(type) instanceof UnionTypeDefinition) {
+            final Optional<TypeDefinition<?>> optionalTypeDef = new UnionTypeReader(console).read(type);
+            if (!optionalTypeDef.isPresent()) {
+                return postSkipOperations(schemaNode);
+            }
+            type = optionalTypeDef.get();
+        }
+
+        if (currentCompleter == null) {
+            currentCompleter = getBaseCompleter(schemaNode);
+        }
+
+        // TODO what if type is leafref, instance-identifier?
+
+        // Handle empty type leaf by question
+        if (isEmptyType(type)) {
+            final Optional<Boolean> shouldAddEmpty = new DecisionReader().read(console, "Add empty type leaf %s ?",
+                    schemaNode.getQName().getLocalName());
+            if (shouldAddEmpty.isPresent()) {
+                if (shouldAddEmpty.get()) {
+                    return wrapValue(schemaNode, "");
+                } else {
+                    return Collections.emptyList();
+                }
+            } else {
+                return postSkipOperations(schemaNode);
+            }
+        }
+
+        final String rawValue = readValue();
+        if (isSkipInput(rawValue)) {
+            return postSkipOperations(schemaNode);
+        }
+
+        final Object resolvedValue = currentCompleter.resolveValue(rawValue);
+
+        // Reset state TODO should be in finally
+        currentCompleter = null;
+        return wrapValue(schemaNode, resolvedValue);
+    }
+
+    private List<Node<?>> postSkipOperations(final DataSchemaNode schemaNode) throws IOException {
+        console.formatLn("Skipping %s", schemaNode.getQName());
+        return Collections.emptyList();
+    }
+
+    private TypeDefinition<?> baseTypeFor(final TypeDefinition<?> type) {
+        if (type.getBaseType() != null) {
+            return baseTypeFor(type.getBaseType());
+        }
+        return type;
+    }
+
+    protected String readValue() throws IOException {
+        return console.read();
+    }
+
+    private List<Node<?>> wrapValue(final T schemaNode, final Object value) {
+        final Node<?> newNode = NodeFactory.createImmutableSimpleNode(schemaNode.getQName(), null, value);
+        return Collections.<Node<?>> singletonList(newNode);
+    }
+
+    protected abstract TypeDefinition<?> getType(final T schemaNode);
+
+    protected final DataHolderCompleter getBaseCompleter(final T schemaNode) {
+        final TypeDefinition<?> type = getType(schemaNode);
+        final DataHolderCompleter currentCompleter;
+
+        // Add enum completer
+        if (type instanceof EnumTypeDefinition) {
+            currentCompleter = new EnumDataHolderCompleter(type);
+        } else if (type instanceof IdentityrefTypeDefinition) {
+            currentCompleter = new IdentityRefDataHolderCompleter(type, getSchemaContext());
+        } else {
+            currentCompleter = new GeneralDataHolderCompleter(type);
+        }
+        this.currentCompleter = currentCompleter;
+        return currentCompleter;
+    }
+
+    private static interface DataHolderCompleter extends Completer {
+
+        Object resolveValue(String rawValue) throws ReadingException;
+    }
+
+    private static class GeneralDataHolderCompleter implements DataHolderCompleter {
+
+        private final Optional<TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>>> codec;
+        private final TypeDefinition<?> type;
+
+        public GeneralDataHolderCompleter(final TypeDefinition<?> type) {
+            this.type = type;
+            codec = getCodecForType(type);
+        }
+
+        protected TypeDefinition<?> getType() {
+            return type;
+        }
+
+        private Optional<TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>>> getCodecForType(
+                final TypeDefinition<?> type) {
+            if (type != null) {
+                return Optional
+                        .<TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>>> fromNullable(TypeDefinitionAwareCodec
+                                .from(type));
+            }
+            return Optional.absent();
+        }
+
+        @Override
+        public Object resolveValue(final String rawValue) throws ReadingException {
+            try {
+                return codec.isPresent() ? codec.get().deserialize(rawValue) : rawValue;
+            } catch (final RuntimeException e) {
+                final String message = "It wasn't possible deserialize value " + rawValue + ".";
+                LOG.error(message, e);
+                throw new ReadingException(message, e);
+            }
+        }
+
+        @Override
+        public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
+            return 0;
+        }
+    }
+
+    private static final class EnumDataHolderCompleter extends GeneralDataHolderCompleter {
+
+        public EnumDataHolderCompleter(final TypeDefinition<?> type) {
+            super(type);
+        }
+
+        @Override
+        public Object resolveValue(final String rawValue) throws ReadingException {
+            return super.resolveValue(rawValue);
+        }
+
+        @Override
+        public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
+            return new StringsCompleter(Collections2.transform(((EnumTypeDefinition) getType()).getValues(),
+                    new Function<EnumPair, String>() {
+                        @Override
+                        public String apply(final EnumPair input) {
+                            return input.getName();
+                        }
+                    })).complete(buffer, cursor, candidates);
+        }
+    }
+
+    private static final class IdentityRefDataHolderCompleter extends GeneralDataHolderCompleter {
+
+        private final BiMap<String, QName> identityMap;
+
+        public IdentityRefDataHolderCompleter(final TypeDefinition<?> type, final SchemaContext schemaContext) {
+            super(type);
+            this.identityMap = getIdentityMap(schemaContext);
+        }
+
+        private static BiMap<String, QName> getIdentityMap(final SchemaContext schemaContext) {
+            final BiMap<String, QName> identityMap = HashBiMap.create();
+            for (final Module module : schemaContext.getModules()) {
+                for (final IdentitySchemaNode identity : module.getIdentities()) {
+                    identityMap.put(getIdentityName(identity, module), identity.getQName());
+                }
+            }
+            return identityMap;
+        }
+
+        private static String getIdentityName(final IdentitySchemaNode rpcDefinition, final Module module) {
+            return IOUtil.qNameToKeyString(rpcDefinition.getQName(), module.getName());
+        }
+
+        @Override
+        public Object resolveValue(final String rawValue) throws ReadingException {
+            final QName qName = identityMap.get(rawValue);
+            if (qName == null) {
+                throw new ReadingException("No identity found for " + rawValue + " available " + identityMap.keySet());
+            }
+            return qName;
+        }
+
+        @Override
+        public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
+
+            return new StringsCompleter(Collections2.transform(((IdentityrefTypeDefinition) getType()).getIdentity()
+                    .getDerivedIdentities(), new Function<IdentitySchemaNode, String>() {
+                @Override
+                public String apply(final IdentitySchemaNode input) {
+                    return identityMap.inverse().get(input.getQName());
+                }
+            })).complete(buffer, cursor, candidates);
+        }
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ChoiceReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ChoiceReader.java
new file mode 100644 (file)
index 0000000..1e69fbb
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.impl;
+
+import static org.opendaylight.controller.netconf.cli.io.IOUtil.isSkipInput;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Maps;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import jline.console.completer.Completer;
+import jline.console.completer.StringsCompleter;
+import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
+import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ChoiceReader extends AbstractReader<ChoiceNode> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ChoiceReader.class);
+
+    private final CommandArgHandlerRegistry argumentHandlerRegistry;
+
+    public ChoiceReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
+            final SchemaContext schemaContext) {
+        super(console, schemaContext);
+        this.argumentHandlerRegistry = argumentHandlerRegistry;
+    }
+
+    public ChoiceReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
+            final SchemaContext schemaContext, final boolean readConfigNode) {
+        super(console, schemaContext, readConfigNode);
+        this.argumentHandlerRegistry = argumentHandlerRegistry;
+    }
+
+    @Override
+    public List<Node<?>> readWithContext(final ChoiceNode choiceNode) throws IOException, ReadingException {
+        final Map<String, ChoiceCaseNode> availableCases = collectAllCases(choiceNode);
+        console.formatLn("Select case for choice %s from: %s", choiceNode.getQName().getLocalName(),
+                formatSet(availableCases.keySet()));
+
+        ChoiceCaseNode selectedCase = null;
+        final String rawValue = console.read();
+        if (isSkipInput(rawValue)) {
+            return Collections.emptyList();
+        }
+
+        selectedCase = availableCases.get(rawValue);
+        if (selectedCase == null) {
+            final String message = String.format("Incorrect value (%s) for choice %s was selected.", rawValue,
+                    choiceNode.getQName().getLocalName());
+            LOG.error(message);
+            throw new ReadingException(message);
+        }
+
+        return readSelectedCase(selectedCase);
+    }
+
+    protected List<Node<?>> readSelectedCase(final ChoiceCaseNode selectedCase) throws ReadingException {
+        // IF there is a case that contains only one Empty type leaf, create the
+        // leaf without question, since the case was selected
+        if (containsOnlyOneEmptyLeaf(selectedCase)) {
+            final Node<?> newNode = NodeFactory.createImmutableSimpleNode(selectedCase.getChildNodes().iterator()
+                    .next().getQName(), null, null);
+            return Collections.<Node<?>> singletonList(newNode);
+        }
+
+        final List<Node<?>> newNodes = new ArrayList<>();
+        for (final DataSchemaNode schemaNode : selectedCase.getChildNodes()) {
+            newNodes.addAll(argumentHandlerRegistry.getGenericReader(getSchemaContext(), getReadConfigNode()).read(
+                    schemaNode));
+        }
+        return newNodes;
+    }
+
+    private Object formatSet(final Set<String> values) {
+        final StringBuilder formatedValues = new StringBuilder();
+        for (final String value : values) {
+            formatedValues.append("\n  ");
+            formatedValues.append(value);
+        }
+        return formatedValues.toString();
+    }
+
+    private boolean containsOnlyOneEmptyLeaf(final ChoiceCaseNode selectedCase) {
+        if (selectedCase.getChildNodes().size() != 1) {
+            return false;
+        }
+        final DataSchemaNode next = selectedCase.getChildNodes().iterator().next();
+        if (next instanceof LeafSchemaNode) {
+            final TypeDefinition<?> type = ((LeafSchemaNode) next).getType();
+            if (isEmptyType(type)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private Map<String, ChoiceCaseNode> collectAllCases(final ChoiceNode schemaNode) {
+        return Maps.uniqueIndex(schemaNode.getCases(), new Function<ChoiceCaseNode, String>() {
+            @Override
+            public String apply(final ChoiceCaseNode input) {
+                return input.getQName().getLocalName();
+            }
+        });
+    }
+
+    @Override
+    protected ConsoleContext getContext(final ChoiceNode schemaNode) {
+        return new BaseConsoleContext<ChoiceNode>(schemaNode) {
+            @Override
+            public List<Completer> getAdditionalCompleters() {
+                return Collections
+                        .<Completer> singletonList(new StringsCompleter(collectAllCases(schemaNode).keySet()));
+            }
+        };
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ContainerReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ContainerReader.java
new file mode 100644 (file)
index 0000000..8e9a29e
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.impl;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
+import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+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 org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class ContainerReader extends AbstractReader<ContainerSchemaNode> {
+
+    private final CommandArgHandlerRegistry argumentHandlerRegistry;
+    private static final InputArgsLocalNameComparator CONTAINER_CHILDS_SORTER = new InputArgsLocalNameComparator();
+
+    public ContainerReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
+            final SchemaContext schemaContext) {
+        super(console, schemaContext);
+        this.argumentHandlerRegistry = argumentHandlerRegistry;
+    }
+
+    public ContainerReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
+            final SchemaContext schemaContext, final boolean readConfigNode) {
+        super(console, schemaContext, readConfigNode);
+        this.argumentHandlerRegistry = argumentHandlerRegistry;
+    }
+
+    @Override
+    public List<Node<?>> readWithContext(final ContainerSchemaNode containerNode) throws IOException, ReadingException {
+        console.formatLn("Submit child nodes for container: %s, %s", containerNode.getQName().getLocalName(),
+                Collections2.transform(containerNode.getChildNodes(), new Function<DataSchemaNode, String>() {
+                    @Override
+                    public String apply(final DataSchemaNode input) {
+                        return input.getQName().getLocalName();
+                    }
+                }));
+
+        final CompositeNodeBuilder<ImmutableCompositeNode> compositeNodeBuilder = ImmutableCompositeNode.builder();
+        compositeNodeBuilder.setQName(containerNode.getQName());
+        final SeparatedNodes separatedNodes = SeparatedNodes.separateNodes(containerNode, getReadConfigNode());
+        for (final DataSchemaNode childNode : sortChildren(separatedNodes.getMandatoryNotKey())) {
+            final List<Node<?>> redNodes = argumentHandlerRegistry.getGenericReader(getSchemaContext(),
+                    getReadConfigNode()).read(childNode);
+            if (redNodes.isEmpty()) {
+                console.formatLn("No data specified for mandatory element %s.", childNode.getQName().getLocalName());
+                return Collections.emptyList();
+            } else {
+                compositeNodeBuilder.addAll(redNodes);
+            }
+        }
+
+        for (final DataSchemaNode childNode : sortChildren(separatedNodes.getOthers())) {
+            compositeNodeBuilder.addAll(argumentHandlerRegistry.getGenericReader(getSchemaContext(),
+                    getReadConfigNode()).read(childNode));
+        }
+        return Collections.<Node<?>> singletonList(compositeNodeBuilder.toInstance());
+    }
+
+    private List<DataSchemaNode> sortChildren(final Set<DataSchemaNode> unsortedNodes) {
+        final List<DataSchemaNode> childNodes = Lists.newArrayList(unsortedNodes);
+        Collections.sort(childNodes, CONTAINER_CHILDS_SORTER);
+        return childNodes;
+    }
+
+    @Override
+    protected ConsoleContext getContext(final ContainerSchemaNode schemaNode) {
+        return new BaseConsoleContext<>(schemaNode);
+    }
+
+    private static class InputArgsLocalNameComparator implements Comparator<DataSchemaNode> {
+        @Override
+        public int compare(final DataSchemaNode o1, final DataSchemaNode o2) {
+            return o1.getQName().getLocalName().compareTo(o2.getQName().getLocalName());
+        }
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/DecisionReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/DecisionReader.java
new file mode 100644 (file)
index 0000000..b1e9a43
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.impl;
+
+import static org.opendaylight.controller.netconf.cli.io.IOUtil.SKIP;
+
+import com.google.common.base.Optional;
+import java.io.IOException;
+import jline.console.completer.AggregateCompleter;
+import jline.console.completer.Completer;
+import jline.console.completer.StringsCompleter;
+import jline.internal.Log;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.io.IOUtil;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+
+public class DecisionReader {
+
+    private static final String YES = "Y";
+    private static final String NO = "N";
+    public static final Completer YES_NO_COMPLETER = new StringsCompleter(YES, NO);
+
+    public Optional<Boolean> read(final ConsoleIO console, final String questionMessageBlueprint,
+            final Object... questionMessageArgs) throws IOException, ReadingException {
+        final ConsoleContext ctx = getContext();
+        console.enterContext(ctx);
+        try {
+            console.formatLn(questionMessageBlueprint, questionMessageArgs);
+            final String rawValue = console.read();
+            if (YES.equals(rawValue.toUpperCase())) {
+                return Optional.of(Boolean.TRUE);
+            } else if (NO.equals(rawValue.toUpperCase())) {
+                return Optional.of(Boolean.FALSE);
+            } else if (SKIP.equals(rawValue)) {
+                return Optional.absent();
+            } else {
+                final String message = String.format("Incorrect possibility (%s) was selected", rawValue);
+                Log.error(message);
+                throw new ReadingException(message);
+            }
+        } finally {
+            console.leaveContext();
+        }
+    }
+
+    private static ConsoleContext getContext() {
+        return new ConsoleContext() {
+
+            @Override
+            public Optional<String> getPrompt() {
+                return Optional.absent();
+            }
+
+            @Override
+            public Completer getCompleter() {
+                return new AggregateCompleter(YES_NO_COMPLETER, new StringsCompleter(IOUtil.SKIP));
+            }
+
+        };
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericListReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericListReader.java
new file mode 100644 (file)
index 0000000..6cf8eb2
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.impl;
+
+import static org.opendaylight.controller.netconf.cli.io.IOUtil.listType;
+
+import com.google.common.base.Optional;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
+import org.opendaylight.controller.netconf.cli.reader.GenericListEntryReader;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GenericListReader<T extends DataSchemaNode> extends AbstractReader<T> {
+    private static final Logger LOG = LoggerFactory.getLogger(GenericListReader.class);
+
+    private final GenericListEntryReader<T> concreteListEntryReader;
+
+    public GenericListReader(final ConsoleIO console, final GenericListEntryReader<T> concreteListEntryReader,
+            final SchemaContext schemaContext) {
+        super(console, schemaContext);
+        this.concreteListEntryReader = concreteListEntryReader;
+    }
+
+    public GenericListReader(final ConsoleIO console, final GenericListEntryReader<T> concreteListEntryReader,
+            final SchemaContext schemaContext, final boolean readConfigNode) {
+        super(console, schemaContext, readConfigNode);
+        this.concreteListEntryReader = concreteListEntryReader;
+    }
+
+    @Override
+    public List<Node<?>> readWithContext(final T schemaNode) throws IOException, ReadingException {
+        final List<Node<?>> newNodes = new ArrayList<>();
+        Optional<Boolean> readNextListEntry = Optional.of(Boolean.TRUE);
+        console.formatLn("Reading collection type argument: %s", schemaNode.getQName().getLocalName());
+        while (readNextListEntry.isPresent() && readNextListEntry.get()) {
+            try {
+                newNodes.addAll(concreteListEntryReader.read(schemaNode));
+            } catch (final ReadingException e) {
+                console.writeLn(e.getMessage());
+            }
+            readNextListEntry = new DecisionReader().read(console, "Add other entry to " + listType(schemaNode) + " "
+                    + schemaNode.getQName().getLocalName() + " " + " [Y|N]?");
+        }
+        console.formatLn("Collection type argument: %s read finished", schemaNode.getQName().getLocalName());
+
+        return newNodes;
+    }
+
+    @Override
+    protected ConsoleContext getContext(final T schemaNode) {
+        return new BaseConsoleContext<>(schemaNode);
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericReader.java
new file mode 100644 (file)
index 0000000..8fbfbb7
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.impl;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
+import org.opendaylight.controller.netconf.cli.commands.CommandConstants;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
+import org.opendaylight.controller.netconf.cli.reader.GenericListEntryReader;
+import org.opendaylight.controller.netconf.cli.reader.Reader;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+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.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+
+public class GenericReader extends AbstractReader<DataSchemaNode> {
+
+    private final CommandArgHandlerRegistry argumentHandlerRegistry;
+
+    public GenericReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
+            final SchemaContext schemaContext) {
+        super(console, schemaContext);
+        this.argumentHandlerRegistry = argumentHandlerRegistry;
+    }
+
+    public GenericReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
+            final SchemaContext schemaContext, final boolean readConfigNode) {
+        super(console, schemaContext, readConfigNode);
+        this.argumentHandlerRegistry = argumentHandlerRegistry;
+    }
+
+    @Override
+    protected List<Node<?>> readWithContext(final DataSchemaNode schemaNode) throws IOException, ReadingException {
+        final Optional<Class<? extends Reader<DataSchemaNode>>> customReaderClassOpt = tryGetCustomHandler(schemaNode);
+
+        if (customReaderClassOpt.isPresent()) {
+            // TODO resolve class cast of generic custom readers
+            final Reader<DataSchemaNode> customReaderInstance = (Reader<DataSchemaNode>) argumentHandlerRegistry
+                    .getCustomReader(customReaderClassOpt.get());
+            Preconditions.checkNotNull(customReaderInstance, "Unknown custom reader: %s", customReaderClassOpt.get());
+            return customReaderInstance.read(schemaNode);
+        } else {
+            return readGeneric(schemaNode);
+        }
+
+        // TODO reuse instances
+    }
+
+    private List<Node<?>> readGeneric(final DataSchemaNode schemaNode) throws ReadingException, IOException {
+        final List<Node<?>> newNodes = new ArrayList<>();
+        boolean isRedCorrectly = false;
+        do {
+            try {
+                if (schemaNode instanceof LeafSchemaNode) {
+                    return new LeafReader(console, getSchemaContext(), getReadConfigNode())
+                            .read((LeafSchemaNode) schemaNode);
+                } else if (schemaNode instanceof ContainerSchemaNode) {
+                    return new ContainerReader(console, argumentHandlerRegistry, getSchemaContext(),
+                            getReadConfigNode()).read((ContainerSchemaNode) schemaNode);
+                } else if (schemaNode instanceof ListSchemaNode) {
+                    final GenericListEntryReader<ListSchemaNode> entryReader = new ListEntryReader(console,
+                            argumentHandlerRegistry, getSchemaContext(), getReadConfigNode());
+                    return new GenericListReader<>(console, entryReader, getSchemaContext(), getReadConfigNode())
+                            .read((ListSchemaNode) schemaNode);
+                } else if (schemaNode instanceof LeafListSchemaNode) {
+                    final GenericListEntryReader<LeafListSchemaNode> entryReader = new LeafListEntryReader(console,
+                            getSchemaContext(), getReadConfigNode());
+                    return new GenericListReader<>(console, entryReader, getSchemaContext(), getReadConfigNode())
+                            .read((LeafListSchemaNode) schemaNode);
+                } else if (schemaNode instanceof ChoiceNode) {
+                    return new ChoiceReader(console, argumentHandlerRegistry, getSchemaContext(), getReadConfigNode())
+                            .read((ChoiceNode) schemaNode);
+                } else if (schemaNode instanceof AnyXmlSchemaNode) {
+                    return new AnyXmlReader(console, getSchemaContext(), getReadConfigNode())
+                            .read((AnyXmlSchemaNode) schemaNode);
+                }
+                isRedCorrectly = true;
+            } catch (final ReadingException e) {
+                console.writeLn(e.getMessage());
+            }
+        } while (!isRedCorrectly);
+        return newNodes;
+    }
+
+    @Override
+    protected ConsoleContext getContext(final DataSchemaNode schemaNode) {
+        // return null context, leave context to specific implementations
+        return NULL_CONTEXT;
+    }
+
+    private <T> Optional<Class<? extends T>> tryGetCustomHandler(final DataSchemaNode dataSchemaNode) {
+
+        for (final UnknownSchemaNode unknownSchemaNode : dataSchemaNode.getUnknownSchemaNodes()) {
+
+            if (isExtenstionForCustomHandler(unknownSchemaNode)) {
+                final String argumentHandlerClassName = unknownSchemaNode.getNodeParameter();
+                try {
+                    final Class<?> argumentClass = Class.forName(argumentHandlerClassName);
+                    // TODO add check before cast
+                    return Optional.<Class<? extends T>> of((Class<? extends T>) argumentClass);
+                } catch (final ClassNotFoundException e) {
+                    throw new IllegalArgumentException("Unknown custom reader class " + argumentHandlerClassName
+                            + " for: " + dataSchemaNode.getQName());
+                }
+            }
+        }
+
+        return Optional.absent();
+    }
+
+    private boolean isExtenstionForCustomHandler(final UnknownSchemaNode unknownSchemaNode) {
+        final QName qName = unknownSchemaNode.getExtensionDefinition().getQName();
+        return qName.equals(CommandConstants.ARG_HANDLER_EXT_QNAME);
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafListEntryReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafListEntryReader.java
new file mode 100644 (file)
index 0000000..a05a169
--- /dev/null
@@ -0,0 +1,55 @@
+
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.impl;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import jline.console.completer.Completer;
+import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.reader.GenericListEntryReader;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+
+import java.util.List;
+
+class LeafListEntryReader extends BasicDataHolderReader<LeafListSchemaNode> implements
+        GenericListEntryReader<LeafListSchemaNode> {
+
+    public LeafListEntryReader(final ConsoleIO console, final SchemaContext schemaContext) {
+        super(console, schemaContext);
+    }
+
+    public LeafListEntryReader(final ConsoleIO console, final SchemaContext schemaContext, final boolean readConfigNode) {
+        super(console, schemaContext, readConfigNode);
+    }
+
+    @Override
+    protected TypeDefinition<?> getType(final LeafListSchemaNode schemaNode) {
+        return schemaNode.getType();
+    }
+
+    @Override
+    protected ConsoleContext getContext(final LeafListSchemaNode schemaNode) {
+        return new BaseConsoleContext<LeafListSchemaNode>(schemaNode) {
+
+            @Override
+            public Optional<String> getPrompt() {
+                return Optional.of("[entry]");
+            }
+
+            @Override
+            protected List<Completer> getAdditionalCompleters() {
+                return Lists.<Completer> newArrayList(getBaseCompleter(getDataSchemaNode()));
+            }
+        };
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafReader.java
new file mode 100644 (file)
index 0000000..9a847f6
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.impl;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import java.util.List;
+import jline.console.completer.Completer;
+import jline.console.completer.StringsCompleter;
+import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+
+public class LeafReader extends BasicDataHolderReader<LeafSchemaNode> {
+
+    public LeafReader(final ConsoleIO console, final SchemaContext schemaContext) {
+        super(console, schemaContext);
+    }
+
+    public LeafReader(final ConsoleIO console, final SchemaContext schemaContext, final boolean readConfigNode) {
+        super(console, schemaContext, readConfigNode);
+    }
+
+    @Override
+    protected TypeDefinition<?> getType(final LeafSchemaNode schemaNode) {
+        return schemaNode.getType();
+    }
+
+    @Override
+    protected ConsoleContext getContext(final LeafSchemaNode schemaNode) {
+        return new BaseConsoleContext<LeafSchemaNode>(schemaNode) {
+            @Override
+            public List<Completer> getAdditionalCompleters() {
+                final List<Completer> completers = Lists.<Completer> newArrayList(getBaseCompleter(schemaNode));
+                final Optional<String> defaultValue = getDefaultValue(schemaNode);
+                if (defaultValue.isPresent()) {
+                    completers.add(new StringsCompleter(defaultValue.get()));
+                }
+                return completers;
+            }
+        };
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ListEntryReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ListEntryReader.java
new file mode 100644 (file)
index 0000000..97f7694
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.impl;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.Collections2;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
+import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
+import org.opendaylight.controller.netconf.cli.reader.GenericListEntryReader;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+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 org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class ListEntryReader extends AbstractReader<ListSchemaNode> implements GenericListEntryReader<ListSchemaNode> {
+    private static final Logger LOG = LoggerFactory.getLogger(ListEntryReader.class);
+
+    private final CommandArgHandlerRegistry argumentHandlerRegistry;
+
+    public ListEntryReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
+            final SchemaContext schemaContext) {
+        super(console, schemaContext);
+        this.argumentHandlerRegistry = argumentHandlerRegistry;
+    }
+
+    public ListEntryReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
+            final SchemaContext schemaContext, final boolean readConfigNode) {
+        super(console, schemaContext, readConfigNode);
+        this.argumentHandlerRegistry = argumentHandlerRegistry;
+    }
+
+    @Override
+    public List<Node<?>> readWithContext(final ListSchemaNode listNode) throws IOException, ReadingException {
+        console.formatLn("Submit child nodes for list entry: %s, %s", listNode.getQName().getLocalName(),
+                Collections2.transform(listNode.getChildNodes(), new Function<DataSchemaNode, String>() {
+                    @Override
+                    public String apply(final DataSchemaNode input) {
+                        return input.getQName().getLocalName();
+                    }
+                }));
+
+        final String listName = listNode.getQName().getLocalName();
+        final CompositeNodeBuilder<ImmutableCompositeNode> compositeNodeBuilder = ImmutableCompositeNode.builder();
+        compositeNodeBuilder.setQName(listNode.getQName());
+
+        final SeparatedNodes separatedChildNodes = SeparatedNodes.separateNodes(listNode, getReadConfigNode());
+
+        final List<Node<?>> nodes = readKeys(separatedChildNodes.getKeyNodes());
+        nodes.addAll(readMandatoryNotKeys(separatedChildNodes.getMandatoryNotKey()));
+        if (!separatedChildNodes.getOthers().isEmpty()) {
+            final Optional<Boolean> readNodesWhichAreNotKey = new DecisionReader().read(console,
+                    "Add non-key, non-mandatory nodes to list %s? [Y|N]", listName);
+            if (readNodesWhichAreNotKey.isPresent() && readNodesWhichAreNotKey.get()) {
+                nodes.addAll(readNotKeys(separatedChildNodes.getOthers()));
+            }
+        }
+
+        if (!nodes.isEmpty()) {
+            compositeNodeBuilder.addAll(nodes);
+            return Collections.<Node<?>> singletonList(compositeNodeBuilder.toInstance());
+        } else {
+            return Collections.emptyList();
+        }
+    }
+
+    private List<Node<?>> readKeys(final Set<DataSchemaNode> keys) throws ReadingException, IOException {
+        final List<Node<?>> newNodes = new ArrayList<>();
+        console.writeLn("Reading keys:");
+        for (final DataSchemaNode key : keys) {
+            final List<Node<?>> readKey = new LeafReader(console, getSchemaContext(), getReadConfigNode())
+                    .read((LeafSchemaNode) key);
+            if (readKey.size() != 1) {
+                final String message = String.format(
+                        "Value for key element %s has to be set. Creation of this entry is canceled.", key.getQName()
+                                .getLocalName());
+                LOG.error(message);
+                throw new ReadingException(message);
+            }
+            newNodes.addAll(readKey);
+        }
+        return newNodes;
+    }
+
+    private List<Node<?>> readMandatoryNotKeys(final Set<DataSchemaNode> mandatoryNotKeys) throws ReadingException,
+            IOException {
+        final List<Node<?>> newNodes = new ArrayList<>();
+        console.writeLn("Reading mandatory not keys nodes:");
+
+        for (final DataSchemaNode mandatoryNode : mandatoryNotKeys) {
+            final List<Node<?>> redValue = argumentHandlerRegistry.getGenericReader(getSchemaContext(),
+                    getReadConfigNode()).read(mandatoryNode);
+            if (redValue.isEmpty()) {
+                final String message = String.format(
+                        "Value for mandatory element %s has to be set. Creation of this entry is canceled.",
+                        mandatoryNode.getQName().getLocalName());
+                LOG.error(message);
+                throw new ReadingException(message);
+            }
+            newNodes.addAll(redValue);
+        }
+        return newNodes;
+    }
+
+    private List<Node<?>> readNotKeys(final Set<DataSchemaNode> notKeys) throws ReadingException {
+        final List<Node<?>> newNodes = new ArrayList<>();
+        for (final DataSchemaNode notKey : notKeys) {
+            newNodes.addAll(argumentHandlerRegistry.getGenericReader(getSchemaContext(), getReadConfigNode()).read(
+                    notKey));
+        }
+        return newNodes;
+    }
+
+    @Override
+    protected ConsoleContext getContext(final ListSchemaNode schemaNode) {
+        return new BaseConsoleContext<ListSchemaNode>(schemaNode) {
+            @Override
+            public Optional<String> getPrompt() {
+                return Optional.of("[entry]");
+            }
+        };
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/SeparatedNodes.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/SeparatedNodes.java
new file mode 100644 (file)
index 0000000..e05f786
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.impl;
+
+import com.google.common.base.Preconditions;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+class SeparatedNodes {
+    private final Set<DataSchemaNode> keyNodes;
+    private final Set<DataSchemaNode> mandatoryNotKey;
+    private final Set<DataSchemaNode> otherNodes;
+
+    public SeparatedNodes(final Set<DataSchemaNode> keyNodes, final Set<DataSchemaNode> mandatoryNotKey,
+            final Set<DataSchemaNode> otherNodes) {
+        this.keyNodes = keyNodes;
+        this.mandatoryNotKey = mandatoryNotKey;
+        this.otherNodes = otherNodes;
+    }
+
+    public Set<DataSchemaNode> getKeyNodes() {
+        return keyNodes;
+    }
+
+    public Set<DataSchemaNode> getMandatoryNotKey() {
+        return mandatoryNotKey;
+    }
+
+    public Set<DataSchemaNode> getOthers() {
+        return otherNodes;
+    }
+
+    static SeparatedNodes separateNodes(final DataNodeContainer dataNodeContainer) {
+        return separateNodes(dataNodeContainer, false);
+    }
+
+    static SeparatedNodes separateNodes(final DataNodeContainer dataNodeContainer, final boolean removeConfigFalseNodes) {
+        final Set<DataSchemaNode> keys = new HashSet<>();
+        final Set<DataSchemaNode> mandatoryNotKeys = new HashSet<>();
+        final Set<DataSchemaNode> others = new HashSet<>();
+
+        List<QName> keyQNames = Collections.emptyList();
+        if (dataNodeContainer instanceof ListSchemaNode) {
+            keyQNames = ((ListSchemaNode) dataNodeContainer).getKeyDefinition();
+        }
+
+        for (final DataSchemaNode dataSchemaNode : dataNodeContainer.getChildNodes()) {
+            if (removeConfigFalseNodes) {
+                if (!dataSchemaNode.isConfiguration()) {
+                    continue;
+                }
+            }
+            if (keyQNames.contains(dataSchemaNode.getQName())) {
+                Preconditions.checkArgument(dataSchemaNode instanceof LeafSchemaNode);
+                keys.add(dataSchemaNode);
+            } else if (dataSchemaNode.getConstraints().isMandatory()) {
+                mandatoryNotKeys.add(dataSchemaNode);
+            } else {
+                others.add(dataSchemaNode);
+            }
+        }
+
+        return new SeparatedNodes(keys, mandatoryNotKeys, others);
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/UnionTypeReader.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/UnionTypeReader.java
new file mode 100644 (file)
index 0000000..e2d186b
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.reader.impl;
+
+import static org.opendaylight.controller.netconf.cli.io.IOUtil.isSkipInput;
+
+import com.google.common.base.Optional;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import jline.console.completer.AggregateCompleter;
+import jline.console.completer.Completer;
+import jline.console.completer.StringsCompleter;
+import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.io.IOUtil;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class UnionTypeReader {
+    private static final Logger LOG = LoggerFactory.getLogger(UnionTypeReader.class);
+
+    private final ConsoleIO console;
+
+    public UnionTypeReader(final ConsoleIO console) {
+        this.console = console;
+    }
+
+    public Optional<TypeDefinition<?>> read(final TypeDefinition<?> unionTypeDefinition) throws IOException,
+            ReadingException {
+        final ConsoleContext context = getContext(unionTypeDefinition);
+        console.enterContext(context);
+        try {
+            final Map<String, TypeDefinition<?>> mapping = ((UnionConsoleContext) context).getMenuItemMapping();
+            console.formatLn("The element is of type union. Choose concrete type from: %s", mapping.keySet());
+
+            final String rawValue = console.read();
+            if (isSkipInput(rawValue)) {
+                return Optional.absent();
+            }
+            final TypeDefinition<?> value = mapping.get(rawValue);
+            if (value != null) {
+                return Optional.<TypeDefinition<?>> of(value);
+            } else {
+                final String message = String.format("Incorrect type (%s) was specified for union type definition", rawValue);
+                LOG.error(message);
+                throw new ReadingException(message);
+            }
+        } finally {
+            console.leaveContext();
+        }
+    }
+
+    private UnionConsoleContext getContext(final TypeDefinition<?> typeDefinition) {
+        return new UnionConsoleContext(typeDefinition);
+    }
+
+    private class UnionConsoleContext implements ConsoleContext {
+
+        private final TypeDefinition<?> typeDef;
+        private final Map<String, TypeDefinition<?>> menuItemsToTypeDefinitions = new HashMap<>();
+
+        public UnionConsoleContext(final TypeDefinition<?> typeDef) {
+            this.typeDef = typeDef;
+        }
+
+        @Override
+        public Optional<String> getPrompt() {
+            return Optional.of("type[" + typeDef.getQName().getLocalName()  + "]");
+        }
+
+        @Override
+        public Completer getCompleter() {
+            List<TypeDefinition<?>> subtypesForMenu = resolveSubtypesFrom(typeDef);
+            if (subtypesForMenu.isEmpty()) {
+                subtypesForMenu = Collections.<TypeDefinition<?>> singletonList(typeDef);
+            }
+            final Collection<String> menuItems = toMenuItem(subtypesForMenu);
+            return new AggregateCompleter(new StringsCompleter(menuItems), new StringsCompleter(IOUtil.SKIP));
+        }
+
+        public Map<String, TypeDefinition<?>> getMenuItemMapping() {
+            return menuItemsToTypeDefinitions;
+        }
+
+        private Collection<String> toMenuItem(final List<TypeDefinition<?>> allTypesBehindUnion) {
+            final List<String> result = new ArrayList<String>();
+            for (final TypeDefinition<?> type : allTypesBehindUnion) {
+                final String menuItem = type.getQName().getLocalName();
+                menuItemsToTypeDefinitions.put(menuItem, type);
+                result.add(menuItem);
+            }
+            return result;
+        }
+
+        /**
+         *
+         * If union type is found in potentialEndTypeCandidate as subtype then
+         * it these subtypes become candidates.
+         *
+         * @param potentialEndTypeCandidate
+         *            candidate to node which has no union subtype
+         */
+        private List<TypeDefinition<?>> resolveSubtypesFrom(final TypeDefinition<?> potentialEndTypeCandidate) {
+            if (potentialEndTypeCandidate instanceof UnionTypeDefinition) {
+                return ((UnionTypeDefinition) potentialEndTypeCandidate).getTypes();
+            }
+            if (potentialEndTypeCandidate.getBaseType() == null) {
+                return Collections.emptyList();
+            }
+            return resolveSubtypesFrom(potentialEndTypeCandidate.getBaseType());
+        }
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/OutFormatter.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/OutFormatter.java
new file mode 100644 (file)
index 0000000..bed27b4
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.writer;
+
+public class OutFormatter {
+
+    public static final String INDENT_STEP = "  ";
+    public static final String COMPOSITE_OPEN_NODE = " {";
+    public static final String COMPOSITE_CLOSE_NODE = "}";
+    public static final String NEW_LINE = "\n";
+
+    int indentLevel = -1;
+    private String currentIndent = "";
+
+    public OutFormatter indent(final StringBuilder buffer) {
+        buffer.append(currentIndent);
+        return this;
+    }
+
+    public OutFormatter openComposite(final StringBuilder buffer) {
+        buffer.append(COMPOSITE_OPEN_NODE);
+        return this;
+    }
+
+    public OutFormatter closeCompositeWithIndent(final StringBuilder buffer) {
+        buffer.append(currentIndent);
+        buffer.append(COMPOSITE_CLOSE_NODE);
+        return this;
+    }
+
+    public OutFormatter newLine(final StringBuilder buffer) {
+        buffer.append(NEW_LINE);
+        return this;
+    }
+
+    private void prepareIndent() {
+        final StringBuilder output = new StringBuilder();
+        for (int i = 0; i < indentLevel; i++) {
+            output.append(INDENT_STEP);
+        }
+        currentIndent = output.toString();
+    }
+
+    public OutFormatter increaseIndent() {
+        indentLevel++;
+        prepareIndent();
+        return this;
+    }
+
+    public OutFormatter decreaseIndent() {
+        indentLevel--;
+        prepareIndent();
+        return this;
+    }
+
+    public OutFormatter addStringWithIndent(final StringBuilder buffer, final String value) {
+        indent(buffer);
+        buffer.append(value);
+        return this;
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/WriteException.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/WriteException.java
new file mode 100644 (file)
index 0000000..b2cc456
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.writer;
+
+public class WriteException extends Exception {
+
+    private static final long serialVersionUID = 8401242676753560336L;
+
+    public WriteException(final String msg, final Exception e) {
+        super(msg, e);
+    }
+
+    public WriteException(final String msg) {
+        super(msg);
+    }
+
+    public static class IncorrectNumberOfNodes extends WriteException {
+        private static final long serialVersionUID = 8910285140705622920L;
+
+        public IncorrectNumberOfNodes(final String msg) {
+            super(msg);
+        }
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/Writer.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/Writer.java
new file mode 100644 (file)
index 0000000..ba3d876
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.writer;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+/**
+ * Generic handler(writer) of output elements for commands
+ */
+public interface Writer<T extends DataSchemaNode> {
+
+    void write(T dataSchemaNode, List<Node<?>> dataNodes) throws WriteException;
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/custom/DataWriter.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/custom/DataWriter.java
new file mode 100644 (file)
index 0000000..3724ecb
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.writer.custom;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.controller.netconf.cli.writer.WriteException;
+import org.opendaylight.controller.netconf.cli.writer.impl.AbstractWriter;
+import org.opendaylight.controller.netconf.cli.writer.impl.NormalizedNodeWriter;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class DataWriter extends AbstractWriter<DataSchemaNode> {
+
+    private final OutFormatter out;
+    private final SchemaContext remoteSchemaContext;
+
+    public DataWriter(final ConsoleIO console, final OutFormatter out, final SchemaContext remoteSchemaContext) {
+        super(console);
+        this.out = out;
+        this.remoteSchemaContext = remoteSchemaContext;
+    }
+
+    @Override
+    protected void writeInner(final DataSchemaNode dataSchemaNode, final List<Node<?>> dataNodes) throws IOException, WriteException {
+        Preconditions.checkArgument(dataNodes.size() == 1, "Expected only 1 element for data node");
+        final Node<?> dataNode = dataNodes.get(0);
+        Preconditions.checkArgument(dataNode instanceof CompositeNode, "Unexpected node type: %s, should be %s", dataNode, CompositeNode.class);
+
+        StringBuilder output = new StringBuilder();
+        out.increaseIndent().addStringWithIndent(output, dataSchemaNode.getQName().getLocalName()).openComposite(output);
+        console.writeLn(output.toString());
+
+        for (final Node<?> childNode : ((CompositeNode) dataNode).getValue()) {
+            final Optional<DataSchemaNode> schemaNode = XmlDocumentUtils.findFirstSchema(childNode.getNodeType(), remoteSchemaContext.getDataDefinitions());
+            Preconditions.checkState(schemaNode.isPresent(), "Unknown data node %s, not defined in schema", childNode.getNodeType());
+            new NormalizedNodeWriter(console, out).write(schemaNode.get(), Collections.<Node<?>>singletonList(childNode));
+        }
+
+        output = new StringBuilder();
+        out.decreaseIndent().closeCompositeWithIndent(output);
+        console.writeLn(output.toString());
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AbstractWriter.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AbstractWriter.java
new file mode 100644 (file)
index 0000000..f9c4e84
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.writer.impl;
+
+import java.io.IOException;
+import java.util.List;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.writer.WriteException;
+import org.opendaylight.controller.netconf.cli.writer.Writer;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+public abstract class AbstractWriter<T extends DataSchemaNode> implements Writer<T> {
+
+    protected ConsoleIO console;
+
+    public AbstractWriter(final ConsoleIO console) {
+        this.console = console;
+    }
+
+    @Override
+    public void write(final T dataSchemaNode, final List<Node<?>> dataNodes) throws WriteException {
+        try {
+            writeInner(dataSchemaNode, dataNodes);
+        } catch (final IOException e) {
+            throw new WriteException("Unable to write data to output for " + dataSchemaNode.getQName(), e);
+        }
+    }
+
+    protected abstract void writeInner(final T dataSchemaNode, final List<Node<?>> dataNodes) throws IOException,
+            WriteException;
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AugmentationNodeCliSerializer.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AugmentationNodeCliSerializer.java
new file mode 100644 (file)
index 0000000..626bc4e
--- /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.controller.netconf.cli.writer.impl;
+
+import com.google.common.base.Preconditions;
+import java.util.Collections;
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.AugmentationNodeBaseSerializer;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.NodeSerializerDispatcher;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+final class AugmentationNodeCliSerializer extends AugmentationNodeBaseSerializer<String> {
+
+    private final NodeSerializerDispatcher<String> dispatcher;
+    private final OutFormatter out;
+
+    AugmentationNodeCliSerializer(final OutFormatter out, final NodeSerializerDispatcher<String> dispatcher) {
+        this.out = Preconditions.checkNotNull(out);
+        this.dispatcher = Preconditions.checkNotNull(dispatcher);
+    }
+
+    @Override
+    public Iterable<String> serialize(final AugmentationSchema schema, final AugmentationNode node) {
+        final StringBuilder output = new StringBuilder();
+        out.increaseIndent();
+        out.addStringWithIndent(output, "augment");
+        out.openComposite(output);
+        out.newLine(output);
+
+        for (final String childOutput : super.serialize(schema, node)) {
+            output.append(childOutput);
+            out.newLine(output);
+        }
+
+        out.closeCompositeWithIndent(output);
+        out.decreaseIndent();
+        return Collections.singletonList(output.toString());
+    }
+
+    @Override
+    protected NodeSerializerDispatcher<String> getNodeDispatcher() {
+        return dispatcher;
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ChoiceNodeCliSerializer.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ChoiceNodeCliSerializer.java
new file mode 100644 (file)
index 0000000..1ca902f
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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.cli.writer.impl;
+
+import com.google.common.base.Preconditions;
+import java.util.Collections;
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.ChoiceNodeBaseSerializer;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.NodeSerializerDispatcher;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+
+final class ChoiceNodeCliSerializer extends ChoiceNodeBaseSerializer<String> {
+    private final NodeSerializerDispatcher<String> dispatcher;
+    private final OutFormatter out;
+
+    ChoiceNodeCliSerializer(final OutFormatter out, final NodeSerializerDispatcher<String> dispatcher) {
+        this.out = Preconditions.checkNotNull(out);
+        this.dispatcher = Preconditions.checkNotNull(dispatcher);
+    }
+
+    @Override
+    public Iterable<String> serialize(final ChoiceNode schema, final org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode node) {
+        final StringBuilder output = new StringBuilder();
+        out.increaseIndent();
+        out.addStringWithIndent(output, "choice ");
+        output.append(schema.getQName().getLocalName());
+        output.append(" (");
+        output.append(detectCase(schema, node));
+        output.append(") ");
+        out.openComposite(output);
+        out.newLine(output);
+
+        for (final String childOutput : super.serialize(schema, node)) {
+            output.append(childOutput);
+            out.newLine(output);
+        }
+
+        out.closeCompositeWithIndent(output);
+        out.decreaseIndent();
+        return Collections.singletonList(output.toString());
+    }
+
+    private String detectCase(final ChoiceNode schema, final org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode node) {
+        for (final DataContainerChild<? extends PathArgument, ?> caseChild : node.getValue()) {
+            final QName presentChildQName = caseChild.getNodeType();
+            for (final ChoiceCaseNode choiceCaseNode : schema.getCases()) {
+                if (choiceCaseNode.getDataChildByName(presentChildQName) != null) {
+                    // Pick the first case that contains first child node
+                    return choiceCaseNode.getQName().getLocalName();
+                }
+            }
+        }
+
+        // Should not happen, nodes should come from one of the cases
+        throw new IllegalStateException("Choice node " + node + " does not conform to choice schema " + schema);
+    }
+
+    @Override
+    protected NodeSerializerDispatcher<String> getNodeDispatcher() {
+        return dispatcher;
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/CliOutputFromNormalizedNodeSerializerFactory.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/CliOutputFromNormalizedNodeSerializerFactory.java
new file mode 100644 (file)
index 0000000..a62af76
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.writer.impl;
+
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.FromNormalizedNodeSerializer;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.FromNormalizedNodeSerializerFactory;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.NodeSerializerDispatcher;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+public final class CliOutputFromNormalizedNodeSerializerFactory implements FromNormalizedNodeSerializerFactory<String> {
+    private final ContainerNodeCliSerializer containerSerializer;
+    private final ChoiceNodeCliSerializer choiceSerializer;
+    private final AugmentationNodeCliSerializer augmentSerializer;
+    private final LeafNodeCliSerializer leafNodeSerializer;
+    private final LeafSetNodeCliSerializer leafSetSerializer;
+    private final MapNodeCliSerializer mapNodeSerializer;
+    private final LeafSetEntryNodeCliSerializer leafSetEntryNodeSerializer;
+    private final MapEntryNodeCliSerializer mapEntryNodeSerializer;
+    final NodeSerializerDispatcher<String> dispatcher = new NodeCliSerializerDispatcher(this);
+
+    private CliOutputFromNormalizedNodeSerializerFactory(final OutFormatter out, final XmlCodecProvider codecProvider) {
+
+        containerSerializer = new ContainerNodeCliSerializer(out, dispatcher);
+        choiceSerializer = new ChoiceNodeCliSerializer(out, dispatcher);
+        augmentSerializer = new AugmentationNodeCliSerializer(out, dispatcher);
+        leafNodeSerializer = new LeafNodeCliSerializer(out);
+
+        leafSetEntryNodeSerializer = new LeafSetEntryNodeCliSerializer(out);
+        leafSetSerializer = new LeafSetNodeCliSerializer(out, leafSetEntryNodeSerializer);
+
+        mapEntryNodeSerializer = new MapEntryNodeCliSerializer(out, dispatcher);
+        mapNodeSerializer = new MapNodeCliSerializer(out, mapEntryNodeSerializer);
+    }
+
+    public NodeSerializerDispatcher<String> getDispatcher() {
+        return dispatcher;
+    }
+
+    public static CliOutputFromNormalizedNodeSerializerFactory getInstance(final OutFormatter out,
+            final XmlCodecProvider codecProvider) {
+        return new CliOutputFromNormalizedNodeSerializerFactory(out, codecProvider);
+    }
+
+    @Override
+    public FromNormalizedNodeSerializer<String, AugmentationNode, AugmentationSchema> getAugmentationNodeSerializer() {
+        return augmentSerializer;
+    }
+
+    @Override
+    public FromNormalizedNodeSerializer<String, ChoiceNode, org.opendaylight.yangtools.yang.model.api.ChoiceNode> getChoiceNodeSerializer() {
+        return choiceSerializer;
+    }
+
+    @Override
+    public FromNormalizedNodeSerializer<String, ContainerNode, ContainerSchemaNode> getContainerNodeSerializer() {
+        return containerSerializer;
+    }
+
+    @Override
+    public FromNormalizedNodeSerializer<String, LeafNode<?>, LeafSchemaNode> getLeafNodeSerializer() {
+        return leafNodeSerializer;
+    }
+
+    @Override
+    public FromNormalizedNodeSerializer<String, LeafSetEntryNode<?>, LeafListSchemaNode> getLeafSetEntryNodeSerializer() {
+        return leafSetEntryNodeSerializer;
+    }
+
+    @Override
+    public FromNormalizedNodeSerializer<String, LeafSetNode<?>, LeafListSchemaNode> getLeafSetNodeSerializer() {
+        return leafSetSerializer;
+    }
+
+    @Override
+    public FromNormalizedNodeSerializer<String, MapEntryNode, ListSchemaNode> getMapEntryNodeSerializer() {
+        return mapEntryNodeSerializer;
+    }
+
+    @Override
+    public FromNormalizedNodeSerializer<String, MapNode, ListSchemaNode> getMapNodeSerializer() {
+        return mapNodeSerializer;
+    }
+
+    @Override
+    public FromNormalizedNodeSerializer<String, AnyXmlNode, AnyXmlSchemaNode> getAnyXmlNodeSerializer() {
+        throw new UnsupportedOperationException();
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/CompositeNodeWriter.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/CompositeNodeWriter.java
new file mode 100644 (file)
index 0000000..57d8f57
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.writer.impl;
+
+import java.io.IOException;
+import java.util.List;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.controller.netconf.cli.writer.WriteException;
+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.DataSchemaNode;
+
+public class CompositeNodeWriter extends AbstractWriter<DataSchemaNode> {
+
+    private final OutFormatter outFormatter;
+
+    public CompositeNodeWriter(final ConsoleIO console, final OutFormatter outFormatter) {
+        super(console);
+        this.outFormatter = outFormatter;
+    }
+
+    @Override
+    protected void writeInner(final DataSchemaNode dataSchemaNode, final List<Node<?>> dataNodes) throws IOException, WriteException {
+        final StringBuilder output = new StringBuilder();
+        writeNode(dataNodes, output);
+        console.writeLn(output);
+    }
+
+    private void writeNode(final List<Node<?>> dataNodes, final StringBuilder output) throws IOException, WriteException {
+        for (final Node<?> dataNode : dataNodes) {
+            outFormatter.increaseIndent();
+            outFormatter.addStringWithIndent(output, dataNode.getNodeType().getLocalName());
+            if (dataNode instanceof CompositeNode) {
+                outFormatter.openComposite(output);
+                outFormatter.newLine(output);
+                writeNode(((CompositeNode) dataNode).getValue(), output);
+                outFormatter.closeCompositeWithIndent(output);
+                outFormatter.newLine(output);
+            } else if (dataNode instanceof SimpleNode<?>) {
+                final SimpleNode<?> simpleNode = (SimpleNode<?>) dataNode;
+                output.append(" ");
+                output.append(simpleNode.getValue());
+                outFormatter.newLine(output);
+            }
+            outFormatter.decreaseIndent();
+        }
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ContainerNodeCliSerializer.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ContainerNodeCliSerializer.java
new file mode 100644 (file)
index 0000000..62b995e
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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.cli.writer.impl;
+
+import com.google.common.base.Preconditions;
+import java.util.Collections;
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.ContainerNodeBaseSerializer;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.NodeSerializerDispatcher;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+
+final class ContainerNodeCliSerializer extends ContainerNodeBaseSerializer<String> {
+
+    private final NodeSerializerDispatcher<String> dispatcher;
+    private final OutFormatter out;
+
+    ContainerNodeCliSerializer(final OutFormatter out, final NodeSerializerDispatcher<String> dispatcher) {
+        this.out = Preconditions.checkNotNull(out);
+        this.dispatcher = Preconditions.checkNotNull(dispatcher);
+    }
+
+    @Override
+    public Iterable<String> serialize(final ContainerSchemaNode schema, final ContainerNode containerNode) {
+        final StringBuilder output = new StringBuilder();
+        out.increaseIndent();
+        out.addStringWithIndent(output, containerNode.getNodeType().getLocalName());
+        out.openComposite(output);
+        out.newLine(output);
+
+        for (final String childOutput : super.serialize(schema, containerNode)) {
+            output.append(childOutput);
+            out.newLine(output);
+        }
+
+        out.closeCompositeWithIndent(output);
+        out.decreaseIndent();
+        return Collections.singletonList(output.toString());
+    }
+
+    @Override
+    protected NodeSerializerDispatcher<String> getNodeDispatcher() {
+        return dispatcher;
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafNodeCliSerializer.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafNodeCliSerializer.java
new file mode 100644 (file)
index 0000000..d3216c2
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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.cli.writer.impl;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.LeafNodeBaseSerializer;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+
+final class LeafNodeCliSerializer extends LeafNodeBaseSerializer<String> {
+    private final OutFormatter out;
+
+    LeafNodeCliSerializer(final OutFormatter out) {
+        this.out = Preconditions.checkNotNull(out);
+    }
+
+    @Override
+    public String serializeLeaf(final LeafSchemaNode schema, final LeafNode<?> node) {
+        final StringBuilder output = new StringBuilder();
+        out.increaseIndent();
+        out.addStringWithIndent(output, node.getNodeType().getLocalName());
+        output.append(" ");
+        output.append(node.getValue());
+        out.decreaseIndent();
+        return output.toString();
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetEntryNodeCliSerializer.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetEntryNodeCliSerializer.java
new file mode 100644 (file)
index 0000000..4937432
--- /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.netconf.cli.writer.impl;
+
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.LeafSetEntryNodeBaseSerializer;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+
+final class LeafSetEntryNodeCliSerializer extends LeafSetEntryNodeBaseSerializer<String> {
+
+    private final OutFormatter out;
+
+    public LeafSetEntryNodeCliSerializer(final OutFormatter out) {
+        this.out = out;
+    }
+
+    @Override
+    protected String serializeLeaf(final LeafListSchemaNode schema, final LeafSetEntryNode<?> node) {
+        final StringBuilder output = new StringBuilder();
+        out.increaseIndent();
+        out.addStringWithIndent(output, node.getValue().toString());
+        out.decreaseIndent();
+        return output.toString();
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetNodeCliSerializer.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetNodeCliSerializer.java
new file mode 100644 (file)
index 0000000..8d618e8
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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.cli.writer.impl;
+
+import java.util.Collections;
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.FromNormalizedNodeSerializer;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+
+final class LeafSetNodeCliSerializer implements
+        FromNormalizedNodeSerializer<String, LeafSetNode<?>, LeafListSchemaNode> {
+    private final LeafSetEntryNodeCliSerializer leafSetEntryNodeSerializer;
+    private final OutFormatter out;
+
+    LeafSetNodeCliSerializer(final OutFormatter out, final LeafSetEntryNodeCliSerializer leafSetEntryNodeSerializer) {
+        this.out = out;
+        this.leafSetEntryNodeSerializer = leafSetEntryNodeSerializer;
+    }
+
+    @Override
+    public Iterable<String> serialize(final LeafListSchemaNode schema, final LeafSetNode<?> node) {
+        final StringBuilder output = new StringBuilder();
+        out.increaseIndent();
+        out.addStringWithIndent(output, node.getNodeType().getLocalName());
+        out.openComposite(output);
+        out.newLine(output);
+        for (final LeafSetEntryNode<?> leafEntryNode : node.getValue()) {
+            final Iterable<String> valueFromLeafSetEntry = leafSetEntryNodeSerializer.serialize(schema, leafEntryNode);
+            output.append(valueFromLeafSetEntry.iterator().next());
+            out.newLine(output);
+        }
+        out.closeCompositeWithIndent(output);
+        out.decreaseIndent();
+        return Collections.singletonList(output.toString());
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapEntryNodeCliSerializer.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapEntryNodeCliSerializer.java
new file mode 100644 (file)
index 0000000..15f86a7
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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.cli.writer.impl;
+
+import com.google.common.base.Preconditions;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.MapEntryNodeBaseSerializer;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.NodeSerializerDispatcher;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+final class MapEntryNodeCliSerializer extends MapEntryNodeBaseSerializer<String> {
+
+    private final NodeSerializerDispatcher<String> dispatcher;
+    private final OutFormatter out;
+
+    MapEntryNodeCliSerializer(final OutFormatter out, final NodeSerializerDispatcher<String> dispatcher) {
+        this.out = Preconditions.checkNotNull(out);
+        this.dispatcher = Preconditions.checkNotNull(dispatcher);
+    }
+
+    @Override
+    public Iterable<String> serialize(final ListSchemaNode schema, final MapEntryNode node) {
+        final StringBuilder output = new StringBuilder();
+        out.increaseIndent();
+        out.addStringWithIndent(output, node.getNodeType().getLocalName());
+        serializeKeysIfPresent(node, output);
+
+        out.openComposite(output);
+        out.newLine(output);
+
+        for (final String childOutput : super.serialize(schema, node)) {
+            output.append(childOutput);
+            out.newLine(output);
+        }
+
+        out.closeCompositeWithIndent(output);
+        out.newLine(output);
+        out.decreaseIndent();
+        return Collections.singletonList(output.toString());
+    }
+
+    private void serializeKeysIfPresent(final MapEntryNode node, final StringBuilder output) {
+        final Map<QName, Object> keyValues = node.getIdentifier().getKeyValues();
+        if (keyValues.isEmpty()) {
+            return;
+        }
+
+        int i = 0;
+        output.append(" [");
+        for (final Entry<QName, Object> qNameObjectEntry : keyValues.entrySet()) {
+            output.append(qNameObjectEntry.getKey().getLocalName());
+            output.append("=");
+            output.append(qNameObjectEntry.getValue().toString());
+            if (++i != keyValues.size()) {
+                output.append(", ");
+            }
+        }
+        output.append("]");
+    }
+
+    @Override
+    protected NodeSerializerDispatcher<String> getNodeDispatcher() {
+        return dispatcher;
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapNodeCliSerializer.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapNodeCliSerializer.java
new file mode 100644 (file)
index 0000000..b08acbf
--- /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.cli.writer.impl;
+
+import com.google.common.base.Preconditions;
+import java.util.Collections;
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.FromNormalizedNodeSerializer;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+final class MapNodeCliSerializer implements FromNormalizedNodeSerializer<String, MapNode, ListSchemaNode> {
+
+    private final FromNormalizedNodeSerializer<String, MapEntryNode, ListSchemaNode> mapEntrySerializer;
+    private final OutFormatter out;
+
+    MapNodeCliSerializer(final OutFormatter out, final MapEntryNodeCliSerializer mapEntrySerializer) {
+        this.out = Preconditions.checkNotNull(out);
+        this.mapEntrySerializer = mapEntrySerializer;
+    }
+
+    @Override
+    public Iterable<String> serialize(final ListSchemaNode schema, final MapNode node) {
+        final StringBuilder output = new StringBuilder();
+
+        out.increaseIndent();
+        out.addStringWithIndent(output, node.getNodeType().getLocalName());
+        output.append(" ");
+        out.openComposite(output);
+        out.newLine(output);
+
+        for (final MapEntryNode mapEntryNode : node.getValue()) {
+            final Iterable<String> valueFromLeafSetEntry = mapEntrySerializer.serialize(schema, mapEntryNode);
+            output.append(valueFromLeafSetEntry.iterator().next());
+        }
+
+        out.closeCompositeWithIndent(output);
+        out.decreaseIndent();
+
+        return Collections.singletonList(output.toString());
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NodeCliSerializerDispatcher.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NodeCliSerializerDispatcher.java
new file mode 100644 (file)
index 0000000..566829d
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * 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.cli.writer.impl;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MixinNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.FromNormalizedNodeSerializerFactory;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.NodeSerializerDispatcher;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+public class NodeCliSerializerDispatcher implements NodeSerializerDispatcher<String> {
+    private final FromNormalizedNodeSerializerFactory<String> factory;
+
+    public NodeCliSerializerDispatcher(final FromNormalizedNodeSerializerFactory<String> factory) {
+        this.factory = Preconditions.checkNotNull(factory);
+    }
+
+    @Override
+    public final Iterable<String> dispatchChildElement(final Object childSchema,
+            final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
+        if (dataContainerChild instanceof ContainerNode) {
+            return onContainerNode(childSchema, dataContainerChild);
+        } else if (dataContainerChild instanceof LeafNode<?>) {
+            return onLeafNode(childSchema, dataContainerChild);
+        } else if (dataContainerChild instanceof MixinNode) {
+            if (dataContainerChild instanceof LeafSetNode<?>) {
+                return onLeafListNode(childSchema, dataContainerChild);
+            } else if (dataContainerChild instanceof MapNode) {
+                return onListNode(childSchema, dataContainerChild);
+            } else if (dataContainerChild instanceof ChoiceNode) {
+                return onChoiceNode(childSchema, dataContainerChild);
+            } else if (dataContainerChild instanceof AugmentationNode) {
+                return onAugmentationSchema(childSchema, dataContainerChild);
+            }
+        }
+        throw new IllegalArgumentException("Unable to serialize " + childSchema);
+    }
+
+    private Iterable<String> onAugmentationSchema(final Object childSchema,
+            final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
+        checkSchemaCompatibility(childSchema, AugmentationSchema.class, dataContainerChild);
+        return factory.getAugmentationNodeSerializer().serialize((AugmentationSchema) childSchema,
+                (AugmentationNode) dataContainerChild);
+    }
+
+    private Iterable<String> onChoiceNode(final Object childSchema,
+            final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
+        checkSchemaCompatibility(childSchema, org.opendaylight.yangtools.yang.model.api.ChoiceNode.class,
+                dataContainerChild);
+        return factory.getChoiceNodeSerializer().serialize(
+                (org.opendaylight.yangtools.yang.model.api.ChoiceNode) childSchema, (ChoiceNode) dataContainerChild);
+    }
+
+    private Iterable<String> onListNode(final Object childSchema,
+            final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
+        checkSchemaCompatibility(childSchema, ListSchemaNode.class, dataContainerChild);
+        return factory.getMapNodeSerializer().serialize((ListSchemaNode) childSchema, (MapNode) dataContainerChild);
+    }
+
+    private Iterable<String> onLeafListNode(final Object childSchema,
+            final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
+        checkSchemaCompatibility(childSchema, LeafListSchemaNode.class, dataContainerChild);
+        return factory.getLeafSetNodeSerializer().serialize((LeafListSchemaNode) childSchema,
+                (LeafSetNode<?>) dataContainerChild);
+    }
+
+    private Iterable<String> onLeafNode(final Object childSchema,
+            final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
+        checkSchemaCompatibility(childSchema, LeafSchemaNode.class, dataContainerChild);
+        final Iterable<String> elements = factory.getLeafNodeSerializer().serialize((LeafSchemaNode) childSchema,
+                (LeafNode<?>) dataContainerChild);
+        checkOnlyOneSerializedElement(elements, dataContainerChild);
+        return elements;
+    }
+
+    private static void checkOnlyOneSerializedElement(final Iterable<?> elements,
+            final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
+        final int size = Iterables.size(elements);
+        Preconditions.checkArgument(size == 1,
+                "Unexpected count of elements for entry serialized from: %s, should be 1, was: %s", dataContainerChild,
+                size);
+    }
+
+    private Iterable<String> onContainerNode(final Object childSchema,
+            final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
+        checkSchemaCompatibility(childSchema, ContainerSchemaNode.class, dataContainerChild);
+
+        final Iterable<String> elements = factory.getContainerNodeSerializer().serialize(
+                (ContainerSchemaNode) childSchema, (ContainerNode) dataContainerChild);
+        checkOnlyOneSerializedElement(elements, dataContainerChild);
+        return elements;
+    }
+
+    private static void checkSchemaCompatibility(final Object childSchema, final Class<?> containerSchemaNodeClass,
+            final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
+        Preconditions.checkArgument(containerSchemaNodeClass.isAssignableFrom(childSchema.getClass()),
+                "Incompatible schema: %s with node: %s, expected: %s", childSchema, dataContainerChild,
+                containerSchemaNodeClass);
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NormalizedNodeWriter.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NormalizedNodeWriter.java
new file mode 100644 (file)
index 0000000..c101db9
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.writer.impl;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.controller.netconf.cli.writer.WriteException;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.NodeSerializerDispatcher;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
+import org.opendaylight.yangtools.yang.data.json.schema.cnsn.parser.CnSnToNormalizedNodeParserFactory;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NormalizedNodeWriter extends AbstractWriter<DataSchemaNode> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NormalizedNodeWriter.class);
+    private final OutFormatter out;
+
+    public NormalizedNodeWriter(final ConsoleIO console, final OutFormatter out) {
+        super(console);
+        this.out = out;
+    }
+
+    public void writeInner(final DataSchemaNode dataSchemaNode, final List<Node<?>> dataNodes) throws WriteException,
+            IOException {
+
+        // TODO - add getDispatcher method to CnSnToNormalizedNodeParserFactory
+        // to be able call dispatchChildElement
+        final DataContainerChild<? extends PathArgument, ?> dataContainerChild = parseToNormalizedNode(dataNodes,
+                dataSchemaNode);
+
+        if (dataContainerChild != null) {
+            console.writeLn(serializeToCliOutput(dataContainerChild, dataSchemaNode));
+        }
+
+    }
+
+    private String serializeToCliOutput(final DataContainerChild<? extends PathArgument, ?> dataContainerChild,
+            final DataSchemaNode childSchema) {
+        final CliOutputFromNormalizedNodeSerializerFactory factorySerialization = CliOutputFromNormalizedNodeSerializerFactory
+                .getInstance(out, DomUtils.defaultValueCodecProvider());
+        final NodeSerializerDispatcher<String> dispatcher = factorySerialization.getDispatcher();
+        final Iterable<String> result = dispatcher.dispatchChildElement(childSchema, dataContainerChild);
+
+        if (result == null) {
+            return "";
+        }
+
+        final Iterator<String> output = result.iterator();
+        if (!output.hasNext()) {
+            return "";
+        }
+
+        return output.next();
+    }
+
+    private DataContainerChild<? extends PathArgument, ?> parseToNormalizedNode(final List<Node<?>> dataNodes,
+            final DataSchemaNode dataSchemaNode) {
+        final CnSnToNormalizedNodeParserFactory factoryParsing = CnSnToNormalizedNodeParserFactory.getInstance();
+        if (dataSchemaNode instanceof ContainerSchemaNode) {
+            return factoryParsing.getContainerNodeParser().parse(dataNodes, (ContainerSchemaNode) dataSchemaNode);
+        } else if (dataSchemaNode instanceof LeafSchemaNode) {
+            return factoryParsing.getLeafNodeParser().parse(dataNodes, (LeafSchemaNode) dataSchemaNode);
+        } else if (dataSchemaNode instanceof LeafListSchemaNode) {
+            return factoryParsing.getLeafSetNodeParser().parse(dataNodes, (LeafListSchemaNode) dataSchemaNode);
+        } else if (dataSchemaNode instanceof ListSchemaNode) {
+            return factoryParsing.getMapNodeParser().parse(dataNodes, (ListSchemaNode) dataSchemaNode);
+        } else if (dataSchemaNode instanceof ChoiceNode) {
+            return factoryParsing.getChoiceNodeParser().parse(dataNodes, (ChoiceNode) dataSchemaNode);
+        } else if (dataSchemaNode instanceof AugmentationSchema) {
+            return factoryParsing.getAugmentationNodeParser().parse(dataNodes, (AugmentationSchema) dataSchemaNode);
+        }
+        return null;
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/resources/logback.xml b/opendaylight/netconf/netconf-cli/src/main/resources/logback.xml
new file mode 100644 (file)
index 0000000..55eedc5
--- /dev/null
@@ -0,0 +1,31 @@
+
+<configuration scan="true">
+  <appender name="netconfcli.log" class="ch.qos.logback.core.FileAppender">
+    <file>netconfcli.log</file>
+
+    <encoder>
+      <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level
+        %logger{35} - %msg%n</pattern>
+    </encoder>
+
+  </appender>
+
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder
+      by default -->
+    <encoder>
+      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+      </pattern>
+    </encoder>
+  </appender>
+
+
+
+  <root level="trace">
+    <appender-ref ref="netconfcli.log" />
+    <!-- <appender-ref ref="STDOUT" /> -->
+  </root>
+
+  <!-- <logger name="org.opendaylight.yangtools.yang.model.api" level="TRACE"
+    additivity="false"> <appender-ref ref="netconfcli.log" /> </logger> -->
+</configuration>
diff --git a/opendaylight/netconf/netconf-cli/src/main/resources/schema/common/ietf-inet-types.yang b/opendaylight/netconf/netconf-cli/src/main/resources/schema/common/ietf-inet-types.yang
new file mode 100644 (file)
index 0000000..edd285d
--- /dev/null
@@ -0,0 +1,427 @@
+module ietf-inet-types {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+  prefix "inet";
+
+  organization
+   "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+  contact
+   "WG Web:   <http://tools.ietf.org/wg/netmod/>
+    WG List:  <mailto:netmod@ietf.org>
+
+    WG Chair: David Partain
+              <mailto:david.partain@ericsson.com>
+
+    WG Chair: David Kessens
+              <mailto:david.kessens@nsn.com>
+
+    Editor:   Juergen Schoenwaelder
+              <mailto:j.schoenwaelder@jacobs-university.de>";
+
+  description
+   "This module contains a collection of generally useful derived
+    YANG data types for Internet addresses and related things.
+
+    Copyright (c) 2010 IETF Trust and the persons identified as
+    authors of the code.  All rights reserved.
+
+
+
+    Redistribution and use in source and binary forms, with or without
+    modification, is permitted pursuant to, and subject to the license
+    terms contained in, the Simplified BSD License set forth in Section
+    4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+    (http://trustee.ietf.org/license-info).
+
+    This version of this YANG module is part of RFC 6021; see
+    the RFC itself for full legal notices.";
+
+  revision 2010-09-24 {
+    description
+     "Initial revision.";
+    reference
+     "RFC 6021: Common YANG Data Types";
+  }
+
+  /*** collection of protocol field related types ***/
+
+  typedef ip-version {
+    type enumeration {
+      enum unknown {
+        value "0";
+        description
+         "An unknown or unspecified version of the Internet protocol.";
+      }
+      enum ipv4 {
+        value "1";
+        description
+         "The IPv4 protocol as defined in RFC 791.";
+      }
+      enum ipv6 {
+        value "2";
+        description
+         "The IPv6 protocol as defined in RFC 2460.";
+      }
+    }
+    description
+     "This value represents the version of the IP protocol.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetVersion textual convention of the SMIv2.";
+    reference
+     "RFC  791: Internet Protocol
+      RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  typedef dscp {
+    type uint8 {
+      range "0..63";
+    }
+    description
+     "The dscp type represents a Differentiated Services Code-Point
+      that may be used for marking packets in a traffic stream.
+
+      In the value set and its semantics, this type is equivalent
+      to the Dscp textual convention of the SMIv2.";
+    reference
+     "RFC 3289: Management Information Base for the Differentiated
+                Services Architecture
+      RFC 2474: Definition of the Differentiated Services Field
+                (DS Field) in the IPv4 and IPv6 Headers
+      RFC 2780: IANA Allocation Guidelines For Values In
+                the Internet Protocol and Related Headers";
+  }
+
+  typedef ipv6-flow-label {
+    type uint32 {
+      range "0..1048575";
+    }
+    description
+     "The flow-label type represents flow identifier or Flow Label
+      in an IPv6 packet header that may be used to discriminate
+      traffic flows.
+
+      In the value set and its semantics, this type is equivalent
+      to the IPv6FlowLabel textual convention of the SMIv2.";
+    reference
+     "RFC 3595: Textual Conventions for IPv6 Flow Label
+      RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+  }
+
+  typedef port-number {
+    type uint16 {
+      range "0..65535";
+    }
+    description
+     "The port-number type represents a 16-bit port number of an
+      Internet transport layer protocol such as UDP, TCP, DCCP, or
+      SCTP.  Port numbers are assigned by IANA.  A current list of
+      all assignments is available from <http://www.iana.org/>.
+
+      Note that the port number value zero is reserved by IANA.  In
+      situations where the value zero does not make sense, it can
+      be excluded by subtyping the port-number type.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetPortNumber textual convention of the SMIv2.";
+    reference
+     "RFC  768: User Datagram Protocol
+      RFC  793: Transmission Control Protocol
+      RFC 4960: Stream Control Transmission Protocol
+      RFC 4340: Datagram Congestion Control Protocol (DCCP)
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  /*** collection of autonomous system related types ***/
+
+  typedef as-number {
+    type uint32;
+    description
+     "The as-number type represents autonomous system numbers
+      which identify an Autonomous System (AS).  An AS is a set
+      of routers under a single technical administration, using
+      an interior gateway protocol and common metrics to route
+      packets within the AS, and using an exterior gateway
+      protocol to route packets to other ASs'.  IANA maintains
+      the AS number space and has delegated large parts to the
+      regional registries.
+
+      Autonomous system numbers were originally limited to 16
+      bits.  BGP extensions have enlarged the autonomous system
+      number space to 32 bits.  This type therefore uses an uint32
+      base type without a range restriction in order to support
+      a larger autonomous system number space.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetAutonomousSystemNumber textual convention of
+      the SMIv2.";
+    reference
+     "RFC 1930: Guidelines for creation, selection, and registration
+                of an Autonomous System (AS)
+      RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+      RFC 4893: BGP Support for Four-octet AS Number Space
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  /*** collection of IP address and hostname related types ***/
+
+  typedef ip-address {
+    type union {
+      type inet:ipv4-address;
+      type inet:ipv6-address;
+    }
+    description
+     "The ip-address type represents an IP address and is IP
+      version neutral.  The format of the textual representations
+      implies the IP version.";
+  }
+
+  typedef ipv4-address {
+    type string {
+      pattern
+        '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+      +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+      + '(%[\p{N}\p{L}]+)?';
+    }
+    description
+      "The ipv4-address type represents an IPv4 address in
+       dotted-quad notation.  The IPv4 address may include a zone
+       index, separated by a % sign.
+
+       The zone index is used to disambiguate identical address
+       values.  For link-local addresses, the zone index will
+       typically be the interface index number or the name of an
+       interface.  If the zone index is not present, the default
+       zone of the device will be used.
+
+       The canonical format for the zone index is the numerical
+       format";
+  }
+
+  typedef ipv6-address {
+    type string {
+      pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+            + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+            + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+            + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+            + '(%[\p{N}\p{L}]+)?';
+      pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+            + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+            + '(%.+)?';
+    }
+    description
+     "The ipv6-address type represents an IPv6 address in full,
+      mixed, shortened, and shortened-mixed notation.  The IPv6
+      address may include a zone index, separated by a % sign.
+
+
+
+
+
+      The zone index is used to disambiguate identical address
+      values.  For link-local addresses, the zone index will
+      typically be the interface index number or the name of an
+      interface.  If the zone index is not present, the default
+      zone of the device will be used.
+
+      The canonical format of IPv6 addresses uses the compressed
+      format described in RFC 4291, Section 2.2, item 2 with the
+      following additional rules: the :: substitution must be
+      applied to the longest sequence of all-zero 16-bit chunks
+      in an IPv6 address.  If there is a tie, the first sequence
+      of all-zero 16-bit chunks is replaced by ::.  Single
+      all-zero 16-bit chunks are not compressed.  The canonical
+      format uses lowercase characters and leading zeros are
+      not allowed.  The canonical format for the zone index is
+      the numerical format as described in RFC 4007, Section
+      11.2.";
+    reference
+     "RFC 4291: IP Version 6 Addressing Architecture
+      RFC 4007: IPv6 Scoped Address Architecture
+      RFC 5952: A Recommendation for IPv6 Address Text Representation";
+  }
+
+  typedef ip-prefix {
+    type union {
+      type inet:ipv4-prefix;
+      type inet:ipv6-prefix;
+    }
+    description
+     "The ip-prefix type represents an IP prefix and is IP
+      version neutral.  The format of the textual representations
+      implies the IP version.";
+  }
+
+  typedef ipv4-prefix {
+    type string {
+      pattern
+         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+       + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+    }
+    description
+     "The ipv4-prefix type represents an IPv4 address prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal to 32.
+
+
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.
+
+      The canonical format of an IPv4 prefix has all bits of
+      the IPv4 address set to zero that are not part of the
+      IPv4 prefix.";
+  }
+
+  typedef ipv6-prefix {
+    type string {
+      pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+            + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+            + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+            + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+            + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+      pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+            + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+            + '(/.+)';
+    }
+    description
+     "The ipv6-prefix type represents an IPv6 address prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal 128.
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.
+
+      The IPv6 address should have all bits that do not belong
+      to the prefix set to zero.
+
+      The canonical format of an IPv6 prefix has all bits of
+      the IPv6 address set to zero that are not part of the
+      IPv6 prefix.  Furthermore, IPv6 address is represented
+      in the compressed format described in RFC 4291, Section
+      2.2, item 2 with the following additional rules: the ::
+      substitution must be applied to the longest sequence of
+      all-zero 16-bit chunks in an IPv6 address.  If there is
+      a tie, the first sequence of all-zero 16-bit chunks is
+      replaced by ::.  Single all-zero 16-bit chunks are not
+      compressed.  The canonical format uses lowercase
+      characters and leading zeros are not allowed.";
+    reference
+     "RFC 4291: IP Version 6 Addressing Architecture";
+  }
+
+
+  /*** collection of domain name and URI types ***/
+
+  typedef domain-name {
+    type string {
+      pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+           +  '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+           +  '|\.';
+      length "1..253";
+    }
+    description
+     "The domain-name type represents a DNS domain name.  The
+      name SHOULD be fully qualified whenever possible.
+
+      Internet domain names are only loosely specified.  Section
+      3.5 of RFC 1034 recommends a syntax (modified in Section
+      2.1 of RFC 1123).  The pattern above is intended to allow
+      for current practice in domain name use, and some possible
+      future expansion.  It is designed to hold various types of
+      domain names, including names used for A or AAAA records
+      (host names) and other records, such as SRV records.  Note
+      that Internet host names have a stricter syntax (described
+      in RFC 952) than the DNS recommendations in RFCs 1034 and
+      1123, and that systems that want to store host names in
+      schema nodes using the domain-name type are recommended to
+      adhere to this stricter standard to ensure interoperability.
+
+      The encoding of DNS names in the DNS protocol is limited
+      to 255 characters.  Since the encoding consists of labels
+      prefixed by a length bytes and there is a trailing NULL
+      byte, only 253 characters can appear in the textual dotted
+      notation.
+
+      The description clause of schema nodes using the domain-name
+      type MUST describe when and how these names are resolved to
+      IP addresses.  Note that the resolution of a domain-name value
+      may require to query multiple DNS records (e.g., A for IPv4
+      and AAAA for IPv6).  The order of the resolution process and
+      which DNS record takes precedence can either be defined
+      explicitely or it may depend on the configuration of the
+      resolver.
+
+      Domain-name values use the US-ASCII encoding.  Their canonical
+      format uses lowercase US-ASCII characters.  Internationalized
+      domain names MUST be encoded in punycode as described in RFC
+      3492";
+    reference
+     "RFC  952: DoD Internet Host Table Specification
+      RFC 1034: Domain Names - Concepts and Facilities
+      RFC 1123: Requirements for Internet Hosts -- Application
+                and Support
+      RFC 2782: A DNS RR for specifying the location of services
+                (DNS SRV)
+      RFC 3492: Punycode: A Bootstring encoding of Unicode for
+                Internationalized Domain Names in Applications
+                (IDNA)
+      RFC 5891: Internationalizing Domain Names in Applications
+                (IDNA): Protocol";
+  }
+
+  typedef host {
+    type union {
+      type inet:ip-address;
+      type inet:domain-name;
+    }
+    description
+     "The host type represents either an IP address or a DNS
+      domain name.";
+  }
+
+  typedef uri {
+    type string;
+    description
+     "The uri type represents a Uniform Resource Identifier
+      (URI) as defined by STD 66.
+
+      Objects using the uri type MUST be in US-ASCII encoding,
+      and MUST be normalized as described by RFC 3986 Sections
+      6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary
+      percent-encoding is removed, and all case-insensitive
+      characters are set to lowercase except for hexadecimal
+      digits, which are normalized to uppercase as described in
+      Section 6.2.2.1.
+
+      The purpose of this normalization is to help provide
+      unique URIs.  Note that this normalization is not
+      sufficient to provide uniqueness.  Two URIs that are
+      textually distinct after this normalization may still be
+      equivalent.
+
+      Objects using the uri type may restrict the schemes that
+      they permit.  For example, 'data:' and 'urn:' schemes
+      might not be appropriate.
+
+      A zero-length URI is not a valid URI.  This can be used to
+      express 'URI absent' where required.
+
+      In the value set and its semantics, this type is equivalent
+      to the Uri SMIv2 textual convention defined in RFC 5017.";
+    reference
+     "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+      RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+                Group: Uniform Resource Identifiers (URIs), URLs,
+                and Uniform Resource Names (URNs): Clarifications
+                and Recommendations
+      RFC 5017: MIB Textual Conventions for Uniform Resource
+                Identifiers (URIs)";
+  }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/resources/schema/common/netconf-cli-ext.yang b/opendaylight/netconf/netconf-cli/src/main/resources/schema/common/netconf-cli-ext.yang
new file mode 100644 (file)
index 0000000..139778a
--- /dev/null
@@ -0,0 +1,18 @@
+module netconf-cli-ext {
+
+  namespace "urn:ietf:params:xml:ns:netconf:base:1.0:cli";
+
+  prefix cliext;
+
+    revision 2014-05-26 {
+      description
+        "Initial revision";
+    }
+
+  extension argument-handler {
+    description
+        "Links custom argument reader to an input argument";
+    argument "name";
+  }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/resources/schema/local/netconf-cli.yang b/opendaylight/netconf/netconf-cli/src/main/resources/schema/local/netconf-cli.yang
new file mode 100644 (file)
index 0000000..52f7b97
--- /dev/null
@@ -0,0 +1,97 @@
+module netconf-cli {
+
+  namespace "netconf:cli";
+  prefix ncli;
+
+  import ietf-inet-types { prefix inet; revision-date 2010-09-24; }
+  import netconf-cli-ext { prefix cliext; revision-date 2014-05-26; }
+
+
+    revision 2014-05-22 {
+      description
+       "Initial revision.";
+    }
+
+  extension java-class {
+      description
+          "This could be used to link between rpc yang definition and custom command implementation";
+
+      argument "name";
+  }
+
+  rpc help {
+    description
+        "Display help";
+
+    output {
+      list commands {
+
+        key "id";
+        leaf id {
+            type string;
+        }
+        leaf description {
+            type string;
+        }
+      }
+    }
+  }
+
+  rpc close {
+      description
+          "Close the whole cli";
+  }
+
+  rpc connect {
+
+        description
+            "Connect to a remote netconf device, if not connected yet. Connection initialization is blocking and might take some time, depending on amount of yang schemas in remote device.";
+
+      input {
+
+         // TODO yangtools keep input arguments unordered so the ordering in cli is random
+         leaf address-name {
+           type inet:host;
+           default localhost;
+         }
+
+         leaf address-port {
+           type inet:port-number;
+           default 830;
+         }
+
+          leaf user-name {
+           type string;
+         }
+
+        leaf user-password {
+            cliext:argument-handler org.opendaylight.controller.netconf.cli.reader.custom.PasswordReader;
+            type string;
+        }
+      }
+
+      output {
+        leaf status {
+            type string;
+        }
+
+        leaf-list remote-commands {
+            type string;
+        }
+      }
+  }
+
+
+  rpc disconnect {
+
+      description
+          "Disconnect from a netconf device that is currently connected";
+
+      output {
+        leaf status {
+            type string;
+        }
+      }
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/main/resources/schema/remote/ietf-netconf.yang b/opendaylight/netconf/netconf-cli/src/main/resources/schema/remote/ietf-netconf.yang
new file mode 100644 (file)
index 0000000..d41c2e3
--- /dev/null
@@ -0,0 +1,943 @@
+module ietf-netconf {
+
+  // the namespace for NETCONF XML definitions is unchanged
+  // from RFC 4741, which this document replaces
+  namespace "urn:ietf:params:xml:ns:netconf:base:1.0";
+
+  prefix nc;
+
+  import ietf-inet-types {
+    prefix inet;
+  }
+
+  import netconf-cli-ext { prefix cliext; revision-date 2014-05-26; }
+
+
+  organization
+    "IETF NETCONF (Network Configuration) Working Group";
+
+  contact
+    "WG Web:   <http://tools.ietf.org/wg/netconf/>
+     WG List:  <netconf@ietf.org>
+
+     WG Chair: Bert Wijnen
+               <bertietf@bwijnen.net>
+
+     WG Chair: Mehmet Ersue
+               <mehmet.ersue@nsn.com>
+
+     Editor:   Martin Bjorklund
+               <mbj@tail-f.com>
+
+     Editor:   Juergen Schoenwaelder
+               <j.schoenwaelder@jacobs-university.de>
+
+     Editor:   Andy Bierman
+               <andy.bierman@brocade.com>";
+  description
+    "NETCONF Protocol Data Types and Protocol Operations.
+
+     Copyright (c) 2011 IETF Trust and the persons identified as
+     the document authors.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6241; see
+     the RFC itself for full legal notices.";
+  revision 2011-06-01 {
+    description
+      "Initial revision";
+    reference
+      "RFC 6241: Network Configuration Protocol";
+  }
+
+  extension get-filter-element-attributes {
+    description
+      "If this extension is present within an 'anyxml'
+       statement named 'filter', which must be conceptually
+       defined within the RPC input section for the <get>
+       and <get-config> protocol operations, then the
+       following unqualified XML attribute is supported
+       within the <filter> element, within a <get> or
+       <get-config> protocol operation:
+
+         type : optional attribute with allowed
+                value strings 'subtree' and 'xpath'.
+                If missing, the default value is 'subtree'.
+
+       If the 'xpath' feature is supported, then the
+       following unqualified XML attribute is
+       also supported:
+
+         select: optional attribute containing a
+                 string representing an XPath expression.
+                 The 'type' attribute must be equal to 'xpath'
+                 if this attribute is present.";
+  }
+
+  // NETCONF capabilities defined as features
+  feature writable-running {
+    description
+      "NETCONF :writable-running capability;
+       If the server advertises the :writable-running
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.2";
+  }
+
+  feature candidate {
+    description
+      "NETCONF :candidate capability;
+       If the server advertises the :candidate
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.3";
+  }
+
+  feature confirmed-commit {
+    if-feature candidate;
+    description
+      "NETCONF :confirmed-commit:1.1 capability;
+       If the server advertises the :confirmed-commit:1.1
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+
+    reference "RFC 6241, Section 8.4";
+  }
+
+  feature rollback-on-error {
+    description
+      "NETCONF :rollback-on-error capability;
+       If the server advertises the :rollback-on-error
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.5";
+  }
+
+  feature validate {
+    description
+      "NETCONF :validate:1.1 capability;
+       If the server advertises the :validate:1.1
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.6";
+  }
+
+  feature startup {
+    description
+      "NETCONF :startup capability;
+       If the server advertises the :startup
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.7";
+  }
+
+  feature url {
+    description
+      "NETCONF :url capability;
+       If the server advertises the :url
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.8";
+  }
+
+  feature xpath {
+    description
+      "NETCONF :xpath capability;
+       If the server advertises the :xpath
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.9";
+  }
+
+  // NETCONF Simple Types
+
+  typedef session-id-type {
+    type uint32 {
+      range "1..max";
+    }
+    description
+      "NETCONF Session Id";
+  }
+
+  typedef session-id-or-zero-type {
+    type uint32;
+    description
+      "NETCONF Session Id or Zero to indicate none";
+  }
+  typedef error-tag-type {
+    type enumeration {
+       enum in-use {
+         description
+           "The request requires a resource that
+            already is in use.";
+       }
+       enum invalid-value {
+         description
+           "The request specifies an unacceptable value for one
+            or more parameters.";
+       }
+       enum too-big {
+         description
+           "The request or response (that would be generated) is
+            too large for the implementation to handle.";
+       }
+       enum missing-attribute {
+         description
+           "An expected attribute is missing.";
+       }
+       enum bad-attribute {
+         description
+           "An attribute value is not correct; e.g., wrong type,
+            out of range, pattern mismatch.";
+       }
+       enum unknown-attribute {
+         description
+           "An unexpected attribute is present.";
+       }
+       enum missing-element {
+         description
+           "An expected element is missing.";
+       }
+       enum bad-element {
+         description
+           "An element value is not correct; e.g., wrong type,
+            out of range, pattern mismatch.";
+       }
+       enum unknown-element {
+         description
+           "An unexpected element is present.";
+       }
+       enum unknown-namespace {
+         description
+           "An unexpected namespace is present.";
+       }
+       enum access-denied {
+         description
+           "Access to the requested protocol operation or
+            data model is denied because authorization failed.";
+       }
+       enum lock-denied {
+         description
+           "Access to the requested lock is denied because the
+            lock is currently held by another entity.";
+       }
+       enum resource-denied {
+         description
+           "Request could not be completed because of
+            insufficient resources.";
+       }
+       enum rollback-failed {
+         description
+           "Request to roll back some configuration change (via
+            rollback-on-error or <discard-changes> operations)
+            was not completed for some reason.";
+
+       }
+       enum data-exists {
+         description
+           "Request could not be completed because the relevant
+            data model content already exists.  For example,
+            a 'create' operation was attempted on data that
+            already exists.";
+       }
+       enum data-missing {
+         description
+           "Request could not be completed because the relevant
+            data model content does not exist.  For example,
+            a 'delete' operation was attempted on
+            data that does not exist.";
+       }
+       enum operation-not-supported {
+         description
+           "Request could not be completed because the requested
+            operation is not supported by this implementation.";
+       }
+       enum operation-failed {
+         description
+           "Request could not be completed because the requested
+            operation failed for some reason not covered by
+            any other error condition.";
+       }
+       enum partial-operation {
+         description
+           "This error-tag is obsolete, and SHOULD NOT be sent
+            by servers conforming to this document.";
+       }
+       enum malformed-message {
+         description
+           "A message could not be handled because it failed to
+            be parsed correctly.  For example, the message is not
+            well-formed XML or it uses an invalid character set.";
+       }
+     }
+     description "NETCONF Error Tag";
+     reference "RFC 6241, Appendix A";
+  }
+
+  typedef error-severity-type {
+    type enumeration {
+      enum error {
+        description "Error severity";
+      }
+      enum warning {
+        description "Warning severity";
+      }
+    }
+    description "NETCONF Error Severity";
+    reference "RFC 6241, Section 4.3";
+  }
+
+  typedef edit-operation-type {
+    type enumeration {
+      enum merge {
+        description
+          "The configuration data identified by the
+           element containing this attribute is merged
+           with the configuration at the corresponding
+           level in the configuration datastore identified
+           by the target parameter.";
+      }
+      enum replace {
+        description
+          "The configuration data identified by the element
+           containing this attribute replaces any related
+           configuration in the configuration datastore
+           identified by the target parameter.  If no such
+           configuration data exists in the configuration
+           datastore, it is created.  Unlike a
+           <copy-config> operation, which replaces the
+           entire target configuration, only the configuration
+           actually present in the config parameter is affected.";
+      }
+      enum create {
+        description
+          "The configuration data identified by the element
+           containing this attribute is added to the
+           configuration if and only if the configuration
+           data does not already exist in the configuration
+           datastore.  If the configuration data exists, an
+           <rpc-error> element is returned with an
+           <error-tag> value of 'data-exists'.";
+      }
+      enum delete {
+        description
+          "The configuration data identified by the element
+           containing this attribute is deleted from the
+           configuration if and only if the configuration
+           data currently exists in the configuration
+           datastore.  If the configuration data does not
+           exist, an <rpc-error> element is returned with
+           an <error-tag> value of 'data-missing'.";
+      }
+      enum remove {
+        description
+          "The configuration data identified by the element
+           containing this attribute is deleted from the
+           configuration if the configuration
+           data currently exists in the configuration
+           datastore.  If the configuration data does not
+           exist, the 'remove' operation is silently ignored
+           by the server.";
+      }
+    }
+    default "merge";
+    description "NETCONF 'operation' attribute values";
+    reference "RFC 6241, Section 7.2";
+  }
+
+  // NETCONF Standard Protocol Operations
+
+  rpc get-config {
+    description
+      "Retrieve all or part of a specified configuration.";
+
+    reference "RFC 6241, Section 7.1";
+
+    input {
+      container source {
+        description
+          "Particular configuration to retrieve.";
+
+        choice config-source {
+          mandatory true;
+          description
+            "The configuration to retrieve.";
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config source.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config source.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config source.
+               This is optional-to-implement on the server because
+               not all servers will support filtering for this
+               datastore.";
+          }
+        }
+      }
+
+      anyxml filter {
+        description
+          "Subtree or XPath filter to use.";
+        nc:get-filter-element-attributes;
+        // TODO this extension should be augmented (anyxml nodes cannot be augmented)
+        // or we can identify custom input/output arguments by schemaPath defined for custom handlers
+        cliext:argument-handler org.opendaylight.controller.netconf.cli.reader.custom.FilterReader;
+      }
+    }
+
+    output {
+      anyxml data {
+        description
+          "Copy of the source datastore subset that matched
+           the filter criteria (if any).  An empty data container
+           indicates that the request did not produce any results.";
+       cliext:argument-handler org.opendaylight.controller.netconf.cli.writer.custom.DataWriter;
+     }
+    }
+  }
+
+  rpc edit-config {
+    description
+      "The <edit-config> operation loads all or part of a specified
+       configuration to the specified target configuration.";
+
+    reference "RFC 6241, Section 7.2";
+
+    input {
+      container target {
+        description
+          "Particular configuration to edit.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config target.";
+          }
+          leaf running {
+            if-feature writable-running;
+            type empty;
+            description
+              "The running configuration is the config source.";
+          }
+        }
+      }
+
+      leaf default-operation {
+        type enumeration {
+          enum merge {
+            description
+              "The default operation is merge.";
+          }
+          enum replace {
+            description
+              "The default operation is replace.";
+          }
+          enum none {
+            description
+              "There is no default operation.";
+          }
+        }
+        default "merge";
+        description
+          "The default operation to use.";
+      }
+
+      leaf test-option {
+        if-feature validate;
+        type enumeration {
+          enum test-then-set {
+            description
+              "The server will test and then set if no errors.";
+          }
+          enum set {
+            description
+              "The server will set without a test first.";
+          }
+
+          enum test-only {
+            description
+              "The server will only test and not set, even
+               if there are no errors.";
+          }
+        }
+        default "test-then-set";
+        description
+          "The test option to use.";
+      }
+
+      leaf error-option {
+        type enumeration {
+          enum stop-on-error {
+            description
+              "The server will stop on errors.";
+          }
+          enum continue-on-error {
+            description
+              "The server may continue on errors.";
+          }
+          enum rollback-on-error {
+            description
+              "The server will roll back on errors.
+               This value can only be used if the 'rollback-on-error'
+               feature is supported.";
+          }
+        }
+        default "stop-on-error";
+        description
+          "The error option to use.";
+      }
+
+      choice edit-content {
+        mandatory true;
+        description
+          "The content for the edit operation.";
+
+        cliext:argument-handler org.opendaylight.controller.netconf.cli.reader.custom.EditContentReader;
+
+        anyxml config {
+          description
+            "Inline Config content.";
+          cliext:argument-handler org.opendaylight.controller.netconf.cli.reader.custom.ConfigReader;
+        }
+
+        leaf url {
+          if-feature url;
+          type inet:uri;
+          description
+            "URL-based config content.";
+        }
+      }
+    }
+  }
+
+  rpc copy-config {
+    description
+      "Create or replace an entire configuration datastore with the
+       contents of another complete configuration datastore.";
+
+    reference "RFC 6241, Section 7.3";
+
+    input {
+      container target {
+        description
+          "Particular configuration to copy to.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target of the copy operation.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config target.";
+          }
+          leaf running {
+            if-feature writable-running;
+            type empty;
+            description
+              "The running configuration is the config target.
+               This is optional-to-implement on the server.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config target.";
+          }
+          leaf url {
+            if-feature url;
+            type inet:uri;
+            description
+              "The URL-based configuration is the config target.";
+          }
+        }
+      }
+
+      container source {
+        description
+          "Particular configuration to copy from.";
+
+        choice config-source {
+          mandatory true;
+          description
+            "The configuration source for the copy operation.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config source.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config source.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config source.";
+          }
+          leaf url {
+            if-feature url;
+            type inet:uri;
+            description
+              "The URL-based configuration is the config source.";
+          }
+          anyxml config {
+            description
+              "Inline Config content: <config> element.  Represents
+               an entire configuration datastore, not
+               a subset of the running datastore.";
+          }
+        }
+      }
+    }
+  }
+
+  rpc delete-config {
+    description
+      "Delete a configuration datastore.";
+
+    reference "RFC 6241, Section 7.4";
+
+    input {
+      container target {
+        description
+          "Particular configuration to delete.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target to delete.";
+
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config target.";
+          }
+          leaf url {
+            if-feature url;
+            type inet:uri;
+            description
+              "The URL-based configuration is the config target.";
+          }
+        }
+      }
+    }
+  }
+
+  rpc lock {
+    description
+      "The lock operation allows the client to lock the configuration
+       system of a device.";
+
+    reference "RFC 6241, Section 7.5";
+
+    input {
+      container target {
+        description
+          "Particular configuration to lock.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target to lock.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config target.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config target.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config target.";
+          }
+        }
+      }
+    }
+  }
+
+  rpc unlock {
+    description
+      "The unlock operation is used to release a configuration lock,
+       previously obtained with the 'lock' operation.";
+
+    reference "RFC 6241, Section 7.6";
+
+    input {
+      container target {
+        description
+          "Particular configuration to unlock.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target to unlock.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config target.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config target.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config target.";
+          }
+        }
+      }
+    }
+  }
+
+  rpc get {
+    description
+      "Retrieve running configuration and device state information.";
+
+    reference "RFC 6241, Section 7.7";
+
+    input {
+      anyxml filter {
+        description
+          "This parameter specifies the portion of the system
+           configuration and state data to retrieve.";
+        nc:get-filter-element-attributes;
+        // TODO this extension should be augmented (anyxml nodes cannot be augmented)
+        cliext:argument-handler org.opendaylight.controller.netconf.cli.reader.custom.FilterReader;
+      }
+    }
+
+    output {
+      anyxml data {
+        description
+          "Copy of the running datastore subset and/or state
+           data that matched the filter criteria (if any).
+           An empty data container indicates that the request did not
+           produce any results.";
+
+       cliext:argument-handler org.opendaylight.controller.netconf.cli.writer.custom.DataWriter;
+
+      }
+    }
+  }
+
+  rpc close-session {
+    description
+      "Request graceful termination of a NETCONF session.";
+
+    reference "RFC 6241, Section 7.8";
+  }
+
+  rpc kill-session {
+    description
+      "Force the termination of a NETCONF session.";
+
+    reference "RFC 6241, Section 7.9";
+
+    input {
+      leaf session-id {
+        type session-id-type;
+        mandatory true;
+        description
+          "Particular session to kill.";
+      }
+    }
+  }
+
+  rpc commit {
+    if-feature candidate;
+
+    description
+      "Commit the candidate configuration as the device's new
+       current configuration.";
+
+    reference "RFC 6241, Section 8.3.4.1";
+
+    input {
+      leaf confirmed {
+        if-feature confirmed-commit;
+        type empty;
+        description
+          "Requests a confirmed commit.";
+        reference "RFC 6241, Section 8.3.4.1";
+      }
+
+      leaf confirm-timeout {
+        if-feature confirmed-commit;
+        type uint32 {
+          range "1..max";
+        }
+        units "seconds";
+        default "600";   // 10 minutes
+        description
+          "The timeout interval for a confirmed commit.";
+        reference "RFC 6241, Section 8.3.4.1";
+      }
+
+      leaf persist {
+        if-feature confirmed-commit;
+        type string;
+        description
+          "This parameter is used to make a confirmed commit
+           persistent.  A persistent confirmed commit is not aborted
+           if the NETCONF session terminates.  The only way to abort
+           a persistent confirmed commit is to let the timer expire,
+           or to use the <cancel-commit> operation.
+
+           The value of this parameter is a token that must be given
+           in the 'persist-id' parameter of <commit> or
+           <cancel-commit> operations in order to confirm or cancel
+           the persistent confirmed commit.
+
+           The token should be a random string.";
+        reference "RFC 6241, Section 8.3.4.1";
+      }
+
+      leaf persist-id {
+        if-feature confirmed-commit;
+        type string;
+        description
+          "This parameter is given in order to commit a persistent
+           confirmed commit.  The value must be equal to the value
+           given in the 'persist' parameter to the <commit> operation.
+           If it does not match, the operation fails with an
+          'invalid-value' error.";
+        reference "RFC 6241, Section 8.3.4.1";
+      }
+
+    }
+  }
+
+  rpc discard-changes {
+    if-feature candidate;
+
+    description
+      "Revert the candidate configuration to the current
+       running configuration.";
+    reference "RFC 6241, Section 8.3.4.2";
+  }
+
+  rpc cancel-commit {
+    if-feature confirmed-commit;
+    description
+      "This operation is used to cancel an ongoing confirmed commit.
+       If the confirmed commit is persistent, the parameter
+       'persist-id' must be given, and it must match the value of the
+       'persist' parameter.";
+    reference "RFC 6241, Section 8.4.4.1";
+
+    input {
+      leaf persist-id {
+        type string;
+        description
+          "This parameter is given in order to cancel a persistent
+           confirmed commit.  The value must be equal to the value
+           given in the 'persist' parameter to the <commit> operation.
+           If it does not match, the operation fails with an
+          'invalid-value' error.";
+      }
+    }
+  }
+
+  rpc validate {
+    if-feature validate;
+
+    description
+      "Validates the contents of the specified configuration.";
+
+    reference "RFC 6241, Section 8.6.4.1";
+
+    input {
+      container source {
+        description
+          "Particular configuration to validate.";
+
+        choice config-source {
+          mandatory true;
+          description
+            "The configuration source to validate.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config source.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config source.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config source.";
+          }
+          leaf url {
+            if-feature url;
+            type inet:uri;
+            description
+              "The URL-based configuration is the config source.";
+          }
+          anyxml config {
+            description
+              "Inline Config content: <config> element.  Represents
+               an entire configuration datastore, not
+               a subset of the running datastore.";
+          }
+        }
+      }
+    }
+  }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ConsoleIOTestImpl.java b/opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ConsoleIOTestImpl.java
new file mode 100644 (file)
index 0000000..29d7abd
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli;
+
+import java.io.IOException;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.opendaylight.controller.netconf.cli.io.ConsoleIOImpl;
+
+public class ConsoleIOTestImpl extends ConsoleIOImpl {
+
+    Map<String, Deque<String>> inputValues = new HashMap<>();
+    String lastMessage;
+    private final List<ValueForMessage> valuesForMessages;
+
+    public ConsoleIOTestImpl(final Map<String, Deque<String>> inputValues, final List<ValueForMessage> valuesForMessages)
+            throws IOException {
+        super();
+        this.inputValues = inputValues;
+        this.valuesForMessages = valuesForMessages;
+    }
+
+    StringBuilder output = new StringBuilder();
+
+    @Override
+    public String read() throws IOException {
+        final String prompt = buildPrompt();
+        output.append(prompt);
+        System.out.print(prompt);
+
+        String value = inputValues.get(prompt).pollFirst();
+        if (value == null) {
+            value = getValueForLastMessage();
+        }
+
+        value = value != null ? value : "****NO VALUE****";
+
+        output.append(value + "\n");
+        System.out.print(value + "\n");
+        return value;
+    }
+
+    private String getValueForLastMessage() {
+        for (final ValueForMessage valueForMessage : valuesForMessages) {
+            if (containsLastMessageKeyWords(valueForMessage.getKeyWords())) {
+                return valueForMessage.getValue();
+            }
+        }
+        return null;
+    }
+
+    private boolean containsLastMessageKeyWords(final List<String> keyWords) {
+        for (final String keyWord : keyWords) {
+            if (!lastMessage.contains(keyWord)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void write(final CharSequence data) throws IOException {
+        output.append(data);
+        lastMessage = (String) data;
+        System.out.print(data);
+    }
+
+    @Override
+    public void writeLn(final CharSequence data) throws IOException {
+        write(data);
+        output.append("\n");
+        System.out.print("\n");
+    }
+
+    public String getConsoleOutput() {
+        return output.toString();
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/NetconfCliTest.java b/opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/NetconfCliTest.java
new file mode 100644 (file)
index 0000000..7d85aa4
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.opendaylight.controller.netconf.cli.io.IOUtil.PROMPT_SUFIX;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.opendaylight.controller.netconf.cli.reader.ReadingException;
+import org.opendaylight.controller.netconf.cli.reader.impl.GenericReader;
+import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
+import org.opendaylight.controller.netconf.cli.writer.WriteException;
+import org.opendaylight.controller.netconf.cli.writer.impl.NormalizedNodeWriter;
+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.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+@Ignore
+public class NetconfCliTest {
+
+    private final static YangContextParser parser = new YangParserImpl();
+
+    private static SchemaContext loadSchemaContext(final String resourceDirectory) throws IOException,
+            URISyntaxException {
+        final URI uri = NetconfCliTest.class.getResource(resourceDirectory).toURI();
+        final File testDir = new File(uri);
+        final String[] fileList = testDir.list();
+        final List<File> testFiles = new ArrayList<File>();
+        if (fileList == null) {
+            throw new FileNotFoundException(resourceDirectory);
+        }
+        for (final String fileName : fileList) {
+            if (new File(testDir, fileName).isDirectory() == false) {
+                testFiles.add(new File(testDir, fileName));
+            }
+        }
+        return parser.parseFiles(testFiles);
+    }
+
+    // @Ignore
+    @Test
+    public void cliTest() throws ReadingException, IOException, WriteException, URISyntaxException {
+
+        final SchemaContext schemaContext = loadSchemaContext("/schema-context");
+        assertNotNull(schemaContext);
+
+        final DataSchemaNode cont1 = findTopLevelElement("ns:model1", "2014-05-14", "cont1", schemaContext);
+        final Map<String, Deque<String>> values = new HashMap<>();
+
+        values.put(prompt("/cont1/cont11/lst111/[entry]/lf1111"), value("55", "32"));
+        values.put(prompt("/cont1/cont11/lst111/[entry]"), value("Y", "Y"));
+        values.put(prompt("/cont1/cont11/lst111/[entry]/cont111/lf1112"),
+                value("value for lf1112", "2value for lf1112"));
+        values.put(prompt("/cont1/cont11/lst111/[entry]/cont111/lflst1111"), value("Y", "N", "Y", "N"));
+        values.put(prompt("/cont1/cont11/lst111/[entry]/cont111/lflst1111/[entry]"), value("10", "15", "20", "30"));
+
+        values.put(prompt("/cont1/cont11/lst111"), value("Y", "N"));
+
+        values.put(prompt("/cont1/cont12/chcA"), value("AB"));
+        values.put(prompt("/cont1/cont12/chcA/cont12AB1/lf12AB1"), value("value for lf12AB1"));
+
+        values.put(prompt("/cont1/cont12/lst121/[entry]/lf1211"), value("value for lf12112", "2value for lf12112"));
+        values.put(prompt("/cont1/cont12/lst121/[entry]"), value("Y", "Y"));
+        values.put(prompt("/cont1/cont12/lst121/[entry]/lst1211"), value("Y", "N", "Y", "N"));
+        values.put(prompt("/cont1/cont12/lst121/[entry]/lst1211/[entry]"), value("Y", "Y", "Y", "Y"));
+        values.put(prompt("/cont1/cont12/lst121/[entry]/lst1211/[entry]/lf12111"), value("5", "10", "21", "50"));
+        values.put(prompt("/cont1/cont12/lst121/[entry]/lst1211/[entry]/lf12112"),
+                value("value for lf12112", "2value for lf12112", "3value for lf12112", "4value for lf12112"));
+
+        values.put(prompt("/cont1/cont12/lst121"), value("Y", "N"));
+
+        values.put(prompt("/cont1/cont12/lst122"), value("Y", "N"));
+
+        values.put(prompt("/cont1/lst11"), value("Y", "Y", "N"));
+        values.put(prompt("/cont1/lst11/[entry]"), value("Y", "Y", "Y"));
+        values.put(prompt("/cont1/lst11/[entry]/lf111"),
+                value("1value for lf111", "2value for lf111", "3value for lf111"));
+
+        values.put(prompt("/cont1/cont12/data"), value("<el1><el11>value</el11><el12>value1</el12></el1>"));
+
+        final List<ValueForMessage> valuesForMessages = new ArrayList<>();
+        valuesForMessages.add(new ValueForMessage("Y", "lst111", "[Y|N]"));
+        valuesForMessages.add(new ValueForMessage("Y", "lst121", "[Y|N]"));
+        valuesForMessages.add(new ValueForMessage("Y", "lst11", "[Y|N]"));
+
+        final ConsoleIOTestImpl console = new ConsoleIOTestImpl(values, valuesForMessages);
+
+        final List<Node<?>> redData = new GenericReader(console, new CommandArgHandlerRegistry(console,
+                new SchemaContextRegistry(schemaContext)), schemaContext).read(cont1);
+        assertNotNull(redData);
+       assertEquals(1, redData.size());
+
+        assertTrue(redData.get(0) instanceof CompositeNode);
+        final CompositeNode redTopLevelNode = (CompositeNode) redData.get(0);
+
+        System.out.println("============================");
+        new NormalizedNodeWriter(console, new OutFormatter()).write(cont1, redData);
+
+    }
+
+    private Deque<String> value(final String... values) {
+        return new ArrayDeque<>(Arrays.asList(values));
+    }
+
+    private String prompt(final String path) {
+        return "/localhost" + path + PROMPT_SUFIX;
+    }
+
+    private DataSchemaNode findTopLevelElement(final String namespace, final String revision,
+            final String topLevelElement, final SchemaContext schemaContext) {
+        final QName requiredElement = QName.create(namespace, revision, topLevelElement);
+        for (final DataSchemaNode dataSchemaNode : schemaContext.getChildNodes()) {
+            if (dataSchemaNode.getQName().equals(requiredElement)) {
+                return dataSchemaNode;
+            }
+        }
+        return null;
+
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ValueForMessages.java b/opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ValueForMessages.java
new file mode 100644 (file)
index 0000000..2532b36
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli;
+
+import java.util.Arrays;
+import java.util.List;
+
+class ValueForMessage {
+    List<String> messageKeyWords;
+    String value;
+
+    public ValueForMessage(final String value, final String... messageKeyWords) {
+        this.messageKeyWords = Arrays.asList(messageKeyWords);
+        this.value = value;
+    }
+
+    public List<String> getKeyWords() {
+        return messageKeyWords;
+    }
+
+    public String getValue() {
+        return value;
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/io/IOUtilTest.java b/opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/io/IOUtilTest.java
new file mode 100644 (file)
index 0000000..5a24452
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.cli.io;
+
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.opendaylight.controller.netconf.cli.commands.CommandConstants;
+import org.opendaylight.yangtools.yang.common.QName;
+
+import com.google.common.collect.Maps;
+
+public class IOUtilTest {
+
+    @Test
+    public void testQNameFromKeyStringNew() throws Exception {
+        final String s = IOUtil.qNameToKeyString(CommandConstants.HELP_QNAME, "module");
+        final Map<String, QName> modulesMap = Maps.newHashMap();
+        modulesMap.put("module", QName.create(CommandConstants.HELP_QNAME, "module"));
+        final QName qName = IOUtil.qNameFromKeyString(s, modulesMap);
+        Assert.assertEquals(CommandConstants.HELP_QNAME, qName);
+    }
+}
diff --git a/opendaylight/netconf/netconf-cli/src/test/resources/schema-context/ietf-inet-types.yang b/opendaylight/netconf/netconf-cli/src/test/resources/schema-context/ietf-inet-types.yang
new file mode 100644 (file)
index 0000000..de20feb
--- /dev/null
@@ -0,0 +1,418 @@
+ module ietf-inet-types {
+
+   namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+   prefix "inet";
+
+   organization
+    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+   contact
+    "WG Web:   <http://tools.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     WG Chair: David Partain
+               <mailto:david.partain@ericsson.com>
+
+     WG Chair: David Kessens
+               <mailto:david.kessens@nsn.com>
+
+     Editor:   Juergen Schoenwaelder
+               <mailto:j.schoenwaelder@jacobs-university.de>";
+
+   description
+    "This module contains a collection of generally useful derived
+     YANG data types for Internet addresses and related things.
+
+     Copyright (c) 2010 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or without
+     modification, is permitted pursuant to, and subject to the license
+     terms contained in, the Simplified BSD License set forth in Section
+     4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6021; see
+     the RFC itself for full legal notices.";
+
+   revision 2010-09-24 {
+     description
+      "Initial revision.";
+     reference
+      "RFC 6021: Common YANG Data Types";
+   }
+
+   /*** collection of protocol field related types ***/
+
+   typedef ip-version {
+     type enumeration {
+       enum unknown {
+         value "0";
+         description
+          "An unknown or unspecified version of the Internet protocol.";
+       }
+       enum ipv4 {
+         value "1";
+         description
+          "The IPv4 protocol as defined in RFC 791.";
+       }
+       enum ipv6 {
+         value "2";
+         description
+          "The IPv6 protocol as defined in RFC 2460.";
+       }
+     }
+     description
+      "This value represents the version of the IP protocol.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetVersion textual convention of the SMIv2.";
+     reference
+      "RFC  791: Internet Protocol
+       RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   typedef dscp {
+     type uint8 {
+       range "0..63";
+     }
+     description
+      "The dscp type represents a Differentiated Services Code-Point
+       that may be used for marking packets in a traffic stream.
+
+       In the value set and its semantics, this type is equivalent
+       to the Dscp textual convention of the SMIv2.";
+     reference
+      "RFC 3289: Management Information Base for the Differentiated
+                 Services Architecture
+       RFC 2474: Definition of the Differentiated Services Field
+                 (DS Field) in the IPv4 and IPv6 Headers
+       RFC 2780: IANA Allocation Guidelines For Values In
+                 the Internet Protocol and Related Headers";
+   }
+
+   typedef ipv6-flow-label {
+     type uint32 {
+       range "0..1048575";
+     }
+     description
+      "The flow-label type represents flow identifier or Flow Label
+       in an IPv6 packet header that may be used to discriminate
+       traffic flows.
+
+       In the value set and its semantics, this type is equivalent
+       to the IPv6FlowLabel textual convention of the SMIv2.";
+     reference
+      "RFC 3595: Textual Conventions for IPv6 Flow Label
+       RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+   }
+
+   typedef port-number {
+     type uint16 {
+       range "0..65535";
+     }
+     description
+      "The port-number type represents a 16-bit port number of an
+       Internet transport layer protocol such as UDP, TCP, DCCP, or
+       SCTP.  Port numbers are assigned by IANA.  A current list of
+       all assignments is available from <http://www.iana.org/>.
+
+       Note that the port number value zero is reserved by IANA.  In
+       situations where the value zero does not make sense, it can
+       be excluded by subtyping the port-number type.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetPortNumber textual convention of the SMIv2.";
+     reference
+      "RFC  768: User Datagram Protocol
+       RFC  793: Transmission Control Protocol
+       RFC 4960: Stream Control Transmission Protocol
+       RFC 4340: Datagram Congestion Control Protocol (DCCP)
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   /*** collection of autonomous system related types ***/
+
+   typedef as-number {
+     type uint32;
+     description
+      "The as-number type represents autonomous system numbers
+       which identify an Autonomous System (AS).  An AS is a set
+       of routers under a single technical administration, using
+       an interior gateway protocol and common metrics to route
+       packets within the AS, and using an exterior gateway
+       protocol to route packets to other ASs'.  IANA maintains
+       the AS number space and has delegated large parts to the
+       regional registries.
+
+       Autonomous system numbers were originally limited to 16
+       bits.  BGP extensions have enlarged the autonomous system
+       number space to 32 bits.  This type therefore uses an uint32
+       base type without a range restriction in order to support
+       a larger autonomous system number space.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetAutonomousSystemNumber textual convention of
+       the SMIv2.";
+     reference
+      "RFC 1930: Guidelines for creation, selection, and registration
+                 of an Autonomous System (AS)
+       RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+       RFC 4893: BGP Support for Four-octet AS Number Space
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   /*** collection of IP address and hostname related types ***/
+
+   typedef ip-address {
+     type union {
+       type inet:ipv4-address;
+       type inet:ipv6-address;
+     }
+     description
+      "The ip-address type represents an IP address and is IP
+       version neutral.  The format of the textual representations
+       implies the IP version.";
+   }
+
+   typedef ipv4-address {
+     type string {
+       pattern
+         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+       + '(%[\p{N}\p{L}]+)?';
+     }
+     description
+       "The ipv4-address type represents an IPv4 address in
+        dotted-quad notation.  The IPv4 address may include a zone
+        index, separated by a % sign.
+
+        The zone index is used to disambiguate identical address
+        values.  For link-local addresses, the zone index will
+        typically be the interface index number or the name of an
+        interface.  If the zone index is not present, the default
+        zone of the device will be used.
+
+        The canonical format for the zone index is the numerical
+        format";
+   }
+
+   typedef ipv6-address {
+     type string {
+       pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+             + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+             + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+             + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+             + '(%[\p{N}\p{L}]+)?';
+       pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+             + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+             + '(%.+)?';
+     }
+     description
+      "The ipv6-address type represents an IPv6 address in full,
+       mixed, shortened, and shortened-mixed notation.  The IPv6
+       address may include a zone index, separated by a % sign.
+
+       The zone index is used to disambiguate identical address
+       values.  For link-local addresses, the zone index will
+       typically be the interface index number or the name of an
+       interface.  If the zone index is not present, the default
+       zone of the device will be used.
+
+       The canonical format of IPv6 addresses uses the compressed
+       format described in RFC 4291, Section 2.2, item 2 with the
+       following additional rules: the :: substitution must be
+       applied to the longest sequence of all-zero 16-bit chunks
+       in an IPv6 address.  If there is a tie, the first sequence
+       of all-zero 16-bit chunks is replaced by ::.  Single
+       all-zero 16-bit chunks are not compressed.  The canonical
+       format uses lowercase characters and leading zeros are
+       not allowed.  The canonical format for the zone index is
+       the numerical format as described in RFC 4007, Section
+       11.2.";
+     reference
+      "RFC 4291: IP Version 6 Addressing Architecture
+       RFC 4007: IPv6 Scoped Address Architecture
+       RFC 5952: A Recommendation for IPv6 Address Text Representation";
+   }
+
+   typedef ip-prefix {
+     type union {
+       type inet:ipv4-prefix;
+       type inet:ipv6-prefix;
+     }
+     description
+      "The ip-prefix type represents an IP prefix and is IP
+       version neutral.  The format of the textual representations
+       implies the IP version.";
+   }
+
+   typedef ipv4-prefix {
+     type string {
+       pattern
+          '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+        +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+        + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+     }
+     description
+      "The ipv4-prefix type represents an IPv4 address prefix.
+       The prefix length is given by the number following the
+       slash character and must be less than or equal to 32.
+
+       A prefix length value of n corresponds to an IP address
+       mask that has n contiguous 1-bits from the most
+       significant bit (MSB) and all other bits set to 0.
+
+       The canonical format of an IPv4 prefix has all bits of
+       the IPv4 address set to zero that are not part of the
+       IPv4 prefix.";
+   }
+
+   typedef ipv6-prefix {
+     type string {
+       pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+             + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+             + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+             + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+             + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+       pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+             + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+             + '(/.+)';
+     }
+     description
+      "The ipv6-prefix type represents an IPv6 address prefix.
+       The prefix length is given by the number following the
+       slash character and must be less than or equal 128.
+
+       A prefix length value of n corresponds to an IP address
+       mask that has n contiguous 1-bits from the most
+       significant bit (MSB) and all other bits set to 0.
+
+       The IPv6 address should have all bits that do not belong
+       to the prefix set to zero.
+
+       The canonical format of an IPv6 prefix has all bits of
+       the IPv6 address set to zero that are not part of the
+       IPv6 prefix.  Furthermore, IPv6 address is represented
+       in the compressed format described in RFC 4291, Section
+       2.2, item 2 with the following additional rules: the ::
+       substitution must be applied to the longest sequence of
+       all-zero 16-bit chunks in an IPv6 address.  If there is
+       a tie, the first sequence of all-zero 16-bit chunks is
+       replaced by ::.  Single all-zero 16-bit chunks are not
+       compressed.  The canonical format uses lowercase
+       characters and leading zeros are not allowed.";
+     reference
+      "RFC 4291: IP Version 6 Addressing Architecture";
+   }
+
+   /*** collection of domain name and URI types ***/
+
+   typedef domain-name {
+     type string {
+       pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+            +  '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+            +  '|\.';
+       length "1..253";
+     }
+     description
+      "The domain-name type represents a DNS domain name.  The
+       name SHOULD be fully qualified whenever possible.
+
+       Internet domain names are only loosely specified.  Section
+       3.5 of RFC 1034 recommends a syntax (modified in Section
+       2.1 of RFC 1123).  The pattern above is intended to allow
+       for current practice in domain name use, and some possible
+       future expansion.  It is designed to hold various types of
+       domain names, including names used for A or AAAA records
+       (host names) and other records, such as SRV records.  Note
+       that Internet host names have a stricter syntax (described
+       in RFC 952) than the DNS recommendations in RFCs 1034 and
+       1123, and that systems that want to store host names in
+       schema nodes using the domain-name type are recommended to
+       adhere to this stricter standard to ensure interoperability.
+
+       The encoding of DNS names in the DNS protocol is limited
+       to 255 characters.  Since the encoding consists of labels
+       prefixed by a length bytes and there is a trailing NULL
+       byte, only 253 characters can appear in the textual dotted
+       notation.
+
+       The description clause of schema nodes using the domain-name
+       type MUST describe when and how these names are resolved to
+       IP addresses.  Note that the resolution of a domain-name value
+       may require to query multiple DNS records (e.g., A for IPv4
+       and AAAA for IPv6).  The order of the resolution process and
+       which DNS record takes precedence can either be defined
+       explicitely or it may depend on the configuration of the
+       resolver.
+
+       Domain-name values use the US-ASCII encoding.  Their canonical
+       format uses lowercase US-ASCII characters.  Internationalized
+       domain names MUST be encoded in punycode as described in RFC
+       3492";
+     reference
+      "RFC  952: DoD Internet Host Table Specification
+       RFC 1034: Domain Names - Concepts and Facilities
+       RFC 1123: Requirements for Internet Hosts -- Application
+                 and Support
+       RFC 2782: A DNS RR for specifying the location of services
+                 (DNS SRV)
+       RFC 3492: Punycode: A Bootstring encoding of Unicode for
+                 Internationalized Domain Names in Applications
+                 (IDNA)
+       RFC 5891: Internationalizing Domain Names in Applications
+                 (IDNA): Protocol";
+   }
+
+   typedef host {
+     type union {
+       type inet:ip-address;
+       type inet:domain-name;
+     }
+     description
+      "The host type represents either an IP address or a DNS
+       domain name.";
+   }
+
+   typedef uri {
+     type string;
+     description
+      "The uri type represents a Uniform Resource Identifier
+       (URI) as defined by STD 66.
+
+       Objects using the uri type MUST be in US-ASCII encoding,
+       and MUST be normalized as described by RFC 3986 Sections
+       6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary
+       percent-encoding is removed, and all case-insensitive
+       characters are set to lowercase except for hexadecimal
+       digits, which are normalized to uppercase as described in
+       Section 6.2.2.1.
+
+       The purpose of this normalization is to help provide
+       unique URIs.  Note that this normalization is not
+       sufficient to provide uniqueness.  Two URIs that are
+       textually distinct after this normalization may still be
+       equivalent.
+
+       Objects using the uri type may restrict the schemes that
+       they permit.  For example, 'data:' and 'urn:' schemes
+       might not be appropriate.
+
+       A zero-length URI is not a valid URI.  This can be used to
+       express 'URI absent' where required.
+
+       In the value set and its semantics, this type is equivalent
+       to the Uri SMIv2 textual convention defined in RFC 5017.";
+     reference
+      "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+       RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+                 Group: Uniform Resource Identifiers (URIs), URLs,
+                 and Uniform Resource Names (URNs): Clarifications
+                 and Recommendations
+       RFC 5017: MIB Textual Conventions for Uniform Resource
+                 Identifiers (URIs)";
+   }
+
+ }
diff --git a/opendaylight/netconf/netconf-cli/src/test/resources/schema-context/ietf-netconf.yang b/opendaylight/netconf/netconf-cli/src/test/resources/schema-context/ietf-netconf.yang
new file mode 100644 (file)
index 0000000..44c19c3
--- /dev/null
@@ -0,0 +1,927 @@
+module ietf-netconf {
+
+  // the namespace for NETCONF XML definitions is unchanged
+  // from RFC 4741, which this document replaces
+  namespace "urn:ietf:params:xml:ns:netconf:base:1.0";
+
+  prefix nc;
+
+  import ietf-inet-types {
+    prefix inet;
+  }
+
+  organization
+    "IETF NETCONF (Network Configuration) Working Group";
+
+  contact
+    "WG Web:   <http://tools.ietf.org/wg/netconf/>
+     WG List:  <netconf@ietf.org>
+
+     WG Chair: Bert Wijnen
+               <bertietf@bwijnen.net>
+
+     WG Chair: Mehmet Ersue
+               <mehmet.ersue@nsn.com>
+
+     Editor:   Martin Bjorklund
+               <mbj@tail-f.com>
+
+     Editor:   Juergen Schoenwaelder
+               <j.schoenwaelder@jacobs-university.de>
+
+     Editor:   Andy Bierman
+               <andy.bierman@brocade.com>";
+  description
+    "NETCONF Protocol Data Types and Protocol Operations.
+
+     Copyright (c) 2011 IETF Trust and the persons identified as
+     the document authors.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6241; see
+     the RFC itself for full legal notices.";
+  revision 2011-06-01 {
+    description
+      "Initial revision";
+    reference
+      "RFC 6241: Network Configuration Protocol";
+  }
+
+  extension get-filter-element-attributes {
+    description
+      "If this extension is present within an 'anyxml'
+       statement named 'filter', which must be conceptually
+       defined within the RPC input section for the <get>
+       and <get-config> protocol operations, then the
+       following unqualified XML attribute is supported
+       within the <filter> element, within a <get> or
+       <get-config> protocol operation:
+
+         type : optional attribute with allowed
+                value strings 'subtree' and 'xpath'.
+                If missing, the default value is 'subtree'.
+
+       If the 'xpath' feature is supported, then the
+       following unqualified XML attribute is
+       also supported:
+
+         select: optional attribute containing a
+                 string representing an XPath expression.
+                 The 'type' attribute must be equal to 'xpath'
+                 if this attribute is present.";
+  }
+
+  // NETCONF capabilities defined as features
+  feature writable-running {
+    description
+      "NETCONF :writable-running capability;
+       If the server advertises the :writable-running
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.2";
+  }
+
+  feature candidate {
+    description
+      "NETCONF :candidate capability;
+       If the server advertises the :candidate
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.3";
+  }
+
+  feature confirmed-commit {
+    if-feature candidate;
+    description
+      "NETCONF :confirmed-commit:1.1 capability;
+       If the server advertises the :confirmed-commit:1.1
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+
+    reference "RFC 6241, Section 8.4";
+  }
+
+  feature rollback-on-error {
+    description
+      "NETCONF :rollback-on-error capability;
+       If the server advertises the :rollback-on-error
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.5";
+  }
+
+  feature validate {
+    description
+      "NETCONF :validate:1.1 capability;
+       If the server advertises the :validate:1.1
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.6";
+  }
+
+  feature startup {
+    description
+      "NETCONF :startup capability;
+       If the server advertises the :startup
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.7";
+  }
+
+  feature url {
+    description
+      "NETCONF :url capability;
+       If the server advertises the :url
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.8";
+  }
+
+  feature xpath {
+    description
+      "NETCONF :xpath capability;
+       If the server advertises the :xpath
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.9";
+  }
+
+  // NETCONF Simple Types
+
+  typedef session-id-type {
+    type uint32 {
+      range "1..max";
+    }
+    description
+      "NETCONF Session Id";
+  }
+
+  typedef session-id-or-zero-type {
+    type uint32;
+    description
+      "NETCONF Session Id or Zero to indicate none";
+  }
+  typedef error-tag-type {
+    type enumeration {
+       enum in-use {
+         description
+           "The request requires a resource that
+            already is in use.";
+       }
+       enum invalid-value {
+         description
+           "The request specifies an unacceptable value for one
+            or more parameters.";
+       }
+       enum too-big {
+         description
+           "The request or response (that would be generated) is
+            too large for the implementation to handle.";
+       }
+       enum missing-attribute {
+         description
+           "An expected attribute is missing.";
+       }
+       enum bad-attribute {
+         description
+           "An attribute value is not correct; e.g., wrong type,
+            out of range, pattern mismatch.";
+       }
+       enum unknown-attribute {
+         description
+           "An unexpected attribute is present.";
+       }
+       enum missing-element {
+         description
+           "An expected element is missing.";
+       }
+       enum bad-element {
+         description
+           "An element value is not correct; e.g., wrong type,
+            out of range, pattern mismatch.";
+       }
+       enum unknown-element {
+         description
+           "An unexpected element is present.";
+       }
+       enum unknown-namespace {
+         description
+           "An unexpected namespace is present.";
+       }
+       enum access-denied {
+         description
+           "Access to the requested protocol operation or
+            data model is denied because authorization failed.";
+       }
+       enum lock-denied {
+         description
+           "Access to the requested lock is denied because the
+            lock is currently held by another entity.";
+       }
+       enum resource-denied {
+         description
+           "Request could not be completed because of
+            insufficient resources.";
+       }
+       enum rollback-failed {
+         description
+           "Request to roll back some configuration change (via
+            rollback-on-error or <discard-changes> operations)
+            was not completed for some reason.";
+
+       }
+       enum data-exists {
+         description
+           "Request could not be completed because the relevant
+            data model content already exists.  For example,
+            a 'create' operation was attempted on data that
+            already exists.";
+       }
+       enum data-missing {
+         description
+           "Request could not be completed because the relevant
+            data model content does not exist.  For example,
+            a 'delete' operation was attempted on
+            data that does not exist.";
+       }
+       enum operation-not-supported {
+         description
+           "Request could not be completed because the requested
+            operation is not supported by this implementation.";
+       }
+       enum operation-failed {
+         description
+           "Request could not be completed because the requested
+            operation failed for some reason not covered by
+            any other error condition.";
+       }
+       enum partial-operation {
+         description
+           "This error-tag is obsolete, and SHOULD NOT be sent
+            by servers conforming to this document.";
+       }
+       enum malformed-message {
+         description
+           "A message could not be handled because it failed to
+            be parsed correctly.  For example, the message is not
+            well-formed XML or it uses an invalid character set.";
+       }
+     }
+     description "NETCONF Error Tag";
+     reference "RFC 6241, Appendix A";
+  }
+
+  typedef error-severity-type {
+    type enumeration {
+      enum error {
+        description "Error severity";
+      }
+      enum warning {
+        description "Warning severity";
+      }
+    }
+    description "NETCONF Error Severity";
+    reference "RFC 6241, Section 4.3";
+  }
+
+  typedef edit-operation-type {
+    type enumeration {
+      enum merge {
+        description
+          "The configuration data identified by the
+           element containing this attribute is merged
+           with the configuration at the corresponding
+           level in the configuration datastore identified
+           by the target parameter.";
+      }
+      enum replace {
+        description
+          "The configuration data identified by the element
+           containing this attribute replaces any related
+           configuration in the configuration datastore
+           identified by the target parameter.  If no such
+           configuration data exists in the configuration
+           datastore, it is created.  Unlike a
+           <copy-config> operation, which replaces the
+           entire target configuration, only the configuration
+           actually present in the config parameter is affected.";
+      }
+      enum create {
+        description
+          "The configuration data identified by the element
+           containing this attribute is added to the
+           configuration if and only if the configuration
+           data does not already exist in the configuration
+           datastore.  If the configuration data exists, an
+           <rpc-error> element is returned with an
+           <error-tag> value of 'data-exists'.";
+      }
+      enum delete {
+        description
+          "The configuration data identified by the element
+           containing this attribute is deleted from the
+           configuration if and only if the configuration
+           data currently exists in the configuration
+           datastore.  If the configuration data does not
+           exist, an <rpc-error> element is returned with
+           an <error-tag> value of 'data-missing'.";
+      }
+      enum remove {
+        description
+          "The configuration data identified by the element
+           containing this attribute is deleted from the
+           configuration if the configuration
+           data currently exists in the configuration
+           datastore.  If the configuration data does not
+           exist, the 'remove' operation is silently ignored
+           by the server.";
+      }
+    }
+    default "merge";
+    description "NETCONF 'operation' attribute values";
+    reference "RFC 6241, Section 7.2";
+  }
+
+  // NETCONF Standard Protocol Operations
+
+  rpc get-config {
+    description
+      "Retrieve all or part of a specified configuration.";
+
+    reference "RFC 6241, Section 7.1";
+
+    input {
+      container source {
+        description
+          "Particular configuration to retrieve.";
+
+        choice config-source {
+          mandatory true;
+          description
+            "The configuration to retrieve.";
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config source.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config source.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config source.
+               This is optional-to-implement on the server because
+               not all servers will support filtering for this
+               datastore.";
+          }
+        }
+      }
+
+      anyxml filter {
+        description
+          "Subtree or XPath filter to use.";
+        nc:get-filter-element-attributes;
+      }
+    }
+
+    output {
+      anyxml data {
+        description
+          "Copy of the source datastore subset that matched
+           the filter criteria (if any).  An empty data container
+           indicates that the request did not produce any results.";
+      }
+    }
+  }
+
+  rpc edit-config {
+    description
+      "The <edit-config> operation loads all or part of a specified
+       configuration to the specified target configuration.";
+
+    reference "RFC 6241, Section 7.2";
+
+    input {
+      container target {
+        description
+          "Particular configuration to edit.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config target.";
+          }
+          leaf running {
+            if-feature writable-running;
+            type empty;
+            description
+              "The running configuration is the config source.";
+          }
+        }
+      }
+
+      leaf default-operation {
+        type enumeration {
+          enum merge {
+            description
+              "The default operation is merge.";
+          }
+          enum replace {
+            description
+              "The default operation is replace.";
+          }
+          enum none {
+            description
+              "There is no default operation.";
+          }
+        }
+        default "merge";
+        description
+          "The default operation to use.";
+      }
+
+      leaf test-option {
+        if-feature validate;
+        type enumeration {
+          enum test-then-set {
+            description
+              "The server will test and then set if no errors.";
+          }
+          enum set {
+            description
+              "The server will set without a test first.";
+          }
+
+          enum test-only {
+            description
+              "The server will only test and not set, even
+               if there are no errors.";
+          }
+        }
+        default "test-then-set";
+        description
+          "The test option to use.";
+      }
+
+      leaf error-option {
+        type enumeration {
+          enum stop-on-error {
+            description
+              "The server will stop on errors.";
+          }
+          enum continue-on-error {
+            description
+              "The server may continue on errors.";
+          }
+          enum rollback-on-error {
+            description
+              "The server will roll back on errors.
+               This value can only be used if the 'rollback-on-error'
+               feature is supported.";
+          }
+        }
+        default "stop-on-error";
+        description
+          "The error option to use.";
+      }
+
+      choice edit-content {
+        mandatory true;
+        description
+          "The content for the edit operation.";
+
+        anyxml config {
+          description
+            "Inline Config content.";
+        }
+        leaf url {
+          if-feature url;
+          type inet:uri;
+          description
+            "URL-based config content.";
+        }
+      }
+    }
+  }
+
+  rpc copy-config {
+    description
+      "Create or replace an entire configuration datastore with the
+       contents of another complete configuration datastore.";
+
+    reference "RFC 6241, Section 7.3";
+
+    input {
+      container target {
+        description
+          "Particular configuration to copy to.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target of the copy operation.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config target.";
+          }
+          leaf running {
+            if-feature writable-running;
+            type empty;
+            description
+              "The running configuration is the config target.
+               This is optional-to-implement on the server.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config target.";
+          }
+          leaf url {
+            if-feature url;
+            type inet:uri;
+            description
+              "The URL-based configuration is the config target.";
+          }
+        }
+      }
+
+      container source {
+        description
+          "Particular configuration to copy from.";
+
+        choice config-source {
+          mandatory true;
+          description
+            "The configuration source for the copy operation.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config source.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config source.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config source.";
+          }
+          leaf url {
+            if-feature url;
+            type inet:uri;
+            description
+              "The URL-based configuration is the config source.";
+          }
+          anyxml config {
+            description
+              "Inline Config content: <config> element.  Represents
+               an entire configuration datastore, not
+               a subset of the running datastore.";
+          }
+        }
+      }
+    }
+  }
+
+  rpc delete-config {
+    description
+      "Delete a configuration datastore.";
+
+    reference "RFC 6241, Section 7.4";
+
+    input {
+      container target {
+        description
+          "Particular configuration to delete.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target to delete.";
+
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config target.";
+          }
+          leaf url {
+            if-feature url;
+            type inet:uri;
+            description
+              "The URL-based configuration is the config target.";
+          }
+        }
+      }
+    }
+  }
+
+  rpc lock {
+    description
+      "The lock operation allows the client to lock the configuration
+       system of a device.";
+
+    reference "RFC 6241, Section 7.5";
+
+    input {
+      container target {
+        description
+          "Particular configuration to lock.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target to lock.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config target.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config target.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config target.";
+          }
+        }
+      }
+    }
+  }
+
+  rpc unlock {
+    description
+      "The unlock operation is used to release a configuration lock,
+       previously obtained with the 'lock' operation.";
+
+    reference "RFC 6241, Section 7.6";
+
+    input {
+      container target {
+        description
+          "Particular configuration to unlock.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target to unlock.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config target.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config target.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config target.";
+          }
+        }
+      }
+    }
+  }
+
+  rpc get {
+    description
+      "Retrieve running configuration and device state information.";
+
+    reference "RFC 6241, Section 7.7";
+
+    input {
+      anyxml filter {
+        description
+          "This parameter specifies the portion of the system
+           configuration and state data to retrieve.";
+        nc:get-filter-element-attributes;
+      }
+    }
+
+    output {
+      anyxml data {
+        description
+          "Copy of the running datastore subset and/or state
+           data that matched the filter criteria (if any).
+           An empty data container indicates that the request did not
+           produce any results.";
+      }
+    }
+  }
+
+  rpc close-session {
+    description
+      "Request graceful termination of a NETCONF session.";
+
+    reference "RFC 6241, Section 7.8";
+  }
+
+  rpc kill-session {
+    description
+      "Force the termination of a NETCONF session.";
+
+    reference "RFC 6241, Section 7.9";
+
+    input {
+      leaf session-id {
+        type session-id-type;
+        mandatory true;
+        description
+          "Particular session to kill.";
+      }
+    }
+  }
+
+  rpc commit {
+    if-feature candidate;
+
+    description
+      "Commit the candidate configuration as the device's new
+       current configuration.";
+
+    reference "RFC 6241, Section 8.3.4.1";
+
+    input {
+      leaf confirmed {
+        if-feature confirmed-commit;
+        type empty;
+        description
+          "Requests a confirmed commit.";
+        reference "RFC 6241, Section 8.3.4.1";
+      }
+
+      leaf confirm-timeout {
+        if-feature confirmed-commit;
+        type uint32 {
+          range "1..max";
+        }
+        units "seconds";
+        default "600";   // 10 minutes
+        description
+          "The timeout interval for a confirmed commit.";
+        reference "RFC 6241, Section 8.3.4.1";
+      }
+
+      leaf persist {
+        if-feature confirmed-commit;
+        type string;
+        description
+          "This parameter is used to make a confirmed commit
+           persistent.  A persistent confirmed commit is not aborted
+           if the NETCONF session terminates.  The only way to abort
+           a persistent confirmed commit is to let the timer expire,
+           or to use the <cancel-commit> operation.
+
+           The value of this parameter is a token that must be given
+           in the 'persist-id' parameter of <commit> or
+           <cancel-commit> operations in order to confirm or cancel
+           the persistent confirmed commit.
+
+           The token should be a random string.";
+        reference "RFC 6241, Section 8.3.4.1";
+      }
+
+      leaf persist-id {
+        if-feature confirmed-commit;
+        type string;
+        description
+          "This parameter is given in order to commit a persistent
+           confirmed commit.  The value must be equal to the value
+           given in the 'persist' parameter to the <commit> operation.
+           If it does not match, the operation fails with an
+          'invalid-value' error.";
+        reference "RFC 6241, Section 8.3.4.1";
+      }
+
+    }
+  }
+
+  rpc discard-changes {
+    if-feature candidate;
+
+    description
+      "Revert the candidate configuration to the current
+       running configuration.";
+    reference "RFC 6241, Section 8.3.4.2";
+  }
+
+  rpc cancel-commit {
+    if-feature confirmed-commit;
+    description
+      "This operation is used to cancel an ongoing confirmed commit.
+       If the confirmed commit is persistent, the parameter
+       'persist-id' must be given, and it must match the value of the
+       'persist' parameter.";
+    reference "RFC 6241, Section 8.4.4.1";
+
+    input {
+      leaf persist-id {
+        type string;
+        description
+          "This parameter is given in order to cancel a persistent
+           confirmed commit.  The value must be equal to the value
+           given in the 'persist' parameter to the <commit> operation.
+           If it does not match, the operation fails with an
+          'invalid-value' error.";
+      }
+    }
+  }
+
+  rpc validate {
+    if-feature validate;
+
+    description
+      "Validates the contents of the specified configuration.";
+
+    reference "RFC 6241, Section 8.6.4.1";
+
+    input {
+      container source {
+        description
+          "Particular configuration to validate.";
+
+        choice config-source {
+          mandatory true;
+          description
+            "The configuration source to validate.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config source.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config source.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config source.";
+          }
+          leaf url {
+            if-feature url;
+            type inet:uri;
+            description
+              "The URL-based configuration is the config source.";
+          }
+          anyxml config {
+            description
+              "Inline Config content: <config> element.  Represents
+               an entire configuration datastore, not
+               a subset of the running datastore.";
+          }
+        }
+      }
+    }
+  }
+
+}
diff --git a/opendaylight/netconf/netconf-cli/src/test/resources/schema-context/model1.yang b/opendaylight/netconf/netconf-cli/src/test/resources/schema-context/model1.yang
new file mode 100644 (file)
index 0000000..c84d55f
--- /dev/null
@@ -0,0 +1,74 @@
+module model1 {
+  namespace "ns:model1";
+  prefix "mod1";
+
+  revision "2014-05-14" {
+  }
+
+  container cont1 {
+    container cont11 {
+        list lst111 {
+            key lf1111;
+            leaf lf1111 {
+                type int32;
+            }
+            container cont111 {
+                leaf lf1112 {
+                    type string;
+                }
+                leaf-list lflst1111 {
+                    type int8;
+                }
+            }
+        }
+    }
+
+    container cont12 {
+        list lst121 {
+            key lf1211;
+            leaf lf1211 {
+                type string;
+            }
+            list lst1211 {
+                leaf lf12111 {
+                    type uint8;
+                }
+                leaf lf12112 {
+                    type string;
+                }
+            }
+        }
+        choice chcA {
+            case AA {
+                leaf lf12AA1 {
+                    type string;
+                }
+            }
+            case AB {
+                container cont12AB1 {
+                    leaf lf12AB1 {
+                        type string;
+                    }
+                }
+            }
+            leaf lf121 { //should be standalone case
+                type string;
+            }
+        }
+        list lst122 {
+        }
+    }
+  }
+
+  container cont2 {
+    container cont23 {
+    }
+  }
+
+  container contA {
+  }
+
+  container contB {
+  }
+
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-cli/src/test/resources/schema-context/model2.yang b/opendaylight/netconf/netconf-cli/src/test/resources/schema-context/model2.yang
new file mode 100644 (file)
index 0000000..e92cbd7
--- /dev/null
@@ -0,0 +1,32 @@
+module model2 {
+  namespace "ns:model2";
+  prefix "mod2";
+
+  import model1 {prefix model1; revision-date 2014-05-14;}
+
+  revision "2014-05-14" {
+  }
+
+  container contA {
+  }
+
+  container contB {
+  }
+
+  augment "/model1:cont2" {
+    container cont21 {
+    }
+
+    container cont22 {
+    }
+  }
+
+  augment "/model1:cont1" {
+    list lst11 {
+       leaf lf111 {
+        type string;
+       }
+    }
+  }
+
+}
\ No newline at end of file
index 829ac304bd667f680d813e32ff58ed9f9b0b6f37..87b3f837e8c43a25f74f78cfbdd0b425bd8d94e9 100644 (file)
@@ -11,9 +11,8 @@ import io.netty.channel.Channel;
 import io.netty.util.concurrent.Promise;
 import java.io.IOException;
 import org.opendaylight.controller.netconf.nettyutil.AbstractChannelInitializer;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.SshHandler;
 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.Invoker;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.SshHandler;
 import org.opendaylight.protocol.framework.SessionListenerFactory;
 
 final class SshClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
@@ -33,8 +32,7 @@ final class SshClientChannelInitializer extends AbstractChannelInitializer<Netco
     @Override
     public void initialize(final Channel ch, final Promise<NetconfClientSession> promise) {
         try {
-            final Invoker invoker = Invoker.subsystem("netconf");
-            ch.pipeline().addFirst(new SshHandler(authenticationHandler, invoker));
+            ch.pipeline().addFirst(SshHandler.createForNetconfSubsystem(authenticationHandler));
             super.initialize(ch,promise);
         } catch (final IOException e) {
             throw new RuntimeException(e);
index afa17532d55ce6628b1659db90e666acf1e97250..18ed18e4ae2d4e89e658995193e8102b8c17b49c 100644 (file)
@@ -56,7 +56,7 @@ public class TestingNetconfClient implements Closeable {
         this.label = clientLabel;
         sessionListener = config.getSessionListener();
         Future<NetconfClientSession> clientFuture = netconfClientDispatcher.createClient(config);
-        clientSession = get(clientFuture);
+        clientSession = get(clientFuture);//TODO: make static
         this.sessionId = clientSession.getSessionId();
     }
 
index f7091beba5fcb09f26cb1248dbdfdd52d600db77..eb99be0dc08f006ece7f7a93193f103bfa2bfb61 100644 (file)
@@ -18,17 +18,18 @@ import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertCo
 import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertElementsCount;
 import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToDocument;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import io.netty.channel.ChannelFuture;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.InetSocketAddress;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
-
 import javax.management.InstanceNotFoundException;
 import javax.management.Notification;
 import javax.management.NotificationListener;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -37,7 +38,6 @@ import org.mockito.stubbing.Answer;
 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.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
@@ -63,10 +63,6 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.xml.sax.SAXException;
 
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import io.netty.channel.ChannelFuture;
-
 public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
 
     private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023);
@@ -76,8 +72,7 @@ public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
 
     @Before
     public void setUp() throws Exception {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,NetconfITTest.getModuleFactoriesS().toArray(
-                new ModuleFactory[0])));
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,NetconfITTest.FACTORIES));
 
         NetconfMonitoringServiceImpl monitoringService = new NetconfMonitoringServiceImpl(getNetconfOperationProvider());
 
index 0969bd92a59a7cb6132a2b3b6cb5ad713af5077e..2f7bd20d615b074a945bf49e2c60c9559c3df7e7 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.netconf.it;
 
+import static java.util.Arrays.asList;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doAnswer;
@@ -99,7 +100,7 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
     }
 
     protected List<ModuleFactory> getModuleFactories() {
-        return NetconfITTest.getModuleFactoriesS();
+        return asList(NetconfITTest.FACTORIES);
     }
 
     @Test
index 60a5207daa2e74b54cbc5a1a2b1ec9dd423a3f2b..8e69e6a345ffef868c2ed4e5bc454c440dc989a4 100644 (file)
@@ -16,6 +16,7 @@ import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 
+import com.google.common.base.Function;
 import com.google.common.base.Throwables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
@@ -28,6 +29,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
@@ -39,11 +41,14 @@ import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.matchers.JUnitMatchers;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory;
 import org.opendaylight.controller.config.yang.test.impl.IdentityTestModuleFactory;
+import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleFactory;
+import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleMXBean;
 import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
 import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean;
 import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
@@ -81,23 +86,27 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
 
 
     private NetconfMessage getConfig, getConfigCandidate, editConfig, closeSession;
-    private DefaultCommitNotificationProducer commitNot;
+    private DefaultCommitNotificationProducer commitNotificationProducer;
     private NetconfServerDispatcher dispatch;
 
     private NetconfClientDispatcherImpl clientDispatcher;
 
+    static ModuleFactory[] FACTORIES = {new TestImplModuleFactory(), new DepTestImplModuleFactory(),
+            new NetconfTestImplModuleFactory(), new IdentityTestModuleFactory(),
+            new MultipleDependenciesModuleFactory()};
+
     @Before
     public void setUp() throws Exception {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,getModuleFactories().toArray(
-                new ModuleFactory[0])));
+        initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
+                FACTORIES
+        ));
 
         loadMessages();
 
         NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
         factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore()));
 
-
-        commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
+        commitNotificationProducer = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
 
         dispatch = createDispatcher(factoriesListener);
         ChannelFuture s = dispatch.createServer(tcpAddress);
@@ -107,7 +116,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
     }
 
     private NetconfServerDispatcher createDispatcher(NetconfOperationServiceFactoryListenerImpl factoriesListener) {
-        return super.createDispatcher(factoriesListener, getNetconfMonitoringListenerService(), commitNot);
+        return super.createDispatcher(factoriesListener, getNetconfMonitoringListenerService(), commitNotificationProducer);
     }
 
     static NetconfMonitoringServiceImpl getNetconfMonitoringListenerService() {
@@ -120,7 +129,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
 
     @After
     public void tearDown() throws Exception {
-        commitNot.close();
+        commitNotificationProducer.close();
         clientDispatcher.close();
     }
 
@@ -155,14 +164,6 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
         return yangDependencies;
     }
 
-    protected List<ModuleFactory> getModuleFactories() {
-        return getModuleFactoriesS();
-    }
-
-    static List<ModuleFactory> getModuleFactoriesS() {
-        return Lists.newArrayList(new TestImplModuleFactory(), new DepTestImplModuleFactory(),
-                new NetconfTestImplModuleFactory(), new IdentityTestModuleFactory());
-    }
 
     @Test
     public void testNetconfClientDemonstration() throws Exception {
@@ -392,4 +393,66 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
         doReturn(codec).when(ret).getIdentityCodec();
         return ret;
     }
+
+
+    @Test
+    public void testMultipleDependencies() throws Exception {
+        // push first xml, should add parent and d1,d2 dependencies
+        try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) {
+            Document rpcReply = netconfClient.sendMessage(
+                    XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_merge_multiple-deps1.xml"))
+                    .getDocument();
+            assertIsOK(rpcReply);
+            commit(netconfClient);
+        }
+        // verify that parent.getTestingDeps == d1,d2
+        MultipleDependenciesModuleMXBean parentProxy = configRegistryClient.newMXBeanProxy(
+                configRegistryClient.lookupConfigBean(MultipleDependenciesModuleFactory.NAME, "parent"),
+                MultipleDependenciesModuleMXBean.class);
+        {
+            List<ObjectName> testingDeps = parentProxy.getTestingDeps();
+            assertEquals(2, testingDeps.size());
+            Set<String> actualRefs = getServiceReferences(testingDeps);
+            assertEquals(Sets.newHashSet("ref_d1", "ref_d2"), actualRefs);
+        }
+
+        // push second xml, should add d3 to parent's dependencies
+        mergeD3(parentProxy);
+        // push second xml again, to test that d3 is not added again
+        mergeD3(parentProxy);
+    }
+
+    public void mergeD3(MultipleDependenciesModuleMXBean parentProxy) throws Exception {
+        try (TestingNetconfClient netconfClient = new TestingNetconfClient(
+                "test " + tcpAddress.toString(), clientDispatcher, getClientConfiguration(tcpAddress, 5000))) {
+
+            Document rpcReply = netconfClient.sendMessage(
+                    XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_merge_multiple-deps2.xml"))
+                    .getDocument();
+            assertIsOK(rpcReply);
+            commit(netconfClient);
+        }
+        {
+            List<ObjectName> testingDeps = parentProxy.getTestingDeps();
+            assertEquals(3, testingDeps.size());
+            Set<String> actualRefs = getServiceReferences(testingDeps);
+            assertEquals(Sets.newHashSet("ref_d1", "ref_d2", "ref_d3"), actualRefs);
+        }
+    }
+
+    public Set<String> getServiceReferences(List<ObjectName> testingDeps) {
+        return new HashSet<>(Lists.transform(testingDeps, new Function<ObjectName, String>() {
+            @Override
+            public String apply(ObjectName input) {
+                return ObjectNameUtil.getReferenceName(input);
+            }
+        }));
+    }
+
+    public void commit(TestingNetconfClient netconfClient) throws Exception {
+        Document rpcReply;
+        rpcReply = netconfClient.sendMessage(XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml"))
+                .getDocument();
+        assertIsOK(rpcReply);
+    }
 }
index 3b263f7e75cc826b55b893a76a1f5fbf4b051c34..05e32577fe771f1e8a47a30bdd3ecbceb43a189d 100644 (file)
@@ -13,6 +13,10 @@ import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText;
 
+import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
+import io.netty.channel.ChannelFuture;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
@@ -22,14 +26,11 @@ import java.net.Socket;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
-
 import junit.framework.Assert;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
-import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
@@ -53,11 +54,6 @@ 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 io.netty.channel.ChannelFuture;
-
 public class NetconfMonitoringITTest extends AbstractNetconfConfigTest {
 
     private static final Logger logger =  LoggerFactory.getLogger(NetconfITTest.class);
@@ -74,8 +70,7 @@ public class NetconfMonitoringITTest extends AbstractNetconfConfigTest {
 
     @Before
     public void setUp() throws Exception {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, NetconfITTest.getModuleFactoriesS().toArray(
-                new ModuleFactory[0])));
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, NetconfITTest.FACTORIES));
 
         monitoringService = new NetconfMonitoringServiceImpl(getNetconfOperationProvider());
 
index 07ca2f134dda4f5910bc4acf11dfd0ba650e4199..4d232a619a49affd154c46d9fd6aa92ec08592b6 100644 (file)
@@ -28,7 +28,7 @@ public final class SSLUtil {
     }
 
     public static SSLContext initializeSecureContext(final String pass, final InputStream ksKeysFile, final InputStream ksTrustFile,
-            final String algorithm) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException,
+                                                     final String algorithm) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException,
             UnrecoverableKeyException, KeyManagementException {
 
         Preconditions.checkNotNull(ksTrustFile, "ksTrustFile cannot be null");
similarity index 83%
rename from opendaylight/netconf/netconf-it/src/test/resources/logback.xml
rename to opendaylight/netconf/netconf-it/src/test/resources/logback-test.xml
index fa467a1080f1c605008f5da36cfab7e1d277a7f1..c5037d34ed4ac01fcea4b5dd264b8f715ad2cc9c 100644 (file)
@@ -6,7 +6,7 @@
         </encoder>
     </appender>
 
-  <logger name="org.opendaylight.controller.netconf" level="DEBUG"/>
+  <logger name="org.opendaylight.controller.netconf" level="TRACE"/>
 
   <root level="error">
     <appender-ref ref="STDOUT" />
index f0e1b3f51fd1abdb445bc33f221f1e90aff1a6dc..de3f732b25763fa19d6b481a64bfbcf4d8bcf87c 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.controller.netconf.nettyutil;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
@@ -60,6 +61,7 @@ extends AbstractSessionNegotiator<NetconfHelloMessage, S> {
     }
 
     private State state = State.IDLE;
+    private final Promise<S> promise;
     private final Timer timer;
     private final long connectionTimeoutMillis;
 
@@ -68,6 +70,7 @@ extends AbstractSessionNegotiator<NetconfHelloMessage, S> {
             L sessionListener, long connectionTimeoutMillis) {
         super(promise, channel);
         this.sessionPreferences = sessionPreferences;
+        this.promise = promise;
         this.timer = timer;
         this.sessionListener = sessionListener;
         this.connectionTimeoutMillis = connectionTimeoutMillis;
@@ -102,32 +105,52 @@ extends AbstractSessionNegotiator<NetconfHelloMessage, S> {
 
     private void start() {
         final NetconfMessage helloMessage = this.sessionPreferences.getHelloMessage();
-        logger.debug("Session negotiation started with hello message {}", XmlUtil.toString(helloMessage.getDocument()));
+        logger.debug("Session negotiation started with hello message {} on channel {}", XmlUtil.toString(helloMessage.getDocument()), channel);
 
         channel.pipeline().addLast(NAME_OF_EXCEPTION_HANDLER, new ExceptionHandlingInboundChannelHandler());
 
+        // FIXME, make sessionPreferences return HelloMessage, move NetconfHelloMessage to API
+        sendMessage((NetconfHelloMessage)helloMessage);
+
+        replaceHelloMessageOutboundHandler();
+        changeState(State.OPEN_WAIT);
+
         timeout = this.timer.newTimeout(new TimerTask() {
             @Override
             public void run(final Timeout timeout) {
                 synchronized (this) {
                     if (state != State.ESTABLISHED) {
+
                         logger.debug("Connection timeout after {}, session is in state {}", timeout, state);
-                        final IllegalStateException cause = new IllegalStateException(
-                                "Session was not established after " + timeout);
-                        negotiationFailed(cause);
-                        changeState(State.FAILED);
+
+                        // Do not fail negotiation if promise is done or canceled
+                        // It would result in setting result of the promise second time and that throws exception
+                        if (isPromiseFinished() == false) {
+                            negotiationFailed(new IllegalStateException("Session was not established after " + timeout));
+                            changeState(State.FAILED);
+
+                            channel.closeFuture().addListener(new GenericFutureListener<ChannelFuture>() {
+                                @Override
+                                public void operationComplete(ChannelFuture future) throws Exception {
+                                    if(future.isSuccess()) {
+                                        logger.debug("Channel {} closed: success", future.channel());
+                                    } else {
+                                        logger.warn("Channel {} closed: fail", future.channel());
+                                    }
+                                }
+                            });
+                        }
                     } else if(channel.isOpen()) {
                         channel.pipeline().remove(NAME_OF_EXCEPTION_HANDLER);
                     }
                 }
             }
-        }, connectionTimeoutMillis, TimeUnit.MILLISECONDS);
 
-        // FIXME, make sessionPreferences return HelloMessage, move NetconfHelloMessage to API
-        sendMessage((NetconfHelloMessage)helloMessage);
+            private boolean isPromiseFinished() {
+                return promise.isDone() || promise.isCancelled();
+            }
 
-        replaceHelloMessageOutboundHandler();
-        changeState(State.OPEN_WAIT);
+        }, connectionTimeoutMillis, TimeUnit.MILLISECONDS);
     }
 
     private void cancelTimeout() {
@@ -200,9 +223,9 @@ extends AbstractSessionNegotiator<NetconfHelloMessage, S> {
     protected abstract S getSession(L sessionListener, Channel channel, NetconfHelloMessage message) throws NetconfDocumentedException;
 
     private synchronized void changeState(final State newState) {
-        logger.debug("Changing state from : {} to : {}", state, newState);
-        Preconditions.checkState(isStateChangePermitted(state, newState), "Cannot change state from %s to %s", state,
-                newState);
+        logger.debug("Changing state from : {} to : {} for channel: {}", state, newState, channel);
+        Preconditions.checkState(isStateChangePermitted(state, newState), "Cannot change state from %s to %s for chanel %s", state,
+                newState, channel);
         this.state = newState;
     }
 
@@ -236,7 +259,7 @@ extends AbstractSessionNegotiator<NetconfHelloMessage, S> {
     private final class ExceptionHandlingInboundChannelHandler extends ChannelInboundHandlerAdapter {
         @Override
         public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
-            logger.warn("An exception occurred during negotiation on channel {}", channel.localAddress(), cause);
+            logger.warn("An exception occurred during negotiation with {}", channel.remoteAddress(), cause);
             cancelTimeout();
             negotiationFailed(cause);
             changeState(State.FAILED);
index f260bcbcefbf0fff5baa41bda46b8b6c4efc617a..a87a08ded72ea97db3396c24697b780be501911d 100644 (file)
@@ -9,56 +9,15 @@
 package org.opendaylight.controller.netconf.nettyutil.handler;
 
 import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.ByteToMessageDecoder;
-
-import java.util.List;
-
+import io.netty.buffer.Unpooled;
+import io.netty.handler.codec.DelimiterBasedFrameDecoder;
 import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Charsets;
+public class NetconfEOMAggregator extends DelimiterBasedFrameDecoder {
 
-public class NetconfEOMAggregator extends ByteToMessageDecoder {
-    private final static Logger logger = LoggerFactory.getLogger(NetconfEOMAggregator.class);
+    public static final ByteBuf DELIMITER = Unpooled.wrappedBuffer(NetconfMessageConstants.END_OF_MESSAGE);
 
-    @Override
-    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
-        int index = indexOfSequence(in, NetconfMessageConstants.END_OF_MESSAGE);
-        if (index == -1) {
-            logger.debug("Message is not complete, read again.");
-            if (logger.isTraceEnabled()) {
-                String str = in.toString(Charsets.UTF_8);
-                logger.trace("Message read so far: {}", str);
-            }
-            ctx.read();
-        } else {
-            ByteBuf msg = in.readBytes(index);
-            in.readBytes(NetconfMessageConstants.END_OF_MESSAGE.length);
-            in.discardReadBytes();
-            logger.debug("Message is complete.");
-            out.add(msg);
-        }
+    public NetconfEOMAggregator() {
+        super(Integer.MAX_VALUE, DELIMITER);
     }
-
-    private int indexOfSequence(ByteBuf in, byte[] sequence) {
-        int index = -1;
-        for (int i = 0; i < in.readableBytes() - sequence.length + 1; i++) {
-            if (in.getByte(i) == sequence[0]) {
-                index = i;
-                for (int j = 1; j < sequence.length; j++) {
-                    if (in.getByte(i + j) != sequence[j]) {
-                        index = -1;
-                        break;
-                    }
-                }
-                if (index != -1) {
-                    return index;
-                }
-            }
-        }
-        return index;
-    }
-
 }
index fae2000bb53c7b0873f90cc677464ef04be6666a..d810a870ff29f68b59b19788bf3064e0218cb148 100644 (file)
@@ -12,6 +12,7 @@ import io.netty.buffer.ByteBufOutputStream;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.MessageToByteEncoder;
 
+import java.io.BufferedWriter;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
@@ -61,7 +62,8 @@ public class NetconfMessageToXMLEncoder extends MessageToByteEncoder<NetconfMess
             transformer.setOutputProperty(OutputKeys.INDENT, "yes");
             transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
 
-            StreamResult result = new StreamResult(new OutputStreamWriter(os));
+            // Wrap OutputStreamWriter with BufferedWriter as suggested in javadoc for OutputStreamWriter
+            StreamResult result = new StreamResult(new BufferedWriter(new OutputStreamWriter(os)));
             DOMSource source = new DOMSource(msg.getDocument());
             transformer.transform(source, result);
         }
index 84353a4646d4500a4fa612d23ad71545e0f70bd4..993709258a3410b80a8a6fbdde47f0374ca15619 100644 (file)
@@ -7,14 +7,12 @@
  */
 package org.opendaylight.controller.netconf.nettyutil.handler.exi;
 
-import org.opendaylight.controller.netconf.api.NetconfMessage;
+import com.google.common.base.Preconditions;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.openexi.proc.common.AlignmentType;
 import org.openexi.proc.common.EXIOptions;
 import org.openexi.proc.common.EXIOptionsException;
 
-import com.google.common.base.Preconditions;
-
 public final class EXIParameters {
     private static final String EXI_PARAMETER_ALIGNMENT = "alignment";
     private static final String EXI_PARAMETER_BYTE_ALIGNED = "byte-aligned";
@@ -29,20 +27,12 @@ public final class EXIParameters {
     private static final String EXI_FIDELITY_PIS = "pis";
     private static final String EXI_FIDELITY_PREFIXES = "prefixes";
 
-    private static final String EXI_PARAMETER_SCHEMA = "schema";
-    private static final String EXI_PARAMETER_SCHEMA_NONE = "none";
-    private static final String EXI_PARAMETER_SCHEMA_BUILT_IN = "builtin";
-    private static final String EXI_PARAMETER_SCHEMA_BASE_1_1 = "base:1.1";
-
     private final EXIOptions options;
 
     private EXIParameters(final EXIOptions options) {
         this.options = Preconditions.checkNotNull(options);
     }
 
-    public static EXIParameters fromNetconfMessage(final NetconfMessage root) throws EXIOptionsException {
-        return fromXmlElement(XmlElement.fromDomDocument(root.getDocument()));
-    }
 
     public static EXIParameters fromXmlElement(final XmlElement root) throws EXIOptionsException {
         final EXIOptions options =  new EXIOptions();
@@ -77,30 +67,6 @@ public final class EXIParameters {
                 options.setPreserveNS(true);
             }
         }
-
-        if (root.getElementsByTagName(EXI_PARAMETER_SCHEMA).getLength() > 0) {
-/*
-                        GrammarFactory grammarFactory = GrammarFactory.newInstance();
-                        if (operationElement
-                                .getElementsByTagName(EXI_PARAMETER_SCHEMA_NONE)
-                                .getLength() > 0) {
-                            this.grammars = grammarFactory.createSchemaLessGrammars();
-                        }
-
-                        if (operationElement.getElementsByTagName(
-                                EXI_PARAMETER_SCHEMA_BUILT_IN).getLength() > 0) {
-                            this.grammars = grammarFactory.createXSDTypesOnlyGrammars();
-                        }
-
-                        if (operationElement.getElementsByTagName(
-                                EXI_PARAMETER_SCHEMA_BASE_1_1).getLength() > 0) {
-                            this.grammars = grammarFactory
-                                    .createGrammars(NETCONF_XSD_LOCATION);
-                        }
-*/
-
-        }
-
         return new EXIParameters(options);
     }
 
index 1b0a34d7e0fa7d0b6ab32c6c3600de52a5f1543f..72eb774b5303efb14769d7fe1da644ea34456d82 100644 (file)
@@ -48,7 +48,7 @@ public final class NetconfStartExiMessage extends NetconfMessage {
         Element startExiElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0,
                 START_EXI);
 
-        addAlignemnt(exiOptions, doc, startExiElement);
+        addAlignment(exiOptions, doc, startExiElement);
         addFidelity(exiOptions, doc, startExiElement);
 
         rpcElement.appendChild(startExiElement);
@@ -75,7 +75,7 @@ public final class NetconfStartExiMessage extends NetconfMessage {
         }
     }
 
-    private static void addAlignemnt(EXIOptions exiOptions, Document doc, Element startExiElement) {
+    private static void addAlignment(EXIOptions exiOptions, Document doc, Element startExiElement) {
         Element alignmentElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0,
                 ALIGNMENT_KEY);
         alignmentElement.setTextContent(exiOptions.getAlignmentType().toString());
index 67027d8014881f7b1286a2eb6229ae3258a32a8a..b67aa0f96dcd53a084965fc3766399a26f2a5869 100644 (file)
@@ -14,7 +14,7 @@ import java.io.IOException;
 
 /**
  * Class Providing username/password authentication option to
- * {@link org.opendaylight.controller.netconf.nettyutil.handler.ssh.SshHandler}
+ * {@link org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.SshHandler}
  */
 public class LoginPassword extends AuthenticationHandler {
     private final String username;
index d542e1952a5e847e09ad771828b1ab57df7b1989..eab2546d6e430d64a185a9ae2e44afd83375259b 100644 (file)
@@ -13,33 +13,38 @@ import java.io.IOException;
  * Abstract class providing mechanism of invoking various SSH level services.
  * Class is not allowed to be extended, as it provides its own implementations via instance initiators.
  */
-public abstract class Invoker {
+abstract class Invoker {
     private boolean invoked = false;
 
-    private Invoker(){}
+    private Invoker() {
+    }
 
     protected boolean isInvoked() {
-        // TODO invoked is always false
         return invoked;
     }
 
+    public void setInvoked() {
+        this.invoked = true;
+    }
+
     abstract void invoke(SshSession session) throws IOException;
 
-    /**
-     * Invoker implementation to invokes subsystem SSH service.
-     *
-     * @param subsystem
-     * @return
-     */
+    public static Invoker netconfSubsystem(){
+        return subsystem("netconf");
+    }
+
     public static Invoker subsystem(final String subsystem) {
         return new Invoker() {
             @Override
-            void invoke(SshSession session) throws IOException {
+            synchronized void invoke(SshSession session) throws IOException {
                 if (isInvoked()) {
                     throw new IllegalStateException("Already invoked.");
                 }
-
-                session.startSubSystem(subsystem);
+                try {
+                    session.startSubSystem(subsystem);
+                } finally {
+                    setInvoked();
+                }
             }
         };
     }
index 3520fe029d41cbf01218cb6c8df9dd4500522be3..271b781b99aa2ebd1154c8a4786180a574d0594b 100644 (file)
@@ -10,18 +10,16 @@ package org.opendaylight.controller.netconf.nettyutil.handler.ssh.client;
 
 import ch.ethz.ssh2.Connection;
 import ch.ethz.ssh2.Session;
-import ch.ethz.ssh2.channel.Channel;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.virtualsocket.VirtualSocket;
-
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.virtualsocket.VirtualSocket;
 
 /**
  * Wrapper class around GANYMED SSH java library.
  */
-public class SshClient {
+class SshClient {
     private final VirtualSocket socket;
     private final Map<Integer, SshSession> openSessions = new HashMap<>();
     private final AuthenticationHandler authenticationHandler;
@@ -51,15 +49,10 @@ public class SshClient {
         authenticationHandler.authenticate(connection);
     }
 
-    public void closeSession(SshSession session) {
-        if (session.getState() == Channel.STATE_OPEN || session.getState() == Channel.STATE_OPENING) {
-            session.close();
-        }
-    }
 
     public void close() {
         for (SshSession session : openSessions.values()){
-            closeSession(session);
+            session.close();
         }
 
         openSessions.clear();
@@ -68,4 +61,11 @@ public class SshClient {
             connection.close();
         }
     }
+
+    @Override
+    public String toString() {
+        return "SshClient{" +
+                "socket=" + socket +
+                '}';
+    }
 }
index ad8b25ff2156d8e937d65d054b41b1e3f34c159e..1a2eb3f1ab43d188179351341264c0e46bc52350 100644 (file)
@@ -8,8 +8,13 @@
 
 package org.opendaylight.controller.netconf.nettyutil.handler.ssh.client;
 
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelPromise;
 import java.io.IOException;
@@ -18,7 +23,6 @@ import java.io.OutputStream;
 import java.util.LinkedList;
 import java.util.Queue;
 import java.util.concurrent.atomic.AtomicBoolean;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.virtualsocket.VirtualSocketException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -27,7 +31,7 @@ import org.slf4j.LoggerFactory;
  * Worker thread class. Handles all downstream and upstream events in SSH Netty
  * pipeline.
  */
-public class SshClientAdapter implements Runnable {
+class SshClientAdapter implements Runnable {
     private static final Logger logger = LoggerFactory.getLogger(SshClientAdapter.class);
 
     private static final int BUFFER_SIZE = 1024;
@@ -51,6 +55,7 @@ public class SshClientAdapter implements Runnable {
         this.invoker = invoker;
     }
 
+    // TODO: refactor
     public void run() {
         try {
             SshSession session = sshClient.openSession();
@@ -80,12 +85,6 @@ public class SshClientAdapter implements Runnable {
                 byteBuf.writeBytes(tranBuff);
                 ctx.fireChannelRead(byteBuf);
             }
-
-        } catch (VirtualSocketException e) {
-            // Netty closed connection prematurely.
-            // Or maybe tried to open ganymed connection without having initialized session
-            // (ctx.channel().remoteAddress() is null)
-            // Just pass and move on.
         } catch (Exception e) {
             logger.error("Unexpected exception", e);
         } finally {
@@ -123,12 +122,23 @@ public class SshClientAdapter implements Runnable {
         }
     }
 
-    public void start(ChannelHandlerContext ctx) {
-        if (this.ctx != null) {
-            // context is already associated.
-            return;
+    public Thread start(ChannelHandlerContext ctx, ChannelFuture channelFuture) {
+        checkArgument(channelFuture.isSuccess());
+        checkNotNull(ctx.channel().remoteAddress());
+        synchronized (this) {
+            checkState(this.ctx == null);
+            this.ctx = ctx;
         }
-        this.ctx = ctx;
-        new Thread(this).start();
+        String threadName = toString();
+        Thread thread = new Thread(this, threadName);
+        thread.start();
+        return thread;
+    }
+
+    @Override
+    public String toString() {
+        return "SshClientAdapter{" +
+                "sshClient=" + sshClient +
+                '}';
     }
 }
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.controller.netconf.nettyutil.handler.ssh;
+package org.opendaylight.controller.netconf.nettyutil.handler.ssh.client;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelFuture;
@@ -14,26 +14,30 @@ import io.netty.channel.ChannelFutureListener;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelOutboundHandlerAdapter;
 import io.netty.channel.ChannelPromise;
-
 import java.io.IOException;
 import java.net.SocketAddress;
-
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.SshClient;
 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.Invoker;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.SshClientAdapter;
 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.virtualsocket.VirtualSocket;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Netty SSH handler class. Acts as interface between Netty and SSH library. All standard Netty message handling
  * stops at instance of this class. All downstream events are handed of to wrapped {@link org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.SshClientAdapter};
  */
 public class SshHandler extends ChannelOutboundHandlerAdapter {
+    private static final Logger logger = LoggerFactory.getLogger(SshHandler.class);
     private static final String SOCKET = "socket";
 
     private final VirtualSocket virtualSocket = new VirtualSocket();
     private final SshClientAdapter sshClientAdapter;
 
+
+    public static SshHandler createForNetconfSubsystem(AuthenticationHandler authenticationHandler) throws IOException {
+        return new SshHandler(authenticationHandler, Invoker.netconfSubsystem());
+    }
+
+
     public SshHandler(AuthenticationHandler authenticationHandler, Invoker invoker) throws IOException {
         SshClient sshClient = new SshClient(virtualSocket, authenticationHandler);
         this.sshClientAdapter = new SshClientAdapter(sshClient, invoker);
@@ -67,7 +71,11 @@ public class SshHandler extends ChannelOutboundHandlerAdapter {
 
         promise.addListener(new ChannelFutureListener() {
             public void operationComplete(ChannelFuture channelFuture) {
-                sshClientAdapter.start(ctx);
+                if (channelFuture.isSuccess()) {
+                    sshClientAdapter.start(ctx, channelFuture);
+                } else {
+                    logger.debug("Failed to connect to remote host");
+                }
             }}
         );
     }
index 8311554cdafde19ca8a2e994d22a0f2b2971b12c..44893b879431fe738e40e91ea26c88c7b9c6009d 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.controller.netconf.nettyutil.handler.ssh.client;
 import ch.ethz.ssh2.Session;
 import ch.ethz.ssh2.StreamGobbler;
 
+import ch.ethz.ssh2.channel.Channel;
 import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
@@ -19,33 +20,18 @@ import java.io.OutputStream;
 /**
  * Wrapper class for proprietary SSH sessions implementations
  */
-public class SshSession implements Closeable {
+class SshSession implements Closeable {
     private final Session session;
 
     public SshSession(Session session) {
         this.session = session;
     }
 
-    public void execCommand(String cmd) throws IOException {
-        session.execCommand(cmd);
-    }
-
-    public void execCommand(String cmd, String charsetName) throws IOException {
-        session.execCommand(cmd, charsetName);
-    }
-
-    public void startShell() throws IOException {
-        session.startShell();
-    }
 
     public void startSubSystem(String name) throws IOException {
         session.startSubSystem(name);
     }
 
-    public int getState() {
-        return session.getState();
-    }
-
     public InputStream getStdout() {
         return new StreamGobbler(session.getStdout());
     }
@@ -58,24 +44,10 @@ public class SshSession implements Closeable {
         return session.getStdin();
     }
 
-    public int waitUntilDataAvailable(long timeout) throws IOException {
-        return session.waitUntilDataAvailable(timeout);
-    }
-
-    public int waitForCondition(int conditionSet, long timeout) {
-        return session.waitForCondition(conditionSet, timeout);
-    }
-
-    public Integer getExitStatus() {
-        return session.getExitStatus();
-    }
-
-    public String getExitSignal() {
-        return session.getExitSignal();
-    }
-
     @Override
     public void close() {
-        session.close();
+        if (session.getState() == Channel.STATE_OPEN || session.getState() == Channel.STATE_OPENING) {
+            session.close();
+        }
     }
 }
index 6debeba97e3fbee1e6a1a96cdba65d90d038ecda..69cce8057ebf13deac5c9234cfcca1638ba8b95b 100644 (file)
@@ -25,32 +25,33 @@ import java.nio.channels.SocketChannel;
  * use OIO application in asynchronous environment and NIO EventLoop. Using VirtualSocket OIO applications
  * are able to use full potential of NIO environment.
  */
+//TODO: refactor - socket should be created when connection is established
 public class VirtualSocket extends Socket implements ChannelHandler {
     private static final String INPUT_STREAM = "inputStream";
     private static final String OUTPUT_STREAM = "outputStream";
 
-    private final ChannelInputStream chis = new ChannelInputStream();
-    private final ChannelOutputStream chos = new ChannelOutputStream();
+    private final ChannelInputStream chais = new ChannelInputStream();
+    private final ChannelOutputStream chaos = new ChannelOutputStream();
     private ChannelHandlerContext ctx;
 
 
     public InputStream getInputStream() {
-        return this.chis;
+        return this.chais;
     }
 
     public OutputStream getOutputStream() {
-        return this.chos;
+        return this.chaos;
     }
 
     public void handlerAdded(ChannelHandlerContext ctx) {
         this.ctx = ctx;
 
         if (ctx.channel().pipeline().get(OUTPUT_STREAM) == null) {
-            ctx.channel().pipeline().addFirst(OUTPUT_STREAM, chos);
+            ctx.channel().pipeline().addFirst(OUTPUT_STREAM, chaos);
         }
 
         if (ctx.channel().pipeline().get(INPUT_STREAM) == null) {
-            ctx.channel().pipeline().addFirst(INPUT_STREAM, chis);
+            ctx.channel().pipeline().addFirst(INPUT_STREAM, chais);
         }
     }
 
@@ -69,7 +70,6 @@ public class VirtualSocket extends Socket implements ChannelHandler {
         ctx.fireExceptionCaught(throwable);
     }
 
-    public VirtualSocket() {super();}
 
     @Override
     public void connect(SocketAddress endpoint) throws IOException {}
@@ -83,12 +83,7 @@ public class VirtualSocket extends Socket implements ChannelHandler {
     @Override
     public InetAddress getInetAddress() {
         InetSocketAddress isa = getInetSocketAddress();
-
-        if (isa == null) {
-            throw new VirtualSocketException();
-        }
-
-        return getInetSocketAddress().getAddress();
+        return isa.getAddress();
     }
 
     @Override
@@ -187,7 +182,7 @@ public class VirtualSocket extends Socket implements ChannelHandler {
 
     @Override
     public String toString() {
-        return "Virtual socket InetAdress["+getInetAddress()+"], Port["+getPort()+"]";
+        return "VirtualSocket{" + getInetAddress() + ":" + getPort() + "}";
     }
 
     @Override
diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/virtualsocket/VirtualSocketException.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/virtualsocket/VirtualSocketException.java
deleted file mode 100644 (file)
index 626ebe9..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler.ssh.virtualsocket;
-
-/**
- * Exception class which provides notification about exceptional situations at the virtual socket layer.
- */
-// FIXME: Switch to checked exception, create a runtime exception to workaround Socket API
-public class VirtualSocketException extends RuntimeException {
-    private static final long serialVersionUID = 1L;
-}
index 8a2387d2c1d450df3e0a9bc964c435e84688844a..febf3abf8e6fcbb6b035dfafffebb784e6392f44 100644 (file)
       <artifactId>mockito-configuration</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-netty-util</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-client</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>
index 08bf9836b22135a295f2e54d68fa6c73ffeadf57..670f50ddd09f9b3b80d855ce244f4a4cce47da14 100644 (file)
@@ -7,9 +7,11 @@
  */
 package org.opendaylight.controller.netconf.ssh;
 
+import com.google.common.annotations.VisibleForTesting;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.local.LocalAddress;
 import java.io.IOException;
+import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.util.concurrent.ExecutorService;
@@ -68,6 +70,11 @@ public final class NetconfSSHServer extends Thread implements AutoCloseable {
         logger.trace("SSH server socket closed.");
     }
 
+    @VisibleForTesting
+    public InetSocketAddress getLocalSocketAddress() {
+        return (InetSocketAddress) serverSocket.getLocalSocketAddress();
+    }
+
     @Override
     public void run() {
         while (up) {
index 8045d32a5038400c650da7ec23fce8e5527ec10e..6300c56e72d80a774891cea2409052946bfab867 100644 (file)
@@ -32,6 +32,7 @@ import io.netty.channel.EventLoopGroup;
 import io.netty.channel.local.LocalAddress;
 import io.netty.channel.local.LocalChannel;
 import io.netty.handler.stream.ChunkedStream;
+import java.io.BufferedOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -119,14 +120,14 @@ public class Handshaker implements Runnable {
 class SSHClientHandler extends ChannelInboundHandlerAdapter {
     private static final Logger logger = LoggerFactory.getLogger(SSHClientHandler.class);
     private final AutoCloseable remoteConnection;
-    private final OutputStream remoteOutputStream;
+    private final BufferedOutputStream remoteOutputStream;
     private final String session;
     private ChannelHandlerContext channelHandlerContext;
 
     public SSHClientHandler(AutoCloseable remoteConnection, OutputStream remoteOutputStream,
                             String session) {
         this.remoteConnection = remoteConnection;
-        this.remoteOutputStream = remoteOutputStream;
+        this.remoteOutputStream = new BufferedOutputStream(remoteOutputStream);
         this.session = session;
     }
 
@@ -137,7 +138,7 @@ class SSHClientHandler extends ChannelInboundHandlerAdapter {
     }
 
     @Override
-    public void channelRead(ChannelHandlerContext ctx, Object msg) {
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws IOException {
         ByteBuf bb = (ByteBuf) msg;
         // we can block the server here so that slow client does not cause memory pressure
         try {
index 5d0c71aa62e0e05d57768c320367b690a50395a3..b768e2b1d1ce08d8cef9585c538837157405bdc6 100644 (file)
@@ -25,29 +25,36 @@ import org.slf4j.LoggerFactory;
  * traffic between the echo client and server by sending the first message to
  * the server.
  */
-public class EchoClient implements Runnable {
+public class EchoClient extends Thread {
     private static final Logger logger = LoggerFactory.getLogger(EchoClient.class);
 
-    private final ChannelHandler clientHandler;
 
+    private final ChannelInitializer<LocalChannel> channelInitializer;
 
-    public EchoClient(ChannelHandler clientHandler) {
-        this.clientHandler = clientHandler;
+
+    public EchoClient(final ChannelHandler clientHandler) {
+        channelInitializer = new ChannelInitializer<LocalChannel>() {
+            @Override
+            public void initChannel(LocalChannel ch) throws Exception {
+                ch.pipeline().addLast(clientHandler);
+            }
+        };
+    }
+
+    public EchoClient(ChannelInitializer<LocalChannel> channelInitializer) {
+        this.channelInitializer = channelInitializer;
     }
 
+    @Override
     public void run() {
         // Configure the client.
         EventLoopGroup group = new NioEventLoopGroup();
         try {
             Bootstrap b = new Bootstrap();
+
             b.group(group)
                     .channel(LocalChannel.class)
-                    .handler(new ChannelInitializer<LocalChannel>() {
-                        @Override
-                        public void initChannel(LocalChannel ch) throws Exception {
-                            ch.pipeline().addLast(clientHandler);
-                        }
-                    });
+                    .handler(channelInitializer);
 
             // Start the client.
             LocalAddress localAddress = new LocalAddress("foo");
index 81182a580eff12b59a77872d416c19f6feba9a30..2a5791710a34cd7869ca4250cab4717c33b32f05 100644 (file)
@@ -13,6 +13,8 @@ import static com.google.common.base.Preconditions.checkState;
 import com.google.common.base.Charsets;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import org.slf4j.Logger;
@@ -23,31 +25,41 @@ import org.slf4j.LoggerFactory;
  * traffic between the echo client and server by sending the first message to
  * the server.
  */
-public class EchoClientHandler extends ChannelInboundHandlerAdapter {
+public class EchoClientHandler extends ChannelInboundHandlerAdapter implements ChannelFutureListener {
     private static final Logger logger = LoggerFactory.getLogger(EchoClientHandler.class);
 
     private ChannelHandlerContext ctx;
+    private final StringBuilder fromServer = new StringBuilder();
+
+    public static enum State {CONNECTING, CONNECTED, FAILED_TO_CONNECT, CONNECTION_CLOSED}
+
+
+    private State state = State.CONNECTING;
 
     @Override
-    public void channelActive(ChannelHandlerContext ctx) {
+    public synchronized void channelActive(ChannelHandlerContext ctx) {
         checkState(this.ctx == null);
-        logger.info("client active");
+        logger.info("channelActive");
         this.ctx = ctx;
+        state = State.CONNECTED;
     }
 
     @Override
-    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
-        ByteBuf bb = (ByteBuf) msg;
-        logger.info(">{}", bb.toString(Charsets.UTF_8));
-        bb.release();
+    public synchronized void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        state = State.CONNECTION_CLOSED;
     }
 
     @Override
-    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
+    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ByteBuf bb = (ByteBuf) msg;
+        String string = bb.toString(Charsets.UTF_8);
+        fromServer.append(string);
+        logger.info(">{}", string);
+        bb.release();
     }
 
     @Override
-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+    public synchronized void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
         // Close the connection when an exception is raised.
         logger.warn("Unexpected exception from downstream.", cause);
         checkState(this.ctx.equals(ctx));
@@ -55,8 +67,30 @@ public class EchoClientHandler extends ChannelInboundHandlerAdapter {
         this.ctx = null;
     }
 
-    public void write(String message) {
+    public synchronized void write(String message) {
         ByteBuf byteBuf = Unpooled.copiedBuffer(message.getBytes());
         ctx.writeAndFlush(byteBuf);
     }
+
+    public synchronized boolean isConnected() {
+        return state == State.CONNECTED;
+    }
+
+    public synchronized String read() {
+        return fromServer.toString();
+    }
+
+    @Override
+    public synchronized void operationComplete(ChannelFuture future) throws Exception {
+        checkState(state == State.CONNECTING);
+        if (future.isSuccess()) {
+            logger.trace("Successfully connected, state will be switched in channelActive");
+        } else {
+            state = State.FAILED_TO_CONNECT;
+        }
+    }
+
+    public State getState() {
+        return state;
+    }
 }
index 2bda51b495c3505741ff9c697712cb3f98a2b1ee..488c3701457039a022b1b0caed1a0d14e899641e 100644 (file)
@@ -8,12 +8,28 @@
 
 package org.opendaylight.controller.netconf.netty;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 
+import com.google.common.base.Stopwatch;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.EventLoopGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.util.HashedWheelTimer;
+import java.net.InetSocketAddress;
+import java.util.concurrent.TimeUnit;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
+import org.opendaylight.controller.netconf.netty.EchoClientHandler.State;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.SshHandler;
 import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
 import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
 import org.opendaylight.controller.netconf.ssh.authentication.PEMGenerator;
@@ -23,6 +39,21 @@ import org.slf4j.LoggerFactory;
 
 public class SSHTest {
     public static final Logger logger = LoggerFactory.getLogger(SSHTest.class);
+    public static final String AHOJ = "ahoj\n";
+    private EventLoopGroup nettyGroup;
+    HashedWheelTimer hashedWheelTimer;
+
+    @Before
+    public void setUp() throws Exception {
+        hashedWheelTimer = new HashedWheelTimer();
+        nettyGroup = new NioEventLoopGroup();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        hashedWheelTimer.stop();
+        nettyGroup.shutdownGracefully();
+    }
 
     @Test
     public void test() throws Exception {
@@ -30,10 +61,63 @@ public class SSHTest {
         AuthProvider authProvider = mock(AuthProvider.class);
         doReturn(PEMGenerator.generate().toCharArray()).when(authProvider).getPEMAsCharArray();
         doReturn(true).when(authProvider).authenticated(anyString(), anyString());
-        NetconfSSHServer thread = NetconfSSHServer.start(10831, NetconfConfigUtil.getNetconfLocalAddress(), authProvider, new NioEventLoopGroup());
-        Thread.sleep(2000);
-        logger.info("Closing socket");
-        thread.close();
-        thread.join();
+        NetconfSSHServer netconfSSHServer = NetconfSSHServer.start(10831, NetconfConfigUtil.getNetconfLocalAddress(),
+                authProvider, new NioEventLoopGroup());
+
+        InetSocketAddress address = netconfSSHServer.getLocalSocketAddress();
+        final EchoClientHandler echoClientHandler = connectClient(address);
+        Stopwatch stopwatch = new Stopwatch().start();
+        while(echoClientHandler.isConnected() == false && stopwatch.elapsed(TimeUnit.SECONDS) < 5) {
+            Thread.sleep(100);
+        }
+        assertTrue(echoClientHandler.isConnected());
+        logger.info("connected, writing to client");
+        echoClientHandler.write(AHOJ);
+        // check that server sent back the same string
+        stopwatch = stopwatch.reset().start();
+        while (echoClientHandler.read().endsWith(AHOJ) == false && stopwatch.elapsed(TimeUnit.SECONDS) < 5) {
+            Thread.sleep(100);
+        }
+        try {
+            String read = echoClientHandler.read();
+            assertTrue(read + " should end with " + AHOJ, read.endsWith(AHOJ));
+        } finally {
+            logger.info("Closing socket");
+            netconfSSHServer.close();
+            netconfSSHServer.join();
+        }
     }
+
+    public EchoClientHandler connectClient(InetSocketAddress address) {
+        final EchoClientHandler echoClientHandler = new EchoClientHandler();
+        ChannelInitializer<NioSocketChannel> channelInitializer = new ChannelInitializer<NioSocketChannel>() {
+            @Override
+            public void initChannel(NioSocketChannel ch) throws Exception {
+                ch.pipeline().addFirst(SshHandler.createForNetconfSubsystem(new LoginPassword("a", "a")));
+                ch.pipeline().addLast(echoClientHandler);
+            }
+        };
+        Bootstrap b = new Bootstrap();
+
+        b.group(nettyGroup)
+                .channel(NioSocketChannel.class)
+                .handler(channelInitializer);
+
+        // Start the client.
+        b.connect(address).addListener(echoClientHandler);
+        return echoClientHandler;
+    }
+
+    @Test
+    public void testClientWithoutServer() throws Exception {
+        InetSocketAddress address = new InetSocketAddress(12345);
+        final EchoClientHandler echoClientHandler = connectClient(address);
+        Stopwatch stopwatch = new Stopwatch().start();
+        while(echoClientHandler.getState() == State.CONNECTING && stopwatch.elapsed(TimeUnit.SECONDS) < 5) {
+            Thread.sleep(100);
+        }
+        assertFalse(echoClientHandler.isConnected());
+        assertEquals(State.FAILED_TO_CONNECT, echoClientHandler.getState());
+    }
+
 }
index 8780925eb185b97493cfc7557620f2846604ecd4..4e3a66b7ec5f7edfe0399bcab74e6a1843ed0449 100644 (file)
@@ -224,11 +224,17 @@ public final class XmlElement {
         });
     }
 
+    /**
+     *
+     * @param tagName tag name without prefix
+     * @return
+     */
     public List<XmlElement> getChildElements(final String tagName) {
         return getChildElementsInternal(new ElementFilteringStrategy() {
             @Override
             public boolean accept(Element e) {
-                return e.getTagName().equals(tagName);
+                // localName returns pure localName without prefix
+                return e.getLocalName().equals(tagName);
             }
         });
     }
index 01b1c8d5642368cfcfb76249ffd163037616134a..9e227ee05d6d9839c1f547ec5b53f1ff5b9f9a67 100644 (file)
@@ -124,8 +124,14 @@ public final class XmlUtil {
     public static Element createTextElementWithNamespacedContent(Document document, String qName, String prefix,
                                                                  String namespace, String contentWithoutPrefix) {
 
+       return createTextElementWithNamespacedContent(document, qName, prefix, namespace, contentWithoutPrefix, Optional.<String>absent());
+    }
+
+    public static Element createTextElementWithNamespacedContent(Document document, String qName, String prefix,
+                                                                 String namespace, String contentWithoutPrefix, Optional<String> namespaceURI) {
+
         String content = createPrefixedValue(XmlNetconfConstants.PREFIX, contentWithoutPrefix);
-        Element element = createTextElement(document, qName, content, Optional.<String>absent());
+        Element element = createTextElement(document, qName, content, namespaceURI);
         String prefixedNamespaceAttr = createPrefixedValue(XMLNS_ATTRIBUTE_KEY, prefix);
         element.setAttributeNS(XMLNS_URI, prefixedNamespaceAttr, namespace);
         return element;
diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_merge_multiple-deps1.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_merge_multiple-deps1.xml
new file mode 100644 (file)
index 0000000..0a02114
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<rpc message-id="6"
+     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+  <edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <target>
+      <candidate/>
+    </target>
+    <default-operation>merge</default-operation>
+    <test-option>set</test-option>
+    <config>
+      <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+        <module>
+          <name>d1</name>
+          <type xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:test:impl">th-java:multiple-dependencies</type>
+        </module>
+        <module>
+          <name>d2</name>
+          <type xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:test:impl">th-java:multiple-dependencies</type>
+        </module>
+        <module>
+          <name>parent</name>
+          <type xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:test:impl">th-java:multiple-dependencies</type>
+
+          <multiple-dependencies xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
+            <testing-deps>
+              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
+              <name>ref_d1</name>
+            </testing-deps>
+            <testing-deps>
+              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
+              <name>ref_d2</name>
+            </testing-deps>
+          </multiple-dependencies>
+
+        </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_d1</name>
+            <provider>/modules/module[type='multiple-dependencies'][name='d1']
+            </provider>
+          </instance>
+        </service>
+        <service>
+          <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
+          <instance>
+            <name>ref_d2</name>
+            <provider>/modules/module[type='multiple-dependencies'][name='d2']
+            </provider>
+          </instance>
+        </service>
+      </services>
+    </config>
+  </edit-config>
+</rpc>
diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_merge_multiple-deps2.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_merge_multiple-deps2.xml
new file mode 100644 (file)
index 0000000..d331976
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<rpc message-id="6"
+     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+  <edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <target>
+      <candidate/>
+    </target>
+    <default-operation>merge</default-operation>
+    <test-option>set</test-option>
+    <config>
+      <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+        <module>
+          <name>d3</name>
+          <type xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:test:impl">th-java:multiple-dependencies</type>
+        </module>
+        <module>
+          <name>parent</name>
+          <type xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:test:impl">th-java:multiple-dependencies</type>
+          <multiple-dependencies xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
+            <testing-deps>
+              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
+              <name>ref_d3</name>
+            </testing-deps>
+          </multiple-dependencies>
+        </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_d3</name>
+            <provider>/modules/module[type='multiple-dependencies'][name='d3']
+            </provider>
+          </instance>
+        </service>
+      </services>
+    </config>
+  </edit-config>
+</rpc>
index d26fcf987e5469388b5c01bac3a391b805a46536..937949a17e5827bbe74d22eb5071904b3a71906d 100644 (file)
@@ -19,6 +19,7 @@
 
   <modules>
     <module>netconf-api</module>
+    <module>netconf-cli</module>
     <module>netconf-impl</module>
     <module>config-netconf-connector</module>
     <module>netconf-util</module>
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronObject.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronObject.java
new file mode 100644 (file)
index 0000000..bebac37
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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
+ *
+ *  Authors : Dave Tucker
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+/**
+ * This class contains behaviour common to Neutron configuration objects
+ */
+public interface INeutronObject {
+    public String getID();
+    public void setID(String id);
+}
index 5b35dc2b34ff73519e4350fa7070ec06cf60801d..a3c38a9265dc50c814a83c776a0c0c7e599f1dba 100644 (file)
@@ -23,7 +23,7 @@ import org.opendaylight.controller.configuration.ConfigurationObject;
 @XmlRootElement(name = "network")
 @XmlAccessorType(XmlAccessType.NONE)
 
-public class NeutronNetwork extends ConfigurationObject implements Serializable {
+public class NeutronNetwork extends ConfigurationObject implements Serializable, INeutronObject {
     // See OpenStack Network API v2.0 Reference for description of
     // annotated attributes
 
@@ -93,6 +93,8 @@ public class NeutronNetwork extends ConfigurationObject implements Serializable
 
     public String getID() { return networkUUID; }
 
+    public void setID(String id) { this.networkUUID = id; }
+
     public String getNetworkUUID() {
         return networkUUID;
     }
index 680a07453b94b3f56072804b2981006574837f5a..b32b01cb3f3015930510d22fd1a39836a25a0cbb 100644 (file)
@@ -25,7 +25,7 @@ import org.opendaylight.controller.configuration.ConfigurationObject;
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
 
-public class NeutronPort extends ConfigurationObject implements Serializable {
+public class NeutronPort extends ConfigurationObject implements Serializable, INeutronObject {
     private static final long serialVersionUID = 1L;
 
     // See OpenStack Network API v2.0 Reference for description of
@@ -76,6 +76,8 @@ public class NeutronPort extends ConfigurationObject implements Serializable {
 
     public String getID() { return portUUID; }
 
+    public void setID(String id) { this.portUUID = id; }
+
     public String getPortUUID() {
         return portUUID;
     }
index fa35f71fd6ae425aac90f7d31524198413ade2f2..2c10cca0c0e4d0819f91d2f7d5543897d216cd65 100644 (file)
@@ -23,7 +23,7 @@ import org.opendaylight.controller.configuration.ConfigurationObject;
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
 
-public class NeutronRouter extends ConfigurationObject implements Serializable {
+public class NeutronRouter extends ConfigurationObject implements Serializable, INeutronObject {
     private static final long serialVersionUID = 1L;
 
     // See OpenStack Network API v2.0 Reference for description of
@@ -57,6 +57,8 @@ public class NeutronRouter extends ConfigurationObject implements Serializable {
 
     public String getID() { return routerUUID; }
 
+    public void setID(String id) { this.routerUUID = id; }
+
     public String getRouterUUID() {
         return routerUUID;
     }
index ae84a72bbac84ddda56c102972c894e21873a603..d032d2e8acf7f1694da85b7fec18a0623176962d 100644 (file)
@@ -25,7 +25,7 @@ import org.opendaylight.controller.configuration.ConfigurationObject;
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
 
-public class NeutronSubnet extends ConfigurationObject implements Serializable {
+public class NeutronSubnet extends ConfigurationObject implements Serializable, INeutronObject {
     private static final long serialVersionUID = 1L;
 
     // See OpenStack Network API v2.0 Reference for description of
@@ -75,7 +75,7 @@ public class NeutronSubnet extends ConfigurationObject implements Serializable {
      */
     List<NeutronPort> myPorts;
 
-    boolean gatewayIPAssigned;
+    Boolean gatewayIPAssigned;
 
     public NeutronSubnet() {
         myPorts = new ArrayList<NeutronPort>();
@@ -83,6 +83,8 @@ public class NeutronSubnet extends ConfigurationObject implements Serializable {
 
     public String getID() { return subnetUUID; }
 
+    public void setID(String id) { this.subnetUUID = id; }
+
     public String getSubnetUUID() {
         return subnetUUID;
     }
@@ -458,6 +460,10 @@ public class NeutronSubnet extends ConfigurationObject implements Serializable {
         gatewayIPAssigned = false;
     }
 
+    public Boolean getGatewayIPAllocated() {
+        return gatewayIPAssigned;
+    }
+
     @Override
     public String toString() {
         return "NeutronSubnet [subnetUUID=" + subnetUUID + ", networkUUID=" + networkUUID + ", name=" + name
index a2d2dac112e932d7578698bd1eccf54f54942f50..cbc1f0c328e58be31f53304c657ed050f746ffe1 100644 (file)
@@ -91,7 +91,6 @@
               javax.ws.rs.core,
               javax.xml.bind,
               javax.xml.bind.annotation,
-              org.objectweb.asm,
               org.opendaylight.controller.sal.utils,
               org.opendaylight.controller.sal.core,
               org.opendaylight.controller.sal.authorization,
index 87f51364ba1c5b59f3b9326a518a07c99c72129c..cf48729113ce7b1304f2a0f7b3f2e4a7c0e05dfc 100644 (file)
@@ -20,6 +20,7 @@ import javax.xml.bind.JAXBException;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.opendaylight.controller.northbound.bundlescanner.IBundleScanService;
+import org.opendaylight.controller.northbound.commons.exception.GenericExceptionMapper;
 import org.opendaylight.controller.northbound.commons.query.QueryContextProvider;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -60,6 +61,7 @@ public class NorthboundApplication extends Application {
         _singletons.add(getJsonProvider());
         _singletons.add(new JacksonJsonProcessingExceptionMapper());
         _singletons.add(new QueryContextProvider());
+        _singletons.add(new GenericExceptionMapper());
     }
 
     ////////////////////////////////////////////////////////////////
diff --git a/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/exception/GenericExceptionMapper.java b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/exception/GenericExceptionMapper.java
new file mode 100644 (file)
index 0000000..d2bbfea
--- /dev/null
@@ -0,0 +1,24 @@
+package org.opendaylight.controller.northbound.commons.exception;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+@Provider
+public class GenericExceptionMapper implements ExceptionMapper<Exception> {
+
+    @Override
+    public Response toResponse(Exception exception) {
+        //check if WebApplicationException and reuse status code
+        if (exception instanceof WebApplicationException) {
+            WebApplicationException ex = (WebApplicationException) exception;
+            return Response.status(ex.getResponse().getStatus()).
+                    entity(ex.getResponse().getEntity()).build();
+        }
+        // throw 500 for all other errors
+        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
+                entity(exception.getMessage()).build();
+    }
+
+}
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/INeutronRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/INeutronRequest.java
new file mode 100644 (file)
index 0000000..8e0ff5c
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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
+ *
+ *  Authors : Dave Tucker
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import org.opendaylight.controller.networkconfig.neutron.INeutronObject;
+
+import java.util.List;
+
+public interface INeutronRequest<T extends INeutronObject> {
+    public T getSingleton();
+    public boolean isSingleton();
+    public List<T> getBulk();
+}
index cebd3c267dd1a1ad2d3b345f2f97d498046631b0..a4c113c2c1803081409e61c4132770482d51f3c0 100644 (file)
@@ -19,7 +19,7 @@ import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
 
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
-public class NeutronNetworkRequest {
+public class NeutronNetworkRequest implements INeutronRequest {
     // See OpenStack Network API v2.0 Reference for description of
     // annotated attributes
 
@@ -29,9 +29,18 @@ public class NeutronNetworkRequest {
     @XmlElement(name="networks")
     List<NeutronNetwork> bulkRequest;
 
+    @XmlElement(name="networks_links")
+    List<NeutronPageLink> links;
+
     NeutronNetworkRequest() {
     }
 
+    NeutronNetworkRequest(List<NeutronNetwork> bulkRequest, List<NeutronPageLink> links) {
+        this.bulkRequest = bulkRequest;
+        this.links = links;
+        this.singletonNetwork = null;
+    }
+
     NeutronNetworkRequest(List<NeutronNetwork> bulk) {
         bulkRequest = bulk;
         singletonNetwork = null;
index 52c3337e40047fb844352fd9dcc0b6c596fcb8d0..9de5aef5f421eb2436ac73a6dff63e24efcf4c64 100644 (file)
@@ -9,8 +9,6 @@
 package org.opendaylight.controller.networkconfig.neutron.northbound;
 
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -33,6 +31,7 @@ import javax.ws.rs.core.Response;
 import org.codehaus.enunciate.jaxrs.ResponseCode;
 import org.codehaus.enunciate.jaxrs.StatusCodes;
 import org.codehaus.enunciate.jaxrs.TypeHint;
+
 import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkAware;
 import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
 import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
@@ -95,13 +94,13 @@ public class NeutronNetworksNorthbound {
             @QueryParam("provider_network_type") String queryProviderNetworkType,
             @QueryParam("provider_physical_network") String queryProviderPhysicalNetwork,
             @QueryParam("provider_segmentation_id") String queryProviderSegmentationID,
-            // pagination
+            // linkTitle
             @QueryParam("limit") Integer limit,
             @QueryParam("marker") String marker,
             @DefaultValue("false") @QueryParam("page_reverse") Boolean pageReverse
             // sorting not supported
             ) {
-        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
         if (networkInterface == null) {
             throw new ServiceUnavailableException("Network CRUD Interface "
                     + RestMessages.SERVICEUNAVAILABLE.toString());
@@ -139,89 +138,11 @@ public class NeutronNetworksNorthbound {
             }
         }
 
-        Comparator<NeutronNetwork> neutronNetworkComparator = new Comparator<NeutronNetwork>() {
-            @Override
-            public int compare(NeutronNetwork o1, NeutronNetwork o2) {
-                return o1.getID().compareTo(o2.getID());
-            }
-        };
-
-        Collections.sort(ans, neutronNetworkComparator);
-
         if (limit != null && ans.size() > 1) {
-            List<NeutronPageLink> links = new ArrayList<>();
-            Integer startPos = null;
-            String startMarker;
-            String endMarker;
-            Boolean firstPage = false;
-            Boolean lastPage = false;
-
-            if (marker == null) {
-                startPos = 0;
-            }
-
-            else {
-
-                NeutronNetwork markerNetwork = new NeutronNetwork();
-                markerNetwork.setNetworkUUID(marker);
-
-                startPos = Collections.binarySearch(ans, markerNetwork, neutronNetworkComparator);
-
-                if (!pageReverse){
-                    startPos = startPos + 1;
-                }
-                else {
-                    startPos = startPos - limit;
-                }
-
-            }
-
-            if (startPos == null) {
-                throw new ResourceNotFoundException("UUID for marker:" + marker + " could not be found");
-            }
-
-            if (startPos == 0){
-                firstPage = true;
-            }
-
-            if (startPos + limit >= ans.size()) {
-                ans = ans.subList(startPos, ans.size());
-                startMarker = ans.get(0).getID();
-                endMarker = ans.get(ans.size() - 1).getID();
-                lastPage = true;
-            }
-            else if (startPos < 0) {
-                if (startPos + limit > 0) {
-                    ans = ans.subList(0, startPos + limit);
-                    startMarker = ans.get(0).getID();
-                    endMarker = ans.get(ans.size() - 1).getID();
-                    firstPage = true;
-                }
-                else {
-                    throw new BadRequestException("Requested page is out of bounds. Please check the supplied limit and marker");
-                }
-            }
-            else {
-                ans = ans.subList(startPos, startPos + limit);
-                startMarker = ans.get(0).getID();
-                endMarker = ans.get(limit-1).getID();
-            }
-
-            if (!lastPage) {
-                NeutronPageLink next = new NeutronPageLink();
-                next.setRef("next");
-                next.setHref(uriInfo.getAbsolutePath().toString() + "?limit=" + limit.toString() + "&marker=" + endMarker);
-                links.add(next);
-            }
-
-            if (!firstPage) {
-                NeutronPageLink previous = new NeutronPageLink();
-                previous.setRef("previous");
-                previous.setHref(uriInfo.getAbsolutePath().toString() + "?limit=" + limit.toString() + "&marker=" + startMarker + "&page_reverse=True");
-                links.add(previous);
-            }
-
-            return Response.status(200).entity(new PaginatedNeutronNetworkRequest(ans, links)).build();
+            // Return a paginated request
+            NeutronNetworkRequest request = (NeutronNetworkRequest) PaginatedRequestFactory.createRequest(limit,
+                    marker, pageReverse, uriInfo, ans, NeutronNetwork.class);
+            return Response.status(200).entity(request).build();
         }
 
     return Response.status(200).entity(new NeutronNetworkRequest(ans)).build();
index 9b3399d9a8bfe72266843b0d4d8c34d6b163ef52..12b58aa2abc54e30799fd0458a4e126b9185124a 100644 (file)
@@ -19,7 +19,7 @@ import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
 
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
-public class NeutronPortRequest {
+public class NeutronPortRequest implements INeutronRequest {
     // See OpenStack Network API v2.0 Reference for description of
     // annotated attributes
 
@@ -29,9 +29,18 @@ public class NeutronPortRequest {
     @XmlElement(name="ports")
     List<NeutronPort> bulkRequest;
 
+    @XmlElement(name="ports_links")
+    List<NeutronPageLink> links;
+
     NeutronPortRequest() {
     }
 
+    public NeutronPortRequest(List<NeutronPort> bulkRequest, List<NeutronPageLink> links) {
+        this.bulkRequest = bulkRequest;
+        this.links = links;
+        this.singletonPort = null;
+    }
+
     NeutronPortRequest(List<NeutronPort> bulk) {
         bulkRequest = bulk;
         singletonPort = null;
index 1a2512fde3c3fd6c689a872f9ee148bba4a67521..5451fbf3e129e4be88addabcc7816e308c2cb2b7 100644 (file)
@@ -15,6 +15,7 @@ import java.util.List;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
@@ -22,8 +23,10 @@ import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 
 import org.codehaus.enunciate.jaxrs.ResponseCode;
 import org.codehaus.enunciate.jaxrs.StatusCodes;
@@ -69,6 +72,9 @@ public class NeutronPortsNorthbound {
         return o.extractFields(fields);
     }
 
+    @Context
+    UriInfo uriInfo;
+
     /**
      * Returns a list of all Ports */
 
@@ -92,10 +98,10 @@ public class NeutronPortsNorthbound {
             @QueryParam("device_id") String queryDeviceID,
             @QueryParam("device_owner") String queryDeviceOwner,
             @QueryParam("tenant_id") String queryTenantID,
-            // pagination
-            @QueryParam("limit") String limit,
+            // linkTitle
+            @QueryParam("limit") Integer limit,
             @QueryParam("marker") String marker,
-            @QueryParam("page_reverse") String pageReverse
+            @DefaultValue("false") @QueryParam("page_reverse") Boolean pageReverse
             // sorting not supported
             ) {
         INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
@@ -124,7 +130,14 @@ public class NeutronPortsNorthbound {
                 }
             }
         }
-        //TODO: apply pagination to results
+
+        if (limit != null && ans.size() > 1) {
+            // Return a paginated request
+            NeutronPortRequest request = (NeutronPortRequest) PaginatedRequestFactory.createRequest(limit,
+                    marker, pageReverse, uriInfo, ans, NeutronPort.class);
+            return Response.status(200).entity(request).build();
+        }
+
         return Response.status(200).entity(
                 new NeutronPortRequest(ans)).build();
     }
index aed9db58bd34c3255c54830c8b76957da6d4de5c..57a724c1cc60936b3a15ed80ba0c1b9bc6d53288 100644 (file)
@@ -20,7 +20,7 @@ import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
 
-public class NeutronSubnetRequest {
+public class NeutronSubnetRequest implements INeutronRequest {
     // See OpenStack Network API v2.0 Reference for description of
     // annotated attributes
 
@@ -30,16 +30,28 @@ public class NeutronSubnetRequest {
     @XmlElement(name="subnets")
     List<NeutronSubnet> bulkRequest;
 
+    @XmlElement(name="subnets_links")
+    List<NeutronPageLink> links;
+
     NeutronSubnetRequest() {
     }
 
+    public NeutronSubnetRequest(List<NeutronSubnet> bulkRequest, List<NeutronPageLink> links) {
+        this.bulkRequest = bulkRequest;
+        this.links = links;
+        this.singletonSubnet = null;
+    }
+
     NeutronSubnetRequest(List<NeutronSubnet> bulk) {
         bulkRequest = bulk;
         singletonSubnet = null;
+        links = null;
     }
 
     NeutronSubnetRequest(NeutronSubnet subnet) {
         singletonSubnet = subnet;
+        bulkRequest = null;
+        links = null;
     }
 
     public NeutronSubnet getSingleton() {
index f397eb3a97b0630002b3fc1b70901a1a25cf0609..8f20269603b1ed1802fc04812974125016c1811b 100644 (file)
@@ -13,8 +13,10 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
@@ -22,8 +24,10 @@ import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 
 import org.codehaus.enunciate.jaxrs.ResponseCode;
 import org.codehaus.enunciate.jaxrs.StatusCodes;
@@ -65,6 +69,8 @@ public class NeutronSubnetsNorthbound {
         return o.extractFields(fields);
     }
 
+    @Context
+    UriInfo uriInfo;
 
     /**
      * Returns a list of all Subnets */
@@ -89,13 +95,13 @@ public class NeutronSubnetsNorthbound {
             @QueryParam("tenant_id") String queryTenantID,
             @QueryParam("ipv6_address_mode") String queryIpV6AddressMode,
             @QueryParam("ipv6_ra_mode") String queryIpV6RaMode,
-            // pagination
-            @QueryParam("limit") String limit,
+            // linkTitle
+            @QueryParam("limit") Integer limit,
             @QueryParam("marker") String marker,
-            @QueryParam("page_reverse") String pageReverse
+            @DefaultValue("false") @QueryParam("page_reverse") Boolean pageReverse
             // sorting not supported
             ) {
-        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
         if (subnetInterface == null) {
             throw new ServiceUnavailableException("Subnet CRUD Interface "
                     + RestMessages.SERVICEUNAVAILABLE.toString());
@@ -122,7 +128,14 @@ public class NeutronSubnetsNorthbound {
                 }
             }
         }
-        //TODO: apply pagination to results
+
+        if (limit != null && ans.size() > 1) {
+            // Return a paginated request
+            NeutronSubnetRequest request = (NeutronSubnetRequest) PaginatedRequestFactory.createRequest(limit,
+                    marker, pageReverse, uriInfo, ans, NeutronSubnet.class);
+            return Response.status(200).entity(request).build();
+        }
+
         return Response.status(200).entity(
                 new NeutronSubnetRequest(ans)).build();
     }
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/PaginatedNeutronNetworkRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/PaginatedNeutronNetworkRequest.java
deleted file mode 100644 (file)
index c050661..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2014 Hewlett-Packard Development Company L.P
- *
- * 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
- *
- * Authors : Dave Tucker
- */
-
-package org.opendaylight.controller.networkconfig.neutron.northbound;
-
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
-
-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.util.List;
-
-@XmlRootElement
-@XmlAccessorType(XmlAccessType.NONE)
-
-public class PaginatedNeutronNetworkRequest {
-
-    @XmlElement (name="networks")
-    List<NeutronNetwork> networks;
-
-    @XmlElement (name="network_links")
-    List<NeutronPageLink> networkLinks;
-
-    public PaginatedNeutronNetworkRequest() {
-    }
-
-    public PaginatedNeutronNetworkRequest(List<NeutronNetwork> networks, List<NeutronPageLink> networkLinks) {
-        this.networks = networks;
-        this.networkLinks = networkLinks;
-    }
-
-    public List<NeutronNetwork> getNetworks() {
-        return networks;
-    }
-
-    public void setNetworks(List<NeutronNetwork> networks) {
-        this.networks = networks;
-    }
-
-    public List<NeutronPageLink> getNetworkLinks() {
-        return networkLinks;
-    }
-
-    public void setNetworkLinks(List<NeutronPageLink> networkLinks) {
-        this.networkLinks = networkLinks;
-    }
-}
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/PaginatedRequestFactory.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/PaginatedRequestFactory.java
new file mode 100644 (file)
index 0000000..8f05e76
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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
+ *
+ *  Authors : Dave Tucker
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import org.opendaylight.controller.networkconfig.neutron.INeutronObject;
+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.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+
+import javax.ws.rs.core.UriInfo;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class PaginatedRequestFactory {
+
+    public static class PaginationResults<T extends INeutronObject> {
+        List<T> collection;
+        List<NeutronPageLink> links;
+
+        public PaginationResults(List<T> collection, List<NeutronPageLink> links) {
+            this.collection = collection;
+            this.links = links;
+        }
+    }
+
+    public static <T extends INeutronObject> INeutronRequest createRequest(Integer limit, String marker,
+                                                                           Boolean pageReverse,
+                                                                           UriInfo uriInfo,
+                                                                           List<T> collection,
+                                                                           Class<T> clazz) {
+        PaginationResults results = _paginate(limit, marker, pageReverse, uriInfo, collection);
+
+        if (clazz.equals(NeutronNetwork.class)){
+            return new NeutronNetworkRequest(results.collection, results.links);
+        }
+        if (clazz.equals(NeutronSubnet.class)){
+            return new NeutronSubnetRequest(results.collection, results.links);
+        }
+        if (clazz.equals(NeutronPort.class)){
+            return new NeutronPortRequest(results.collection, results.links);
+        }
+        return null;
+    }
+
+    private static <T extends INeutronObject> PaginationResults _paginate(Integer limit, String marker, Boolean pageReverse, UriInfo uriInfo, List<T> collection) {
+        List<NeutronPageLink> links = new ArrayList<>();
+        Integer startPos = null;
+        String startMarker;
+        String endMarker;
+        Boolean firstPage = false;
+        Boolean lastPage = false;
+
+        Comparator<INeutronObject> neutronObjectComparator = new Comparator<INeutronObject>() {
+            @Override
+            public int compare(INeutronObject o1, INeutronObject o2) {
+                return o1.getID().compareTo(o2.getID());
+            }
+        };
+
+        Collections.sort(collection, neutronObjectComparator);
+
+        if (marker == null) {
+            startPos = 0;
+        }
+
+        else {
+
+            class MarkerObject implements INeutronObject {
+                private String id;
+
+                public String getID() {
+                    return id;
+                }
+
+                public void setID(String id) {
+                    this.id = id;
+                }
+            }
+
+            INeutronObject markerObject = new MarkerObject();
+
+            markerObject.setID(marker);
+
+            startPos = Collections.binarySearch(collection, markerObject, neutronObjectComparator);
+
+            if (!pageReverse){
+                startPos = startPos + 1;
+            }
+            else {
+                startPos = startPos - limit;
+            }
+
+        }
+
+        if (startPos == null) {
+            throw new ResourceNotFoundException("UUID for marker:" + marker + " could not be found");
+        }
+
+        if (startPos == 0){
+            firstPage = true;
+        }
+
+        if (startPos + limit >= collection.size()) {
+            collection = collection.subList(startPos, collection.size());
+            startMarker = collection.get(0).getID();
+            endMarker = collection.get(collection.size() - 1).getID();
+            lastPage = true;
+        }
+        else if (startPos < 0) {
+            if (startPos + limit > 0) {
+                collection = collection.subList(0, startPos + limit);
+                startMarker = collection.get(0).getID();
+                endMarker = collection.get(collection.size() - 1).getID();
+                firstPage = true;
+            }
+            else {
+                throw new BadRequestException("Requested page is out of bounds. Please check the supplied limit and marker");
+            }
+        }
+        else {
+            collection = collection.subList(startPos, startPos + limit);
+            startMarker = collection.get(0).getID();
+            endMarker = collection.get(limit-1).getID();
+        }
+
+        if (!lastPage) {
+            NeutronPageLink next = new NeutronPageLink();
+            next.setRef("next");
+            next.setHref(uriInfo.getAbsolutePath().toString() + "?limit=" + limit.toString() + "&marker=" + endMarker);
+            links.add(next);
+        }
+
+        if (!firstPage) {
+            NeutronPageLink previous = new NeutronPageLink();
+            previous.setRef("previous");
+            previous.setHref(uriInfo.getAbsolutePath().toString() + "?limit=" + limit.toString() + "&marker=" + startMarker + "&page_reverse=True");
+            links.add(previous);
+        }
+
+        return new PaginationResults(collection, links);
+    }
+}
index 9825d0eefb791098bf1724d5996c44f881c0da6f..4c0c94ccb82a50d5027b1be6ea23718939cc3a28 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.controller.sal.packet;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
+
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 import org.opendaylight.controller.sal.match.Match;
@@ -156,4 +157,14 @@ public class IEEE8021Q extends Packet {
         match.setField(MatchType.DL_VLAN_PR, this.getPcp());
         match.setField(MatchType.DL_TYPE, this.getEtherType());
     }
+
+    /**
+     * Gets the header size in bits
+     * @return The .1Q header size in bits
+     */
+    @Override
+    public int getHeaderSize() {
+        return 32;
+    }
+
 }
diff --git a/pom.xml b/pom.xml
index c54d9a930f28ad39ad680f30314508248bd2eea5..8bebd2aa61050f0d8058d82f312ac572ec44bf86 100644 (file)
--- a/pom.xml
+++ b/pom.xml
     <module>opendaylight/commons/filter-valve</module>
 
     <!-- Karaf Distribution -->
-    <module>features/base</module>
-    <module>features/controller</module>
     <module>opendaylight/dummy-console</module>
     <module>opendaylight/karaf-branding</module>
     <module>opendaylight/distribution/opendaylight-karaf</module>
+    <module>features</module>
   </modules>
   <scm>
     <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>