Merge "Small fix to xsql dependencies"
authorTony Tkacik <ttkacik@cisco.com>
Tue, 2 Sep 2014 11:14:21 +0000 (11:14 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 2 Sep 2014 11:14:21 +0000 (11:14 +0000)
179 files changed:
features/mdsal/pom.xml
features/mdsal/src/main/resources/features.xml
opendaylight/commons/opendaylight/pom.xml
opendaylight/distribution/opendaylight/pom.xml
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.java
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FlowCookieProducer.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FlowNodeReconciliation.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/ForwardingRulesCommiter.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/ForwardingRulesManager.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/AbstractListeningCommiter.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/FlowForwarder.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/FlowNodeReconciliationImpl.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/ForwardingRulesManagerImpl.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/GroupForwarder.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/MeterForwarder.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/reconil/FlowNodeReconcilListener.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/reconil/FlowNodeReconcilProvider.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/FlowListenerTest.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/GroupListenerTest.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/MeterListenerTest.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/NodeListenerTest.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/AbstractDataBrokerTest.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/AbstractSchemaAwareTest.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/DataBrokerTestCustomizer.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/FRMTest.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/MockSchemaService.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/RpcProviderRegistryMock.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/SalFlowServiceMock.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/SalGroupServiceMock.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/SalMeterServiceMock.java [new file with mode: 0644]
opendaylight/md-sal/md-sal-config/src/main/resources/initial/01-md-sal.xml
opendaylight/md-sal/sal-akka-raft/pom.xml
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/messages/KeyValue.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AppendEntries.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/protobuff/client/messages/Payload.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/protobuff/messages/VotingMessages.java [deleted file]
opendaylight/md-sal/sal-akka-raft/src/main/resources/VotingMessages.proto [deleted file]
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActorContext.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DomToBindingRpcForwarder.java
opendaylight/md-sal/sal-clustering-commons/pom.xml
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/NormalizedNodeToNodeCodec.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/NormalizedNodeDeSerializationContext.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/NormalizedNodeSerializationContext.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/NormalizedNodeSerializer.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/NormalizedNodeType.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/PathArgumentSerializer.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/PathArgumentType.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/ValueSerializer.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/ValueType.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/common/actor/MeteredBoundedMailbox.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/protobuff/messages/cluster/example/KeyValueMessages.java [moved from opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/example/protobuff/messages/KeyValueMessages.java with 78% similarity]
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/protobuff/messages/cluster/raft/AppendEntriesMessages.java [moved from opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/protobuff/messages/AppendEntriesMessages.java with 79% similarity]
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/protobuff/messages/cluster/raft/test/MockPayloadMessages.java [moved from opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/protobuff/messages/MockPayloadMessages.java with 66% similarity]
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/protobuff/messages/common/NormalizedNodeMessages.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/protobuff/messages/persistent/PersistentMessages.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/protobuff/messages/shard/CompositeModificationPayload.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/protobuff/messages/transaction/ShardTransactionMessages.java
opendaylight/md-sal/sal-clustering-commons/src/main/resources/AppendEntriesMessages.proto [moved from opendaylight/md-sal/sal-akka-raft/src/main/resources/AppendEntriesMessages.proto with 88% similarity]
opendaylight/md-sal/sal-clustering-commons/src/main/resources/Common.proto
opendaylight/md-sal/sal-clustering-commons/src/main/resources/KeyValueMessages.proto [moved from opendaylight/md-sal/sal-akka-raft/src/main/resources/KeyValueMessages.proto with 79% similarity]
opendaylight/md-sal/sal-clustering-commons/src/main/resources/MockPayload.proto [moved from opendaylight/md-sal/sal-akka-raft/src/test/resources/MockPayload.proto with 54% similarity]
opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/NormalizedNodeToNodeCodecTest.java
opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/NormalizedNodeSerializerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/PathArgumentSerializerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/ValueSerializerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/util/TestModel.java
opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/common/actor/MeteredBoundedMailboxTest.java
opendaylight/md-sal/sal-clustering-commons/src/test/resources/odl-datastore-test.yang
opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/akka.conf
opendaylight/md-sal/sal-distributed-datastore/pom.xml
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/CompositeModificationPayload.java
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
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistration.java
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
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreProperties.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/ShardContext.java [new file with mode: 0644]
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/ShardReadTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardReadWriteTransaction.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/ShardWriteTransaction.java
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/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/utils/ActorContext.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java
opendaylight/md-sal/sal-distributed-datastore/src/main/resources/application.conf
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/BasicIntegrationTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/CompositeModificationPayloadTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxyTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreIntegrationTest.java
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/ShardTransactionFailureTest.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/ThreePhaseCommitCohortFailureTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/TransactionChainProxyTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/TransactionProxyTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/resources/application.conf
opendaylight/md-sal/sal-dom-xsql/src/main/java/org/opendaylight/controller/md/sal/dom/xsql/XSQLAdapter.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/yang/opendaylight-inmemory-datastore-provider.yang
opendaylight/md-sal/sal-karaf-xsql/pom.xml [new file with mode: 0644]
opendaylight/md-sal/sal-karaf-xsql/src/main/java/org/opendaylight/controller/xsql/xsql.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/pom.xml
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/RpcManager.java
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RpcRegistry.java
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/gossip/BucketStore.java
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/gossip/Gossiper.java
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/utils/ActorUtil.java
opendaylight/md-sal/sal-remoterpc-connector/src/main/resources/application.conf
opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/RemoteRpcProviderTest.java
opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/RouteRpcListenerTest.java
opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/RpcListenerTest.java
opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/registry/RpcRegistryTest.java
opendaylight/md-sal/sal-remoterpc-connector/src/test/java/org/opendaylight/controller/remote/rpc/utils/LatestEntryRoutingLogicTest.java
opendaylight/md-sal/sal-remoterpc-connector/src/test/resources/application.conf
opendaylight/md-sal/sal-rest-connector/pom.xml
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfConstants.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/impl/AbstractIdentifierAwareJaxRsProvider.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonNormalizedNodeBodyReader.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/NormalizedNodeJsonBodyWriter.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/NormalizedNodeXmlBodyWriter.java [new file with mode: 0644]
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/StructuredDataToJsonProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlNormalizedNodeBodyReader.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToCompositeNodeReader.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToNormalizedNodeReaderWithSchema.java [deleted file]
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/ControllerContext.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/InstanceIdentifierContext.java [moved from opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/InstanceIdWithSchemaNode.java with 71% similarity]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/NormalizedDataPrunner.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/NormalizedNodeContext.java [new file with mode: 0644]
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/resources/WEB-INF/web.xml
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/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/RestconfDocumentedExceptionMapperTest.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-docgen/src/main/resources/WEB-INF/web.xml
opendaylight/md-sal/sal-rest-docgen/src/main/resources/explorer/index.html
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java
opendaylight/netconf/netconf-auth/pom.xml [new file with mode: 0644]
opendaylight/netconf/netconf-auth/src/main/java/org/opendaylight/controller/netconf/auth/AuthConstants.java [new file with mode: 0644]
opendaylight/netconf/netconf-auth/src/main/java/org/opendaylight/controller/netconf/auth/AuthProvider.java [moved from opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java with 56% similarity]
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java
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/osgi/NetconfSSHActivator.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/StubUserManager.java [deleted file]
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/netty/SSHTest.java
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/ssh/authentication/SSHServerTest.java
opendaylight/netconf/netconf-usermanager/pom.xml [new file with mode: 0644]
opendaylight/netconf/netconf-usermanager/src/main/java/org/opendaylight/controller/netconf/auth/usermanager/AuthProviderActivator.java [new file with mode: 0644]
opendaylight/netconf/netconf-usermanager/src/main/java/org/opendaylight/controller/netconf/auth/usermanager/AuthProviderImpl.java [moved from opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderImpl.java with 65% similarity]
opendaylight/netconf/pom.xml
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java
opendaylight/samples/northbound/loadbalancer/pom.xml

index 056d8ed..41f1eab 100644 (file)
       <type>xml</type>
       <classifier>config</classifier>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-rest-docgen</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-annotations</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.datatype</groupId>
+      <artifactId>jackson-datatype-json-org</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.module</groupId>
+      <artifactId>jackson-module-jaxb-annotations</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.jaxrs</groupId>
+      <artifactId>jackson-jaxrs-base</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.jaxrs</groupId>
+      <artifactId>jackson-jaxrs-json-provider</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.json</groupId>
+      <artifactId>json</artifactId>
+    </dependency>
     <!-- test to validate features.xml -->
     <dependency>
       <groupId>org.opendaylight.yangtools</groupId>
index 9e29fc8..0176a03 100644 (file)
         <bundle>mvn:org.opendaylight.controller/sal-dom-xsql/${project.version}</bundle>
         <configfile finalname="${config.configfile.directory}/${config.xsql.configfile}">mvn:org.opendaylight.controller/sal-dom-xsql-config/${project.version}/xml/config</configfile>
     </feature>
+    <feature name ='odl-mdsal-apidocs' version='${project.version}'>
+        <feature version='${project.version}'>odl-restconf</feature>
+        <bundle>mvn:org.opendaylight.controller/sal-rest-docgen/${project.version}</bundle>
+        <bundle>mvn:com.fasterxml.jackson.core/jackson-annotations/${jackson.version}</bundle>
+        <bundle>mvn:com.fasterxml.jackson.core/jackson-core/${jackson.version}</bundle>
+        <bundle>mvn:com.fasterxml.jackson.core/jackson-databind/${jackson.version}</bundle>
+        <bundle>mvn:com.fasterxml.jackson.datatype/jackson-datatype-json-org/${jackson.version}</bundle>
+        <bundle>mvn:com.fasterxml.jackson.module/jackson-module-jaxb-annotations/${jackson.version}</bundle>
+        <bundle>mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/${jackson.version}</bundle>
+        <bundle>mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/${jackson.version}</bundle>
+        <bundle>mvn:com.sun.jersey/jersey-core/${jersey.version}</bundle>
+        <bundle>mvn:com.sun.jersey/jersey-server/${jersey.version}</bundle>
+        <bundle>mvn:com.sun.jersey/jersey-servlet/${jersey.version}</bundle>
+        <bundle>wrap:mvn:org.json/json/${org.json.version}</bundle>
+    </feature>
 </features>
index db0f9ca..1fc32b3 100644 (file)
@@ -39,6 +39,7 @@
     <clustering.test.version>0.4.2-SNAPSHOT</clustering.test.version>
     <commmons.northbound.version>0.4.2-SNAPSHOT</commmons.northbound.version>
     <!-- Third Party Versions -->
+    <codahale.metrics.version>3.0.1</codahale.metrics.version>
     <commons.catalina>7.0.32.v201211201336</commons.catalina>
     <commons.catalina.ha>7.0.32.v201211201952</commons.catalina.ha>
     <commons.catalina.tribes>7.0.32.v201211201952</commons.catalina.tribes>
         <artifactId>logback-core</artifactId>
         <version>${logback.version}</version>
       </dependency>
+      <dependency>
+        <groupId>com.codahale.metrics</groupId>
+        <artifactId>metrics-core</artifactId>
+        <version>${codahale.metrics.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.codahale.metrics</groupId>
+        <artifactId>metrics-graphite</artifactId>
+        <version>${codahale.metrics.version}</version>
+      </dependency>
       <dependency>
         <groupId>com.fasterxml.jackson.core</groupId>
         <artifactId>jackson-annotations</artifactId>
         <version>${netconf.version}</version>
         <type>test-jar</type>
       </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>netconf-auth</artifactId>
+            <version>${netconf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>netconf-usermanager</artifactId>
+            <version>${netconf.version}</version>
+        </dependency>
       <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>netconf-ssh</artifactId>
         <artifactId>yang-data-composite-node</artifactId>
         <version>${yangtools.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>yang-data-codec-gson</artifactId>
+        <version>${yangtools.version}</version>
+      </dependency>
 
       <!-- yangtools dependencies -->
       <dependency>
index 9a76770..4ae35c9 100644 (file)
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>netconf-ssh</artifactId>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>netconf-auth</artifactId>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>netconf-usermanager</artifactId>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>netconf-tcp</artifactId>
           <groupId>org.opendaylight.yangtools</groupId>
           <artifactId>yang-parser-impl</artifactId>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-data-codec-gson</artifactId>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
           <artifactId>yang-data-composite-node</artifactId>
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java
deleted file mode 100644 (file)
index 130c096..0000000
+++ /dev/null
@@ -1,173 +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.frm;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-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.inventory.rev130819.nodes.Node;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * AbstractChangeListner implemented basic {@link AsyncDataChangeEvent} processing for
- * flow node subDataObject (flows, groups and meters).
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- */
-public abstract class AbstractChangeListener implements DataChangeListener {
-
-    private final static Logger LOG = LoggerFactory.getLogger(AbstractChangeListener.class);
-
-    private final AtomicLong txNum = new AtomicLong();
-    private String transactionId;
-
-    @Override
-    public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
-        this.transactionId = this.newTransactionIdentifier().toString();
-        /* All DataObjects for create */
-        final Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries =
-                changeEvent.getCreatedData().entrySet();
-        /* All DataObjects for updates - init HashSet */
-        final Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = new HashSet<>();
-        /* Filtered DataObject for update processing only */
-        Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updateConfigEntrySet =
-                changeEvent.getUpdatedData().entrySet();
-        updatedEntries.addAll(updateConfigEntrySet);
-        updatedEntries.removeAll(createdEntries);
-        /* All DataObjects for remove */
-        final Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers =
-                changeEvent.getRemovedPaths();
-        /* Create DataObject processing (send to device) */
-        for (final Entry<InstanceIdentifier<? extends DataObject>, DataObject> createdEntry : createdEntries) {
-            InstanceIdentifier<? extends DataObject> entryKey = createdEntry.getKey();
-            DataObject entryValue = createdEntry.getValue();
-            if (preconditionForChange(entryKey, entryValue, null)) {
-                this.add(entryKey, entryValue);
-            }
-        }
-
-        for (final Entry<InstanceIdentifier<?>, DataObject> updatedEntrie : updatedEntries) {
-            Map<InstanceIdentifier<? extends DataObject>, DataObject> origConfigData =
-                    changeEvent.getOriginalData();
-
-            InstanceIdentifier<? extends Object> entryKey = updatedEntrie.getKey();
-            final DataObject original = origConfigData.get(entryKey);
-            final DataObject updated = updatedEntrie.getValue();
-            if (preconditionForChange(entryKey, original, updated)) {
-                this.update(entryKey, original, updated);
-            }
-        }
-
-        for (final InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers) {
-            Map<InstanceIdentifier<? extends DataObject>, DataObject> origConfigData =
-                    changeEvent.getOriginalData();
-
-            final DataObject removeValue = origConfigData.get(instanceId);
-            if (preconditionForChange(instanceId, removeValue, null)) {
-                this.remove(instanceId, removeValue);
-            }
-        }
-    }
-
-    /**
-     * Method returns generated transaction ID, which is unique for
-     * every transaction. ID is composite from prefix ("DOM") and unique number.
-     *
-     * @return String transactionID
-     */
-    public String getTransactionId() {
-        return this.transactionId;
-    }
-
-    private Object newTransactionIdentifier() {
-        return "DOM-" + txNum.getAndIncrement();
-    }
-
-    /**
-     * Method check all local preconditions for apply relevant changes.
-     *
-     * @param InstanceIdentifier identifier - the whole path to DataObject
-     * @param DataObject original - original DataObject (for update)
-     *                              or relevant DataObject (add/delete operations)
-     * @param DataObject update - changed DataObject (contain updates)
-     *                              or should be null for (add/delete operations)
-     *
-     * @return boolean - applicable
-     */
-    protected abstract boolean preconditionForChange(
-            final InstanceIdentifier<? extends DataObject> identifier,
-            final DataObject original, final DataObject update);
-
-    /**
-     * Method checks the node data path in DataStore/OPERATIONAL because
-     * without the Node Identifier in DataStore/OPERATIONAL, device
-     * is not connected and device pre-configuration is allowed only.
-     *
-     * @param InstanceIdentifier identifier - could be whole path to DataObject,
-     *            but parent Node.class InstanceIdentifier is used for a check only
-     *
-     * @return boolean - is the Node available in DataStore/OPERATIONAL (is connected)
-     */
-    protected boolean isNodeAvailable(final InstanceIdentifier<? extends DataObject> identifier,
-            final ReadOnlyTransaction readTrans) {
-        final InstanceIdentifier<Node> nodeInstanceId = identifier.firstIdentifierOf(Node.class);
-        try {
-            return readTrans.read(LogicalDatastoreType.OPERATIONAL, nodeInstanceId).get().isPresent();
-        }
-        catch (InterruptedException | ExecutionException e) {
-            LOG.error("Unexpected exception by reading Node ".concat(nodeInstanceId.toString()), e);
-            return false;
-        }
-        finally {
-            readTrans.close();
-        }
-    }
-
-    /**
-     * Method removes DataObject which is identified by InstanceIdentifier
-     * from device.
-     *
-     * @param InstanceIdentifier identifier - the whole path to DataObject
-     * @param DataObject remove - DataObject for removing
-     */
-    protected abstract void remove(final InstanceIdentifier<? extends DataObject> identifier,
-            final DataObject remove);
-
-    /**
-     * Method updates the original DataObject to the update DataObject
-     * in device. Both are identified by same InstanceIdentifier
-     *
-     * @param InstanceIdentifier identifier - the whole path to DataObject
-     * @param DataObject original - original DataObject (for update)
-     * @param DataObject update - changed DataObject (contain updates)
-     */
-    protected abstract void update(final InstanceIdentifier<? extends DataObject> identifier,
-            final DataObject original, final DataObject update);
-
-    /**
-     * Method adds the DataObject which is identified by InstanceIdentifier
-     * to device.
-     *
-     * @param InstanceIdentifier identifier - the whole path to new DataObject
-     * @param DataObject add - new DataObject
-     */
-    protected abstract void add(final InstanceIdentifier<? extends DataObject> identifier,
-            final DataObject add);
-}
index c75c644..9878d16 100644 (file)
@@ -7,10 +7,7 @@
  */
 package org.opendaylight.controller.frm;
 
-import org.opendaylight.controller.frm.flow.FlowProvider;
-import org.opendaylight.controller.frm.group.GroupProvider;
-import org.opendaylight.controller.frm.meter.MeterProvider;
-import org.opendaylight.controller.frm.reconil.FlowNodeReconcilProvider;
+import org.opendaylight.controller.frm.impl.ForwardingRulesManagerImpl;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
@@ -21,8 +18,7 @@ import org.slf4j.LoggerFactory;
 /**
  * Forwarding Rules Manager Activator
  *
- * Activator manages all Providers ({@link FlowProvider}, {@link GroupProvider},
- * {@link MeterProvider} and the {@link FlowNodeReconcilProvider}).
+ * Activator {@link ForwardingRulesManager}.
  * It registers all listeners (DataChangeEvent, ReconcilNotification)
  * in the Session Initialization phase.
  *
@@ -33,56 +29,33 @@ public class FRMActivator extends AbstractBindingAwareProvider {
 
     private final static Logger LOG = LoggerFactory.getLogger(FRMActivator.class);
 
-    private final FlowProvider flowProvider;
-    private final GroupProvider groupProvider;
-    private final MeterProvider meterProvider;
-    private final FlowNodeReconcilProvider flowNodeReconcilProvider;
-
-    public FRMActivator() {
-        this.flowProvider = new FlowProvider();
-        this.groupProvider = new GroupProvider();
-        this.meterProvider = new MeterProvider();
-        this.flowNodeReconcilProvider = new FlowNodeReconcilProvider();
-    }
+    private ForwardingRulesManager  manager;
 
     @Override
-    public void onSessionInitiated(final ProviderContext session) {
+    public void onSessionInitiated(ProviderContext session) {
         LOG.info("FRMActivator initialization.");
-        /* Flow */
         try {
-            final DataBroker flowSalService = session.getSALService(DataBroker.class);
-            this.flowProvider.init(flowSalService);
-            this.flowProvider.start(session);
-            /* Group */
-            final DataBroker groupSalService = session.getSALService(DataBroker.class);
-            this.groupProvider.init(groupSalService);
-            this.groupProvider.start(session);
-            /* Meter */
-            final DataBroker meterSalService = session.getSALService(DataBroker.class);
-            this.meterProvider.init(meterSalService);
-            this.meterProvider.start(session);
-            /* FlowNode Reconciliation */
-            final DataBroker dbs = session.getSALService(DataBroker.class);
-            this.flowNodeReconcilProvider.init(dbs);
-            this.flowNodeReconcilProvider.start(session);
-
-            LOG.info("FRMActivator started successfully");
-        } catch (Exception e) {
-            String errMsg = "Unexpected error by starting FRMActivator";
-            LOG.error(errMsg, e);
-            throw new IllegalStateException(errMsg, e);
+            final DataBroker dataBroker = session.getSALService(DataBroker.class);
+            this.manager = new ForwardingRulesManagerImpl(dataBroker, session);
+            this.manager.start();
+            LOG.info("FRMActivator initialization successfull.");
+        }
+        catch (Exception e) {
+            LOG.error("Unexpected error by FRM initialization!", e);
+            this.stopImpl(null);
         }
     }
 
     @Override
     protected void stopImpl(final BundleContext context) {
-        try {
-            this.flowProvider.close();
-            this.groupProvider.close();
-            this.meterProvider.close();
-            this.flowNodeReconcilProvider.close();
-        } catch (Exception e) {
-            LOG.error("Unexpected error by stopping FRMActivator", e);
+        if (manager != null) {
+            try {
+                manager.close();
+            } catch (Exception e) {
+                LOG.error("Unexpected error by stopping FRMActivator", e);
+            }
+            manager = null;
+            LOG.info("FRMActivator stopped.");
         }
     }
   }
\ No newline at end of file
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FlowCookieProducer.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FlowCookieProducer.java
deleted file mode 100644 (file)
index d7b54e8..0000000
+++ /dev/null
@@ -1,79 +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.frm;
-
-import java.math.BigInteger;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.AtomicLongMap;
-
-/**
- * forwardingrules-manager
- * org.opendaylight.controller.frm
- *
- * Singleton FlowCookieProducer contains a FlowCookie generator which is generated unique
- * flowCookie identifier for every flow in same Table. That could help with quick
- * identification of flow statistic because DataStore/CONFIGURATION could contains
- * a lot of flows with same flowCookie. So we are replacing original flowCookie
- * with unique and we are building final FlowCookieMap in DataStore/OPERATIONAL
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- * Created: Jun 13, 2014
- */
-public enum FlowCookieProducer {
-
-    INSTANCE;
-
-    /* Flow_Cookie_Key and Flow_Ids MapHolder */
-    private static final AtomicLongMap<InstanceIdentifier<Table>> cookieKeys = AtomicLongMap.create();
-
-    /**
-     * Method returns the unique cookie for a node table.
-     * Flow Cookie Key signs List<FlowId> for a right flow statistic identification
-     * in the DataStore/operational.
-     * We need a List<FlowId> because system doesn't guarantee unique mapping
-     * from flow_cookie to flow_id. REST Operations doesn't used FRM yet, so
-     * cookie from user input could have a user input flow ID and an alien system ID
-     * which is generated by system.
-     *
-     * @param InstanceIdentifier<Table> tableIdentifier
-     * @return unique BigInteger flowCookie for a node table
-     */
-    public BigInteger getNewCookie(final InstanceIdentifier<Table> tableIdentifier) {
-        FlowCookieProducer.validationTableIdentifier(tableIdentifier);
-        if ( cookieKeys.containsKey(tableIdentifier)) {
-            /* new identifier always starts from ONE because
-             * ZERO is reserved for the NO_COOKIES flows */
-            return BigInteger.valueOf(cookieKeys.addAndGet(tableIdentifier, 1L));
-        } else {
-            return BigInteger.valueOf(cookieKeys.incrementAndGet(tableIdentifier));
-        }
-    }
-
-    /**
-     * Method cleans the node table flow_cookie_key for the disconnected Node.
-     *
-     * @param InstanceIdentifier<Table> tableIdentifier
-     */
-    public void clean(final InstanceIdentifier<Table> tableIdentifier) {
-        FlowCookieProducer.validationTableIdentifier(tableIdentifier);
-        cookieKeys.remove(tableIdentifier);
-    }
-
-    /*
-     * Help the TableIdentifer input validation method
-     */
-    private static void validationTableIdentifier(final InstanceIdentifier<Table> tableIdent) {
-        Preconditions.checkArgument(tableIdent != null, "Input validation exception: TableIdentifier can not be null !");
-    }
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FlowNodeReconciliation.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FlowNodeReconciliation.java
new file mode 100644 (file)
index 0000000..fb3178d
--- /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.frm;
+
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * forwardingrules-manager
+ * org.opendaylight.controller.frm
+ *
+ * FlowNodeReconciliation
+ * It represent Reconciliation functionality for every new device.
+ * So we have to read all possible pre-configured Flows, Meters and Groups from
+ * Config/DS and add all to new device.
+ * New device is represented by new {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode}
+ * in Operational/DS. So we have to add listener for Wildcarded path in base data change scope.
+ *
+ * WildCarded InstanceIdentifier:
+ * {@code
+ *
+ * InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class)
+ *
+ * }
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Aug 26, 2014
+ */
+public interface FlowNodeReconciliation extends DataChangeListener, AutoCloseable {
+
+    /**
+     * Method contains Node registration to {@link ForwardingRulesManager} functionality
+     * as a prevention to use a validation check to the Operational/DS for identify
+     * pre-configure transaction and serious device commit in every transaction.
+     *
+     * Second part of functionality is own reconciliation pre-configure
+     * Flows, Meters and Groups.
+     *
+     * @param connectedNode - {@link org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier} to new Node
+     */
+    void flowNodeConnected(InstanceIdentifier<FlowCapableNode> connectedNode);
+
+    /**
+     * Method contains functionality for registered Node {@FlowCapableNode} removing
+     * from {@Link ForwardingRulesManager}
+     *
+     * @param disconnectedNode - {@link org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier} to removed Node
+     */
+    void flowNodeDisconnected(InstanceIdentifier<FlowCapableNode> disconnectedNode);
+}
+
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/ForwardingRulesCommiter.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/ForwardingRulesCommiter.java
new file mode 100644 (file)
index 0000000..2228785
--- /dev/null
@@ -0,0 +1,64 @@
+/**
+ * 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.frm;
+
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * forwardingrules-manager
+ * org.opendaylight.controller.frm
+ *
+ * ForwardingRulesCommiter
+ * It represent a contract between DataStore DataChangeEvent and relevant
+ * SalRpcService for device. Every implementation has to be registered for
+ * Configurational/DS tree path.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Aug 25, 2014
+ */
+public interface ForwardingRulesCommiter <D extends DataObject> extends AutoCloseable, DataChangeListener {
+
+    /**
+     * Method removes DataObject which is identified by InstanceIdentifier
+     * from device.
+     *
+     * @param InstanceIdentifier identifier - the whole path to DataObject
+     * @param DataObject remove - DataObject for removing
+     * @param InstanceIdentifier<FlowCapableNode> parent Node InstanceIdentifier
+     */
+    void remove(InstanceIdentifier<D> identifier, D del,
+            InstanceIdentifier<FlowCapableNode> nodeIdent);
+
+    /**
+     * Method updates the original DataObject to the update DataObject
+     * in device. Both are identified by same InstanceIdentifier
+     *
+     * @param InstanceIdentifier identifier - the whole path to DataObject
+     * @param DataObject original - original DataObject (for update)
+     * @param DataObject update - changed DataObject (contain updates)
+     */
+    void update(InstanceIdentifier<D> identifier, D original, D update,
+            InstanceIdentifier<FlowCapableNode> nodeIdent);
+
+    /**
+     * Method adds the DataObject which is identified by InstanceIdentifier
+     * to device.
+     *
+     * @param InstanceIdentifier identifier - the whole path to new DataObject
+     * @param DataObject add - new DataObject
+     */
+    void add(InstanceIdentifier<D> identifier, D add,
+            InstanceIdentifier<FlowCapableNode> nodeIdent);
+
+}
+
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/ForwardingRulesManager.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/ForwardingRulesManager.java
new file mode 100644 (file)
index 0000000..504c108
--- /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.frm;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * forwardingrules-manager
+ * org.opendaylight.controller.frm
+ *
+ * ForwardingRulesManager
+ * It represent a central point for whole modul. Implementation
+ * Flow Provider registers the link FlowChangeListener} and it holds all needed
+ * services for link FlowChangeListener}.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Aug 25, 2014
+ */
+public interface ForwardingRulesManager extends AutoCloseable {
+
+    public void start();
+
+    /**
+     * Method returns information :
+     * "is Node with send InstanceIdentifier connected"?
+     *
+     * @param InstanceIdentifier<FlowCapableNode> ident - the key of the node
+     * @return boolean - is device connected
+     */
+    public boolean isNodeActive(InstanceIdentifier<FlowCapableNode> ident);
+
+    /**
+     * Method add new {@link FlowCapableNode} to active Node Holder.
+     * ActiveNodeHolder prevent unnecessary Operational/DS read for identify
+     * pre-configure and serious Configure/DS transactions.
+     *
+     * @param InstanceIdentifier<FlowCapableNode> ident - the key of the node
+     */
+    public void registrateNewNode(InstanceIdentifier<FlowCapableNode> ident);
+
+    /**
+     * Method remove disconnected {@link FlowCapableNode} from active Node
+     * Holder. And all next flows or groups or meters will stay in Config/DS
+     * only.
+     *
+     * @param InstanceIdentifier<FlowCapableNode> ident - the key of the node
+     */
+    public void unregistrateNode(InstanceIdentifier<FlowCapableNode> ident);
+
+    /**
+     * Method returns generated transaction ID, which is unique for
+     * every transaction. ID is composite from prefix ("DOM") and unique number.
+     *
+     * @return String transactionID for RPC transaction identification
+     */
+    public String getNewTransactionId();
+
+    /**
+     * Method returns Read Transacion. It is need for Node reconciliation only.
+     *
+     * @return ReadOnlyTransaction
+     */
+    public ReadOnlyTransaction getReadTranaction();
+
+    /**
+     * Flow RPC service
+     *
+     * @return
+     */
+    public SalFlowService getSalFlowService();
+
+    /**
+     * Group RPC service
+     *
+     * @return
+     */
+    public SalGroupService getSalGroupService();
+
+    /**
+     * Meter RPC service
+     *
+     * @return
+     */
+    public SalMeterService getSalMeterService();
+
+    /**
+     * Content definition method and prevent code duplicity in Reconcil
+     * @return ForwardingRulesCommiter<Flow>
+     */
+    public ForwardingRulesCommiter<Flow> getFlowCommiter();
+
+    /**
+     * Content definition method and prevent code duplicity in Reconcil
+     * @return ForwardingRulesCommiter<Group>
+     */
+    public ForwardingRulesCommiter<Group> getGroupCommiter();
+
+    /**
+     * Content definition method and prevent code duplicity
+     * @return ForwardingRulesCommiter<Meter>
+     */
+    public ForwardingRulesCommiter<Meter> getMeterCommiter();
+
+    /**
+     * Content definition method
+     * @return FlowNodeReconciliation
+     */
+    public FlowNodeReconciliation getFlowNodeReconciliation();
+}
+
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java
deleted file mode 100644 (file)
index c10b0da..0000000
+++ /dev/null
@@ -1,126 +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.frm.flow;
-
-import java.math.BigInteger;
-
-import org.opendaylight.controller.frm.AbstractChangeListener;
-import org.opendaylight.controller.frm.FlowCookieProducer;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.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.flow.service.rev130819.AddFlowInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Flow Change Listener
- *  add, update and remove {@link Flow} processing from {@link org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent}.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- */
-public class FlowChangeListener extends AbstractChangeListener {
-
-    private static final Logger LOG = LoggerFactory.getLogger(FlowChangeListener.class);
-
-    private final FlowProvider provider;
-
-    public FlowChangeListener (final FlowProvider provider) {
-        this.provider = Preconditions.checkNotNull(provider, "FlowProvider can not be null !");
-    }
-
-    @Override
-    protected void remove(final InstanceIdentifier<? extends DataObject> identifier,
-                          final DataObject removeDataObj) {
-
-        final Flow flow = ((Flow) removeDataObj);
-        final InstanceIdentifier<Table> tableIdent = identifier.firstIdentifierOf(Table.class);
-        final InstanceIdentifier<Node> nodeIdent = identifier.firstIdentifierOf(Node.class);
-        final RemoveFlowInputBuilder builder = new RemoveFlowInputBuilder(flow);
-
-        // use empty cookie mask in order to delete flow even with generated cookie
-        builder.setCookieMask(new FlowCookie(BigInteger.ZERO));
-
-        builder.setFlowRef(new FlowRef(identifier));
-        builder.setNode(new NodeRef(nodeIdent));
-        builder.setFlowTable(new FlowTableRef(tableIdent));
-
-        Uri uri = new Uri(this.getTransactionId());
-        builder.setTransactionUri(uri);
-        this.provider.getSalFlowService().removeFlow(builder.build());
-        LOG.debug("Transaction {} - Removed Flow has removed flow: {}", new Object[]{uri, removeDataObj});
-    }
-
-    @Override
-    protected void update(final InstanceIdentifier<? extends DataObject> identifier,
-                          final DataObject original, final DataObject update) {
-
-        final Flow originalFlow = ((Flow) original);
-        final Flow updatedFlow = ((Flow) update);
-        final InstanceIdentifier<Node> nodeIdent = identifier.firstIdentifierOf(Node.class);
-        final UpdateFlowInputBuilder builder = new UpdateFlowInputBuilder();
-
-        builder.setNode(new NodeRef(nodeIdent));
-        builder.setFlowRef(new FlowRef(identifier));
-
-        Uri uri = new Uri(this.getTransactionId());
-        builder.setTransactionUri(uri);
-
-        builder.setUpdatedFlow((new UpdatedFlowBuilder(updatedFlow)).build());
-        builder.setOriginalFlow((new OriginalFlowBuilder(originalFlow)).build());
-
-        this.provider.getSalFlowService().updateFlow(builder.build());
-        LOG.debug("Transaction {} - Update Flow has updated flow {} with {}", new Object[]{uri, original, update});
-    }
-
-    @Override
-    protected void add(final InstanceIdentifier<? extends DataObject> identifier,
-                       final DataObject addDataObj) {
-
-        final Flow flow = ((Flow) addDataObj);
-        final InstanceIdentifier<Table> tableIdent = identifier.firstIdentifierOf(Table.class);
-        final NodeRef nodeRef = new NodeRef(identifier.firstIdentifierOf(Node.class));
-        final FlowCookie flowCookie = new FlowCookie(FlowCookieProducer.INSTANCE.getNewCookie(tableIdent));
-        final AddFlowInputBuilder builder = new AddFlowInputBuilder(flow);
-
-        builder.setNode(nodeRef);
-        builder.setFlowRef(new FlowRef(identifier));
-        builder.setFlowTable(new FlowTableRef(tableIdent));
-        builder.setCookie( flowCookie );
-
-        Uri uri = new Uri(this.getTransactionId());
-        builder.setTransactionUri(uri);
-        this.provider.getSalFlowService().addFlow(builder.build());
-        LOG.debug("Transaction {} - Add Flow has added flow: {}", new Object[]{uri, addDataObj});
-    }
-
-    @Override
-    protected boolean preconditionForChange(final InstanceIdentifier<? extends DataObject> identifier,
-            final DataObject dataObj, final DataObject update) {
-
-        final ReadOnlyTransaction trans = this.provider.getDataService().newReadOnlyTransaction();
-        return update != null
-                ? (dataObj instanceof Flow && update instanceof Flow && isNodeAvailable(identifier, trans))
-                : (dataObj instanceof Flow && isNodeAvailable(identifier, trans));
-    }
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java
deleted file mode 100644 (file)
index 8c248fa..0000000
+++ /dev/null
@@ -1,107 +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.frm.flow;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-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.LogicalDatastoreType;
-import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
-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.flow.service.rev130819.SalFlowService;
-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.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Flow Provider registers the {@link FlowChangeListener} and it holds all needed
- * services for {@link FlowChangeListener}.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- */
-public class FlowProvider implements AutoCloseable {
-
-    private static final Logger LOG = LoggerFactory.getLogger(FlowProvider.class);
-
-    private SalFlowService salFlowService;
-    private DataBroker dataService;
-
-    /* DataChangeListener */
-    private DataChangeListener flowDataChangeListener;
-    private ListenerRegistration<DataChangeListener> flowDataChangeListenerRegistration;
-
-    /**
-     * Provider Initialization Phase.
-     *
-     * @param DataProviderService dataService
-     */
-    public void init (final DataBroker dataService) {
-        LOG.info("FRM Flow Config Provider initialization.");
-        this.dataService = Preconditions.checkNotNull(dataService, "DataProviderService can not be null !");
-    }
-
-    /**
-     * Listener Registration Phase
-     *
-     * @param RpcConsumerRegistry rpcRegistry
-     */
-    public void start(final RpcConsumerRegistry rpcRegistry) {
-        Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
-
-        this.salFlowService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalFlowService.class),
-                "RPC SalFlowService not found.");
-
-        /* Build Path */
-        InstanceIdentifier<Flow> flowIdentifier = InstanceIdentifier.create(Nodes.class)
-                .child(Node.class).augmentation(FlowCapableNode.class).child(Table.class).child(Flow.class);
-
-        /* DataChangeListener registration */
-        this.flowDataChangeListener = new FlowChangeListener(FlowProvider.this);
-        this.flowDataChangeListenerRegistration =
-                this.dataService.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
-                        flowIdentifier, flowDataChangeListener, DataChangeScope.SUBTREE);
-
-        LOG.info("FRM Flow Config Provider started.");
-    }
-
-    @Override
-    public void close() {
-        LOG.info("FRM Flow Config Provider stopped.");
-        if (flowDataChangeListenerRegistration != null) {
-            try {
-                flowDataChangeListenerRegistration.close();
-            } catch (Exception e) {
-                String errMsg = "Error by stop FRM Flow Config Provider.";
-                LOG.error(errMsg, e);
-                throw new IllegalStateException(errMsg, e);
-            } finally {
-                flowDataChangeListenerRegistration = null;
-            }
-        }
-    }
-
-    public DataChangeListener getFlowDataChangeListener() {
-        return flowDataChangeListener;
-    }
-
-    public SalFlowService getSalFlowService() {
-        return salFlowService;
-    }
-
-    public DataBroker getDataService() {
-        return dataService;
-    }
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java
deleted file mode 100644 (file)
index 9b03eaa..0000000
+++ /dev/null
@@ -1,111 +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.frm.group;
-
-import org.opendaylight.controller.frm.AbstractChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Group Change Listener
- *  add, update and remove {@link Group} processing from {@link org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent}.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- */
-public class GroupChangeListener extends AbstractChangeListener {
-
-    private static final Logger LOG = LoggerFactory.getLogger(GroupChangeListener.class);
-
-    private final GroupProvider provider;
-
-    public GroupChangeListener(final GroupProvider provider) {
-        this.provider = Preconditions.checkNotNull(provider, "GroupProvider can not be null !");
-    }
-
-    @Override
-    protected void remove(final InstanceIdentifier<? extends DataObject> identifier,
-                          final DataObject removeDataObj) {
-
-        final Group group = ((Group) removeDataObj);
-        final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
-        final RemoveGroupInputBuilder builder = new RemoveGroupInputBuilder(group);
-
-        builder.setNode(new NodeRef(nodeInstanceId));
-        builder.setGroupRef(new GroupRef(identifier));
-
-        Uri uri = new Uri(this.getTransactionId());
-        builder.setTransactionUri(uri);
-        this.provider.getSalGroupService().removeGroup(builder.build());
-        LOG.debug("Transaction {} - Remove Group has removed group: {}", new Object[]{uri, removeDataObj});
-    }
-
-    @Override
-    protected void update(final InstanceIdentifier<? extends DataObject> identifier,
-                          final DataObject original, final DataObject update) {
-
-        final Group originalGroup = ((Group) original);
-        final Group updatedGroup = ((Group) update);
-        final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
-        final UpdateGroupInputBuilder builder = new UpdateGroupInputBuilder();
-
-        builder.setNode(new NodeRef(nodeInstanceId));
-        builder.setGroupRef(new GroupRef(identifier));
-
-        Uri uri = new Uri(this.getTransactionId());
-        builder.setTransactionUri(uri);
-
-        builder.setUpdatedGroup((new UpdatedGroupBuilder(updatedGroup)).build());
-        builder.setOriginalGroup((new OriginalGroupBuilder(originalGroup)).build());
-
-        this.provider.getSalGroupService().updateGroup(builder.build());
-        LOG.debug("Transaction {} - Update Group has updated group {} with group {}", new Object[]{uri, original, update});
-    }
-
-    @Override
-    protected void add(final InstanceIdentifier<? extends DataObject> identifier,
-                       final DataObject addDataObj) {
-
-        final Group group = ((Group) addDataObj);
-        final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
-        final AddGroupInputBuilder builder = new AddGroupInputBuilder(group);
-
-        builder.setNode(new NodeRef(nodeInstanceId));
-        builder.setGroupRef(new GroupRef(identifier));
-
-        Uri uri = new Uri(this.getTransactionId());
-        builder.setTransactionUri(uri);
-        this.provider.getSalGroupService().addGroup(builder.build());
-        LOG.debug("Transaction {} - Add Group has added group: {}", new Object[]{uri, addDataObj});
-    }
-
-    @Override
-    protected boolean preconditionForChange(final InstanceIdentifier<? extends DataObject> identifier,
-            final DataObject dataObj, final DataObject update) {
-
-        final ReadOnlyTransaction trans = this.provider.getDataService().newReadOnlyTransaction();
-        return update != null
-                ? (dataObj instanceof Group && update instanceof Group && isNodeAvailable(identifier, trans))
-                : (dataObj instanceof Group && isNodeAvailable(identifier, trans));
-    }
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java
deleted file mode 100644 (file)
index a999242..0000000
+++ /dev/null
@@ -1,105 +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.frm.group;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-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.LogicalDatastoreType;
-import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Group Provider registers the {@link GroupChangeListener} and it holds all needed
- * services for {@link GroupChangeListener}.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- */
-public class GroupProvider implements AutoCloseable {
-
-    private static final Logger LOG = LoggerFactory.getLogger(GroupProvider.class);
-
-    private SalGroupService salGroupService;
-    private DataBroker dataService;
-
-    /* DataChangeListener */
-    private DataChangeListener groupDataChangeListener;
-    private ListenerRegistration<DataChangeListener> groupDataChangeListenerRegistration;
-
-    /**
-     * Provider Initialization Phase.
-     *
-     * @param DataProviderService dataService
-     */
-    public void init (final DataBroker dataService) {
-        LOG.info("FRM Group Config Provider initialization.");
-        this.dataService = Preconditions.checkNotNull(dataService, "DataService can not be null !");
-    }
-
-    /**
-     * Listener Registration Phase
-     *
-     * @param RpcConsumerRegistry rpcRegistry
-     */
-    public void start(final RpcConsumerRegistry rpcRegistry) {
-        Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
-
-        this.salGroupService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalGroupService.class),
-                "RPC SalGroupService not found.");
-
-        /* Build Path */
-        InstanceIdentifier<Group> groupIdentifier = InstanceIdentifier.create(Nodes.class)
-                .child(Node.class).augmentation(FlowCapableNode.class).child(Group.class);
-
-        /* DataChangeListener registration */
-        this.groupDataChangeListener = new GroupChangeListener(GroupProvider.this);
-        this.groupDataChangeListenerRegistration = this.dataService.registerDataChangeListener(
-                LogicalDatastoreType.CONFIGURATION, groupIdentifier, groupDataChangeListener, DataChangeScope.SUBTREE);
-
-        LOG.info("FRM Group Config Provider started.");
-    }
-
-    @Override
-    public void close() {
-        LOG.info("FRM Group Config Provider stopped.");
-        if (groupDataChangeListenerRegistration != null) {
-            try {
-                groupDataChangeListenerRegistration.close();
-            } catch (Exception e) {
-                String errMsg = "Error by stop FRM Group Config Provider.";
-                LOG.error(errMsg, e);
-                throw new IllegalStateException(errMsg, e);
-            } finally {
-                groupDataChangeListenerRegistration = null;
-            }
-        }
-    }
-
-    public DataChangeListener getGroupDataChangeListener() {
-        return groupDataChangeListener;
-    }
-
-    public SalGroupService getSalGroupService() {
-        return salGroupService;
-    }
-
-    public DataBroker getDataService() {
-        return dataService;
-    }
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/AbstractListeningCommiter.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/AbstractListeningCommiter.java
new file mode 100644 (file)
index 0000000..ec49e61
--- /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.frm.impl;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.frm.ForwardingRulesCommiter;
+import org.opendaylight.controller.frm.ForwardingRulesManager;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * AbstractChangeListner implemented basic {@link AsyncDataChangeEvent} processing for
+ * flow node subDataObject (flows, groups and meters).
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public abstract class AbstractListeningCommiter <T extends DataObject> implements ForwardingRulesCommiter<T> {
+
+    protected ForwardingRulesManager provider;
+
+    protected final Class<T> clazz;
+
+    public AbstractListeningCommiter (ForwardingRulesManager provider, Class<T> clazz) {
+        this.provider = Preconditions.checkNotNull(provider, "ForwardingRulesManager can not be null!");
+        this.clazz = Preconditions.checkNotNull(clazz, "Class can not be null!");
+    }
+
+    @Override
+    public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
+        Preconditions.checkNotNull(changeEvent,"Async ChangeEvent can not be null!");
+
+        /* All DataObjects for create */
+        final Map<InstanceIdentifier<?>, DataObject> createdData = changeEvent.getCreatedData() != null
+                ? changeEvent.getCreatedData() : Collections.<InstanceIdentifier<?>, DataObject> emptyMap();
+        /* All DataObjects for remove */
+        final Set<InstanceIdentifier<?>> removeData = changeEvent.getRemovedPaths() != null
+                ? changeEvent.getRemovedPaths() : Collections.<InstanceIdentifier<?>> emptySet();
+        /* All DataObjects for updates */
+        final Map<InstanceIdentifier<?>, DataObject> updateData = changeEvent.getUpdatedData() != null
+                ? changeEvent.getUpdatedData() : Collections.<InstanceIdentifier<?>, DataObject> emptyMap();
+        /* All Original DataObjects */
+        final Map<InstanceIdentifier<?>, DataObject> originalData = changeEvent.getOriginalData() != null
+                ? changeEvent.getOriginalData() : Collections.<InstanceIdentifier<?>, DataObject> emptyMap();
+
+        this.createData(createdData);
+        this.updateData(updateData, originalData);
+        this.removeData(removeData, originalData);
+    }
+
+    /**
+     * Method return wildCardPath for Listener registration
+     * and for identify the correct KeyInstanceIdentifier from data;
+     */
+    protected abstract InstanceIdentifier<T> getWildCardPath();
+
+
+
+    @SuppressWarnings("unchecked")
+    private void createData(final Map<InstanceIdentifier<?>, DataObject> createdData) {
+        final Set<InstanceIdentifier<?>> keys = createdData.keySet() != null
+                ? createdData.keySet() : Collections.<InstanceIdentifier<?>> emptySet();
+        for (InstanceIdentifier<?> key : keys) {
+            if (clazz.equals(key.getTargetType())) {
+                final InstanceIdentifier<FlowCapableNode> nodeIdent =
+                        key.firstIdentifierOf(FlowCapableNode.class);
+                if (preConfigurationCheck(nodeIdent)) {
+                    InstanceIdentifier<T> createKeyIdent = key.firstIdentifierOf(clazz);
+                    final Optional<DataObject> value = Optional.of(createdData.get(key));
+                    if (value.isPresent()) {
+                        this.add(createKeyIdent, (T)value.get(), nodeIdent);
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void updateData(final Map<InstanceIdentifier<?>, DataObject> updateData,
+            final Map<InstanceIdentifier<?>, DataObject> originalData) {
+
+        final Set<InstanceIdentifier<?>> keys = updateData.keySet() != null
+                ? updateData.keySet() : Collections.<InstanceIdentifier<?>> emptySet();
+        for (InstanceIdentifier<?> key : keys) {
+            if (clazz.equals(key.getTargetType())) {
+                final InstanceIdentifier<FlowCapableNode> nodeIdent =
+                        key.firstIdentifierOf(FlowCapableNode.class);
+                if (preConfigurationCheck(nodeIdent)) {
+                    InstanceIdentifier<T> updateKeyIdent = key.firstIdentifierOf(clazz);
+                    final Optional<DataObject> value = Optional.of(updateData.get(key));
+                    final Optional<DataObject> original = Optional.of(originalData.get(key));
+                    if (value.isPresent() && original.isPresent()) {
+                        this.update(updateKeyIdent, (T)original.get(), (T)value.get(), nodeIdent);
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void removeData(final Set<InstanceIdentifier<?>> removeData,
+            final Map<InstanceIdentifier<?>, DataObject> originalData) {
+
+        for (InstanceIdentifier<?> key : removeData) {
+            if (clazz.equals(key.getTargetType())) {
+                final InstanceIdentifier<FlowCapableNode> nodeIdent =
+                        key.firstIdentifierOf(FlowCapableNode.class);
+                if (preConfigurationCheck(nodeIdent)) {
+                    final InstanceIdentifier<T> ident = key.firstIdentifierOf(clazz);
+                    final DataObject removeValue = originalData.get(key);
+                    this.remove(ident, (T)removeValue, nodeIdent);
+                }
+            }
+        }
+    }
+
+    private boolean preConfigurationCheck(final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+        Preconditions.checkNotNull(nodeIdent, "FlowCapableNode ident can not be null!");
+        return provider.isNodeActive(nodeIdent);
+    }
+}
+
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/FlowForwarder.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/FlowForwarder.java
new file mode 100644 (file)
index 0000000..fd0ddec
--- /dev/null
@@ -0,0 +1,140 @@
+/**ab
+ * 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.frm.impl;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.frm.ForwardingRulesManager;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+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.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef;
+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.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * GroupForwarder
+ * It implements {@link org.opendaylight.controller.md.sal.binding.api.DataChangeListener}}
+ * for WildCardedPath to {@link Flow} and ForwardingRulesCommiter interface for methods:
+ *  add, update and remove {@link Flow} processing for
+ *  {@link org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent}.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class FlowForwarder extends AbstractListeningCommiter<Flow> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(FlowForwarder.class);
+
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+
+    public FlowForwarder (final ForwardingRulesManager manager, final DataBroker db) {
+        super(manager, Flow.class);
+        Preconditions.checkNotNull(db, "DataBroker can not be null!");
+        this.listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+                getWildCardPath(), FlowForwarder.this, DataChangeScope.BASE);
+    }
+
+    @Override
+    public void close() {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (Exception e) {
+                LOG.error("Error by stop FRM FlowChangeListener.", e);
+            }
+            listenerRegistration = null;
+        }
+    }
+
+    @Override
+    public void remove(final InstanceIdentifier<Flow> identifier,
+                       final Flow removeDataObj,
+                       final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+        final TableKey tableKey = identifier.firstKeyOf(Table.class, TableKey.class);
+        if (tableIdValidationPrecondition(tableKey, removeDataObj)) {
+            final RemoveFlowInputBuilder builder = new RemoveFlowInputBuilder(removeDataObj);
+            builder.setFlowRef(new FlowRef(identifier));
+            builder.setNode(new NodeRef(nodeIdent));
+            builder.setFlowTable(new FlowTableRef(nodeIdent.child(Table.class, tableKey)));
+            builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+            this.provider.getSalFlowService().removeFlow(builder.build());
+        }
+    }
+
+    @Override
+    public void update(final InstanceIdentifier<Flow> identifier,
+                       final Flow original, final Flow update,
+                       final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+        final TableKey tableKey = identifier.firstKeyOf(Table.class, TableKey.class);
+        if (tableIdValidationPrecondition(tableKey, update)) {
+            final UpdateFlowInputBuilder builder = new UpdateFlowInputBuilder();
+
+            builder.setNode(new NodeRef(nodeIdent));
+            builder.setFlowRef(new FlowRef(identifier));
+            builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+            builder.setUpdatedFlow((new UpdatedFlowBuilder(update)).build());
+            builder.setOriginalFlow((new OriginalFlowBuilder(original)).build());
+
+            this.provider.getSalFlowService().updateFlow(builder.build());
+        }
+    }
+
+    @Override
+    public void add(final InstanceIdentifier<Flow> identifier,
+                    final Flow addDataObj,
+                    final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+        final TableKey tableKey = identifier.firstKeyOf(Table.class, TableKey.class);
+        if (tableIdValidationPrecondition(tableKey, addDataObj)) {
+            final AddFlowInputBuilder builder = new AddFlowInputBuilder(addDataObj);
+
+            builder.setNode(new NodeRef(nodeIdent));
+            builder.setFlowRef(new FlowRef(identifier));
+            builder.setFlowTable(new FlowTableRef(nodeIdent.child(Table.class, tableKey)));
+            builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+            this.provider.getSalFlowService().addFlow(builder.build());
+        }
+    }
+
+    @Override
+    protected InstanceIdentifier<Flow> getWildCardPath() {
+        return InstanceIdentifier.create(Nodes.class).child(Node.class)
+                .augmentation(FlowCapableNode.class).child(Table.class).child(Flow.class);
+    }
+
+    private boolean tableIdValidationPrecondition (final TableKey tableKey, final Flow flow) {
+        Preconditions.checkNotNull(tableKey, "TableKey can not be null or empty!");
+        Preconditions.checkNotNull(flow, "Flow can not be null or empty!");
+        if (flow.getTableId() != tableKey.getId()) {
+            LOG.error("TableID in URI tableId={} and in palyload tableId={} is not same.",
+                    flow.getTableId(), tableKey.getId());
+            return false;
+        }
+        return true;
+    }
+}
+
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/FlowNodeReconciliationImpl.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/FlowNodeReconciliationImpl.java
new file mode 100644 (file)
index 0000000..f1e8dfe
--- /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.frm.impl;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.opendaylight.controller.frm.FlowNodeReconciliation;
+import org.opendaylight.controller.frm.ForwardingRulesManager;
+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.ReadOnlyTransaction;
+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.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.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.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+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.binding.KeyedInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+/**
+ * forwardingrules-manager
+ * org.opendaylight.controller.frm
+ *
+ * FlowNode Reconciliation Listener
+ * Reconciliation for a new FlowNode
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Jun 13, 2014
+ */
+public class FlowNodeReconciliationImpl implements FlowNodeReconciliation {
+
+    private static final Logger LOG = LoggerFactory.getLogger(FlowNodeReconciliationImpl.class);
+
+    private final ForwardingRulesManager provider;
+
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+
+    public FlowNodeReconciliationImpl (final ForwardingRulesManager manager, final DataBroker db) {
+        this.provider = Preconditions.checkNotNull(manager, "ForwardingRulesManager can not be null!");
+        Preconditions.checkNotNull(db, "DataBroker can not be null!");
+        /* Build Path */
+        InstanceIdentifier<FlowCapableNode> flowNodeWildCardIdentifier = InstanceIdentifier.create(Nodes.class)
+                .child(Node.class).augmentation(FlowCapableNode.class);
+        this.listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+                flowNodeWildCardIdentifier, FlowNodeReconciliationImpl.this, DataChangeScope.BASE);
+    }
+
+    @Override
+    public void close() {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (Exception e) {
+                LOG.error("Error by stop FRM FlowNodeReconilListener.", e);
+            }
+            listenerRegistration = null;
+        }
+    }
+
+    @Override
+    public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
+        Preconditions.checkNotNull(changeEvent,"Async ChangeEvent can not be null!");
+        /* All DataObjects for create */
+        final Set<InstanceIdentifier<?>>  createdData = changeEvent.getCreatedData() != null
+                ? changeEvent.getCreatedData().keySet() : Collections.<InstanceIdentifier<?>> emptySet();
+        /* All DataObjects for remove */
+        final Set<InstanceIdentifier<?>> removeData = changeEvent.getRemovedPaths() != null
+                ? changeEvent.getRemovedPaths() : Collections.<InstanceIdentifier<?>> emptySet();
+
+        for (InstanceIdentifier<?> entryKey : removeData) {
+            final InstanceIdentifier<FlowCapableNode> nodeIdent = entryKey
+                    .firstIdentifierOf(FlowCapableNode.class);
+            if ( ! nodeIdent.isWildcarded()) {
+                flowNodeDisconnected(nodeIdent);
+            }
+        }
+        for (InstanceIdentifier<?> entryKey : createdData) {
+            final InstanceIdentifier<FlowCapableNode> nodeIdent = entryKey
+                    .firstIdentifierOf(FlowCapableNode.class);
+            if ( ! nodeIdent.isWildcarded()) {
+                flowNodeConnected(nodeIdent);
+            }
+        }
+    }
+
+    @Override
+    public void flowNodeDisconnected(InstanceIdentifier<FlowCapableNode> disconnectedNode) {
+        provider.unregistrateNode(disconnectedNode);
+    }
+
+    @Override
+    public void flowNodeConnected(InstanceIdentifier<FlowCapableNode> connectedNode) {
+        if ( ! provider.isNodeActive(connectedNode)) {
+            provider.registrateNewNode(connectedNode);
+            reconciliation(connectedNode);
+        }
+    }
+
+    private void reconciliation(final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+        ReadOnlyTransaction trans = provider.getReadTranaction();
+        Optional<FlowCapableNode> flowNode = Optional.absent();
+
+        try {
+            flowNode = trans.read(LogicalDatastoreType.CONFIGURATION, nodeIdent).get();
+        }
+        catch (Exception e) {
+            LOG.error("Fail with read Config/DS for Node {} !", nodeIdent, e);
+        }
+
+        if (flowNode.isPresent()) {
+            /* Groups - have to be first */
+            List<Group> groups = flowNode.get().getGroup() != null
+                    ? flowNode.get().getGroup() : Collections.<Group> emptyList();
+            for (Group group : groups) {
+                final KeyedInstanceIdentifier<Group, GroupKey> groupIdent =
+                        nodeIdent.child(Group.class, group.getKey());
+                this.provider.getGroupCommiter().add(groupIdent, group, nodeIdent);
+            }
+            /* Meters */
+            List<Meter> meters = flowNode.get().getMeter() != null
+                    ? flowNode.get().getMeter() : Collections.<Meter> emptyList();
+            for (Meter meter : meters) {
+                final KeyedInstanceIdentifier<Meter, MeterKey> meterIdent =
+                        nodeIdent.child(Meter.class, meter.getKey());
+                this.provider.getMeterCommiter().add(meterIdent, meter, nodeIdent);
+            }
+            /* Flows */
+            List<Table> tables = flowNode.get().getTable() != null
+                    ? flowNode.get().getTable() : Collections.<Table> emptyList();
+            for (Table table : tables) {
+                final KeyedInstanceIdentifier<Table, TableKey> tableIdent =
+                        nodeIdent.child(Table.class, table.getKey());
+                List<Flow> flows = table.getFlow() != null ? table.getFlow() : Collections.<Flow> emptyList();
+                for (Flow flow : flows) {
+                    final KeyedInstanceIdentifier<Flow, FlowKey> flowIdent =
+                            tableIdent.child(Flow.class, flow.getKey());
+                    this.provider.getFlowCommiter().add(flowIdent, flow, nodeIdent);
+                }
+            }
+        }
+        /* clean transaction */
+        trans.close();
+    }
+}
+
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/ForwardingRulesManagerImpl.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/ForwardingRulesManagerImpl.java
new file mode 100644 (file)
index 0000000..7cb7acf
--- /dev/null
@@ -0,0 +1,185 @@
+/**
+ * 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.frm.impl;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.opendaylight.controller.frm.FlowNodeReconciliation;
+import org.opendaylight.controller.frm.ForwardingRulesCommiter;
+import org.opendaylight.controller.frm.ForwardingRulesManager;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
+
+/**
+ * forwardingrules-manager
+ * org.opendaylight.controller.frm.impl
+ *
+ * Manager and middle point for whole module.
+ * It contains ActiveNodeHolder and provide all RPC services.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Aug 25, 2014
+ */
+public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ForwardingRulesManagerImpl.class);
+
+    private final AtomicLong txNum = new AtomicLong();
+    private final Object lockObj = new Object();
+    private Set<InstanceIdentifier<FlowCapableNode>> activeNodes = Collections.emptySet();
+
+    private final DataBroker dataService;
+    private final SalFlowService salFlowService;
+    private final SalGroupService salGroupService;
+    private final SalMeterService salMeterService;
+
+    private ForwardingRulesCommiter<Flow> flowListener;
+    private ForwardingRulesCommiter<Group> groupListener;
+    private ForwardingRulesCommiter<Meter> meterListener;
+    private FlowNodeReconciliation nodeListener;
+
+    public ForwardingRulesManagerImpl(final DataBroker dataBroker,
+            final RpcConsumerRegistry rpcRegistry) {
+        this.dataService = Preconditions.checkNotNull(dataBroker, "DataBroker can not be null!");
+
+        Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
+
+        this.salFlowService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalFlowService.class),
+                "RPC SalFlowService not found.");
+        this.salGroupService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalGroupService.class),
+                "RPC SalGroupService not found.");
+        this.salMeterService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalMeterService.class),
+                "RPC SalMeterService not found.");
+    }
+
+    @Override
+    public void start() {
+        this.flowListener = new FlowForwarder(this, dataService);
+        this.groupListener = new GroupForwarder(this, dataService);
+        this.meterListener = new MeterForwarder(this, dataService);
+        this.nodeListener = new FlowNodeReconciliationImpl(this, dataService);
+        LOG.info("ForwardingRulesManager has started successfull.");
+    }
+
+    @Override
+    public void close() throws Exception {
+        if(this.flowListener != null) {
+            this.flowListener.close();
+            this.flowListener = null;
+        }
+        if (this.groupListener != null) {
+            this.groupListener.close();
+            this.groupListener = null;
+        }
+        if (this.meterListener != null) {
+            this.meterListener.close();
+            this.meterListener = null;
+        }
+        if (this.nodeListener != null) {
+            this.nodeListener.close();
+            this.nodeListener = null;
+        }
+    }
+
+    @Override
+    public ReadOnlyTransaction getReadTranaction() {
+        return dataService.newReadOnlyTransaction();
+    }
+
+    @Override
+    public String getNewTransactionId() {
+        return "DOM-" + txNum.getAndIncrement();
+    }
+
+    @Override
+    public boolean isNodeActive(InstanceIdentifier<FlowCapableNode> ident) {
+        return activeNodes.contains(ident);
+    }
+
+    @Override
+    public void registrateNewNode(InstanceIdentifier<FlowCapableNode> ident) {
+        if ( ! activeNodes.contains(ident)) {
+            synchronized (lockObj) {
+                if ( ! activeNodes.contains(ident)) {
+                    Set<InstanceIdentifier<FlowCapableNode>> set =
+                            Sets.newHashSet(activeNodes);
+                    set.add(ident);
+                    activeNodes = Collections.unmodifiableSet(set);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void unregistrateNode(InstanceIdentifier<FlowCapableNode> ident) {
+        if (activeNodes.contains(ident)) {
+            synchronized (lockObj) {
+                if (activeNodes.contains(ident)) {
+                    Set<InstanceIdentifier<FlowCapableNode>> set =
+                            Sets.newHashSet(activeNodes);
+                    set.remove(ident);
+                    activeNodes = Collections.unmodifiableSet(set);
+                }
+            }
+        }
+    }
+
+    @Override
+    public SalFlowService getSalFlowService() {
+        return salFlowService;
+    }
+
+    @Override
+    public SalGroupService getSalGroupService() {
+        return salGroupService;
+    }
+
+    @Override
+    public SalMeterService getSalMeterService() {
+        return salMeterService;
+    }
+
+    @Override
+    public ForwardingRulesCommiter<Flow> getFlowCommiter() {
+        return flowListener;
+    }
+
+    @Override
+    public ForwardingRulesCommiter<Group> getGroupCommiter() {
+        return groupListener;
+    }
+
+    @Override
+    public ForwardingRulesCommiter<Meter> getMeterCommiter() {
+        return meterListener;
+    }
+
+    @Override
+    public FlowNodeReconciliation getFlowNodeReconciliation() {
+        return nodeListener;
+    }
+}
+
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/GroupForwarder.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/GroupForwarder.java
new file mode 100644 (file)
index 0000000..77ef162
--- /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.frm.impl;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.frm.ForwardingRulesManager;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+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.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * GroupForwarder
+ * It implements {@link org.opendaylight.controller.md.sal.binding.api.DataChangeListener}}
+ * for WildCardedPath to {@link Group} and ForwardingRulesCommiter interface for methods:
+ *  add, update and remove {@link Group} processing for
+ *  {@link org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent}.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class GroupForwarder extends AbstractListeningCommiter<Group> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(GroupForwarder.class);
+
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+
+    public GroupForwarder (final ForwardingRulesManager manager, final DataBroker db) {
+        super(manager, Group.class);
+        Preconditions.checkNotNull(db, "DataBroker can not be null!");
+        this.listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+                getWildCardPath(), GroupForwarder.this, DataChangeScope.BASE);
+    }
+
+    @Override
+    public void close() {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (Exception e) {
+                LOG.error("Error by stop FRM GroupChangeListener.", e);
+            }
+            listenerRegistration = null;
+        }
+    }
+
+    @Override
+    protected InstanceIdentifier<Group> getWildCardPath() {
+        return InstanceIdentifier.create(Nodes.class).child(Node.class)
+                .augmentation(FlowCapableNode.class).child(Group.class);
+    }
+
+    @Override
+    public void remove(final InstanceIdentifier<Group> identifier, final Group removeDataObj,
+                       final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+        final Group group = (removeDataObj);
+        final RemoveGroupInputBuilder builder = new RemoveGroupInputBuilder(group);
+
+        builder.setNode(new NodeRef(nodeIdent));
+        builder.setGroupRef(new GroupRef(identifier));
+        builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+        this.provider.getSalGroupService().removeGroup(builder.build());
+    }
+
+    @Override
+    public void update(final InstanceIdentifier<Group> identifier,
+                       final Group original, final Group update,
+                       final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+        final Group originalGroup = (original);
+        final Group updatedGroup = (update);
+        final UpdateGroupInputBuilder builder = new UpdateGroupInputBuilder();
+
+        builder.setNode(new NodeRef(nodeIdent));
+        builder.setGroupRef(new GroupRef(identifier));
+        builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+        builder.setUpdatedGroup((new UpdatedGroupBuilder(updatedGroup)).build());
+        builder.setOriginalGroup((new OriginalGroupBuilder(originalGroup)).build());
+
+        this.provider.getSalGroupService().updateGroup(builder.build());
+    }
+
+    @Override
+    public void add(final InstanceIdentifier<Group> identifier, final Group addDataObj,
+                    final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+        final Group group = (addDataObj);
+        final AddGroupInputBuilder builder = new AddGroupInputBuilder(group);
+
+        builder.setNode(new NodeRef(nodeIdent));
+        builder.setGroupRef(new GroupRef(identifier));
+        builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+        this.provider.getSalGroupService().addGroup(builder.build());
+    }
+}
+
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/MeterForwarder.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/impl/MeterForwarder.java
new file mode 100644 (file)
index 0000000..9511fb8
--- /dev/null
@@ -0,0 +1,114 @@
+/**
+ * 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.frm.impl;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.frm.ForwardingRulesManager;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+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.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+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.meter.service.rev130918.AddMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * MeterForwarder
+ * It implements {@link org.opendaylight.controller.md.sal.binding.api.DataChangeListener}}
+ * for WildCardedPath to {@link Meter} and ForwardingRulesCommiter interface for methods:
+ *  add, update and remove {@link Meter} processing for
+ *  {@link org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent}.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class MeterForwarder extends AbstractListeningCommiter<Meter> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(MeterForwarder.class);
+
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+
+    public MeterForwarder (final ForwardingRulesManager manager, final DataBroker db) {
+        super(manager, Meter.class);
+        Preconditions.checkNotNull(db, "DataBroker can not be null!");
+        this.listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+                getWildCardPath(), MeterForwarder.this, DataChangeScope.BASE);
+    }
+
+    @Override
+    public void close() {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (Exception e) {
+                LOG.error("Error by stop FRM MeterChangeListener.", e);
+            }
+            listenerRegistration = null;
+        }
+    }
+
+    @Override
+    protected InstanceIdentifier<Meter> getWildCardPath() {
+        return InstanceIdentifier.create(Nodes.class).child(Node.class)
+                .augmentation(FlowCapableNode.class).child(Meter.class);
+    }
+
+    @Override
+    public void remove(final InstanceIdentifier<Meter> identifier, final Meter removeDataObj,
+                       final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+        final RemoveMeterInputBuilder builder = new RemoveMeterInputBuilder(removeDataObj);
+
+        builder.setNode(new NodeRef(nodeIdent));
+        builder.setMeterRef(new MeterRef(identifier));
+        builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+        this.provider.getSalMeterService().removeMeter(builder.build());
+    }
+
+    @Override
+    public void update(final InstanceIdentifier<Meter> identifier,
+                       final Meter original, final Meter update,
+                       final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+        final UpdateMeterInputBuilder builder = new UpdateMeterInputBuilder();
+
+        builder.setNode(new NodeRef(nodeIdent));
+        builder.setMeterRef(new MeterRef(identifier));
+        builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+        builder.setUpdatedMeter((new UpdatedMeterBuilder(update)).build());
+        builder.setOriginalMeter((new OriginalMeterBuilder(original)).build());
+
+        this.provider.getSalMeterService().updateMeter(builder.build());
+    }
+
+    @Override
+    public void add(final InstanceIdentifier<Meter> identifier, final Meter addDataObj,
+                    final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+        final AddMeterInputBuilder builder = new AddMeterInputBuilder(addDataObj);
+
+        builder.setNode(new NodeRef(nodeIdent));
+        builder.setMeterRef(new MeterRef(identifier));
+        builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+        this.provider.getSalMeterService().addMeter(builder.build());
+    }
+}
+
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java
deleted file mode 100644 (file)
index a2def84..0000000
+++ /dev/null
@@ -1,112 +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.frm.meter;
-
-import org.opendaylight.controller.frm.AbstractChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeterBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Meter Change Listener
- *  add, update and remove {@link Meter} processing from {@link org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent}.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- */
-public class MeterChangeListener extends AbstractChangeListener {
-
-    private static final Logger LOG = LoggerFactory.getLogger(MeterChangeListener.class);
-
-    private final MeterProvider provider;
-
-    public MeterChangeListener (final MeterProvider provider) {
-        this.provider = Preconditions.checkNotNull(provider, "MeterProvider can not be null !");
-    }
-
-    @Override
-    protected void remove(final InstanceIdentifier<? extends DataObject> identifier,
-                          final DataObject removeDataObj) {
-
-        final Meter meter = ((Meter) removeDataObj);
-        final InstanceIdentifier<Node> nodeIdent = identifier.firstIdentifierOf(Node.class);
-        final RemoveMeterInputBuilder builder = new RemoveMeterInputBuilder(meter);
-
-        builder.setNode(new NodeRef(nodeIdent));
-        builder.setMeterRef(new MeterRef(identifier));
-
-        Uri uri = new Uri(this.getTransactionId());
-        builder.setTransactionUri(uri);
-        this.provider.getSalMeterService().removeMeter(builder.build());
-        LOG.debug("Transaction {} - Remove Meter has removed meter: {}", new Object[]{uri, removeDataObj});
-    }
-
-    @Override
-    protected void update(final InstanceIdentifier<? extends DataObject> identifier,
-                          final DataObject original, final DataObject update) {
-
-        final Meter originalMeter = ((Meter) original);
-        final Meter updatedMeter = ((Meter) update);
-        final InstanceIdentifier<Node> nodeInstanceId = identifier.firstIdentifierOf(Node.class);
-        final UpdateMeterInputBuilder builder = new UpdateMeterInputBuilder();
-
-        builder.setNode(new NodeRef(nodeInstanceId));
-        builder.setMeterRef(new MeterRef(identifier));
-
-        Uri uri = new Uri(this.getTransactionId());
-        builder.setTransactionUri(uri);
-
-        builder.setUpdatedMeter((new UpdatedMeterBuilder(updatedMeter)).build());
-        builder.setOriginalMeter((new OriginalMeterBuilder(originalMeter)).build());
-
-        this.provider.getSalMeterService().updateMeter(builder.build());
-        LOG.debug("Transaction {} - Update Meter has updated meter {} with {}", new Object[]{uri, original, update});
-
-    }
-
-    @Override
-    protected void add(final InstanceIdentifier<? extends DataObject> identifier,
-                       final DataObject addDataObj) {
-
-        final Meter meter = ((Meter) addDataObj);
-        final InstanceIdentifier<Node> nodeInstanceId = identifier.firstIdentifierOf(Node.class);
-        final AddMeterInputBuilder builder = new AddMeterInputBuilder(meter);
-
-        builder.setNode(new NodeRef(nodeInstanceId));
-        builder.setMeterRef(new MeterRef(identifier));
-
-        Uri uri = new Uri(this.getTransactionId());
-        builder.setTransactionUri(uri);
-        this.provider.getSalMeterService().addMeter(builder.build());
-        LOG.debug("Transaction {} - Add Meter has added meter: {}", new Object[]{uri, addDataObj});
-    }
-
-    @Override
-    protected boolean preconditionForChange(final InstanceIdentifier<? extends DataObject> identifier,
-            final DataObject dataObj, final DataObject update) {
-
-        final ReadOnlyTransaction trans = this.provider.getDataService().newReadOnlyTransaction();
-        return update != null
-                ? (dataObj instanceof Meter && update instanceof Meter && isNodeAvailable(identifier, trans))
-                : (dataObj instanceof Meter && isNodeAvailable(identifier, trans));
-    }
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java
deleted file mode 100644 (file)
index 44de7af..0000000
+++ /dev/null
@@ -1,105 +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.frm.meter;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-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.LogicalDatastoreType;
-import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-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.meter.service.rev130918.SalMeterService;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Meter Provider registers the {@link MeterChangeListener} and it holds all needed
- * services for {@link MeterChangeListener}.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- */
-public class MeterProvider implements AutoCloseable {
-
-    private static final Logger LOG = LoggerFactory.getLogger(MeterProvider.class);
-
-    private SalMeterService salMeterService;
-    private DataBroker dataService;
-
-    /* DataChangeListener */
-    private DataChangeListener meterDataChangeListener;
-    private ListenerRegistration<DataChangeListener> meterDataChangeListenerRegistration;
-
-    /**
-     * Provider Initialization Phase.
-     *
-     * @param DataProviderService dataService
-     */
-    public void init(final DataBroker dataService) {
-        LOG.info("FRM Meter Config Provider initialization.");
-        this.dataService = Preconditions.checkNotNull(dataService, "DataProviderService can not be null !");
-    }
-
-    /**
-     * Listener Registration Phase
-     *
-     * @param RpcConsumerRegistry rpcRegistry
-     */
-    public void start(final RpcConsumerRegistry rpcRegistry) {
-        Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
-        this.salMeterService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalMeterService.class),
-                "RPC SalMeterService not found.");
-
-        /* Build Path */
-        InstanceIdentifier<Meter> meterIdentifier = InstanceIdentifier.create(Nodes.class)
-                .child(Node.class).augmentation(FlowCapableNode.class).child(Meter.class);
-
-        /* DataChangeListener registration */
-        this.meterDataChangeListener = new MeterChangeListener(MeterProvider.this);
-        this.meterDataChangeListenerRegistration =
-                this.dataService.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
-                        meterIdentifier, meterDataChangeListener, DataChangeScope.SUBTREE);
-
-        LOG.info("FRM Meter Config Provider started.");
-    }
-
-    @Override
-    public void close() {
-        LOG.info("FRM Meter Config Provider stopped.");
-        if (meterDataChangeListenerRegistration != null) {
-            try {
-                meterDataChangeListenerRegistration.close();
-            } catch (Exception e) {
-                String errMsg = "Error by stop FRM Meter Config Provider.";
-                LOG.error(errMsg, e);
-                throw new IllegalStateException(errMsg, e);
-            } finally {
-                meterDataChangeListenerRegistration = null;
-            }
-        }
-    }
-
-    public DataChangeListener getMeterDataChangeListener() {
-        return meterDataChangeListener;
-    }
-
-    public DataBroker getDataService() {
-        return dataService;
-    }
-
-    public SalMeterService getSalMeterService() {
-        return salMeterService;
-    }
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/reconil/FlowNodeReconcilListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/reconil/FlowNodeReconcilListener.java
deleted file mode 100644 (file)
index 6308f2a..0000000
+++ /dev/null
@@ -1,196 +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.frm.reconil;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.controller.frm.AbstractChangeListener;
-import org.opendaylight.controller.frm.FlowCookieProducer;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-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.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-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.flow.service.rev130819.AddFlowInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * forwardingrules-manager
- * org.opendaylight.controller.frm
- *
- * FlowNode Reconciliation Listener
- * Reconciliation for a new FlowNode
- * Remove CookieMapKey for removed FlowNode
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- * Created: Jun 13, 2014
- */
-public class FlowNodeReconcilListener extends AbstractChangeListener {
-
-    private static final Logger LOG = LoggerFactory.getLogger(FlowNodeReconcilListener.class);
-
-    private final FlowNodeReconcilProvider provider;
-
-    public FlowNodeReconcilListener(final FlowNodeReconcilProvider provider) {
-        this.provider = Preconditions.checkNotNull(provider, "Flow Node Reconcil Provider can not be null!");
-    }
-
-    @Override
-    public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
-        /* FlowCapableNode DataObjects for reconciliation */
-        final Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries =
-                changeEvent.getCreatedData().entrySet();
-        /* FlowCapableNode DataObjects for clean FlowCookieHolder */
-        final Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers =
-                changeEvent.getRemovedPaths();
-        for (final Entry<InstanceIdentifier<? extends DataObject>, DataObject> createdEntry : createdEntries) {
-            InstanceIdentifier<? extends DataObject> entryKey = createdEntry.getKey();
-            DataObject entryValue = createdEntry.getValue();
-            if (preconditionForChange(entryKey, entryValue, null)) {
-                this.add(entryKey, entryValue);
-            }
-        }
-        for (final InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers) {
-            Map<InstanceIdentifier<? extends DataObject>, DataObject> origConfigData =
-                    changeEvent.getOriginalData();
-            final DataObject removeValue = origConfigData.get(instanceId);
-            if (preconditionForChange(instanceId, removeValue, null)) {
-                this.remove(instanceId, removeValue);
-            }
-        }
-    }
-
-    @Override
-    /* Cleaning FlowCookieManager holder for all node tables */
-    protected void remove(final InstanceIdentifier<? extends DataObject> identifier,
-                          final DataObject removeDataObj) {
-
-        final InstanceIdentifier<FlowCapableNode> flowNodeIdent =
-                identifier.firstIdentifierOf(FlowCapableNode.class);
-        final FlowCapableNode flowNode = ((FlowCapableNode) removeDataObj);
-
-        for (Table flowTable : flowNode.getTable()) {
-            final InstanceIdentifier<Table> tableIdent =
-                    flowNodeIdent.child(Table.class, flowTable.getKey());
-            FlowCookieProducer.INSTANCE.clean(tableIdent);
-        }
-    }
-
-    @Override
-    /* Reconciliation by connect new FlowCapableNode */
-    protected void add(final InstanceIdentifier<? extends DataObject> identifier,
-                       final DataObject addDataObj) {
-
-        final InstanceIdentifier<FlowCapableNode> flowNodeIdent =
-                identifier.firstIdentifierOf(FlowCapableNode.class);
-        final Optional<FlowCapableNode> flowCapNode = this.readFlowCapableNode(flowNodeIdent);
-
-        if (flowCapNode.isPresent()) {
-            final InstanceIdentifier<Node> nodeIdent = identifier.firstIdentifierOf(Node.class);
-            final NodeRef nodeRef = new NodeRef(nodeIdent);
-            /* Groups - have to be first */
-            List<Group> groups = flowCapNode.get().getGroup();
-            if(groups != null) {
-                for (Group group : groups) {
-                    final GroupRef groupRef = new GroupRef(flowNodeIdent.child(Group.class, group.getKey()));
-                    final AddGroupInputBuilder groupBuilder = new AddGroupInputBuilder(group);
-                    groupBuilder.setGroupRef(groupRef);
-                    groupBuilder.setNode(nodeRef);
-                    this.provider.getSalGroupService().addGroup(groupBuilder.build());
-                }
-            }
-            /* Meters */
-            List<Meter> meters = flowCapNode.get().getMeter();
-            if(meters != null) {
-                for (Meter meter : meters) {
-                    final MeterRef meterRef = new MeterRef(flowNodeIdent.child(Meter.class, meter.getKey()));
-                    final AddMeterInputBuilder meterBuilder = new AddMeterInputBuilder(meter);
-                    meterBuilder.setMeterRef(meterRef);
-                    meterBuilder.setNode(nodeRef);
-                    this.provider.getSalMeterService().addMeter(meterBuilder.build());
-                }
-            }
-            /* Flows */
-            List<Table> tables = flowCapNode.get().getTable();
-            if(tables != null) {
-                for (Table flowTable : tables) {
-                    final InstanceIdentifier<Table> tableIdent = flowNodeIdent.child(Table.class, flowTable.getKey());
-                    List<Flow> flows = flowTable.getFlow();
-                    if(flows != null) {
-                        for (Flow flow : flows) {
-                            final FlowCookie flowCookie = new FlowCookie(FlowCookieProducer.INSTANCE.getNewCookie(tableIdent));
-                            final FlowRef flowRef = new FlowRef(tableIdent.child(Flow.class, flow.getKey()));
-                            final FlowTableRef flowTableRef = new FlowTableRef(tableIdent);
-                            final AddFlowInputBuilder flowBuilder = new AddFlowInputBuilder(flow);
-                            flowBuilder.setCookie(flowCookie);
-                            flowBuilder.setNode(nodeRef);
-                            flowBuilder.setFlowTable(flowTableRef);
-                            flowBuilder.setFlowRef(flowRef);
-                            this.provider.getSalFlowService().addFlow(flowBuilder.build());
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    protected void update(final InstanceIdentifier<? extends DataObject> identifier,
-                          final DataObject original, final DataObject update) {
-        // NOOP - Listener is registered for DataChangeScope.BASE only
-    }
-
-    @Override
-    protected boolean preconditionForChange(final InstanceIdentifier<? extends DataObject> identifier,
-                                            final DataObject dataObj, final DataObject update) {
-        return (dataObj instanceof FlowCapableNode);
-    }
-
-    private Optional<FlowCapableNode> readFlowCapableNode(final InstanceIdentifier<FlowCapableNode> flowNodeIdent) {
-        ReadOnlyTransaction readTrans = this.provider.getDataService().newReadOnlyTransaction();
-        try {
-            ListenableFuture<Optional<FlowCapableNode>> confFlowNode =
-                    readTrans.read(LogicalDatastoreType.CONFIGURATION, flowNodeIdent);
-            if (confFlowNode.get().isPresent()) {
-                return Optional.<FlowCapableNode> of(confFlowNode.get().get());
-            } else {
-                return Optional.absent();
-            }
-        }
-        catch (InterruptedException | ExecutionException e) {
-            LOG.error("Unexpected exception by reading flow ".concat(flowNodeIdent.toString()), e);
-            return Optional.absent();
-        }
-        finally {
-            readTrans.close();
-        }
-    }
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/reconil/FlowNodeReconcilProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/reconil/FlowNodeReconcilProvider.java
deleted file mode 100644 (file)
index ad970d6..0000000
+++ /dev/null
@@ -1,115 +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.frm.reconil;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-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.LogicalDatastoreType;
-import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-/**
- * forwardingrules-manager
- * org.opendaylight.controller.frm
- *
- * FlowNode Reconciliation Provider registers the FlowNodeReconilListener
- * and it holds all needed services for FlowNodeReconcilListener.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- * Created: Jun 13, 2014
- */
-public class FlowNodeReconcilProvider implements AutoCloseable {
-
-    private static final Logger LOG = LoggerFactory.getLogger(FlowNodeReconcilProvider.class);
-
-    private SalFlowService salFlowService;
-    private SalMeterService salMeterService;
-    private SalGroupService salGroupService;
-    private DataBroker dataService;
-
-    /* DataChangeListener */
-    private DataChangeListener flowNodeReconcilListener;
-    private ListenerRegistration<DataChangeListener> flowNodeReconcilListenerRegistration;
-
-    public void init (final DataBroker dataService) {
-        LOG.info("FRM Flow Node Config Reconcil Provider initialization.");
-
-        this.dataService = Preconditions.checkNotNull(dataService, "DataProviderService can not be null !");
-    }
-
-    public void start( final RpcConsumerRegistry rpcRegistry ) {
-        Preconditions.checkArgument(rpcRegistry != null, "RpcConcumerRegistry can not be null !");
-
-        this.salFlowService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalFlowService.class),
-                "RPC SalFlowService not found.");
-        this.salMeterService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalMeterService.class),
-                "RPC SalMeterService not found.");
-        this.salGroupService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalGroupService.class),
-                "RPC SalGroupService not found.");
-
-        /* Build Path */
-        InstanceIdentifier<FlowCapableNode> flowCapableNodeIdent =
-                InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class);
-
-        /* ReconcilNotificationListener registration */
-        this.flowNodeReconcilListener = new FlowNodeReconcilListener(FlowNodeReconcilProvider.this);
-        this.flowNodeReconcilListenerRegistration = this.dataService.registerDataChangeListener(
-                LogicalDatastoreType.OPERATIONAL, flowCapableNodeIdent, flowNodeReconcilListener, DataChangeScope.BASE);
-        LOG.info("FRM Flow Node Config Reconcil Provider started.");
-    }
-
-    @Override
-    public void close() {
-        LOG.info("FRM Flow Node Config Reconcil Provider stopped.");
-        if (flowNodeReconcilListenerRegistration != null) {
-            try {
-                flowNodeReconcilListenerRegistration.close();
-            } catch (Exception e) {
-                String errMsg = "Error by stop FRM Flow Node Config Reconcil Provider.";
-                LOG.error(errMsg, e);
-                throw new IllegalStateException(errMsg, e);
-            } finally {
-                flowNodeReconcilListenerRegistration = null;
-            }
-        }
-    }
-
-    public DataChangeListener getFlowNodeReconcilListener() {
-        return flowNodeReconcilListener;
-    }
-
-    public DataBroker getDataService() {
-        return dataService;
-    }
-
-    public SalFlowService getSalFlowService() {
-        return salFlowService;
-    }
-
-    public SalMeterService getSalMeterService() {
-        return salMeterService;
-    }
-
-    public SalGroupService getSalGroupService() {
-        return salGroupService;
-    }
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/FlowListenerTest.java b/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/FlowListenerTest.java
new file mode 100644 (file)
index 0000000..85f4b14
--- /dev/null
@@ -0,0 +1,210 @@
+/**
+ * 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 test.mock;
+
+import org.junit.Test;
+import org.opendaylight.controller.frm.impl.ForwardingRulesManagerImpl;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.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.model.match.types.rev131026.match.IpMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import test.mock.util.FRMTest;
+import test.mock.util.RpcProviderRegistryMock;
+import test.mock.util.SalFlowServiceMock;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class FlowListenerTest extends FRMTest {
+    RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
+    NodeKey s1Key = new NodeKey(new NodeId("S1"));
+    TableKey tableKey = new TableKey((short) 2);
+
+    @Test
+    public void addTwoFlowsTest() throws Exception {
+        ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+        forwardingRulesManager.start();
+
+        addFlowCapableNode(s1Key);
+
+        FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
+        InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
+        InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
+        Table table = new TableBuilder().setKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
+        Flow flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).build();
+
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+        assertCommit(writeTx.submit());
+        SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+        List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
+        assertEquals(1, addFlowCalls.size());
+        assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
+
+        flowKey = new FlowKey(new FlowId("test_Flow2"));
+        flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
+        flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).build();
+        writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+        assertCommit(writeTx.submit());
+        salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+        addFlowCalls = salFlowService.getAddFlowCalls();
+        assertEquals(2, addFlowCalls.size());
+        assertEquals("DOM-1", addFlowCalls.get(1).getTransactionUri().getValue());
+        assertEquals(2, addFlowCalls.get(1).getTableId().intValue());
+        assertEquals(flowII, addFlowCalls.get(1).getFlowRef().getValue());
+
+        forwardingRulesManager.close();
+    }
+
+    @Test
+    public void updateFlowTest() throws Exception {
+        ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+        forwardingRulesManager.start();
+
+        addFlowCapableNode(s1Key);
+
+        FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
+        InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
+        InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
+        Table table = new TableBuilder().setKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
+        Flow flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).build();
+
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+        assertCommit(writeTx.submit());
+        SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+        List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
+        assertEquals(1, addFlowCalls.size());
+        assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
+
+        flowKey = new FlowKey(new FlowId("test_Flow"));
+        flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
+        flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).setOutGroup((long) 5).build();
+        writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+        assertCommit(writeTx.submit());
+        salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+        List<UpdateFlowInput> updateFlowCalls = salFlowService.getUpdateFlowCalls();
+        assertEquals(1, updateFlowCalls.size());
+        assertEquals("DOM-1", updateFlowCalls.get(0).getTransactionUri().getValue());
+        assertEquals(flowII, updateFlowCalls.get(0).getFlowRef().getValue());
+
+        forwardingRulesManager.close();
+    }
+
+    @Test
+    public void updateFlowScopeTest() throws Exception {
+        ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+        forwardingRulesManager.start();
+
+        addFlowCapableNode(s1Key);
+
+        FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
+        InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
+        InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
+        Table table = new TableBuilder().setKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
+        IpMatch ipMatch = new IpMatchBuilder().setIpDscp(new Dscp((short)4)).build();
+        Match match = new MatchBuilder().setIpMatch(ipMatch).build();
+        Flow flow = new FlowBuilder().setMatch(match).setKey(flowKey).setTableId((short) 2).build();
+
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+        assertCommit(writeTx.submit());
+        SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+        List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
+        assertEquals(1, addFlowCalls.size());
+        assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
+
+        flowKey = new FlowKey(new FlowId("test_Flow"));
+        flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
+        ipMatch = new IpMatchBuilder().setIpDscp(new Dscp((short)5)).build();
+        match = new MatchBuilder().setIpMatch(ipMatch).build();
+        flow = new FlowBuilder().setMatch(match).setKey(flowKey).setTableId((short) 2).build();
+        writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+        assertCommit(writeTx.submit());
+        salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+        List<UpdateFlowInput> updateFlowCalls = salFlowService.getUpdateFlowCalls();
+        assertEquals(1, updateFlowCalls.size());
+        assertEquals("DOM-1", updateFlowCalls.get(0).getTransactionUri().getValue());
+        assertEquals(flowII, updateFlowCalls.get(0).getFlowRef().getValue());
+        assertEquals(ipMatch, updateFlowCalls.get(0).getUpdatedFlow().getMatch().getIpMatch());
+        forwardingRulesManager.close();
+    }
+
+    @Test
+    public void deleteFlowTest() throws Exception {
+        ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+        forwardingRulesManager.start();
+
+        addFlowCapableNode(s1Key);
+
+        FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
+        InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
+        InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
+        Table table = new TableBuilder().setKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
+        Flow flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).build();
+
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+        assertCommit(writeTx.submit());
+        SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+        List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
+        assertEquals(1, addFlowCalls.size());
+        assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
+
+        writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.delete(LogicalDatastoreType.CONFIGURATION, flowII);
+        assertCommit(writeTx.submit());
+        salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+        List<RemoveFlowInput> removeFlowCalls = salFlowService.getRemoveFlowCalls();
+        assertEquals(1, removeFlowCalls.size());
+        assertEquals("DOM-1", removeFlowCalls.get(0).getTransactionUri().getValue());
+        assertEquals(flowII, removeFlowCalls.get(0).getFlowRef().getValue());
+
+        forwardingRulesManager.close();
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/GroupListenerTest.java b/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/GroupListenerTest.java
new file mode 100644 (file)
index 0000000..97eb899
--- /dev/null
@@ -0,0 +1,137 @@
+/**
+ * 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 test.mock;
+
+import org.junit.Test;
+import org.opendaylight.controller.frm.impl.ForwardingRulesManagerImpl;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput;
+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.GroupBuilder;
+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.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import test.mock.util.FRMTest;
+import test.mock.util.RpcProviderRegistryMock;
+import test.mock.util.SalGroupServiceMock;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class GroupListenerTest extends FRMTest {
+    RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
+    NodeKey s1Key = new NodeKey(new NodeId("S1"));
+
+    @Test
+    public void addTwoGroupsTest() throws Exception {
+        ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+        forwardingRulesManager.start();
+
+        addFlowCapableNode(s1Key);
+
+        GroupKey groupKey = new GroupKey(new GroupId((long) 255));
+        InstanceIdentifier<Group> groupII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Group.class, groupKey);
+        Group group = new GroupBuilder().setKey(groupKey).setGroupName("Group1").build();
+
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, groupII, group);
+        assertCommit(writeTx.submit());
+        SalGroupServiceMock salGroupService = (SalGroupServiceMock) forwardingRulesManager.getSalGroupService();
+        List<AddGroupInput> addGroupCalls = salGroupService.getAddGroupCalls();
+        assertEquals(1, addGroupCalls.size());
+        assertEquals("DOM-0", addGroupCalls.get(0).getTransactionUri().getValue());
+
+        groupKey = new GroupKey(new GroupId((long) 256));
+        groupII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Group.class, groupKey);
+        group = new GroupBuilder().setKey(groupKey).setGroupName("Group1").build();
+        writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, groupII, group);
+        assertCommit(writeTx.submit());
+        salGroupService = (SalGroupServiceMock) forwardingRulesManager.getSalGroupService();
+        addGroupCalls = salGroupService.getAddGroupCalls();
+        assertEquals(2, addGroupCalls.size());
+        assertEquals("DOM-1", addGroupCalls.get(1).getTransactionUri().getValue());
+
+        forwardingRulesManager.close();
+    }
+
+    @Test
+    public void updateGroupTest() throws Exception {
+        ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+        forwardingRulesManager.start();
+
+        addFlowCapableNode(s1Key);
+
+        GroupKey groupKey = new GroupKey(new GroupId((long) 255));
+        InstanceIdentifier<Group> groupII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Group.class, groupKey);
+        Group group = new GroupBuilder().setKey(groupKey).setGroupName("Group1").build();
+
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, groupII, group);
+        assertCommit(writeTx.submit());
+        SalGroupServiceMock salGroupService = (SalGroupServiceMock) forwardingRulesManager.getSalGroupService();
+        List<AddGroupInput> addGroupCalls = salGroupService.getAddGroupCalls();
+        assertEquals(1, addGroupCalls.size());
+        assertEquals("DOM-0", addGroupCalls.get(0).getTransactionUri().getValue());
+
+        group = new GroupBuilder().setKey(groupKey).setGroupName("Group2").build();
+        writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, groupII, group);
+        assertCommit(writeTx.submit());
+        salGroupService = (SalGroupServiceMock) forwardingRulesManager.getSalGroupService();
+        List<UpdateGroupInput> updateGroupCalls = salGroupService.getUpdateGroupCalls();
+        assertEquals(1, updateGroupCalls.size());
+        assertEquals("DOM-1", updateGroupCalls.get(0).getTransactionUri().getValue());
+
+        forwardingRulesManager.close();
+    }
+
+    @Test
+    public void removeGroupTest() throws Exception {
+        ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+        forwardingRulesManager.start();
+
+        addFlowCapableNode(s1Key);
+
+        GroupKey groupKey = new GroupKey(new GroupId((long) 255));
+        InstanceIdentifier<Group> groupII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Group.class, groupKey);
+        Group group = new GroupBuilder().setKey(groupKey).setGroupName("Group1").build();
+
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, groupII, group);
+        assertCommit(writeTx.submit());
+        SalGroupServiceMock salGroupService = (SalGroupServiceMock) forwardingRulesManager.getSalGroupService();
+        List<AddGroupInput> addGroupCalls = salGroupService.getAddGroupCalls();
+        assertEquals(1, addGroupCalls.size());
+        assertEquals("DOM-0", addGroupCalls.get(0).getTransactionUri().getValue());
+
+        writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.delete(LogicalDatastoreType.CONFIGURATION, groupII);
+        assertCommit(writeTx.submit());
+        salGroupService = (SalGroupServiceMock) forwardingRulesManager.getSalGroupService();
+        List<RemoveGroupInput> removeGroupCalls = salGroupService.getRemoveGroupCalls();
+        assertEquals(1, removeGroupCalls.size());
+        assertEquals("DOM-1", removeGroupCalls.get(0).getTransactionUri().getValue());
+
+        forwardingRulesManager.close();
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/MeterListenerTest.java b/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/MeterListenerTest.java
new file mode 100644 (file)
index 0000000..0d32f9f
--- /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 test.mock;
+
+import org.junit.Test;
+import org.opendaylight.controller.frm.impl.ForwardingRulesManagerImpl;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
+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.meter.service.rev130918.AddMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import test.mock.util.FRMTest;
+import test.mock.util.RpcProviderRegistryMock;
+import test.mock.util.SalMeterServiceMock;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class MeterListenerTest extends FRMTest {
+    RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
+    NodeKey s1Key = new NodeKey(new NodeId("S1"));
+
+    @Test
+    public void addTwoMetersTest() throws Exception {
+        ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+        forwardingRulesManager.start();
+
+        addFlowCapableNode(s1Key);
+
+        MeterKey meterKey = new MeterKey(new MeterId((long) 2000));
+        InstanceIdentifier<Meter> meterII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Meter.class, meterKey);
+        Meter meter = new MeterBuilder().setKey(meterKey).setMeterName("meter_one").build();
+
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, meterII, meter);
+        assertCommit(writeTx.submit());
+        SalMeterServiceMock salMeterService = (SalMeterServiceMock) forwardingRulesManager.getSalMeterService();
+        List<AddMeterInput> addMeterCalls = salMeterService.getAddMeterCalls();
+        assertEquals(1, addMeterCalls.size());
+        assertEquals("DOM-0", addMeterCalls.get(0).getTransactionUri().getValue());
+
+        meterKey = new MeterKey(new MeterId((long) 2001));
+        meterII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Meter.class, meterKey);
+        meter = new MeterBuilder().setKey(meterKey).setMeterName("meter_two").setBarrier(true).build();
+        writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, meterII, meter);
+        assertCommit(writeTx.submit());
+        salMeterService = (SalMeterServiceMock) forwardingRulesManager.getSalMeterService();
+        addMeterCalls = salMeterService.getAddMeterCalls();
+        assertEquals(2, addMeterCalls.size());
+        assertEquals("DOM-1", addMeterCalls.get(1).getTransactionUri().getValue());
+        assertEquals(meterII, addMeterCalls.get(1).getMeterRef().getValue());
+
+        forwardingRulesManager.close();
+    }
+
+    @Test
+    public void updateMeterTest() throws Exception {
+        ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+        forwardingRulesManager.start();
+
+        addFlowCapableNode(s1Key);
+
+        MeterKey meterKey = new MeterKey(new MeterId((long) 2000));
+        InstanceIdentifier<Meter> meterII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Meter.class, meterKey);
+        Meter meter = new MeterBuilder().setKey(meterKey).setMeterName("meter_one").setBarrier(false).build();
+
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, meterII, meter);
+        assertCommit(writeTx.submit());
+        SalMeterServiceMock salMeterService = (SalMeterServiceMock) forwardingRulesManager.getSalMeterService();
+        List<AddMeterInput> addMeterCalls = salMeterService.getAddMeterCalls();
+        assertEquals(1, addMeterCalls.size());
+        assertEquals("DOM-0", addMeterCalls.get(0).getTransactionUri().getValue());
+
+        meter = new MeterBuilder().setKey(meterKey).setMeterName("meter_two").setBarrier(true).build();
+        writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, meterII, meter);
+        assertCommit(writeTx.submit());
+        salMeterService = (SalMeterServiceMock) forwardingRulesManager.getSalMeterService();
+        List<UpdateMeterInput> updateMeterCalls = salMeterService.getUpdateMeterCalls();
+        assertEquals(1, updateMeterCalls.size());
+        assertEquals("DOM-1", updateMeterCalls.get(0).getTransactionUri().getValue());
+        assertEquals(meterII, updateMeterCalls.get(0).getMeterRef().getValue());
+
+        forwardingRulesManager.close();
+    }
+
+    @Test
+    public void removeMeterTest() throws Exception {
+        ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+        forwardingRulesManager.start();
+
+        addFlowCapableNode(s1Key);
+
+        MeterKey meterKey = new MeterKey(new MeterId((long) 2000));
+        InstanceIdentifier<Meter> meterII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class).child(Meter.class, meterKey);
+        Meter meter = new MeterBuilder().setKey(meterKey).setMeterName("meter_one").build();
+
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, meterII, meter);
+        assertCommit(writeTx.submit());
+        SalMeterServiceMock salMeterService = (SalMeterServiceMock) forwardingRulesManager.getSalMeterService();
+        List<AddMeterInput> addMeterCalls = salMeterService.getAddMeterCalls();
+        assertEquals(1, addMeterCalls.size());
+        assertEquals("DOM-0", addMeterCalls.get(0).getTransactionUri().getValue());
+
+        writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.delete(LogicalDatastoreType.CONFIGURATION, meterII);
+        assertCommit(writeTx.submit());
+        salMeterService = (SalMeterServiceMock) forwardingRulesManager.getSalMeterService();
+        List<RemoveMeterInput> removeMeterCalls = salMeterService.getRemoveMeterCalls();
+        assertEquals(1, removeMeterCalls.size());
+        assertEquals("DOM-1", removeMeterCalls.get(0).getTransactionUri().getValue());
+        assertEquals(meterII, removeMeterCalls.get(0).getMeterRef().getValue());
+
+        forwardingRulesManager.close();
+    }
+
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/NodeListenerTest.java b/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/NodeListenerTest.java
new file mode 100644 (file)
index 0000000..3cf2e93
--- /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 test.mock;
+
+import org.junit.Test;
+import org.opendaylight.controller.frm.impl.ForwardingRulesManagerImpl;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+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.yang.binding.InstanceIdentifier;
+import test.mock.util.FRMTest;
+import test.mock.util.RpcProviderRegistryMock;
+
+import java.util.concurrent.ExecutionException;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class NodeListenerTest extends FRMTest {
+
+    RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
+    NodeKey s1Key = new NodeKey(new NodeId("S1"));
+
+    @Test
+    public void addRemoveNodeTest() throws ExecutionException, InterruptedException {
+        ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+        forwardingRulesManager.start();
+
+        addFlowCapableNode(s1Key);
+
+        InstanceIdentifier<FlowCapableNode> nodeII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+                .augmentation(FlowCapableNode.class);
+
+        boolean nodeActive = forwardingRulesManager.isNodeActive(nodeII);
+        assertTrue(nodeActive);
+
+        removeNode(s1Key);
+
+        nodeActive = forwardingRulesManager.isNodeActive(nodeII);
+        assertFalse(nodeActive);
+    }
+
+
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/AbstractDataBrokerTest.java b/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/AbstractDataBrokerTest.java
new file mode 100644 (file)
index 0000000..f9efa51
--- /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 test.mock.util;
+
+import com.google.common.util.concurrent.ListenableFuture;
+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 java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+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/forwardingrules-manager/src/test/java/test/mock/util/AbstractSchemaAwareTest.java b/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/AbstractSchemaAwareTest.java
new file mode 100644 (file)
index 0000000..d520d59
--- /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 test.mock.util;
+
+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/forwardingrules-manager/src/test/java/test/mock/util/DataBrokerTestCustomizer.java b/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/DataBrokerTestCustomizer.java
new file mode 100644 (file)
index 0000000..36ab41f
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * 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 test.mock.util;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import javassist.ClassPool;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+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;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.core.spi.data.DOMStore;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.DataObjectSerializerGenerator;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
+import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class DataBrokerTestCustomizer {
+
+    private DOMDataBroker domDataBroker;
+    private final RuntimeGeneratedMappingServiceImpl mappingService;
+    private final MockSchemaService schemaService;
+    private ImmutableMap<LogicalDatastoreType, DOMStore> datastores;
+    private final BindingToNormalizedNodeCodec bindingToNormalized ;
+
+    public ImmutableMap<LogicalDatastoreType, DOMStore> createDatastores() {
+        return ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
+                .put(LogicalDatastoreType.OPERATIONAL, createOperationalDatastore())
+                .put(LogicalDatastoreType.CONFIGURATION,createConfigurationDatastore())
+                .build();
+    }
+
+    public DataBrokerTestCustomizer() {
+        schemaService = new MockSchemaService();
+        ClassPool pool = ClassPool.getDefault();
+        mappingService = new RuntimeGeneratedMappingServiceImpl(pool);
+        DataObjectSerializerGenerator generator = StreamWriterGenerator.create(JavassistUtils.forClassPool(pool));
+        BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(generator);
+        GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
+        bindingToNormalized = new BindingToNormalizedNodeCodec(loading, mappingService, codecRegistry);
+        schemaService.registerSchemaContextListener(bindingToNormalized);
+    }
+
+    public DOMStore createConfigurationDatastore() {
+        InMemoryDOMDataStore store = new InMemoryDOMDataStore("CFG",
+                MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor());
+        schemaService.registerSchemaContextListener(store);
+        return store;
+    }
+
+    public DOMStore createOperationalDatastore() {
+        InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER",
+                MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor());
+        schemaService.registerSchemaContextListener(store);
+        return store;
+    }
+
+    public DOMDataBroker createDOMDataBroker() {
+        return new DOMDataBrokerImpl(getDatastores(), getCommitCoordinatorExecutor());
+    }
+
+    public ListeningExecutorService getCommitCoordinatorExecutor() {
+        return MoreExecutors.sameThreadExecutor();
+    }
+
+    public DataBroker createDataBroker() {
+        return new ForwardedBindingDataBroker(getDOMDataBroker(), bindingToNormalized, schemaService );
+    }
+
+    public ForwardedBackwardsCompatibleDataBroker createBackwardsCompatibleDataBroker() {
+        return new ForwardedBackwardsCompatibleDataBroker(getDOMDataBroker(), bindingToNormalized, getSchemaService(), MoreExecutors.sameThreadExecutor());
+    }
+
+    private SchemaService getSchemaService() {
+        return schemaService;
+    }
+
+    private DOMDataBroker getDOMDataBroker() {
+        if(domDataBroker == null) {
+            domDataBroker = createDOMDataBroker();
+        }
+        return domDataBroker;
+    }
+
+    private synchronized ImmutableMap<LogicalDatastoreType, DOMStore> getDatastores() {
+        if (datastores == null) {
+            datastores = createDatastores();
+        }
+        return datastores;
+    }
+
+    public void updateSchema(final SchemaContext ctx) {
+        schemaService.changeSchema(ctx);
+        mappingService.onGlobalContextUpdated(ctx);
+    }
+
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/FRMTest.java b/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/FRMTest.java
new file mode 100644 (file)
index 0000000..811d6ca
--- /dev/null
@@ -0,0 +1,42 @@
+package test.mock.util;
+
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.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.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import java.util.Collections;
+import java.util.concurrent.ExecutionException;
+
+public abstract class FRMTest extends AbstractDataBrokerTest{
+
+    public void addFlowCapableNode(NodeKey nodeKey) throws ExecutionException, InterruptedException {
+        Nodes nodes = new NodesBuilder().setNode(Collections.<Node>emptyList()).build();
+        InstanceIdentifier<Node> flowNodeIdentifier = InstanceIdentifier.create(Nodes.class)
+                .child(Node.class, nodeKey);
+
+        FlowCapableNodeBuilder fcnBuilder = new FlowCapableNodeBuilder();
+        NodeBuilder nodeBuilder = new NodeBuilder();
+        nodeBuilder.setKey(nodeKey);
+        nodeBuilder.addAugmentation(FlowCapableNode.class, fcnBuilder.build());
+
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class), nodes);
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, flowNodeIdentifier, nodeBuilder.build());
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Nodes.class), nodes);
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, flowNodeIdentifier, nodeBuilder.build());
+        assertCommit(writeTx.submit());
+    }
+
+    public void removeNode(NodeKey nodeKey) throws ExecutionException, InterruptedException {
+        WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.delete(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class).child(Node.class, nodeKey));
+        writeTx.submit().get();
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/MockSchemaService.java b/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/MockSchemaService.java
new file mode 100644 (file)
index 0000000..b4876a3
--- /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 test.mock.util;
+
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.util.ListenerRegistry;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+
+@SuppressWarnings("deprecation")
+public final class MockSchemaService implements SchemaService, SchemaContextProvider {
+
+    private SchemaContext schemaContext;
+
+    ListenerRegistry<SchemaContextListener> listeners = ListenerRegistry.create();
+
+    @Override
+    public void addModule(final Module module) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public synchronized SchemaContext getGlobalContext() {
+        return schemaContext;
+    }
+
+    @Override
+    public synchronized SchemaContext getSessionContext() {
+        return schemaContext;
+    }
+
+    @Override
+    public ListenerRegistration<SchemaContextListener> registerSchemaContextListener(
+            final SchemaContextListener listener) {
+        return listeners.register(listener);
+    }
+
+    @Override
+    public void removeModule(final Module module) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public synchronized SchemaContext getSchemaContext() {
+        return schemaContext;
+    }
+
+    public synchronized void changeSchema(final SchemaContext newContext) {
+        schemaContext = newContext;
+        for (ListenerRegistration<SchemaContextListener> listener : listeners) {
+            listener.getInstance().onGlobalContextUpdated(schemaContext);
+        }
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/RpcProviderRegistryMock.java b/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/RpcProviderRegistryMock.java
new file mode 100644 (file)
index 0000000..ff17a0c
--- /dev/null
@@ -0,0 +1,42 @@
+package test.mock.util;
+
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+public class RpcProviderRegistryMock implements RpcProviderRegistry {
+    @Override
+    public <T extends RpcService> BindingAwareBroker.RpcRegistration<T> addRpcImplementation(Class<T> serviceInterface, T implementation) throws IllegalStateException {
+        return null;
+    }
+
+    @Override
+    public <T extends RpcService> BindingAwareBroker.RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> serviceInterface, T implementation) throws IllegalStateException {
+        return null;
+    }
+
+    @Override
+    public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(L listener) {
+        return null;
+    }
+
+    @Override
+    public <T extends RpcService> T getRpcService(Class<T> serviceInterface) {
+        if (serviceInterface.equals(SalFlowService.class)) {
+            return (T) new SalFlowServiceMock();
+        } else if (serviceInterface.equals(SalGroupService.class)) {
+            return (T) new SalGroupServiceMock();
+        } else if (serviceInterface.equals(SalMeterService.class)) {
+            return (T) new SalMeterServiceMock();
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/SalFlowServiceMock.java b/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/SalFlowServiceMock.java
new file mode 100644 (file)
index 0000000..4bddc69
--- /dev/null
@@ -0,0 +1,51 @@
+package test.mock.util;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+
+public class SalFlowServiceMock implements SalFlowService{
+    private List<AddFlowInput> addFlowCalls = new ArrayList<>();
+    private List<RemoveFlowInput> removeFlowCalls = new ArrayList<>();
+    private List<UpdateFlowInput> updateFlowCalls = new ArrayList<>();
+
+    @Override
+    public Future<RpcResult<AddFlowOutput>> addFlow(AddFlowInput input) {
+        addFlowCalls.add(input);
+        return null;
+    }
+
+
+    @Override
+    public Future<RpcResult<RemoveFlowOutput>> removeFlow(RemoveFlowInput input) {
+        removeFlowCalls.add(input);
+        return null;
+    }
+
+    @Override
+    public Future<RpcResult<UpdateFlowOutput>> updateFlow(UpdateFlowInput input) {
+        updateFlowCalls.add(input);
+        return null;
+    }
+
+    public List<AddFlowInput> getAddFlowCalls() {
+        return addFlowCalls;
+    }
+
+    public List<RemoveFlowInput> getRemoveFlowCalls() {
+        return removeFlowCalls;
+    }
+
+    public List<UpdateFlowInput> getUpdateFlowCalls() {
+        return updateFlowCalls;
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/SalGroupServiceMock.java b/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/SalGroupServiceMock.java
new file mode 100644 (file)
index 0000000..9fa7b76
--- /dev/null
@@ -0,0 +1,50 @@
+package test.mock.util;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+
+public class SalGroupServiceMock implements SalGroupService {
+    private List<AddGroupInput> addGroupCalls = new ArrayList<>();
+    private List<RemoveGroupInput> removeGroupCalls = new ArrayList<>();
+    private List<UpdateGroupInput> updateGroupCalls = new ArrayList<>();
+
+    @Override
+    public Future<RpcResult<AddGroupOutput>> addGroup(AddGroupInput input) {
+        addGroupCalls.add(input);
+        return null;
+    }
+
+    @Override
+    public Future<RpcResult<RemoveGroupOutput>> removeGroup(RemoveGroupInput input) {
+        removeGroupCalls.add(input);
+        return null;
+    }
+
+    @Override
+    public Future<RpcResult<UpdateGroupOutput>> updateGroup(UpdateGroupInput input) {
+        updateGroupCalls.add(input);
+        return null;
+    }
+
+    public List<AddGroupInput> getAddGroupCalls() {
+        return addGroupCalls;
+    }
+
+    public List<RemoveGroupInput> getRemoveGroupCalls() {
+        return removeGroupCalls;
+    }
+
+    public List<UpdateGroupInput> getUpdateGroupCalls() {
+        return updateGroupCalls;
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/SalMeterServiceMock.java b/opendaylight/md-sal/forwardingrules-manager/src/test/java/test/mock/util/SalMeterServiceMock.java
new file mode 100644 (file)
index 0000000..fb053cb
--- /dev/null
@@ -0,0 +1,50 @@
+package test.mock.util;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+
+public class SalMeterServiceMock implements SalMeterService {
+    private List<AddMeterInput> addMeterCalls = new ArrayList<>();
+    private List<RemoveMeterInput> removeMeterCalls = new ArrayList<>();
+    private List<UpdateMeterInput> updateMeterCalls = new ArrayList<>();
+
+    @Override
+    public Future<RpcResult<AddMeterOutput>> addMeter(AddMeterInput input) {
+        addMeterCalls.add(input);
+        return null;
+    }
+
+    @Override
+    public Future<RpcResult<RemoveMeterOutput>> removeMeter(RemoveMeterInput input) {
+        removeMeterCalls.add(input);
+        return null;
+    }
+
+    @Override
+    public Future<RpcResult<UpdateMeterOutput>> updateMeter(UpdateMeterInput input) {
+        updateMeterCalls.add(input);
+        return null;
+    }
+
+    public List<AddMeterInput> getAddMeterCalls() {
+        return addMeterCalls;
+    }
+
+    public List<RemoveMeterInput> getRemoveMeterCalls() {
+        return removeMeterCalls;
+    }
+
+    public List<UpdateMeterInput> getUpdateMeterCalls() {
+        return updateMeterCalls;
+    }
+}
index c58f6cb..7664a9b 100644 (file)
                 <module>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider">prefix:inmemory-config-datastore-provider</type>
                     <name>config-store-service</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>
+                    <inmemory-config-datastore-provider xmlns="urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider">
+                        <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>
+                    </inmemory-config-datastore-provider>
                 </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>
+                    <inmemory-operational-datastore-provider xmlns="urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider">
+                        <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>
+                    </inmemory-operational-datastore-provider>
                 </module>
                 <!--
                      Tree-based in-memory data store. This is the data store which is currently
index 084ef16..325005b 100644 (file)
@@ -11,9 +11,9 @@
 
   <dependencies>
     <dependency>
-      <groupId>com.google.protobuf</groupId>
-      <artifactId>protobuf-java</artifactId>
-      <version>2.5.0</version>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-clustering-commons</artifactId>
+      <version>1.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>com.google.guava</groupId>
index 560d5fc..db3e683 100644 (file)
@@ -9,9 +9,9 @@
 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.protobuff.messages.cluster.example.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.cluster.raft.AppendEntriesMessages;
 
 import java.io.Serializable;
 import java.util.HashMap;
index 94366ef..6665d75 100644 (file)
@@ -12,7 +12,7 @@ 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 org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages;
 
 import java.util.ArrayList;
 import java.util.Iterator;
index 9a251cd..502c338 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.cluster.raft.protobuff.client.messages;
 
 
 import com.google.protobuf.GeneratedMessage;
-import org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages;
+import org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages;
 
 import java.util.Map;
 
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
deleted file mode 100644 (file)
index 5b3bd2b..0000000
+++ /dev/null
@@ -1,767 +0,0 @@
-// 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/VotingMessages.proto b/opendaylight/md-sal/sal-akka-raft/src/main/resources/VotingMessages.proto
deleted file mode 100644 (file)
index 6a45a2b..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-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;
-
-}
index 70671a6..ea3c9e7 100644 (file)
@@ -16,8 +16,8 @@ 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 org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages;
+import org.opendaylight.controller.protobuff.messages.cluster.raft.test.MockPayloadMessages;
 import com.google.common.base.Preconditions;
 
 import java.io.Serializable;
index ab6d56c..6be5f2d 100644 (file)
@@ -3,6 +3,12 @@ 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 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;
+
 import java.lang.ref.WeakReference;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
@@ -21,13 +27,13 @@ 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.util.ClassLoaderUtils;
 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;
@@ -35,12 +41,6 @@ import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMapping
 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);
@@ -65,8 +65,8 @@ class DomToBindingRpcForwarder implements RpcImplementation, InvocationHandler {
     static {
         try {
             EQUALS_METHOD = Object.class.getMethod("equals", Object.class);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
+        } catch (NoSuchMethodException | SecurityException e) {
+            throw new ExceptionInInitializerError(e);
         }
     }
 
@@ -94,7 +94,7 @@ class DomToBindingRpcForwarder implements RpcImplementation, InvocationHandler {
     }
 
     /**
-     * Constructor for Routed RPC Forwareder.
+     * Constructor for Routed RPC Forwarder.
      *
      * @param service
      * @param context
index 4419d19..b8980cd 100644 (file)
 
   <packaging>bundle</packaging>
 
-  <dependencies>
+    <dependencies>
+
+    <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.scala-lang</groupId>
+        <artifactId>scala-library</artifactId>
+    </dependency>
+
+
+    <dependency>
+        <groupId>com.typesafe.akka</groupId>
+        <artifactId>akka-slf4j_${scala.version}</artifactId>
+    </dependency>
+
+
     <dependency>
       <groupId>com.google.code.findbugs</groupId>
       <artifactId>jsr305</artifactId>
       <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>
           <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>jsr305</artifactId>
           <version>2.0.1</version>
       </dependency>
-
       <dependency>
           <groupId>com.codahale.metrics</groupId>
           <artifactId>metrics-core</artifactId>
-          <version>3.0.1</version>
+      </dependency>
+      <dependency>
+          <groupId>com.codahale.metrics</groupId>
+          <artifactId>metrics-graphite</artifactId>
       </dependency>
   </dependencies>
+  <build>
+      <plugins>
+          <plugin>
+              <groupId>org.jacoco</groupId>
+              <artifactId>jacoco-maven-plugin</artifactId>
+              <configuration>
+                  <includes>
+                      <include>org.opendaylight.controller.*</include>
+                  </includes>
+                  <excludes>
+                      <exclude>org.opendaylight.controller.protobuff.*</exclude>
+                  </excludes>
+                  <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>
+      </plugins>
+  </build>
 
 </project>
index d1ae264..4e76e37 100644 (file)
@@ -10,9 +10,9 @@
 
 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.controller.cluster.datastore.node.utils.serialization.NormalizedNodeSerializer;
+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;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -29,45 +29,27 @@ public class NormalizedNodeToNodeCodec {
     }
 
     public NormalizedNodeMessages.Container encode(YangInstanceIdentifier id, NormalizedNode node){
+
+        NormalizedNodeMessages.Container.Builder builder = NormalizedNodeMessages.Container.newBuilder();
         String parentPath = "";
 
         if(id != null){
             parentPath = PathUtils.getParentPath(PathUtils.toString(id));
         }
 
+        builder.setParentPath(parentPath);
+        if(node != null) {
+            builder.setNormalizedNode(NormalizedNodeSerializer.serialize(node));
+        }
 
-        NormalizedNodeToProtocolBufferNode encoder = new NormalizedNodeToProtocolBufferNode();
-        encoder.encode(parentPath, node);
-
-        return encoder.getContainer();
-
-
+        return builder.build();
     }
 
     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;
-            }
+        if(node.getIntType() < 0 || node.getSerializedSize() == 0){
+            return null;
+        }
+        return NormalizedNodeSerializer.deSerialize(node);
     }
 
 
diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/NormalizedNodeDeSerializationContext.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/NormalizedNodeDeSerializationContext.java
new file mode 100644 (file)
index 0000000..0ed1317
--- /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.datastore.node.utils.serialization;
+
+/**
+ * NormalizedNodeDeSerializationContext provides methods which help in decoding
+ * certain components of a NormalizedNode properly
+ */
+
+public interface NormalizedNodeDeSerializationContext {
+    String getNamespace(int namespace);
+    String getRevision(int revision);
+    String getLocalName(int localName);
+}
diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/NormalizedNodeSerializationContext.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/NormalizedNodeSerializationContext.java
new file mode 100644 (file)
index 0000000..660bc28
--- /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.datastore.node.utils.serialization;
+
+import java.net.URI;
+import java.util.Date;
+
+/**
+ * NormalizedNodeSerializationContext provides methods which help in encoding
+ * certain components of a NormalizedNode properly
+ */
+public interface NormalizedNodeSerializationContext {
+    int addNamespace(URI namespace);
+    int addRevision(Date revision);
+    int addLocalName(String localName);
+}
diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/NormalizedNodeSerializer.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/NormalizedNodeSerializer.java
new file mode 100644 (file)
index 0000000..3e1bd35
--- /dev/null
@@ -0,0 +1,551 @@
+/*
+ * 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.utils.serialization;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+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.DataContainerChild;
+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.OrderedMapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+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.DataContainerNodeAttrBuilder;
+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.NormalizedNodeAttrBuilder;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.ANY_XML_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.AUGMENTATION_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.CHOICE_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.CONTAINER_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.LEAF_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.LEAF_SET_ENTRY_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.LEAF_SET_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.MAP_ENTRY_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.MAP_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.ORDERED_LEAF_SET_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.ORDERED_MAP_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.UNKEYED_LIST_ENTRY_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.UNKEYED_LIST_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.getSerializableNodeType;
+
+/**
+ * NormalizedNodeSerializer can be used to convert a Normalized node to and and
+ * from a protocol buffer message.
+ *
+ *
+ */
+public class NormalizedNodeSerializer {
+
+    /**
+     * Serialize a NormalizedNode into a protocol buffer message
+     * <p>
+     * The significant things to be aware of the Serialization process are
+     * <ul>
+     *     <li>Repeated strings like namespaces, revisions and localNames are
+     *     compressed to codes and stored in the top level of the normalized
+     *     node protocol buffer message
+     *     </li>
+     *     <li>All value types are encoded for each leaf value. This is so that
+     *     the deSerialization process does not need to use the schema context to
+     *     figure out how to decode values
+     *     </li>
+     * </ul>
+     *
+     * One question which may arise is why not use something like gzip to
+     * compress the protocol buffer message instead of rolling our own
+     * encoding scheme. This has to be explored further as it is a more
+     * general solution.
+     *
+     * @param node
+     * @return
+     */
+    public static NormalizedNodeMessages.Node serialize(NormalizedNode node){
+        Preconditions.checkNotNull(node, "node should not be null");
+        return new Serializer(node).serialize();
+    }
+
+
+    /**
+     * DeSerialize a protocol buffer message back into a NormalizedNode
+     *
+     * @param node
+     * @return
+     */
+    public static NormalizedNode deSerialize(NormalizedNodeMessages.Node node){
+        return new DeSerializer(node).deSerialize();
+    }
+
+    /**
+     * DeSerialize a PathArgument which is in the protocol buffer format into
+     * a yang PathArgument. The protocol buffer path argument is specially
+     * encoded and can only be interpreted in the context of a top level
+     * serialized NormalizedNode protocol buffer message. The reason for this
+     * is that during the NormalizedNode serialization process certain repeated
+     * strings are encoded into a "codes" list and the actual strings are
+     * replaced by an integer which is an index into that list.
+     *
+     * @param node
+     * @param pathArgument
+     * @return
+     */
+    public static YangInstanceIdentifier.PathArgument deSerialize(NormalizedNodeMessages.Node node, NormalizedNodeMessages.PathArgument pathArgument){
+        Preconditions.checkNotNull(node, "node should not be null");
+        Preconditions.checkNotNull(pathArgument, "pathArgument should not be null");
+        return new DeSerializer(node).deSerialize(pathArgument);
+    }
+
+    private static class Serializer implements NormalizedNodeSerializationContext {
+
+        private final NormalizedNode node;
+
+        private final Map<Object, Integer> codeMap = new HashMap<>();
+        private final List<String> codes = new ArrayList<>();
+
+        private Serializer(NormalizedNode node) {
+            this.node = node;
+        }
+
+        private NormalizedNodeMessages.Node serialize() {
+            return this.serialize(node).addAllCode(codes).build();
+        }
+
+        private NormalizedNodeMessages.Node.Builder serialize(
+            NormalizedNode node) {
+            NormalizedNodeMessages.Node.Builder builder =
+                NormalizedNodeMessages.Node.newBuilder();
+
+            builder.setPathArgument(PathArgumentSerializer.serialize(this, node.getIdentifier()));
+            Integer nodeType = getSerializableNodeType(node).ordinal();
+            builder.setIntType(nodeType);
+            Object value = node.getValue();
+
+            // We need to do a specific check of the type of the node here
+            // because if we looked at the value type alone we will not be
+            // able to distinguish if the value was supposed to be added
+            // as a child or whether the value should be added as a value of the
+            // node.
+            // One use case where this check is necessary when you have a node
+            // with a bits value. In that case the value of the node is a Set
+            // which is also a Collection. Without the following check being
+            // done first the code would flow into the Collection if condition
+            // and the Set would be added as child nodes
+            if(nodeType == NormalizedNodeType.LEAF_NODE_TYPE.ordinal() ||
+               nodeType == NormalizedNodeType.LEAF_SET_ENTRY_NODE_TYPE.ordinal()){
+
+                ValueSerializer.serialize(builder, this, value);
+
+            } else if (value instanceof Iterable) {
+                Iterable iterable = (Iterable) value;
+
+                for (Object o : iterable) {
+                    if (o instanceof NormalizedNode) {
+                        builder.addChild(serialize((NormalizedNode) o));
+                    }
+                }
+
+            } else if (value instanceof NormalizedNode) {
+
+                builder.addChild(serialize((NormalizedNode) value));
+
+            } else {
+
+                ValueSerializer.serialize(builder, this, value);
+            }
+
+            return builder;
+        }
+
+
+        @Override public int addNamespace(URI namespace) {
+            int namespaceInt = getCode(namespace);
+
+            if(namespaceInt == -1) {
+                namespaceInt = addCode(namespace, namespace.toString());
+            }
+            return namespaceInt;
+        }
+
+        @Override public int addRevision(Date revision) {
+            if(revision == null){
+                return -1;
+            }
+
+            int revisionInt = getCode(revision);
+            if(revisionInt == -1) {
+                String formattedRevision =
+                    SimpleDateFormatUtil.getRevisionFormat().format(revision);
+                revisionInt = addCode(revision, formattedRevision);
+            }
+            return revisionInt;
+        }
+
+        @Override public int addLocalName(String localName) {
+            int localNameInt = getCode(localName);
+            if(localNameInt == -1) {
+                localNameInt = addCode(localName, localName.toString());
+            }
+            return localNameInt;
+
+        }
+
+        public int addCode(Object code, String codeStr){
+            int count = codes.size();
+            codes.add(codeStr);
+            codeMap.put(code, Integer.valueOf(count));
+            return count;
+        }
+
+        public int getCode(Object code){
+            if(codeMap.containsKey(code)){
+                return codeMap.get(code);
+            }
+            return -1;
+        }
+    }
+
+    private static class DeSerializer implements NormalizedNodeDeSerializationContext {
+        private static Map<NormalizedNodeType, DeSerializationFunction>
+            deSerializationFunctions = new HashMap<>();
+
+        static {
+            deSerializationFunctions.put(CONTAINER_NODE_TYPE,
+                new DeSerializationFunction() {
+                    @Override public NormalizedNode apply(
+                        DeSerializer deSerializer,
+                        NormalizedNodeMessages.Node node) {
+                        DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode>
+                            builder = Builders.containerBuilder();
+
+                        builder
+                            .withNodeIdentifier(deSerializer.toNodeIdentifier(
+                                node.getPathArgument()));
+
+                        return deSerializer.buildDataContainer(builder, node);
+
+                    }
+
+                });
+
+            deSerializationFunctions.put(LEAF_NODE_TYPE,
+                new DeSerializationFunction() {
+                    @Override public NormalizedNode apply(
+                        DeSerializer deSerializer,
+                        NormalizedNodeMessages.Node node) {
+                        NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, Object, LeafNode<Object>>
+                            builder = Builders.leafBuilder();
+
+                        builder
+                            .withNodeIdentifier(deSerializer.toNodeIdentifier(
+                                node.getPathArgument()));
+
+                        return deSerializer.buildNormalizedNode(builder, node);
+
+                    }
+                });
+
+            deSerializationFunctions.put(MAP_NODE_TYPE,
+                new DeSerializationFunction() {
+                    @Override public NormalizedNode apply(
+                        DeSerializer deSerializer,
+                        NormalizedNodeMessages.Node node) {
+                        CollectionNodeBuilder<MapEntryNode, MapNode>
+                            builder = Builders.mapBuilder();
+
+                        return deSerializer.buildCollectionNode(builder, node);
+                    }
+                });
+
+            deSerializationFunctions.put(MAP_ENTRY_NODE_TYPE,
+                new DeSerializationFunction() {
+                    @Override public NormalizedNode apply(
+                        DeSerializer deSerializer,
+                        NormalizedNodeMessages.Node node) {
+                        DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode>
+                            builder = Builders.mapEntryBuilder();
+
+                        builder.withNodeIdentifier(deSerializer.toNodeIdentifierWithPredicates(
+                            node.getPathArgument()));
+
+                        return deSerializer.buildDataContainer(builder, node);
+                    }
+                });
+
+            deSerializationFunctions.put(AUGMENTATION_NODE_TYPE,
+                new DeSerializationFunction() {
+                    @Override public NormalizedNode apply(
+                        DeSerializer deSerializer,
+                        NormalizedNodeMessages.Node node) {
+                        DataContainerNodeBuilder<YangInstanceIdentifier.AugmentationIdentifier, AugmentationNode>
+                            builder = Builders.augmentationBuilder();
+
+                        builder.withNodeIdentifier(
+                            deSerializer.toAugmentationIdentifier(
+                                node.getPathArgument()));
+
+                        return deSerializer.buildDataContainer(builder, node);
+                    }
+                });
+
+            deSerializationFunctions.put(LEAF_SET_NODE_TYPE,
+                new DeSerializationFunction() {
+                    @Override public NormalizedNode apply(
+                        DeSerializer deSerializer,
+                        NormalizedNodeMessages.Node node) {
+                        ListNodeBuilder<Object, LeafSetEntryNode<Object>>
+                            builder = Builders.leafSetBuilder();
+
+                        return deSerializer.buildListNode(builder, node);
+                    }
+                });
+
+            deSerializationFunctions.put(LEAF_SET_ENTRY_NODE_TYPE,
+                new DeSerializationFunction() {
+                    @Override public NormalizedNode apply(
+                        DeSerializer deSerializer,
+                        NormalizedNodeMessages.Node node) {
+                        NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeWithValue, Object, LeafSetEntryNode<Object>>
+                            builder = Builders.leafSetEntryBuilder();
+
+                        builder.withNodeIdentifier(deSerializer.toNodeWithValue(
+                            node.getPathArgument()));
+
+                        return deSerializer.buildNormalizedNode(builder, node);
+                    }
+                });
+
+            deSerializationFunctions.put(CHOICE_NODE_TYPE,
+                new DeSerializationFunction() {
+                    @Override public NormalizedNode apply(
+                        DeSerializer deSerializer,
+                        NormalizedNodeMessages.Node node) {
+                        DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ChoiceNode>
+                            builder =
+                            Builders.choiceBuilder();
+
+                        builder
+                            .withNodeIdentifier(deSerializer.toNodeIdentifier(
+                                node.getPathArgument()));
+
+                        return deSerializer.buildDataContainer(builder, node);
+                    }
+                });
+
+            deSerializationFunctions.put(ORDERED_LEAF_SET_NODE_TYPE,
+                new DeSerializationFunction() {
+                    @Override public NormalizedNode apply(
+                        DeSerializer deSerializer,
+                        NormalizedNodeMessages.Node node) {
+                        ListNodeBuilder<Object, LeafSetEntryNode<Object>>
+                            builder =
+                            Builders.orderedLeafSetBuilder();
+
+                        return deSerializer.buildListNode(builder, node);
+
+
+                    }
+                });
+
+            deSerializationFunctions.put(ORDERED_MAP_NODE_TYPE,
+                new DeSerializationFunction() {
+                    @Override public NormalizedNode apply(
+                        DeSerializer deSerializer,
+                        NormalizedNodeMessages.Node node) {
+                        CollectionNodeBuilder<MapEntryNode, OrderedMapNode>
+                            builder =
+                            Builders.orderedMapBuilder();
+
+                        return deSerializer.buildCollectionNode(builder, node);
+                    }
+                });
+
+            deSerializationFunctions.put(UNKEYED_LIST_NODE_TYPE,
+                new DeSerializationFunction() {
+                    @Override public NormalizedNode apply(
+                        DeSerializer deSerializer,
+                        NormalizedNodeMessages.Node node) {
+                        CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode>
+                            builder =
+                            Builders.unkeyedListBuilder();
+
+                        return deSerializer.buildCollectionNode(builder, node);
+                    }
+                });
+
+            deSerializationFunctions.put(UNKEYED_LIST_ENTRY_NODE_TYPE,
+                new DeSerializationFunction() {
+                    @Override public NormalizedNode apply(
+                        DeSerializer deSerializer,
+                        NormalizedNodeMessages.Node node) {
+                        DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, UnkeyedListEntryNode>
+                            builder =
+                            Builders.unkeyedListEntryBuilder();
+
+                        builder
+                            .withNodeIdentifier(deSerializer.toNodeIdentifier(
+                                node.getPathArgument()));
+
+                        return deSerializer.buildDataContainer(builder, node);
+                    }
+                });
+
+            deSerializationFunctions.put(ANY_XML_NODE_TYPE,
+                new DeSerializationFunction() {
+
+                    @Override public NormalizedNode apply(
+                        DeSerializer deSerializer,
+                        NormalizedNodeMessages.Node node) {
+                        NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, Node<?>, AnyXmlNode>
+                            builder =
+                            Builders.anyXmlBuilder();
+
+                        builder
+                            .withNodeIdentifier(deSerializer.toNodeIdentifier(
+                                node.getPathArgument()));
+
+                        return deSerializer.buildNormalizedNode(builder, node);
+                    }
+                });
+
+        }
+
+        private final NormalizedNodeMessages.Node node;
+
+        public DeSerializer(NormalizedNodeMessages.Node node){
+            this.node = node;
+        }
+
+        public NormalizedNode deSerialize(){
+            return deSerialize(node);
+        }
+
+        private NormalizedNode deSerialize(NormalizedNodeMessages.Node node){
+            Preconditions.checkNotNull(node, "node should not be null");
+            DeSerializationFunction deSerializationFunction =
+                Preconditions.checkNotNull(deSerializationFunctions.get(NormalizedNodeType.values()[node.getIntType()]), "Unknown type " + node);
+
+            return deSerializationFunction.apply(this, node);
+        }
+
+
+        private NormalizedNode buildCollectionNode(
+            CollectionNodeBuilder builder,
+            NormalizedNodeMessages.Node node) {
+
+            builder.withNodeIdentifier(toNodeIdentifier(node.getPathArgument()));
+
+            for(NormalizedNodeMessages.Node child : node.getChildList()){
+                builder.withChild(deSerialize(child));
+            }
+
+            return builder.build();
+        }
+
+
+        private NormalizedNode buildListNode(
+            ListNodeBuilder<Object, LeafSetEntryNode<Object>> builder,
+            NormalizedNodeMessages.Node node) {
+            builder.withNodeIdentifier(toNodeIdentifier(node.getPathArgument()));
+
+            for(NormalizedNodeMessages.Node child : node.getChildList()){
+                builder.withChild((LeafSetEntryNode<Object>) deSerialize(child));
+            }
+
+            return builder.build();
+        }
+
+        private NormalizedNode buildDataContainer(DataContainerNodeBuilder builder, NormalizedNodeMessages.Node node){
+
+            for(NormalizedNodeMessages.Node child : node.getChildList()){
+                builder.withChild((DataContainerChild<?, ?>) deSerialize(child));
+            }
+
+            //TODO : Also handle attributes
+
+            return builder.build();
+        }
+
+        private NormalizedNode buildNormalizedNode(NormalizedNodeAttrBuilder builder, NormalizedNodeMessages.Node node){
+
+            builder.withValue(ValueSerializer.deSerialize(this, node));
+
+            //TODO : Also handle attributes
+
+            return builder.build();
+
+        }
+
+
+        private YangInstanceIdentifier.NodeIdentifierWithPredicates toNodeIdentifierWithPredicates(
+            NormalizedNodeMessages.PathArgument path) {
+            return (YangInstanceIdentifier.NodeIdentifierWithPredicates) PathArgumentSerializer.deSerialize(this, path);
+        }
+
+        private YangInstanceIdentifier.AugmentationIdentifier toAugmentationIdentifier(
+            NormalizedNodeMessages.PathArgument path) {
+            return (YangInstanceIdentifier.AugmentationIdentifier) PathArgumentSerializer.deSerialize(this, path);
+        }
+
+        private YangInstanceIdentifier.NodeWithValue toNodeWithValue(
+            NormalizedNodeMessages.PathArgument path) {
+            return (YangInstanceIdentifier.NodeWithValue) PathArgumentSerializer.deSerialize(
+                this, path);
+        }
+
+        private YangInstanceIdentifier.NodeIdentifier toNodeIdentifier(NormalizedNodeMessages.PathArgument path){
+            return (YangInstanceIdentifier.NodeIdentifier) PathArgumentSerializer.deSerialize(
+                this, path);
+        }
+
+        @Override public String getNamespace(int namespace) {
+            return node.getCode(namespace);
+        }
+
+        @Override public String getRevision(int revision) {
+            return node.getCode(revision);
+        }
+
+        @Override public String getLocalName(int localName) {
+            return node.getCode(localName);
+        }
+
+        public YangInstanceIdentifier.PathArgument deSerialize(
+            NormalizedNodeMessages.PathArgument pathArgument) {
+            return PathArgumentSerializer.deSerialize(this, pathArgument);
+        }
+
+        private static interface DeSerializationFunction {
+            NormalizedNode apply(DeSerializer deserializer, NormalizedNodeMessages.Node node);
+        }
+    }
+
+
+
+
+}
diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/NormalizedNodeType.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/NormalizedNodeType.java
new file mode 100644 (file)
index 0000000..eebd580
--- /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.datastore.node.utils.serialization;
+
+import com.google.common.base.Preconditions;
+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.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedLeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+
+public enum NormalizedNodeType {
+    CONTAINER_NODE_TYPE,
+    LEAF_NODE_TYPE,
+    MAP_NODE_TYPE,
+    MAP_ENTRY_NODE_TYPE,
+    AUGMENTATION_NODE_TYPE,
+    LEAF_SET_NODE_TYPE,
+    LEAF_SET_ENTRY_NODE_TYPE,
+    CHOICE_NODE_TYPE,
+    ORDERED_LEAF_SET_NODE_TYPE,
+    ORDERED_MAP_NODE_TYPE,
+    UNKEYED_LIST_NODE_TYPE,
+    UNKEYED_LIST_ENTRY_NODE_TYPE,
+    ANY_XML_NODE_TYPE;
+
+    public static NormalizedNodeType getSerializableNodeType(NormalizedNode node){
+        Preconditions.checkNotNull(node, "node should not be null");
+
+        if(node instanceof ContainerNode){
+            return CONTAINER_NODE_TYPE;
+        } else if(node instanceof LeafNode){
+            return LEAF_NODE_TYPE;
+        } else if(node instanceof MapNode){
+            return MAP_NODE_TYPE;
+        } else if(node instanceof MapEntryNode){
+            return MAP_ENTRY_NODE_TYPE;
+        } else if(node instanceof AugmentationNode){
+            return AUGMENTATION_NODE_TYPE;
+        } else if(node instanceof LeafSetNode){
+            return LEAF_SET_NODE_TYPE;
+        } else if(node instanceof LeafSetEntryNode){
+            return LEAF_SET_ENTRY_NODE_TYPE;
+        } else if(node instanceof ChoiceNode){
+            return CHOICE_NODE_TYPE;
+        } else if(node instanceof OrderedLeafSetNode){
+            return ORDERED_LEAF_SET_NODE_TYPE;
+        } else if(node instanceof OrderedMapNode){
+            return ORDERED_MAP_NODE_TYPE;
+        } else if(node instanceof UnkeyedListNode){
+            return UNKEYED_LIST_NODE_TYPE;
+        } else if(node instanceof UnkeyedListEntryNode){
+            return UNKEYED_LIST_ENTRY_NODE_TYPE;
+        } else if(node instanceof AnyXmlNode){
+            return ANY_XML_NODE_TYPE;
+        }
+        throw new IllegalArgumentException("Node type unknown : " + node.getClass().getSimpleName());
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/PathArgumentSerializer.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/PathArgumentSerializer.java
new file mode 100644 (file)
index 0000000..d7627c0
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * 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.utils.serialization;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.cluster.datastore.node.utils.NodeIdentifierFactory;
+import org.opendaylight.controller.cluster.datastore.node.utils.QNameFactory;
+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.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.PathArgumentType.getSerializablePathArgumentType;
+
+public class PathArgumentSerializer {
+    private static final Map<Class, PathArgumentAttributesGetter> pathArgumentAttributesGetters = new HashMap<>();
+
+    public static NormalizedNodeMessages.PathArgument serialize(NormalizedNodeSerializationContext context, YangInstanceIdentifier.PathArgument pathArgument){
+        Preconditions.checkNotNull(context, "context should not be null");
+        Preconditions.checkNotNull(pathArgument, "pathArgument should not be null");
+
+        QName nodeType = null;
+        if (!(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier)) {
+            nodeType = pathArgument.getNodeType();
+        }
+
+        NormalizedNodeMessages.PathArgument.Builder builder =
+            NormalizedNodeMessages.PathArgument.newBuilder();
+
+        NormalizedNodeMessages.PathArgument serializablePathArgument =
+            builder
+                .setIntType(getSerializablePathArgumentType(pathArgument))
+                .setNodeType(encodeQName(context, nodeType))
+                .addAllAttribute(getPathArgumentAttributes(context, pathArgument))
+                .build();
+
+        return serializablePathArgument;
+    }
+
+
+    public static YangInstanceIdentifier.PathArgument deSerialize(NormalizedNodeDeSerializationContext context, NormalizedNodeMessages.PathArgument pathArgument){
+        Preconditions.checkNotNull(context, "context should not be null");
+        Preconditions.checkNotNull(pathArgument, "pathArgument should not be null");
+
+        return parsePathArgument(context, pathArgument);
+    }
+
+
+    private static interface PathArgumentAttributesGetter {
+        Iterable<? extends NormalizedNodeMessages.PathArgumentAttribute> get(NormalizedNodeSerializationContext context,
+            YangInstanceIdentifier.PathArgument pathArgument);
+    }
+
+    static {
+        pathArgumentAttributesGetters.put(YangInstanceIdentifier.NodeWithValue.class, new PathArgumentAttributesGetter() {
+            @Override
+            public Iterable<? extends NormalizedNodeMessages.PathArgumentAttribute> get(
+                NormalizedNodeSerializationContext context,
+                YangInstanceIdentifier.PathArgument pathArgument) {
+                List<NormalizedNodeMessages.PathArgumentAttribute> attributes =
+                    new ArrayList<>();
+
+                YangInstanceIdentifier.NodeWithValue identifier
+                    = (YangInstanceIdentifier.NodeWithValue) pathArgument;
+
+                NormalizedNodeMessages.PathArgumentAttribute attribute =
+                    buildAttribute(context, null, identifier.getValue());
+
+                attributes.add(attribute);
+
+                return attributes;
+
+            }
+        });
+
+        pathArgumentAttributesGetters.put(YangInstanceIdentifier.NodeIdentifierWithPredicates.class, new PathArgumentAttributesGetter() {
+            @Override
+            public Iterable<? extends NormalizedNodeMessages.PathArgumentAttribute> get(
+                NormalizedNodeSerializationContext context,
+                YangInstanceIdentifier.PathArgument pathArgument) {
+
+                List<NormalizedNodeMessages.PathArgumentAttribute> attributes =
+                    new ArrayList<>();
+
+                YangInstanceIdentifier.NodeIdentifierWithPredicates identifier
+                    = (YangInstanceIdentifier.NodeIdentifierWithPredicates) pathArgument;
+
+                for (QName key : identifier.getKeyValues().keySet()) {
+                    Object value = identifier.getKeyValues().get(key);
+                    NormalizedNodeMessages.PathArgumentAttribute attribute =
+                        buildAttribute(context, key, value);
+
+                    attributes.add(attribute);
+
+                }
+
+                return attributes;
+
+            }
+        });
+
+        pathArgumentAttributesGetters.put(YangInstanceIdentifier.AugmentationIdentifier.class, new PathArgumentAttributesGetter() {
+            @Override
+            public Iterable<? extends NormalizedNodeMessages.PathArgumentAttribute> get(
+                NormalizedNodeSerializationContext context,
+                YangInstanceIdentifier.PathArgument pathArgument) {
+
+                List<NormalizedNodeMessages.PathArgumentAttribute> attributes =
+                    new ArrayList<>();
+
+                YangInstanceIdentifier.AugmentationIdentifier identifier
+                    = (YangInstanceIdentifier.AugmentationIdentifier) pathArgument;
+
+                for (QName key : identifier.getPossibleChildNames()) {
+                    Object value = key;
+                    NormalizedNodeMessages.PathArgumentAttribute attribute =
+                        buildAttribute(context, key, value);
+
+                    attributes.add(attribute);
+
+                }
+
+                return attributes;
+
+            }
+        });
+
+
+        pathArgumentAttributesGetters.put(YangInstanceIdentifier.NodeIdentifier.class, new PathArgumentAttributesGetter() {
+            @Override
+            public Iterable<? extends NormalizedNodeMessages.PathArgumentAttribute> get(
+                NormalizedNodeSerializationContext context,
+                YangInstanceIdentifier.PathArgument pathArgument) {
+                return Collections.emptyList();
+            }
+        });
+    }
+
+    private static NormalizedNodeMessages.PathArgumentAttribute buildAttribute(NormalizedNodeSerializationContext context,QName name, Object value){
+        NormalizedNodeMessages.PathArgumentAttribute.Builder builder =
+            NormalizedNodeMessages.PathArgumentAttribute.newBuilder();
+
+        builder.setName(encodeQName(context, name));
+        ValueSerializer.serialize(builder, context, value);
+
+        return builder.build();
+
+    }
+
+    private static NormalizedNodeMessages.QName.Builder encodeQName(NormalizedNodeSerializationContext context, QName qName){
+        if(qName == null){
+            return NormalizedNodeMessages.QName.getDefaultInstance().toBuilder();
+        }
+        NormalizedNodeMessages.QName.Builder qNameBuilder =
+            NormalizedNodeMessages.QName.newBuilder();
+
+        qNameBuilder.setNamespace(context.addNamespace(qName.getNamespace()));
+
+        qNameBuilder.setRevision(context.addRevision(qName.getRevision()));
+
+        qNameBuilder.setLocalName(context.addLocalName(qName.getLocalName()));
+
+        return qNameBuilder;
+    }
+
+    private static Iterable<? extends NormalizedNodeMessages.PathArgumentAttribute> getPathArgumentAttributes(
+            NormalizedNodeSerializationContext context,
+            YangInstanceIdentifier.PathArgument pathArgument) {
+
+        return pathArgumentAttributesGetters.get(pathArgument.getClass()).get(context, pathArgument);
+
+    }
+
+
+    private static String qNameToString(NormalizedNodeDeSerializationContext context,
+        NormalizedNodeMessages.QName qName){
+        // If this serializer is used qName cannot be null (see encodeQName)
+        // adding null check only in case someone tried to deSerialize a protocol buffer node
+        // that was not serialized using the PathArgumentSerializer
+        Preconditions.checkNotNull(qName, "qName should not be null");
+        Preconditions.checkArgument(!"".equals(qName.getLocalName()),
+            "qName.localName cannot be empty qName = " + qName.toString());
+        Preconditions.checkArgument(qName.getNamespace() != -1, "qName.namespace should be valid");
+
+        StringBuilder sb = new StringBuilder();
+        String namespace = context.getNamespace(qName.getNamespace());
+        String revision = "";
+        String localName = context.getLocalName(qName.getLocalName());
+        if(qName.getRevision() != -1){
+            revision = context.getRevision(qName.getRevision());
+            sb.append("(").append(namespace).append("?revision=").append(
+                revision).append(")").append(
+                localName);
+        } else {
+            sb.append("(").append(namespace).append(")").append(
+                localName);
+        }
+
+        return sb.toString();
+
+    }
+
+    /**
+     * 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(
+        NormalizedNodeDeSerializationContext context,
+        NormalizedNodeMessages.PathArgument pathArgument) {
+
+        Preconditions.checkArgument(pathArgument.getIntType() >= 0
+            && pathArgument.getIntType() < PathArgumentType.values().length,
+            "Illegal PathArgumentType " + pathArgument.getIntType());
+
+        switch(PathArgumentType.values()[pathArgument.getIntType()]){
+            case NODE_IDENTIFIER_WITH_VALUE : {
+
+                YangInstanceIdentifier.NodeWithValue nodeWithValue =
+                    new YangInstanceIdentifier.NodeWithValue(
+                        QNameFactory.create(qNameToString(context, pathArgument.getNodeType())),
+                        parseAttribute(context, pathArgument.getAttribute(0)));
+
+                return nodeWithValue;
+            }
+
+            case NODE_IDENTIFIER_WITH_PREDICATES : {
+
+                YangInstanceIdentifier.NodeIdentifierWithPredicates
+                    nodeIdentifierWithPredicates =
+                    new YangInstanceIdentifier.NodeIdentifierWithPredicates(
+                        QNameFactory.create(qNameToString(context, pathArgument.getNodeType())),
+                        toAttributesMap(context, pathArgument.getAttributeList()));
+
+                return nodeIdentifierWithPredicates;
+            }
+
+            case AUGMENTATION_IDENTIFIER: {
+
+                Set<QName> qNameSet = new HashSet<>();
+
+                for(NormalizedNodeMessages.PathArgumentAttribute attribute : pathArgument.getAttributeList()){
+                    qNameSet.add(QNameFactory.create(qNameToString(context, attribute.getName())));
+                }
+
+                return new YangInstanceIdentifier.AugmentationIdentifier(qNameSet);
+
+            }
+            default: {
+                return NodeIdentifierFactory.getArgument(qNameToString(context,
+                    pathArgument.getNodeType()));
+            }
+
+        }
+    }
+
+    private static Map<QName, Object> toAttributesMap(
+        NormalizedNodeDeSerializationContext context,
+        List<NormalizedNodeMessages.PathArgumentAttribute> attributesList) {
+
+        Map<QName, Object> map = new HashMap<>();
+
+        for(NormalizedNodeMessages.PathArgumentAttribute attribute : attributesList){
+            NormalizedNodeMessages.QName name = attribute.getName();
+            Object value = parseAttribute(context, attribute);
+
+            map.put(QNameFactory.create(qNameToString(context, name)), value);
+        }
+
+        return map;
+    }
+
+    private static Object parseAttribute(NormalizedNodeDeSerializationContext context, NormalizedNodeMessages.PathArgumentAttribute attribute){
+        return ValueSerializer.deSerialize(context, attribute);
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/PathArgumentType.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/PathArgumentType.java
new file mode 100644 (file)
index 0000000..20009d8
--- /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.node.utils.serialization;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public enum PathArgumentType {
+    AUGMENTATION_IDENTIFIER,
+    NODE_IDENTIFIER,
+    NODE_IDENTIFIER_WITH_VALUE,
+    NODE_IDENTIFIER_WITH_PREDICATES;
+
+    public static int getSerializablePathArgumentType(YangInstanceIdentifier.PathArgument pathArgument){
+        Preconditions.checkNotNull(pathArgument, "pathArgument should not be null");
+
+        if(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier){
+            return AUGMENTATION_IDENTIFIER.ordinal();
+        } else if(pathArgument instanceof YangInstanceIdentifier.NodeIdentifier){
+            return NODE_IDENTIFIER.ordinal();
+        } else if(pathArgument instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates){
+            return NODE_IDENTIFIER_WITH_PREDICATES.ordinal();
+        } else if(pathArgument instanceof YangInstanceIdentifier.NodeWithValue){
+            return NODE_IDENTIFIER_WITH_VALUE.ordinal();
+        }
+        throw new IllegalArgumentException("Unknown type of PathArgument = " + pathArgument.toString());
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/ValueSerializer.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/ValueSerializer.java
new file mode 100644 (file)
index 0000000..04c95d6
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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.utils.serialization;
+
+import com.google.common.base.Preconditions;
+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.YangInstanceIdentifier;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ValueSerializer {
+    public static void serialize(NormalizedNodeMessages.Node.Builder builder,
+        NormalizedNodeSerializationContext context, Object value){
+        builder.setIntValueType(ValueType.getSerializableType(value).ordinal());
+
+        if(value instanceof YangInstanceIdentifier) {
+            builder.setInstanceIdentifierValue(
+                InstanceIdentifierUtils.toSerializable((YangInstanceIdentifier) value));
+        } else if(value instanceof Set) {
+            Set set = (Set) value;
+            if(!set.isEmpty()){
+                for(Object o : set){
+                    if(o instanceof String){
+                        builder.addBitsValue(o.toString());
+                    } else {
+                        throw new IllegalArgumentException("Expected value type to be Bits but was : " +
+                            value.toString());
+                    }
+                }
+            }
+        } else {
+            builder.setValue(value.toString());
+        }
+    }
+
+    public static void serialize(NormalizedNodeMessages.PathArgumentAttribute.Builder builder,
+        NormalizedNodeSerializationContext context, Object value){
+
+        builder.setType(ValueType.getSerializableType(value).ordinal());
+        builder.setValue(value.toString());
+    }
+
+    public static Object deSerialize(
+        NormalizedNodeDeSerializationContext context, NormalizedNodeMessages.Node node) {
+        if(node.getIntValueType() == ValueType.YANG_IDENTIFIER_TYPE.ordinal()){
+            return InstanceIdentifierUtils.fromSerializable(
+                node.getInstanceIdentifierValue());
+        } else if(node.getIntValueType() == ValueType.BITS_TYPE.ordinal()){
+            return new HashSet(node.getBitsValueList());
+        }
+        return deSerializeBasicTypes(node.getIntValueType(), node.getValue());
+    }
+
+    public static Object deSerialize(
+        NormalizedNodeDeSerializationContext context,
+        NormalizedNodeMessages.PathArgumentAttribute attribute) {
+        return deSerializeBasicTypes(attribute.getType(), attribute.getValue());
+    }
+
+
+    private static Object deSerializeBasicTypes(int valueType, String value) {
+        Preconditions.checkArgument(valueType >= 0 && valueType < ValueType.values().length,
+            "Illegal value type " + valueType );
+
+        switch(ValueType.values()[valueType]){
+           case SHORT_TYPE: {
+               return Short.valueOf(value);
+           }
+           case BOOL_TYPE: {
+               return Boolean.valueOf(value);
+           }
+           case BYTE_TYPE: {
+               return Byte.valueOf(value);
+           }
+           case INT_TYPE : {
+                return Integer.valueOf(value);
+           }
+           case LONG_TYPE: {
+               return Long.valueOf(value);
+           }
+           case QNAME_TYPE: {
+               return QNameFactory.create(value);
+           }
+           case BIG_INTEGER_TYPE: {
+               return new BigInteger(value);
+           }
+           case BIG_DECIMAL_TYPE: {
+               return new BigDecimal(value);
+           }
+           default: {
+               return value;
+           }
+        }
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/ValueType.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/serialization/ValueType.java
new file mode 100644 (file)
index 0000000..8724dfe
--- /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.cluster.datastore.node.utils.serialization;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public enum ValueType {
+    SHORT_TYPE,
+    BYTE_TYPE,
+    INT_TYPE,
+    LONG_TYPE,
+    BOOL_TYPE,
+    QNAME_TYPE,
+    BITS_TYPE,
+    YANG_IDENTIFIER_TYPE,
+    STRING_TYPE,
+    BIG_INTEGER_TYPE,
+    BIG_DECIMAL_TYPE;
+
+    private static Map<Class, ValueType> types = new HashMap<>();
+
+    static {
+        types.put(String.class, STRING_TYPE);
+        types.put(Byte.class, BYTE_TYPE);
+        types.put(Integer.class, INT_TYPE);
+        types.put(Long.class, LONG_TYPE);
+        types.put(Boolean.class, BOOL_TYPE);
+        types.put(QName.class, QNAME_TYPE);
+        types.put(Set.class, BITS_TYPE);
+        types.put(YangInstanceIdentifier.class, YANG_IDENTIFIER_TYPE);
+        types.put(Short.class,SHORT_TYPE);
+        types.put(BigInteger.class, BIG_INTEGER_TYPE);
+        types.put(BigDecimal.class, BIG_DECIMAL_TYPE);
+    }
+
+    public static final ValueType getSerializableType(Object node){
+        Preconditions.checkNotNull(node, "node should not be null");
+
+        if(types.containsKey(node.getClass())) {
+            return types.get(node.getClass());
+        } else if(node instanceof Set){
+            return BITS_TYPE;
+        }
+
+        throw new IllegalArgumentException("Unknown value type " + node.getClass().getSimpleName());
+    }
+}
index 6464315..c6d3625 100644 (file)
@@ -11,9 +11,8 @@ package org.opendaylight.controller.common.actor;
 import akka.actor.ActorPath;
 import akka.actor.ActorRef;
 import akka.actor.ActorSystem;
-import akka.dispatch.BoundedMailbox;
+import akka.dispatch.BoundedDequeBasedMailbox;
 import akka.dispatch.MailboxType;
-import akka.dispatch.MessageQueue;
 import akka.dispatch.ProducesMessageQueue;
 import com.codahale.metrics.Gauge;
 import com.codahale.metrics.MetricRegistry;
@@ -24,7 +23,7 @@ import scala.concurrent.duration.FiniteDuration;
 
 import java.util.concurrent.TimeUnit;
 
-public class MeteredBoundedMailbox implements MailboxType, ProducesMessageQueue<BoundedMailbox.MessageQueue> {
+public class MeteredBoundedMailbox implements MailboxType, ProducesMessageQueue<MeteredBoundedMailbox.MeteredMessageQueue> {
 
     private MeteredMessageQueue queue;
     private Integer capacity;
@@ -33,16 +32,18 @@ public class MeteredBoundedMailbox implements MailboxType, ProducesMessageQueue<
     private MetricsReporter reporter;
 
     private final String QUEUE_SIZE = "queue-size";
+    private final String CAPACITY = "mailbox-capacity";
+    private final String TIMEOUT  = "mailbox-push-timeout-time";
     private final Long DEFAULT_TIMEOUT = 10L;
 
     public MeteredBoundedMailbox(ActorSystem.Settings settings, Config config) {
         Preconditions.checkArgument( config.hasPath("mailbox-capacity"), "Missing configuration [mailbox-capacity]" );
-        this.capacity = config.getInt("mailbox-capacity");
+        this.capacity = config.getInt(CAPACITY);
         Preconditions.checkArgument( this.capacity > 0, "mailbox-capacity must be > 0");
 
         Long timeout = -1L;
-        if ( config.hasPath("mailbox-push-timeout-time") ){
-            timeout = config.getDuration("mailbox-push-timeout-time", TimeUnit.NANOSECONDS);
+        if ( config.hasPath(TIMEOUT) ){
+            timeout = config.getDuration(TIMEOUT, TimeUnit.NANOSECONDS);
         } else {
             timeout = DEFAULT_TIMEOUT;
         }
@@ -54,7 +55,7 @@ public class MeteredBoundedMailbox implements MailboxType, ProducesMessageQueue<
 
 
     @Override
-    public MessageQueue create(final scala.Option<ActorRef> owner, scala.Option<ActorSystem> system) {
+    public MeteredMessageQueue create(final scala.Option<ActorRef> owner, scala.Option<ActorSystem> system) {
         this.queue = new MeteredMessageQueue(this.capacity, this.pushTimeOut);
         monitorQueueSize(owner, this.queue);
         return this.queue;
@@ -65,14 +66,15 @@ public class MeteredBoundedMailbox implements MailboxType, ProducesMessageQueue<
             return; //there's no actor to monitor
         }
         actorPath = owner.get().path();
-        MetricRegistry registry = reporter.getMetricsRegistry();
+        String actorInstanceId = Integer.toString(owner.get().hashCode());
 
-        String actorName = registry.name(actorPath.toString(), QUEUE_SIZE);
+        MetricRegistry registry = reporter.getMetricsRegistry();
+        String actorName = registry.name(actorPath.toString(), actorInstanceId, QUEUE_SIZE);
 
         if (registry.getMetrics().containsKey(actorName))
             return; //already registered
 
-        reporter.getMetricsRegistry().register(actorName,
+        registry.register(actorName,
                 new Gauge<Integer>() {
                     @Override
                     public Integer getValue() {
@@ -82,7 +84,7 @@ public class MeteredBoundedMailbox implements MailboxType, ProducesMessageQueue<
     }
 
 
-    public static class MeteredMessageQueue extends BoundedMailbox.MessageQueue {
+    public static class MeteredMessageQueue extends BoundedDequeBasedMailbox.MessageQueue {
 
         public MeteredMessageQueue(int capacity, FiniteDuration pushTimeOut) {
             super(capacity, pushTimeOut);
@@ -1,14 +1,14 @@
 // Generated by the protocol buffer compiler.  DO NOT EDIT!
 // source: KeyValueMessages.proto
 
-package org.opendaylight.controller.cluster.example.protobuff.messages;
+package org.opendaylight.controller.protobuff.messages.cluster.example;
 
 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);
+    registry.add(org.opendaylight.controller.protobuff.messages.cluster.example.KeyValueMessages.key);
+    registry.add(org.opendaylight.controller.protobuff.messages.cluster.example.KeyValueMessages.value);
   }
   public static final int KEY_FIELD_NUMBER = 2;
   /**
@@ -16,7 +16,7 @@ public final class KeyValueMessages {
    */
   public static final
     com.google.protobuf.GeneratedMessage.GeneratedExtension<
-      org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload,
+      org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload,
       java.lang.String> key = com.google.protobuf.GeneratedMessage
           .newFileScopedGeneratedExtension(
         java.lang.String.class,
@@ -27,7 +27,7 @@ public final class KeyValueMessages {
    */
   public static final
     com.google.protobuf.GeneratedMessage.GeneratedExtension<
-      org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload,
+      org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload,
       java.lang.String> value = com.google.protobuf.GeneratedMessage
           .newFileScopedGeneratedExtension(
         java.lang.String.class,
@@ -49,7 +49,7 @@ public final class KeyValueMessages {
       "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" +
+      "er.protobuff.messages.cluster.exampleB\020K" +
       "eyValueMessagesH\001"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
@@ -65,7 +65,7 @@ public final class KeyValueMessages {
     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.cluster.raft.AppendEntriesMessages.getDescriptor(),
         }, assigner);
   }
 
@@ -1,7 +1,7 @@
 // Generated by the protocol buffer compiler.  DO NOT EDIT!
 // source: AppendEntriesMessages.proto
 
-package org.opendaylight.controller.cluster.raft.protobuff.messages;
+package org.opendaylight.controller.protobuff.messages.cluster.raft;
 
 public final class AppendEntriesMessages {
   private AppendEntriesMessages() {}
@@ -60,12 +60,12 @@ public final class AppendEntriesMessages {
     /**
      * <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> 
+    java.util.List<org.opendaylight.controller.protobuff.messages.cluster.raft.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);
+    org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry getLogEntries(int index);
     /**
      * <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
      */
@@ -73,12 +73,12 @@ public final class AppendEntriesMessages {
     /**
      * <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> 
+    java.util.List<? extends org.opendaylight.controller.protobuff.messages.cluster.raft.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(
+    org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder getLogEntriesOrBuilder(
         int index);
 
     // optional int64 leaderCommit = 6;
@@ -164,10 +164,10 @@ public final class AppendEntriesMessages {
             }
             case 42: {
               if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
-                logEntries_ = new java.util.ArrayList<org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry>();
+                logEntries_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry>();
                 mutable_bitField0_ |= 0x00000010;
               }
-              logEntries_.add(input.readMessage(org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PARSER, extensionRegistry));
+              logEntries_.add(input.readMessage(org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PARSER, extensionRegistry));
               break;
             }
             case 48: {
@@ -192,14 +192,14 @@ public final class AppendEntriesMessages {
     }
     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;
+      return org.opendaylight.controller.protobuff.messages.cluster.raft.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
+      return org.opendaylight.controller.protobuff.messages.cluster.raft.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);
+              org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.class, org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.Builder.class);
     }
 
     public static com.google.protobuf.Parser<AppendEntries> PARSER =
@@ -248,11 +248,11 @@ public final class AppendEntriesMessages {
       /**
        * <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();
+      org.opendaylight.controller.protobuff.messages.cluster.raft.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();
+      org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PayloadOrBuilder getDataOrBuilder();
     }
     /**
      * Protobuf type {@code org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry}
@@ -316,11 +316,11 @@ public final class AppendEntriesMessages {
                 break;
               }
               case 26: {
-                org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder subBuilder = null;
+                org.opendaylight.controller.protobuff.messages.cluster.raft.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);
+                data_ = input.readMessage(org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.PARSER, extensionRegistry);
                 if (subBuilder != null) {
                   subBuilder.mergeFrom(data_);
                   data_ = subBuilder.buildPartial();
@@ -342,14 +342,14 @@ public final class AppendEntriesMessages {
       }
       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;
+        return org.opendaylight.controller.protobuff.messages.cluster.raft.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
+        return org.opendaylight.controller.protobuff.messages.cluster.raft.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);
+                org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.class, org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder.class);
       }
 
       public static com.google.protobuf.Parser<ReplicatedLogEntry> PARSER =
@@ -393,7 +393,7 @@ public final class AppendEntriesMessages {
           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) {
+        private Payload(com.google.protobuf.GeneratedMessage.ExtendableBuilder<org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload, ?> builder) {
           super(builder);
           this.unknownFields = builder.getUnknownFields();
         }
@@ -456,14 +456,14 @@ public final class AppendEntriesMessages {
         }
         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;
+          return org.opendaylight.controller.protobuff.messages.cluster.raft.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
+          return org.opendaylight.controller.protobuff.messages.cluster.raft.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);
+                  org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.class, org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder.class);
         }
 
         public