Merge "L3: Add eth to br-ex"
authorSam Hague <shague@redhat.com>
Sun, 22 Nov 2015 15:58:28 +0000 (15:58 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Sun, 22 Nov 2015 15:58:29 +0000 (15:58 +0000)
307 files changed:
commons/parent/pom.xml
features/ovsdb/pom.xml
features/ovsdb/src/main/features/features.xml
hwvtepsouthbound/hwvtepsouthbound-api/src/main/yang/hwvtep.yang
hwvtepsouthbound/hwvtepsouthbound-features/pom.xml
hwvtepsouthbound/hwvtepsouthbound-features/src/main/features/features.xml
hwvtepsouthbound/hwvtepsouthbound-impl/pom.xml
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/config/default-config.xml
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepConnectionInstance.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepConnectionManager.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepDataChangeListener.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepMonitorCallback.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSchemaConstants.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundConstants.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundMapper.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundProvider.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundUtil.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/InstanceIdentifierCodec.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/impl/HwvtepSouthboundProvider.java [deleted file]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/AbstractTransactCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/HwvtepOperationalState.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalSwitchRemoveCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalSwitchUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalLocatorRemoveCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalLocatorUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortRemoveCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactCommandAggregator.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactInvoker.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactInvokerImpl.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactUtils.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/AbstractTransactionCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/GlobalUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepGlobalRemoveCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepManagerUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepOperationalCommandAggregator.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepTunnelUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/LogicalSwitchRemoveCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/LogicalSwitchUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/McastMacsLocalUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/McastMacsRemoteUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalLocatorSetUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalLocatorUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalPortRemoveCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalPortUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalSwitchRemoveCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalSwitchUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/TransactionCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/TransactionInvoker.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/TransactionInvokerImpl.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/UcastMacsLocalUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/UcastMacsRemoteUpdateCommand.java [new file with mode: 0644]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/hwvtepsouthbound/impl/rev150901/HwvtepSouthboundModule.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/yang/hwvtepsouthbound-impl.yang
hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/hwvtepsouthbound/impl/rev150901/HwvtepSouthboundModuleTest.java
hwvtepsouthbound/hwvtepsouthbound-karaf/pom.xml
library/features/src/main/features/features.xml
library/impl/pom.xml
library/impl/src/main/config/default-config.xml
library/impl/src/main/java/org/opendaylight/ovsdb/lib/ConfigActivator.java [deleted file]
library/impl/src/main/java/org/opendaylight/ovsdb/lib/OvsdbClient.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/error/ColumnSchemaNotFoundException.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/error/SchemaVersionMismatchException.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/error/TableSchemaNotFoundException.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/impl/LibraryProvider.java [deleted file]
library/impl/src/main/java/org/opendaylight/ovsdb/lib/impl/OvsdbClientImpl.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/impl/OvsdbConnectionService.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/message/MonitorRequest.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/message/MonitorRequestBuilder.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/message/TableUpdate.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/message/TransactResponse.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/notation/Function.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/notation/Mutator.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/notation/OvsdbMap.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/operations/OperationResult.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/operations/TransactionBuilder.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/schema/TableSchema.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TypedColumn.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TypedTable.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/schema/typed/TyperUtils.java
library/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/library/impl/rev141210/LibraryModule.java
library/impl/src/main/yang/library-impl.yang
library/impl/src/test/java/org/opendaylight/ovsdb/lib/jsonrpc/JsonRpcDecoderTest.java
library/impl/src/test/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/library/impl/rev141210/LibraryModuleTest.java
library/it/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/OvsdbClientTestIT.java
library/it/src/test/java/org/opendaylight/ovsdb/integrationtest/schema/hardwarevtep/HardwareVTEPIT.java
library/it/src/test/java/org/opendaylight/ovsdb/integrationtest/schema/openvswitch/OpenVSwitchIT.java
openstack/net-virt-it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/it/NetvirtIT.java
openstack/net-virt-it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/it/SouthboundConstants.java
openstack/net-virt-it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/it/SouthboundMapper.java
openstack/net-virt-providers/pom.xml
openstack/net-virt-providers/src/main/config/default-config.xml
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/ConfigActivator.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/NetvirtProvidersProvider.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/OF13Provider.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/PipelineOrchestrator.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/PipelineOrchestratorImpl.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/Service.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/ClassifierService.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/EgressAclService.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/IngressAclService.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/arp/Arp.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/arp/ArpFlowFactory.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/arp/ArpOperation.java
openstack/net-virt-providers/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/AbstractServiceInstanceTest.java
openstack/net-virt-providers/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/EgressAclServiceTest.java
openstack/net-virt-providers/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/IngressAclServiceTest.java
openstack/net-virt-providers/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/L2FowardingServiceTest.java
openstack/net-virt-providers/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/LoadBalancerServiceTest.java
openstack/net-virt-sfc/api/pom.xml
openstack/net-virt-sfc/api/src/main/yang/ietf-acl.yang [deleted file]
openstack/net-virt-sfc/api/src/main/yang/netvirt-acl.yang
openstack/net-virt-sfc/api/src/main/yang/netvirt-classifier.yang
openstack/net-virt-sfc/api/src/main/yang/packet-fields.yang [deleted file]
openstack/net-virt-sfc/features/production/pom.xml
openstack/net-virt-sfc/features/production/src/main/features/features.xml
openstack/net-virt-sfc/features/test/src/main/features/features.xml
openstack/net-virt-sfc/impl/pom.xml
openstack/net-virt-sfc/impl/src/main/config/default-config.xml
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/AbstractDataTreeListener.java
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/INetvirtSfcOF13Provider.java [moved from openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/openflow13/INetvirtSfcOF13Provider.java with 56% similarity]
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/ISfcClassifierService.java [new file with mode: 0644]
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/NetvirtSfcAclListener.java
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/NetvirtSfcClassifierListener.java
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/NetvirtSfcProvider.java
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/NshUtils.java [new file with mode: 0644]
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/SfcUtils.java [new file with mode: 0644]
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/openflow13/NetvirtSfcOF13Provider.java [deleted file]
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/standalone/openflow13/NetvirtSfcStandaloneOF13Provider.java [new file with mode: 0644]
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/standalone/openflow13/SfcClassifier.java [new file with mode: 0644]
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/standalone/openflow13/services/SfcClassifierService.java [new file with mode: 0644]
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/NetvirtSfcWorkaroundOF13Provider.java [new file with mode: 0644]
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/services/SfcClassifierService.java [new file with mode: 0644]
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/netvirt/sfc/rev141210/NetvirtSfcModule.java
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/netvirt/sfc/rev141210/NetvirtSfcModuleFactory.java
openstack/net-virt-sfc/impl/src/main/yang/netvirt-sfc.yang
openstack/net-virt-sfc/impl/src/test/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/netvirt/sfc/rev141210/NetvirtSfcModuleTest.java
openstack/net-virt-sfc/it/pom.xml
openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/NetvirtSfcIT.java
openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/AbstractUtils.java [new file with mode: 0644]
openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/AclUtils.java
openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ClassifierUtils.java
openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ServiceFunctionChainUtils.java [new file with mode: 0644]
openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ServiceFunctionForwarderUtils.java [new file with mode: 0644]
openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ServiceFunctionPathUtils.java [new file with mode: 0644]
openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ServiceFunctionUtils.java [new file with mode: 0644]
openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/SfcUtils.java
openstack/net-virt/pom.xml
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/ConfigActivator.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/MdsalHelper.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/NetvirtProvider.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/NeutronCacheUtils.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/NorthboundEvent.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/PortSecurityHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/EgressAclProvider.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/IngressAclProvider.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/LoadBalancerConfiguration.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/SecurityGroupCacheManger.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/SecurityServicesManager.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/Southbound.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/MdsalUtils.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/NeutronL3Adapter.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/NodeCacheManagerImpl.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/OvsdbInventoryServiceImpl.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/SecurityGroupCacheManagerImpl.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/SecurityServicesImpl.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/SouthboundImpl.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFirewall.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFirewallPolicy.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFirewallRule.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFloatingIP.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancer.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerHealthMonitor.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerListener.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerPool.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerPoolMember.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronNetwork.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronPort.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronRouter.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSecurityGroup.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSecurityRule.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSubnet.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSubnetIPAllocationPool.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronFloatingIPInterface.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerInterface.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerPoolInterface.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronNetworkInterface.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronPortInterface.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronRouterInterface.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronSecurityGroupInterface.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronSecurityRuleInterface.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronSubnetInterface.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronIAwareUtil.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronNetworkChangeListener.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronPortChangeListener.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronRouterChangeListener.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronSecurityGroupDataChangeListener.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronSecurityRuleDataChangeListener.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronSubnetChangeListener.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/FloatingIPHandlerTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolHandlerTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolMemberHandlerTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/NeutronCacheUtilsTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/PortHandlerTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/PortSecurityHandlerTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/SouthboundHandlerTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/SubnetHandlerTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/api/LoadBalancerConfigurationTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/BridgeConfigurationManagerImplTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/MdsalUtilsTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/NeutronL3AdapterTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/NodeCacheManagerImplTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/ProviderNetworkManagerImplTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/SecurityServicesImplTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/TenantNetworkManagerImplTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/VlanConfigurationCacheImplTest.java
ovsdb-ui/module/src/main/resources/ovsdb/LogicalGraph.js
ovsdb-ui/module/src/main/resources/ovsdb/OvsCore.js
ovsdb-ui/module/src/main/resources/ovsdb/assets/dhcp.png
ovsdb-ui/module/src/main/resources/ovsdb/assets/router.png
ovsdb-ui/module/src/main/resources/ovsdb/assets/vm.png
ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.constant.js
ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.directives.js
ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.services.js
ovsdb-ui/module/src/main/resources/ovsdb/views/index.tpl.html
resources/commons/NetvirtSfc.json.postman_collection
resources/commons/Ovsdb-HwvtepSouthbound-Collection.json.postman_collection [new file with mode: 0755]
resources/commons/README
southbound/southbound-api/pom.xml
southbound/southbound-features/pom.xml
southbound/southbound-features/src/main/features/features.xml
southbound/southbound-impl/pom.xml
southbound/southbound-impl/src/main/config/default-config.xml
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/InstanceIdentifierCodec.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionInstance.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManager.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbDataChangeListener.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbSchemaContants.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/SouthboundConstants.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/SouthboundMapper.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/SouthboundProvider.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeRemovedCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeUpdateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/DataChangesManagedByOvsdbNodeEvent.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/OvsdbNodeUpdateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/ProtocolUpdateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TerminationPointCreateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TerminationPointUpdateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactCommandAggregator.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactInvokerImpl.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactUtils.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OpenVSwitchUpdateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbBridgeUpdateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbControllerRemovedCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbControllerUpdateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbManagersRemovedCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbManagersUpdateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbNodeRemoveCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbOperationalCommandAggregator.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbPortUpdateCommand.java
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/TransactionInvokerImpl.java
southbound/southbound-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/southbound/impl/rev141210/SouthboundImplModule.java
southbound/southbound-impl/src/main/yang/southbound-impl.yang
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionInstanceTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManagerTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbDataChangeListenerTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/SouthboundMapperTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/SouthboundProviderTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/AbstractTransactCommandTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeOperationalStateTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeRemovedCommandTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeUpdateCommandTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/ControllerRemovedCommandTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/ControllerUpdateCommandTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/DataChangesManagedByOvsdbNodeEventTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/OpenVSwitchBridgeAddCommandTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/OvsdbNodeUpdateCommandTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/ProtocolUpdateCommandTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TerminationPointCreateCommandTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TerminationPointDeleteCommandTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TerminationPointUpdateCommandTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactCommandAggregatorTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactInvokerImplTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactUtilsTest.java [new file with mode: 0644]
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/transactions/md/OpenVSwitchUpdateCommandTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbBridgeRemovedCommandTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbBridgeUpdateCommandTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbControllerRemovedCommandTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbControllerUpdateCommandTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbManagersRemovedCommandTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbManagersUpdateCommandTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbNodeRemoveCommandTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbOperationalCommandAggregatorTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/transactions/md/OvsdbPortUpdateCommandTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/transactions/md/TransactionInvokerImplTest.java
southbound/southbound-it/src/test/java/org/opendaylight/ovsdb/southbound/it/SouthboundIT.java
utils/mdsal-node/src/main/java/org/opendaylight/ovsdb/utils/mdsal/node/StringConvertor.java
utils/mdsal-openflow/pom.xml
utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/ActionUtils.java
utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/FlowUtils.java [new file with mode: 0644]
utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/InstructionUtils.java
utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/MatchUtils.java
utils/mdsal-utils/pom.xml
utils/mdsal-utils/src/main/java/org/opendaylight/ovsdb/utils/mdsal/utils/NeutronModelsDataStoreHelper.java [new file with mode: 0644]
utils/servicehelper/pom.xml
utils/southbound-utils/src/main/java/org/opendaylight/ovsdb/utils/southbound/utils/SouthboundUtils.java

index 641001fb555920ebbc27971422eb667bffe82349..073bc212466cfa1816a2b3780064353c1cbefac0 100644 (file)
@@ -96,10 +96,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <sal.version>0.10.0-SNAPSHOT</sal.version>
     <switchmanager.api.version>0.9.0-SNAPSHOT</switchmanager.api.version>
     <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
-    <!-- 3rd Pary Dependency Versions -->
-    <commons.collection.version>1.0</commons.collection.version>
-    <httpcomponents.version>4.2.1</httpcomponents.version>
-    <portlet.version>2.0</portlet.version>
+    <!-- 3rd Party Dependency Versions -->
     <powermock.version>1.5.2</powermock.version>
     <dlux.version>0.3.0-SNAPSHOT</dlux.version>
     <ovsdb.ui.version>0.1.0-SNAPSHOT</ovsdb.ui.version>
@@ -121,46 +118,16 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
         <type>pom</type>
         <scope>import</scope>
       </dependency>
-      <dependency>
-        <groupId>commons-collections</groupId>
-        <artifactId>commons-collections</artifactId>
-        <version>${commons.collection.version}</version>
-      </dependency>
       <dependency>
         <groupId>io.netty</groupId>
         <artifactId>netty-all</artifactId>
         <version>${netty.version}</version>
       </dependency>
-      <dependency>
-        <groupId>javax.portlet</groupId>
-        <artifactId>portlet-api</artifactId>
-        <version>${portlet.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.httpcomponents</groupId>
-        <artifactId>httpcore-nio</artifactId>
-        <version>${httpcomponents.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.controller</groupId>
-        <artifactId>commons.northbound</artifactId>
-        <version>${northbound.commons.version}</version>
-      </dependency>
       <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-api</artifactId>
         <version>${controller.config.version}</version>
       </dependency>
-      <dependency>
-        <groupId>org.opendaylight.controller</groupId>
-        <artifactId>containermanager</artifactId>
-        <version>${containermanager.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.controller</groupId>
-        <artifactId>forwardingrulesmanager</artifactId>
-        <version>${forwardingrulesmanager.version}</version>
-      </dependency>
       <dependency>
         <groupId>org.opendaylight.neutron</groupId>
         <artifactId>neutron-spi</artifactId>
@@ -172,11 +139,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
         <version>1.6.0-SNAPSHOT</version>
         <type>zip</type>
       </dependency>
-      <dependency>
-        <groupId>org.opendaylight.controller</groupId>
-        <artifactId>sal</artifactId>
-        <version>${sal.version}</version>
-      </dependency>
 
       <dependency>
         <groupId>org.opendaylight.yangtools</groupId>
@@ -207,11 +169,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
         <scope>import</scope>
       </dependency>
 
-      <dependency>
-        <groupId>org.opendaylight.controller</groupId>
-        <artifactId>switchmanager</artifactId>
-        <version>${switchmanager.api.version}</version>
-      </dependency>
       <dependency>
         <groupId>org.opendaylight.openflowplugin.model</groupId>
         <artifactId>model-flow-base</artifactId>
index 94cf2abe84776cdcc62da6497ad6fa5bcd7dbe87..a5d890a212116632d84761ebfa27ebd9a61e073d 100644 (file)
@@ -15,7 +15,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>features-parent</artifactId>
     <version>1.6.0-SNAPSHOT</version>
-    <relativePath></relativePath>
+    <relativePath/>
   </parent>
 
   <groupId>org.opendaylight.ovsdb</groupId>
@@ -47,7 +47,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <properties>
     <odl.karaf.base.version>1.6.0-SNAPSHOT</odl.karaf.base.version>
     <mdsal.version>1.3.0-SNAPSHOT</mdsal.version>
-    <io.netty.version>3.8.0.Final</io.netty.version>
     <networkconfig.neutron.version>0.6.0-SNAPSHOT</networkconfig.neutron.version>
     <ovsdb.library.version>1.2.1-SNAPSHOT</ovsdb.library.version>
     <openstack.netvirt.version>1.2.1-SNAPSHOT</openstack.netvirt.version>
@@ -118,12 +117,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-lang3</artifactId>
-      <version>${commons.lang3.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>io.netty</groupId>
-      <artifactId>netty</artifactId>
-      <version>${io.netty.version}</version>
     </dependency>
     <dependency>
       <groupId>io.netty</groupId>
@@ -133,42 +126,34 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <dependency>
       <groupId>io.netty</groupId>
       <artifactId>netty-buffer</artifactId>
-      <version>${netty.version}</version>
     </dependency>
     <dependency>
       <groupId>io.netty</groupId>
       <artifactId>netty-codec</artifactId>
-      <version>${netty.version}</version>
     </dependency>
     <dependency>
       <groupId>io.netty</groupId>
       <artifactId>netty-codec-http</artifactId>
-      <version>${netty.version}</version>
     </dependency>
     <dependency>
       <groupId>io.netty</groupId>
       <artifactId>netty-common</artifactId>
-      <version>${netty.version}</version>
     </dependency>
     <dependency>
       <groupId>io.netty</groupId>
       <artifactId>netty-handler</artifactId>
-      <version>${netty.version}</version>
     </dependency>
     <dependency>
       <groupId>io.netty</groupId>
       <artifactId>netty-transport</artifactId>
-      <version>${netty.version}</version>
     </dependency>
     <dependency>
       <groupId>equinoxSDK381</groupId>
       <artifactId>javax.servlet</artifactId>
-      <version>3.0.0.v201112011016</version>
     </dependency>
     <dependency>
       <groupId>equinoxSDK381</groupId>
       <artifactId>javax.servlet.jsp</artifactId>
-      <version>2.2.0.v201112011158</version>
     </dependency>
     <dependency>
       <groupId>equinoxSDK381</groupId>
@@ -285,6 +270,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>utils.servicehelper</artifactId>
       <version>${ovsdb.utils.servicehelper.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.mdsal-utils</artifactId>
+      <version>${project.version}</version>
+    </dependency>
     <dependency>
       <groupId>com.google.code.gson</groupId>
       <artifactId>gson</artifactId>
@@ -322,10 +312,5 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <classifier>features</classifier>
       <type>xml</type>
     </dependency>
-    <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>ovsdb-ui-bundle</artifactId>
-        <version>${ovsdb.ui.version}</version>
-    </dependency>
   </dependencies>
 </project>
index 1abdab4e67534b0040e3952a154e7fc7f6c2d862..e36f3d1158e9e9a233463fb9a8e221fef4bbf6b5 100644 (file)
@@ -2,13 +2,13 @@
 <features name="ovsdb-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
-  <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin-extension/${openflowplugin.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/${openflowplugin.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.neutron/features-neutron/${networkconfig.neutron.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin-extension/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.neutron/features-neutron/{{VERSION}}/xml/features</repository>
   <repository>mvn:org.opendaylight.ovsdb/southbound-features/1.2.1-SNAPSHOT/xml/features</repository>
-  <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.ovsdb/library-features/${ovsdb.library.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.dlux/features-dlux/${dlux.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.controller/features-mdsal/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.ovsdb/library-features/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.dlux/features-dlux/{{VERSION}}/xml/features</repository>
 
   <feature name="odl-ovsdb-all" description="OpenDaylight :: OVSDB :: all"
            version='${project.version}'>
   <feature name="odl-ovsdb-schema-openvswitch" description="OVSDB :: Schema :: Open_vSwitch"
            version='${schema.openvswitch.version}'>
     <feature version="${ovsdb.library.version}">odl-ovsdb-library</feature>
-    <bundle>mvn:org.opendaylight.ovsdb/schema.openvswitch/${schema.openvswitch.version}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/schema.openvswitch/{{VERSION}}</bundle>
   </feature>
 
   <feature name="odl-ovsdb-schema-hardwarevtep" description="OVSDB :: Schema :: hardware_vtep"
            version='${schema.hardwarevtep.version}'>
     <feature version="${ovsdb.library.version}">odl-ovsdb-library</feature>
-    <bundle>mvn:org.opendaylight.ovsdb/schema.hardwarevtep/${schema.hardwarevtep.version}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/schema.hardwarevtep/{{VERSION}}</bundle>
   </feature>
 
   <feature name="odl-ovsdb-openstack" description="OpenDaylight :: OVSDB :: OpenStack Network Virtualization"
     <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
     <feature version="${openflowplugin.version}">odl-openflowplugin-nsf-model</feature>
     <feature version="${networkconfig.neutron.version}">odl-neutron-service</feature>
-    <feature version="1.2.1-SNAPSHOT">odl-ovsdb-southbound-impl-ui</feature>
+    <feature version="${project.version}">odl-ovsdb-southbound-impl-ui</feature>
     <feature version="${openflowplugin.version}">odl-openflowplugin-flow-services</feature>
     <feature version="${openflowplugin.version}">odl-openflowplugin-nxm-extensions</feature>
-    <bundle>mvn:org.opendaylight.ovsdb/utils.servicehelper/${ovsdb.utils.servicehelper.version}</bundle>
-    <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt/${openstack.netvirt.version}</bundle>
-    <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt-providers/${openstack.netvirt.providers.version}</bundle>
-    <bundle>mvn:org.opendaylight.neutron/dummyprovider/${networkconfig.neutron.version}</bundle>
-    <configfile finalname="etc/opendaylight/karaf/netvirt-impl-default-config.xml">mvn:org.opendaylight.ovsdb/openstack.net-virt/${project.version}/xml/config</configfile>
-    <configfile finalname="etc/opendaylight/karaf/netvirt-providers-impl-default-config.xml">mvn:org.opendaylight.ovsdb/openstack.net-virt-providers/${project.version}/xml/config</configfile>
+    <bundle>mvn:org.opendaylight.ovsdb/utils.servicehelper/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/utils.mdsal-utils/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt-providers/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.neutron/dummyprovider/{{VERSION}}</bundle>
+    <configfile finalname="etc/opendaylight/karaf/netvirt-impl-default-config.xml">mvn:org.opendaylight.ovsdb/openstack.net-virt/{{VERSION}}/xml/config</configfile>
+    <configfile finalname="etc/opendaylight/karaf/netvirt-providers-impl-default-config.xml">mvn:org.opendaylight.ovsdb/openstack.net-virt-providers/{{VERSION}}/xml/config</configfile>
   </feature>
   <feature name="odl-ovsdb-ui" description="OpenDaylight :: OVSDB :: DLUX Integration Plugin" version='${ovsdb.ui.version}'>
     <feature version="${dlux.version}">odl-dlux-core</feature>
-    <bundle>mvn:org.opendaylight.ovsdb/ovsdb-ui-bundle/${ovsdb.ui.version}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/ovsdb-ui-bundle/{{VERSION}}</bundle>
   </feature>
 </features>
index 8b5bdbee1cd6cca06ac9faab6dd8e669a5d2f8c7..6244999fa1165ac50e770d3aa4c74fcf385891cc 100644 (file)
@@ -256,6 +256,10 @@ module hwvtep {
             description "Per Logical Switch tunnel key";
             type string;
         }
+        leaf logical-switch-managed-by {
+            description "The hwvtep global node to which this logical switch belongs to";
+            type hwvtep-global-ref;
+        }
     }
 
     grouping hwvtep-physical-port-attributes {
index 1a60860e7730997367c96745e72232913fd23e97..b881ebdd04b3ee6dfb40d16744f0c72cbf77e56c 100644 (file)
@@ -105,5 +105,12 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <artifactId>hwvtepsouthbound-api</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>library-features</artifactId>
+      <type>xml</type>
+      <classifier>features</classifier>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
 </project>
index 967a07c36ae80b821bfa68097e494519d100e769..7cfcc3b66d430d22af938c3a71b04c6ee93f89f1 100644 (file)
@@ -10,20 +10,28 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
 <features name="odl-ovsdb-hwvtepsouthbound-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
-  <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.netconf/features-restconf/${restconf.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/${mdsal.model.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.dlux/features-dlux/${dlux.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.yangtools/features-yangtools/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.controller/features-mdsal/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.netconf/features-restconf/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.dlux/features-dlux/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.ovsdb/library-features/{{VERSION}}/xml/features</repository>
   <feature name='odl-ovsdb-hwvtepsouthbound-api' version='${project.version}' description='OpenDaylight :: hwvtepsouthbound :: api'>
     <feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
-    <bundle>mvn:org.opendaylight.ovsdb/hwvtepsouthbound-api/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/hwvtepsouthbound-api/{{VERSION}}</bundle>
   </feature>
   <feature name='odl-ovsdb-hwvtepsouthbound' version='${project.version}' description='OpenDaylight :: hwvtepsouthbound'>
     <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
     <feature version='${project.version}'>odl-ovsdb-hwvtepsouthbound-api</feature>
-    <bundle>mvn:org.opendaylight.ovsdb/hwvtepsouthbound-impl/${project.version}</bundle>
-    <configfile finalname="${configfile.directory}/hwvtepsouthbound.xml">mvn:org.opendaylight.ovsdb/hwvtepsouthbound-impl/${project.version}/xml/config</configfile>
+    <bundle>mvn:org.opendaylight.ovsdb/hwvtepsouthbound-impl/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/library/{{VERSION}}</bundle>
+    <bundle>mvn:com.fasterxml.jackson.core/jackson-annotations/{{VERSION}}</bundle>
+    <bundle>mvn:com.fasterxml.jackson.core/jackson-core/{{VERSION}}</bundle>
+    <bundle>mvn:com.fasterxml.jackson.core/jackson-databind/{{VERSION}}</bundle>
+    <bundle>mvn:com.fasterxml.jackson.datatype/jackson-datatype-json-org/{{VERSION}}</bundle>
+    <bundle>wrap:mvn:org.json/json/{{VERSION}}</bundle>
+    <feature version='${project.version}'>odl-ovsdb-library</feature>
+    <configfile finalname="${configfile.directory}/hwvtepsouthbound.xml">mvn:org.opendaylight.ovsdb/hwvtepsouthbound-impl/{{VERSION}}/xml/config</configfile>
   </feature>
   <feature name='odl-ovsdb-hwvtepsouthbound-rest' version='${project.version}' description='OpenDaylight :: hwvtepsouthbound :: REST'>
     <feature version="${project.version}">odl-ovsdb-hwvtepsouthbound</feature>
index 7d3d0fe29d5e020ec88982b337f195035293f517..eadf1ac67eeb918cfe4b82ec67c59c8179619263 100644 (file)
@@ -26,6 +26,16 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>hwvtepsouthbound-api</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>library</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>schema.hardwarevtep</artifactId>
+      <version>${project.version}</version>
+    </dependency>
 
     <!-- Testing Dependencies -->
     <dependency>
@@ -43,6 +53,16 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
 
   <build>
     <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Private-Package>org.opendaylight.ovsdb.schema.hardwarevtep</Private-Package>
+            <Export-Package>org.opendaylight.ovsdb.hwvtepsouthbound.*,org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hwvtepsouthbound.impl.rev150901.*</Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-checkstyle-plugin</artifactId>
index 491fe69344e4150e63a09a7bb076874b59ab8fa6..bd700948984dd773911e31bf9397d9f563115383 100644 (file)
@@ -11,6 +11,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <required-capabilities>
     <!--  <capability>urn:opendaylight:params:xml:ns:yang:hwvtepsouthbound:impl?module=hwvtepsouthbound-impl&amp;revision=2015-09-01</capability> -->
       <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
+      <capability>urn:opendaylight:params:xml:ns:yang:library:impl?module=library&amp;revision=2014-12-10</capability>
   </required-capabilities>
   <configuration>
 
@@ -23,6 +24,22 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
             <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
             <name>binding-osgi-broker</name>
           </broker>
+          <schema-service>
+            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+            <name>yang-schema-service</name>
+          </schema-service>
+          <binding-normalized-node-serializer>
+            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-normalized-node-serializer</type>
+            <name>runtime-mapping-singleton</name>
+          </binding-normalized-node-serializer>
+          <clustering-entity-ownership-service>
+             <type xmlns:ns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:entity-ownership-service">ns:entity-ownership-service</type>
+             <name>entity-ownership-service</name>
+          </clustering-entity-ownership-service>
+          <connection-service>
+            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:library:impl">prefix:connection-service</type>
+            <name>connection-service</name>
+          </connection-service>
         </module>
       </modules>
     </data>
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepConnectionInstance.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepConnectionInstance.java
new file mode 100644 (file)
index 0000000..7eec7e1
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+
+import javax.annotation.Nonnull;
+
+import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transact.TransactCommand;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transact.TransactInvoker;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transact.TransactInvokerImpl;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.TransactionInvoker;
+import org.opendaylight.ovsdb.lib.EchoServiceCallbackFilters;
+import org.opendaylight.ovsdb.lib.LockAquisitionCallback;
+import org.opendaylight.ovsdb.lib.LockStolenCallback;
+import org.opendaylight.ovsdb.lib.MonitorCallBack;
+import org.opendaylight.ovsdb.lib.MonitorHandle;
+import org.opendaylight.ovsdb.lib.OvsdbClient;
+import org.opendaylight.ovsdb.lib.OvsdbConnectionInfo;
+import org.opendaylight.ovsdb.lib.message.MonitorRequest;
+import org.opendaylight.ovsdb.lib.message.MonitorRequestBuilder;
+import org.opendaylight.ovsdb.lib.message.MonitorSelect;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.Row;
+import org.opendaylight.ovsdb.lib.operations.Operation;
+import org.opendaylight.ovsdb.lib.operations.OperationResult;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+import org.opendaylight.ovsdb.lib.schema.TableSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfo;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class HwvtepConnectionInstance implements OvsdbClient{
+    private static final Logger LOG = LoggerFactory.getLogger(HwvtepConnectionInstance.class);
+    private ConnectionInfo connectionInfo;
+    private OvsdbClient client;
+    private InstanceIdentifier<Node> instanceIdentifier;
+    private TransactionInvoker txInvoker;
+    private Map<DatabaseSchema,TransactInvoker> transactInvokers;
+    private MonitorCallBack callback;
+    private volatile boolean hasDeviceOwnership = false;
+    private Entity connectedEntity;
+    private EntityOwnershipCandidateRegistration deviceOwnershipCandidateRegistration;
+    private HwvtepGlobalAugmentation initialCreatedData = null;
+
+
+    HwvtepConnectionInstance (ConnectionInfo key,OvsdbClient client,
+                    InstanceIdentifier<Node> iid, TransactionInvoker txInvoker) {
+        this.connectionInfo = key;
+        this.client = client;
+        this.instanceIdentifier = iid;
+        this.txInvoker = txInvoker;
+    }
+
+    public void transact(TransactCommand command) {
+        for (TransactInvoker transactInvoker: transactInvokers.values()) {
+            transactInvoker.invoke(command);
+        }
+    }
+
+    public void registerCallbacks() {
+        if ( this.callback == null) {
+            if(this.initialCreatedData != null) {
+                this.updateConnectionAttributes();
+            }
+
+            try {
+                List<String> databases = getDatabases().get();
+                this.callback = new HwvtepMonitorCallback(this,txInvoker);
+                for (String database : databases) {
+                    DatabaseSchema dbSchema = getSchema(database).get();
+                    if (dbSchema != null) {
+                        monitorAllTables(database, dbSchema, HwvtepSchemaConstants.databaseName);
+                    } else {
+                        LOG.warn("No schema reported for database {} for key {}",database,connectionInfo);
+                    }
+                }
+            } catch (InterruptedException | ExecutionException e) {
+                LOG.warn("Exception attempting to registerCallbacks {}: {}",connectionInfo,e);
+            }
+        }
+    }
+
+    public void createTransactInvokers() {
+        if (transactInvokers == null) {
+            try {
+                transactInvokers = new HashMap<>();
+                DatabaseSchema dbSchema = getSchema(HwvtepSchemaConstants.databaseName).get();
+                if(dbSchema != null) {
+                    transactInvokers.put(dbSchema, new TransactInvokerImpl(this,dbSchema));
+                }
+            } catch (InterruptedException | ExecutionException e) {
+                LOG.warn("Exception attempting to createTransactionInvokers {}: {}",connectionInfo,e);
+            }
+        }
+    }
+
+    private void monitorAllTables(String database, DatabaseSchema dbSchema, String filter) {
+        if((filter != null) && (!dbSchema.getName().equals(filter))) {
+            LOG.debug("Not monitoring tables in {}, filter: {}", dbSchema.getName(), filter);
+            return;
+        }
+        Set<String> tables = dbSchema.getTables();
+        if (tables != null) {
+            List<MonitorRequest> monitorRequests = Lists.newArrayList();
+            for (String tableName : tables) {
+                LOG.debug("HwvtepSouthbound monitoring table {} in {}", tableName, dbSchema.getName());
+                GenericTableSchema tableSchema = dbSchema.table(tableName, GenericTableSchema.class);
+                Set<String> columns = tableSchema.getColumns();
+                MonitorRequestBuilder<GenericTableSchema> monitorBuilder = MonitorRequestBuilder.builder(tableSchema);
+                for (String column : columns) {
+                    monitorBuilder.addColumn(column);
+                }
+                monitorRequests.add(monitorBuilder.with(new MonitorSelect(true, true, true, true)).build());
+            }
+            this.callback.update(monitor(dbSchema, monitorRequests, callback),dbSchema);
+        } else {
+            LOG.warn("No tables for schema {} for database {} for key {}",dbSchema,database,connectionInfo);
+        }
+    }
+
+    private void updateConnectionAttributes() {
+        LOG.debug("Update attributes of ovsdb node ip: {} port: {}",
+                    this.initialCreatedData.getConnectionInfo().getRemoteIp(),
+                    this.initialCreatedData.getConnectionInfo().getRemotePort());
+        /*
+         * TODO: Do we have anything to update?
+         * Hwvtep doesn't have other_config or external_ids like
+         * Open_vSwitch. What else will be needed?
+         */
+    }
+
+    public ListenableFuture<List<String>> getDatabases() {
+        return client.getDatabases();
+    }
+
+    public ListenableFuture<DatabaseSchema> getSchema(String database) {
+        return client.getSchema(database);
+    }
+
+    public TransactionBuilder transactBuilder(DatabaseSchema dbSchema) {
+        return client.transactBuilder(dbSchema);
+    }
+
+    public ListenableFuture<List<OperationResult>> transact(DatabaseSchema dbSchema, List<Operation> operations) {
+        return client.transact(dbSchema, operations);
+    }
+
+    public <E extends TableSchema<E>> TableUpdates monitor(DatabaseSchema schema,
+                    List<MonitorRequest> monitorRequests, MonitorCallBack callback) {
+        return client.monitor(schema, monitorRequests, callback);
+    }
+
+    @Override
+    public <E extends TableSchema<E>> TableUpdates monitor(DatabaseSchema schema,
+                    List<MonitorRequest> monitorRequests, MonitorHandle monitorHandle, MonitorCallBack callback) {
+        return null;
+    }
+
+    public void cancelMonitor(MonitorHandle handler) {
+        client.cancelMonitor(handler);
+    }
+
+    public void lock(String lockId, LockAquisitionCallback lockedCallBack, LockStolenCallback stolenCallback) {
+        client.lock(lockId, lockedCallBack, stolenCallback);
+    }
+
+    public ListenableFuture<Boolean> steal(String lockId) {
+        return client.steal(lockId);
+    }
+
+    public ListenableFuture<Boolean> unLock(String lockId) {
+        return client.unLock(lockId);
+    }
+
+    public void startEchoService(EchoServiceCallbackFilters callbackFilters) {
+        client.startEchoService(callbackFilters);
+    }
+
+    public void stopEchoService() {
+        client.stopEchoService();
+    }
+
+    public OvsdbConnectionInfo getConnectionInfo() {
+        return client.getConnectionInfo();
+    }
+
+    public boolean isActive() {
+        return client.isActive();
+    }
+
+    public void disconnect() {
+        client.disconnect();
+    }
+
+    public DatabaseSchema getDatabaseSchema(String dbName) {
+        return client.getDatabaseSchema(dbName);
+    }
+
+    public <T extends TypedBaseTable<?>> T createTypedRowWrapper(Class<T> klazz) {
+        return client.createTypedRowWrapper(klazz);
+    }
+
+    public <T extends TypedBaseTable<?>> T createTypedRowWrapper(DatabaseSchema dbSchema, Class<T> klazz) {
+        return client.createTypedRowWrapper(dbSchema, klazz);
+    }
+
+    public <T extends TypedBaseTable<?>> T getTypedRowWrapper(Class<T> klazz, Row<GenericTableSchema> row) {
+        return client.getTypedRowWrapper(klazz, row);
+    }
+
+    public ConnectionInfo getMDConnectionInfo() {
+        return connectionInfo;
+    }
+
+    public void setMDConnectionInfo(ConnectionInfo key) {
+        this.connectionInfo = key;
+    }
+
+    public InstanceIdentifier<Node> getInstanceIdentifier() {
+        return instanceIdentifier;
+    }
+
+    public NodeKey getNodeKey() {
+        //TODO: What is the alternative here?
+        return getInstanceIdentifier().firstKeyOf(Node.class, NodeKey.class);
+    }
+
+    public NodeId getNodeId() {
+        return getNodeKey().getNodeId();
+    }
+
+    public void setInstanceIdentifier(InstanceIdentifier<Node> iid) {
+        this.instanceIdentifier = iid;
+    }
+
+    public Entity getConnectedEntity() {
+        return this.connectedEntity;
+    }
+
+    public void setConnectedEntity(Entity entity ) {
+        this.connectedEntity = entity;
+    }
+
+    public Boolean hasOvsdbClient(OvsdbClient otherClient) {
+        return client.equals(otherClient);
+    }
+
+    public Boolean getHasDeviceOwnership() {
+        return hasDeviceOwnership;
+    }
+
+    public void setHasDeviceOwnership(Boolean hasDeviceOwnership) {
+        if (hasDeviceOwnership != null) {
+            this.hasDeviceOwnership = hasDeviceOwnership;
+        }
+    }
+
+    public void setDeviceOwnershipCandidateRegistration(@Nonnull EntityOwnershipCandidateRegistration registration) {
+        this.deviceOwnershipCandidateRegistration = registration;
+    }
+
+    public void closeDeviceOwnershipCandidateRegistration() {
+        if (deviceOwnershipCandidateRegistration != null) {
+            this.deviceOwnershipCandidateRegistration.close();
+            setHasDeviceOwnership(Boolean.FALSE);
+        }
+    }
+
+    public void setHwvtepGlobalAugmentation(HwvtepGlobalAugmentation hwvtepGlobalData) {
+        this.initialCreatedData = hwvtepGlobalData;
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepConnectionManager.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepConnectionManager.java
new file mode 100644 (file)
index 0000000..6945424
--- /dev/null
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound;
+
+import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+
+import javax.annotation.Nonnull;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
+import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipState;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.HwvtepGlobalRemoveCommand;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.PhysicalSwitchRemoveCommand;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.TransactionInvoker;
+import org.opendaylight.ovsdb.lib.OvsdbClient;
+import org.opendaylight.ovsdb.lib.OvsdbConnectionListener;
+import org.opendaylight.ovsdb.lib.impl.OvsdbConnectionService;
+import org.opendaylight.ovsdb.lib.operations.Operation;
+import org.opendaylight.ovsdb.lib.operations.OperationResult;
+import org.opendaylight.ovsdb.lib.operations.Select;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.Global;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalSwitchAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfo;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+
+public class HwvtepConnectionManager implements OvsdbConnectionListener, AutoCloseable{
+    private Map<ConnectionInfo, HwvtepConnectionInstance> clients =
+                    new ConcurrentHashMap<ConnectionInfo,HwvtepConnectionInstance>();
+    private static final Logger LOG = LoggerFactory.getLogger(HwvtepConnectionManager.class);
+    private static final String ENTITY_TYPE = "hwvtep";
+
+    private DataBroker db;
+    private TransactionInvoker txInvoker;
+    private Map<ConnectionInfo,InstanceIdentifier<Node>> instanceIdentifiers =
+                    new ConcurrentHashMap<ConnectionInfo,InstanceIdentifier<Node>>();
+    private Map<Entity, HwvtepConnectionInstance> entityConnectionMap =
+                    new ConcurrentHashMap<>();
+    private EntityOwnershipService entityOwnershipService;
+    private HwvtepDeviceEntityOwnershipListener hwvtepDeviceEntityOwnershipListener;
+
+    public HwvtepConnectionManager(DataBroker db, TransactionInvoker txInvoker,
+                    EntityOwnershipService entityOwnershipService) {
+        this.db = db;
+        this.txInvoker = txInvoker;
+        this.entityOwnershipService = entityOwnershipService;
+        this.hwvtepDeviceEntityOwnershipListener = new HwvtepDeviceEntityOwnershipListener(this,entityOwnershipService);
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (hwvtepDeviceEntityOwnershipListener != null) {
+            hwvtepDeviceEntityOwnershipListener.close();
+        }
+
+        for (OvsdbClient client: clients.values()) {
+            client.disconnect();
+        }
+    }
+
+    @Override
+    public void connected(@Nonnull final OvsdbClient client) {
+        HwvtepConnectionInstance hwClient = connectedButCallBacksNotRegistered(client);
+        registerEntityForOwnership(hwClient);
+        LOG.trace("connected client: {}", client);
+    }
+
+    @Override
+    public void disconnected(OvsdbClient client) {
+        LOG.info("HWVTEP Disconnected from {}:{}. Cleaning up the operational data store"
+                        ,client.getConnectionInfo().getRemoteAddress(),
+                        client.getConnectionInfo().getRemotePort());
+        ConnectionInfo key = HwvtepSouthboundMapper.createConnectionInfo(client);
+        HwvtepConnectionInstance hwvtepConnectionInstance = getConnectionInstance(key);
+        if (hwvtepConnectionInstance != null) {
+            //TODO: remove all the hwvtep nodes
+            txInvoker.invoke(new HwvtepGlobalRemoveCommand(hwvtepConnectionInstance, null, null));
+            removeConnectionInstance(key);
+
+            // Unregister Cluster Ownership for ConnectionInfo
+            unregisterEntityForOwnership(hwvtepConnectionInstance);
+        } else {
+            LOG.warn("HWVTEP disconnected event did not find connection instance for {}", key);
+        }
+        LOG.trace("disconnected client: {}", client);
+    }
+
+    public OvsdbClient connect(InstanceIdentifier<Node> iid, HwvtepGlobalAugmentation hwvtepGlobal) throws UnknownHostException {
+        InetAddress ip = HwvtepSouthboundMapper.createInetAddress(hwvtepGlobal.getConnectionInfo().getRemoteIp());
+        OvsdbClient client = OvsdbConnectionService.getService()
+                        .connect(ip, hwvtepGlobal.getConnectionInfo().getRemotePort().getValue());
+        if(client != null) {
+            putInstanceIdentifier(hwvtepGlobal.getConnectionInfo(), iid.firstIdentifierOf(Node.class));
+            HwvtepConnectionInstance hwvtepConnectionInstance = connectedButCallBacksNotRegistered(client);
+            hwvtepConnectionInstance.setHwvtepGlobalAugmentation(hwvtepGlobal);
+            hwvtepConnectionInstance.setInstanceIdentifier(iid.firstIdentifierOf(Node.class));
+
+            // Register Cluster Ownership for ConnectionInfo
+            registerEntityForOwnership(hwvtepConnectionInstance);
+        } else {
+            LOG.warn("Failed to connect to OVSDB node: {}", hwvtepGlobal.getConnectionInfo());
+        }
+        return client;
+    }
+    public void disconnect(HwvtepGlobalAugmentation ovsdbNode) throws UnknownHostException {
+        HwvtepConnectionInstance client = getConnectionInstance(ovsdbNode.getConnectionInfo());
+        if (client != null) {
+            client.disconnect();
+            // Unregister Cluster Ownership for ConnectionInfo
+            unregisterEntityForOwnership(client);
+            removeInstanceIdentifier(ovsdbNode.getConnectionInfo());
+        }
+    }
+
+    public HwvtepConnectionInstance connectedButCallBacksNotRegistered(final OvsdbClient externalClient) {
+        LOG.info("OVSDB Connection from {}:{}",externalClient.getConnectionInfo().getRemoteAddress(),
+                externalClient.getConnectionInfo().getRemotePort());
+        ConnectionInfo key = HwvtepSouthboundMapper.createConnectionInfo(externalClient);
+        HwvtepConnectionInstance hwvtepConnectionInstance = getConnectionInstance(key);
+
+        // Check if existing hwvtepConnectionInstance for the OvsdbClient present.
+        // In such cases, we will see if the hwvtepConnectionInstance has same externalClient.
+        if (hwvtepConnectionInstance != null) {
+            if (hwvtepConnectionInstance.hasOvsdbClient(externalClient)) {
+                LOG.warn("HWVTEP Connection Instance {} already exists for client {}", key, externalClient);
+                return hwvtepConnectionInstance;
+            }
+            LOG.warn("HWVTEP Connection Instance {} being replaced with client {}", key, externalClient);
+            hwvtepConnectionInstance.disconnect();
+
+            // Unregister Cluster Ownership for ConnectionInfo
+            // Because the hwvtepConnectionInstance is about to be completely replaced!
+            unregisterEntityForOwnership(hwvtepConnectionInstance);
+
+            removeConnectionInstance(key);
+        }
+
+        hwvtepConnectionInstance = new HwvtepConnectionInstance(key, externalClient, getInstanceIdentifier(key),
+                txInvoker);
+        hwvtepConnectionInstance.createTransactInvokers();
+        return hwvtepConnectionInstance;
+    }
+
+    private void putConnectionInstance(ConnectionInfo key,HwvtepConnectionInstance instance) {
+        ConnectionInfo connectionInfo = HwvtepSouthboundMapper.suppressLocalIpPort(key);
+        clients.put(connectionInfo, instance);
+        LOG.info("Clients after put: {}", clients);
+    }
+
+    public HwvtepConnectionInstance getConnectionInstance(ConnectionInfo key) {
+        ConnectionInfo connectionInfo = HwvtepSouthboundMapper.suppressLocalIpPort(key);
+        return clients.get(connectionInfo);
+    }
+
+    public HwvtepConnectionInstance getConnectionInstance(Node node) {
+        Preconditions.checkNotNull(node);
+        HwvtepGlobalAugmentation hwvtepGlobal = node.getAugmentation(HwvtepGlobalAugmentation.class);
+        PhysicalSwitchAugmentation pSwitchNode = node.getAugmentation(PhysicalSwitchAugmentation.class);
+        if (hwvtepGlobal != null) {
+            return getConnectionInstance(hwvtepGlobal.getConnectionInfo());
+        } //TODO: We could get it from Managers also.
+        else if(pSwitchNode != null){
+            return getConnectionInstance(pSwitchNode);
+        } else {
+            LOG.warn("This is not a node that gives any hint how to find its OVSDB Manager: {}",node);
+            return null;
+        }
+    }
+
+    public HwvtepConnectionInstance getConnectionInstance(InstanceIdentifier<Node> nodePath) {
+        try {
+            ReadOnlyTransaction transaction = db.newReadOnlyTransaction();
+            CheckedFuture<Optional<Node>, ReadFailedException> nodeFuture = transaction.read(
+                    LogicalDatastoreType.OPERATIONAL, nodePath);
+            transaction.close();
+            Optional<Node> optional = nodeFuture.get();
+            if (optional != null && optional.isPresent() && optional.get() instanceof Node) {
+                return this.getConnectionInstance(optional.get());
+            } else {
+                LOG.warn("Found non-topological node {} on path {}",optional);
+                return null;
+            }
+        } catch (Exception e) {
+            LOG.warn("Failed to get Hwvtep Node {}",nodePath, e);
+            return null;
+        }
+    }
+
+    private HwvtepConnectionInstance getConnectionInstance(HwvtepPhysicalSwitchAttributes pNode) {
+        Optional<HwvtepGlobalAugmentation> optional = HwvtepSouthboundUtil.getManagingNode(db, pNode);
+        if(optional.isPresent()) {
+            return getConnectionInstance(optional.get().getConnectionInfo());
+        } else {
+            return null;
+        }
+    }
+
+    private void removeConnectionInstance(ConnectionInfo key) {
+        ConnectionInfo connectionInfo = HwvtepSouthboundMapper.suppressLocalIpPort(key);
+        clients.remove(connectionInfo);
+        LOG.info("Clients after remove: {}", clients);
+    }
+
+    private void putInstanceIdentifier(ConnectionInfo key,InstanceIdentifier<Node> iid) {
+        ConnectionInfo connectionInfo = HwvtepSouthboundMapper.suppressLocalIpPort(key);
+        instanceIdentifiers.put(connectionInfo, iid);
+    }
+
+    public InstanceIdentifier<Node> getInstanceIdentifier(ConnectionInfo key) {
+        ConnectionInfo connectionInfo = HwvtepSouthboundMapper.suppressLocalIpPort(key);
+        InstanceIdentifier<Node> iid = instanceIdentifiers.get(connectionInfo);
+        return iid;
+    }
+
+    private void removeInstanceIdentifier(ConnectionInfo key) {
+        ConnectionInfo connectionInfo = HwvtepSouthboundMapper.suppressLocalIpPort(key);
+        instanceIdentifiers.remove(connectionInfo);
+    }
+
+    public OvsdbClient getClient(ConnectionInfo connectionInfo) {
+        return getConnectionInstance(connectionInfo);
+    }
+
+    private void registerEntityForOwnership(HwvtepConnectionInstance hwvtepConnectionInstance) {
+
+        Entity candidateEntity = getEntityFromConnectionInstance(hwvtepConnectionInstance);
+        entityConnectionMap.put(candidateEntity, hwvtepConnectionInstance);
+        hwvtepConnectionInstance.setConnectedEntity(candidateEntity);
+
+        try {
+            EntityOwnershipCandidateRegistration registration =
+                    entityOwnershipService.registerCandidate(candidateEntity);
+            hwvtepConnectionInstance.setDeviceOwnershipCandidateRegistration(registration);
+            LOG.info("HWVTEP entity {} is registered for ownership.", candidateEntity);
+
+            //If entity already has owner, it won't get notification from EntityOwnershipService
+            //so cache the connection instances.
+            Optional<EntityOwnershipState> ownershipStateOpt =
+                    entityOwnershipService.getOwnershipState(candidateEntity);
+            if (ownershipStateOpt.isPresent()) {
+                EntityOwnershipState ownershipState = ownershipStateOpt.get();
+                if (ownershipState.hasOwner() && !ownershipState.isOwner()) {
+                    if (getConnectionInstance(hwvtepConnectionInstance.getMDConnectionInfo()) != null) {
+                        LOG.info("OVSDB entity {} is already owned by other southbound plugin "
+                                + "instance, so *this* instance is NOT an OWNER of the device",
+                                hwvtepConnectionInstance.getConnectionInfo());
+                        putConnectionInstance(hwvtepConnectionInstance.getMDConnectionInfo(),hwvtepConnectionInstance);
+                    }
+                }
+            }
+        } catch (CandidateAlreadyRegisteredException e) {
+            LOG.warn("OVSDB entity {} was already registered for {} ownership", candidateEntity, e);
+        }
+
+    }
+
+    private Global getHwvtepGlobalTableEntry(HwvtepConnectionInstance connectionInstance) {
+        DatabaseSchema dbSchema = null;
+        Global globalRow = null;
+
+        try {
+            dbSchema = connectionInstance.getSchema(HwvtepSchemaConstants.databaseName).get();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.warn("Not able to fetch schema for database {} from device {}",
+                    HwvtepSchemaConstants.databaseName,connectionInstance.getConnectionInfo(),e);
+        }
+
+        if (dbSchema != null) {
+            GenericTableSchema hwvtepSchema = TyperUtils.getTableSchema(dbSchema, Global.class);
+
+            List<String> hwvtepTableColumn = new ArrayList<String>();
+            hwvtepTableColumn.addAll(hwvtepSchema.getColumns());
+            Select<GenericTableSchema> selectOperation = op.select(hwvtepSchema);
+            selectOperation.setColumns(hwvtepTableColumn);;
+
+            ArrayList<Operation> operations = new ArrayList<Operation>();
+            operations.add(selectOperation);
+            operations.add(op.comment("Fetching hardware_vtep table rows"));
+
+            List<OperationResult> results = null;
+            try {
+                results = connectionInstance.transact(dbSchema, operations).get();
+                if (results != null ) {
+                    OperationResult selectResult = results.get(0);
+                    globalRow = TyperUtils.getTypedRowWrapper(
+                            dbSchema,Global.class,selectResult.getRows().get(0));
+                }
+            } catch (InterruptedException | ExecutionException e) {
+                LOG.warn("Not able to fetch hardware_vtep table row from device {}",
+                        connectionInstance.getConnectionInfo(),e);
+            }
+        }
+        LOG.trace("Fetched global {} from hardware_vtep schema",globalRow);
+        return globalRow;
+    }
+
+    private Entity getEntityFromConnectionInstance(@Nonnull HwvtepConnectionInstance hwvtepConnectionInstance) {
+        YangInstanceIdentifier entityId = null;
+        InstanceIdentifier<Node> iid = hwvtepConnectionInstance.getInstanceIdentifier();
+        if ( iid == null ) {
+            //TODO: Is Global the right one?
+            Global hwvtepGlobalRow = getHwvtepGlobalTableEntry(hwvtepConnectionInstance);
+            iid = HwvtepSouthboundMapper.getInstanceIdentifier(hwvtepGlobalRow);
+            /* Let's set the iid now */
+            hwvtepConnectionInstance.setInstanceIdentifier(iid);
+            LOG.info("InstanceIdentifier {} generated for device "
+                    + "connection {}",iid, hwvtepConnectionInstance.getConnectionInfo());
+
+        }
+        entityId = HwvtepSouthboundUtil.getInstanceIdentifierCodec().getYangInstanceIdentifier(iid);
+        Entity deviceEntity = new Entity(ENTITY_TYPE, entityId);
+        LOG.debug("Entity {} created for device connection {}",
+                deviceEntity, hwvtepConnectionInstance.getConnectionInfo());
+        return deviceEntity;
+    }
+    private void unregisterEntityForOwnership(HwvtepConnectionInstance hwvtepConnectionInstance) {
+        hwvtepConnectionInstance.closeDeviceOwnershipCandidateRegistration();
+        entityConnectionMap.remove(hwvtepConnectionInstance.getConnectedEntity());
+    }
+
+    public void handleOwnershipChanged(EntityOwnershipChange ownershipChange) {
+        HwvtepConnectionInstance hwvtepConnectionInstance = getConnectionInstanceFromEntity(ownershipChange.getEntity());
+        LOG.info("handleOwnershipChanged: {} event received for device {}",
+                ownershipChange, hwvtepConnectionInstance != null ? hwvtepConnectionInstance.getConnectionInfo()
+                        : "THAT'S NOT REGISTERED BY THIS SOUTHBOUND PLUGIN INSTANCE");
+
+        if (hwvtepConnectionInstance == null) {
+            if (ownershipChange.isOwner()) {
+                LOG.warn("handleOwnershipChanged: found no connection instance for {}", ownershipChange.getEntity());
+            } else {
+                // EntityOwnershipService sends notification to all the nodes, irrespective of whether
+                // that instance registered for the device ownership or not. It is to make sure that
+                // If all the controller instance that was connected to the device are down, so the
+                // running instance can clear up the operational data store even though it was not
+                // connected to the device.
+                LOG.debug("handleOwnershipChanged: found no connection instance for {}", ownershipChange.getEntity());
+            }
+
+            // If entity has no owner, clean up the operational data store (it's possible because owner controller
+            // might went down abruptly and didn't get a chance to clean up the operational data store.
+            if (!ownershipChange.hasOwner()) {
+                LOG.debug("{} has no owner, cleaning up the operational data store", ownershipChange.getEntity());
+                // Below code might look weird but it's required. We want to give first opportunity to the
+                // previous owner of the device to clean up the operational data store if there is no owner now.
+                // That way we will avoid lot of nasty md-sal exceptions because of concurrent delete.
+                if (ownershipChange.wasOwner()) {
+                    cleanEntityOperationalData(ownershipChange.getEntity());
+                }
+                // If first cleanEntityOperationalData() was called, this call will be no-op.
+                cleanEntityOperationalData(ownershipChange.getEntity());
+            }
+            return;
+        }
+        //Connection detail need to be cached, irrespective of ownership result.
+        putConnectionInstance(hwvtepConnectionInstance.getMDConnectionInfo(),hwvtepConnectionInstance);
+
+        if (ownershipChange.isOwner() == hwvtepConnectionInstance.getHasDeviceOwnership()) {
+            LOG.debug("handleOwnershipChanged: no change in ownership for {}. Ownership status is : {}",
+                    hwvtepConnectionInstance.getConnectionInfo(), hwvtepConnectionInstance.getHasDeviceOwnership());
+            return;
+        }
+
+        hwvtepConnectionInstance.setHasDeviceOwnership(ownershipChange.isOwner());
+        // You were not an owner, but now you are
+        if (ownershipChange.isOwner()) {
+            LOG.info("handleOwnershipChanged: *this* southbound plugin instance is owner of device {}",
+                    hwvtepConnectionInstance.getConnectionInfo());
+
+            //*this* instance of southbound plugin is owner of the device,
+            //so register for monitor callbacks
+            hwvtepConnectionInstance.registerCallbacks();
+
+        } else {
+            //You were owner of the device, but now you are not. With the current ownership
+            //grant mechanism, this scenario should not occur. Because this scenario will occur
+            //when this controller went down or switch flap the connection, but in both the case
+            //it will go through the re-registration process. We need to implement this condition
+            //when clustering service implement a ownership grant strategy which can revoke the
+            //device ownership for load balancing the devices across the instances.
+            //Once this condition occur, we should unregister the callback.
+            LOG.error("handleOwnershipChanged: *this* southbound plugin instance is no longer the owner of device {}",
+                    hwvtepConnectionInstance.getNodeId().getValue());
+        }
+    }
+
+    private void cleanEntityOperationalData(Entity entity) {
+        InstanceIdentifier<Node> nodeIid = (InstanceIdentifier<Node>) HwvtepSouthboundUtil
+                .getInstanceIdentifierCodec().bindingDeserializer(entity.getId());
+
+        final ReadWriteTransaction transaction = db.newReadWriteTransaction();
+        Optional<Node> node = HwvtepSouthboundUtil.readNode(transaction, nodeIid);
+        if (node.isPresent()) {
+            HwvtepSouthboundUtil.deleteNode(transaction, nodeIid);
+        }
+    }
+
+    private HwvtepConnectionInstance getConnectionInstanceFromEntity(Entity entity) {
+        return entityConnectionMap.get(entity);
+    }
+
+    private class HwvtepDeviceEntityOwnershipListener implements EntityOwnershipListener {
+        private HwvtepConnectionManager hcm;
+        private EntityOwnershipListenerRegistration listenerRegistration;
+
+        HwvtepDeviceEntityOwnershipListener(HwvtepConnectionManager hcm, EntityOwnershipService entityOwnershipService) {
+            this.hcm = hcm;
+            listenerRegistration = entityOwnershipService.registerListener(ENTITY_TYPE, this);
+        }
+        public void close() {
+            listenerRegistration.close();
+        }
+        @Override
+        public void ownershipChanged(EntityOwnershipChange ownershipChange) {
+            hcm.handleOwnershipChanged(ownershipChange);
+        }
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepDataChangeListener.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepDataChangeListener.java
new file mode 100644 (file)
index 0000000..bdf84e6
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound;
+
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transact.HwvtepOperationalState;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transact.TransactCommandAggregator;
+import org.opendaylight.ovsdb.lib.OvsdbClient;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfoBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HwvtepDataChangeListener implements DataTreeChangeListener<Node>, AutoCloseable {
+
+    private ListenerRegistration<HwvtepDataChangeListener> registration;
+    private HwvtepConnectionManager hcm;
+    private DataBroker db;
+    private static final Logger LOG = LoggerFactory.getLogger(HwvtepDataChangeListener.class);
+
+    HwvtepDataChangeListener(DataBroker db, HwvtepConnectionManager hcm) {
+        LOG.info("Registering HwvtepDataChangeListener");
+        this.db = db;
+        this.hcm = hcm;
+        registerListener(db);
+    }
+
+    private void registerListener(final DataBroker db) {
+        final DataTreeIdentifier<Node> treeId =
+                        new DataTreeIdentifier<Node>(LogicalDatastoreType.CONFIGURATION, getWildcardPath());
+        try {
+            LOG.trace("Registering on path: {}", treeId);
+            registration = db.registerDataTreeChangeListener(treeId, HwvtepDataChangeListener.this);
+        } catch (final Exception e) {
+            LOG.warn("HwvtepDataChangeListener registration failed");
+            //TODO: Should we throw an exception here?
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+        if(registration != null) {
+            registration.close();
+        }
+    }
+
+    @Override
+    public void onDataTreeChanged(Collection<DataTreeModification<Node>> changes) {
+        LOG.trace("onDataTreeChanged: {}", changes);
+
+        /* TODO:
+         * Currently only handling changes to Global.
+         * Rest will be added later.
+         */
+        connect(changes);
+        
+        updateConnections(changes);
+        
+        updateData(changes);
+        
+        disconnect(changes);
+        /*
+        for (DataTreeModification<Node> change : changes) {
+            final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+            final DataObjectModification<Node> mod = change.getRootNode();
+                switch (mod.getModificationType()) {
+                case DELETE:
+                    LOG.trace("Data deleted: {}", mod.getDataBefore());
+                    //disconnect(mod);
+                    break;
+                case SUBTREE_MODIFIED:
+                    LOG.trace("Data modified: {} to {}", mod.getDataBefore(),mod.getDataAfter());
+                    updateConnections(mod);
+                    break;
+                case WRITE:
+                    if (mod.getDataBefore() == null) {
+                        LOG.trace("Data added: {}", mod.getDataAfter());
+                        connect(mod.getDataAfter());
+                    } else {
+                        LOG.trace("Data modified: {} to {}", mod.getDataBefore(),mod.getDataAfter());
+                        updateConnections(mod);
+                    }
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
+                }
+        }
+        */
+    }
+
+    private void connect(Collection<DataTreeModification<Node>> changes) {
+        for (DataTreeModification<Node> change : changes) {
+            final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+            final DataObjectModification<Node> mod = change.getRootNode();
+            Node node = getCreated(mod);
+            if (node != null) {
+                HwvtepGlobalAugmentation hwvtepGlobal = node.getAugmentation(HwvtepGlobalAugmentation.class);
+                if (hwvtepGlobal != null) {
+                    ConnectionInfo connection = hwvtepGlobal.getConnectionInfo();
+                    InstanceIdentifier<Node> iid = hcm.getInstanceIdentifier(connection);
+                    if (iid != null) {
+                        LOG.warn("Connection to device {} already exists. Plugin does not allow multiple connections "
+                                        + "to same device, hence dropping the request {}", connection, hwvtepGlobal);
+                    } else {
+                        try {
+                            hcm.connect(HwvtepSouthboundMapper.createInstanceIdentifier(node.getNodeId()), hwvtepGlobal);
+                        } catch (UnknownHostException e) {
+                            LOG.warn("Failed to connect to OVSDB node", e);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void updateConnections(Collection<DataTreeModification<Node>> changes) {
+        for (DataTreeModification<Node> change : changes) {
+            final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+            final DataObjectModification<Node> mod = change.getRootNode();
+            Node updated = getUpdated(mod);
+            if (updated != null) {
+                Node original = getOriginal(mod);
+                HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class);
+                HwvtepGlobalAugmentation hgOriginal = original.getAugmentation(HwvtepGlobalAugmentation.class);
+                if (hgUpdated != null && hgOriginal != null) {
+                    OvsdbClient client = hcm.getClient(hgUpdated.getConnectionInfo());
+                    if (client == null) {
+                        try {
+                            hcm.disconnect(hgOriginal);
+                            hcm.connect(HwvtepSouthboundMapper.createInstanceIdentifier(original.getNodeId()), hgUpdated);
+                        } catch (UnknownHostException e) {
+                            LOG.warn("Failed to update connection on OVSDB Node", e);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void updateData(Collection<DataTreeModification<Node>> changes) {
+        /* TODO: 
+         * Get connection instances for each change
+         * Update data for each connection
+         * Requires Command patterns. TBD.
+         */
+        for (Entry<HwvtepConnectionInstance, Collection<DataTreeModification<Node>>> changesEntry :
+                changesByConnectionInstance(changes).entrySet()) {
+            HwvtepConnectionInstance connectionInstance = changesEntry.getKey();
+            connectionInstance.transact(new TransactCommandAggregator(
+                new HwvtepOperationalState(db, changesEntry.getValue()),changesEntry.getValue()));
+        }
+    }
+
+    private void disconnect(Collection<DataTreeModification<Node>> changes) {
+        for (DataTreeModification<Node> change : changes) {
+            final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+            final DataObjectModification<Node> mod = change.getRootNode();
+            Node deleted = getRemoved(mod);
+            if (deleted != null) {
+                HwvtepGlobalAugmentation hgDeleted = deleted.getAugmentation(HwvtepGlobalAugmentation.class);
+                if (hgDeleted != null) {
+                    try {
+                        hcm.disconnect(hgDeleted);
+                    } catch (UnknownHostException e) {
+                        LOG.warn("Failed to disconnect OVSDB Node", e);
+                    }
+                }
+            }
+        }
+    }
+
+    private Node getCreated(DataObjectModification<Node> mod) {
+        if((mod.getModificationType() == ModificationType.WRITE)
+                        && (mod.getDataBefore() == null)){
+            return mod.getDataAfter();
+        }
+        return null;
+    }
+
+    private Node getRemoved(DataObjectModification<Node> mod) {
+        if(mod.getModificationType() == ModificationType.DELETE){
+            return mod.getDataBefore();
+        }
+        return null;
+    }
+
+    private Node getUpdated(DataObjectModification<Node> mod) {
+        Node node = null;
+        switch(mod.getModificationType()) {
+            case SUBTREE_MODIFIED:
+                node = mod.getDataAfter();
+                break;
+            case WRITE:
+                if(mod.getDataBefore() !=  null) {
+                    node = mod.getDataAfter();
+                }
+                break;
+            default:
+                break;
+        }
+        return node;
+    }
+
+    private Node getOriginal(DataObjectModification<Node> mod) {
+        Node node = null;
+        switch(mod.getModificationType()) {
+            case SUBTREE_MODIFIED:
+                node = mod.getDataBefore();
+                break;
+            case WRITE:
+                if(mod.getDataBefore() !=  null) {
+                    node = mod.getDataBefore();
+                }
+                break;
+            case DELETE:
+                node = mod.getDataBefore();
+                break;
+            default:
+                break;
+        }
+        return node;
+    }
+
+    private InstanceIdentifier<Node> getWildcardPath() {
+        InstanceIdentifier<Node> path = InstanceIdentifier
+                        .create(NetworkTopology.class)
+                        .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
+                        .child(Node.class);
+        return path;
+    }
+
+    private Map<HwvtepConnectionInstance, Collection<DataTreeModification<Node>>> changesByConnectionInstance(
+            Collection<DataTreeModification<Node>> changes) {
+        Map<HwvtepConnectionInstance, Collection<DataTreeModification<Node>>> result =
+                new HashMap<HwvtepConnectionInstance, Collection<DataTreeModification<Node>>>();
+        for (DataTreeModification<Node> change : changes) {
+            final DataObjectModification<Node> mod = change.getRootNode();
+            //From original node to get connection instance
+            Node node = mod.getDataBefore()!=null ? mod.getDataBefore() : mod.getDataAfter();
+            HwvtepConnectionInstance connection = hcm.getConnectionInstance(node);
+            if (connection != null) {
+                if (!result.containsKey(connection)) {
+                    List<DataTreeModification<Node>> tempChanges= new ArrayList<DataTreeModification<Node>>();
+                    tempChanges.add(change);
+                    result.put(connection, tempChanges);
+                } else {
+                    result.get(connection).add(change);
+                }
+            } else {
+                LOG.warn("Failed to get the connection of changed node: {}", node);
+            }
+        }
+        LOG.trace("Connection Change Map: {}", result);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepMonitorCallback.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepMonitorCallback.java
new file mode 100644 (file)
index 0000000..f73a0be
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.hwvtepsouthbound;
+
+import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.HwvtepOperationalCommandAggregator;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.TransactionInvoker;
+import org.opendaylight.ovsdb.lib.MonitorCallBack;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HwvtepMonitorCallback implements MonitorCallBack {
+
+    private static final Logger LOG = LoggerFactory.getLogger(HwvtepMonitorCallback.class);
+    private HwvtepConnectionInstance key;
+    private TransactionInvoker txInvoker;
+
+    HwvtepMonitorCallback(HwvtepConnectionInstance key,TransactionInvoker txInvoker) {
+        this.txInvoker = txInvoker;
+        this.key = key;
+    }
+
+    @Override
+    public void update(TableUpdates result, DatabaseSchema dbSchema) {
+        LOG.trace("result: {} dbSchema: {}",result,dbSchema.getName());
+        txInvoker.invoke(new HwvtepOperationalCommandAggregator(key, result, dbSchema));
+        LOG.trace("update exit");
+    }
+
+    @Override
+    public void exception(Throwable exception) {
+        LOG.warn("exception {}", exception);
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSchemaConstants.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSchemaConstants.java
new file mode 100644 (file)
index 0000000..3cb4590
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound;
+
+public class HwvtepSchemaConstants {
+    public static final String databaseName = "hardware_vtep";
+    public enum HWVTEPSCHEMATABLES {
+        GLOBAL("Global", null, null),
+        MANAGER("Manager","Global","managers"),
+        PHYSICALSWITCH("Physical_Switch","Global","switches"),
+        PHYSICALPORT("Physical_Port","Physical_Switch","ports"),
+        TUNNEL("Tunnel","Physical_Switch","tunnels"),
+        LOGICALSWITCH("Logical_Switch","Physical_Port","vlan_bindings"),
+        ACL("ACL","Physical_Port","acl_bindings"),
+        LOGICALBINDINGSTATS("Logical_Binding_Stats","Physical_Port","vlan_stats"),
+//        PHYSICALLOCATORLOCAL("Physical_Locator","Tunnel","local"),
+//        PHYSICALLOCATORREMOTE("Physical_Locator","Tunnel","remote"),
+        UCASTMACSLOCAL("Ucast_Macs_Local",null, null),
+        UCASTMACSREMOTE("Ucast_Macs_Remote",null, null),
+        MCASTMACSLOCAL("Mcast_Macs_Local",null, null),
+        PHYSICALLOCATORSET("Physical_Locator_Set","Mcast_Macs_Local", "locator_set"),
+        MCASTMACSREMOTE("Mcast_Macs_Remote",null, null),
+        LOGICALROUTER("Logical_Router",null, null),
+        ARPSOURCESLOCAL("Arp_Sources_Local",null, null),
+        ARPSOURCESREMOTE("Arp_Sources_Remote",null, null),
+        PHYSICALLOCATOR("Physical_Locator","Physical_Locator_Set", "locators"),
+        ACLENTRY("Acl_Entry","ACL", "acl_entries");
+
+        private final String tableName;
+        private final String parentTableName;
+        private final String columnNameInParentTable;
+
+        HWVTEPSCHEMATABLES(
+                final String tableName, final String parentTableName,
+                final String columnNameInParentTable) {
+            this.tableName = tableName;
+            this.parentTableName = parentTableName;
+            this.columnNameInParentTable = columnNameInParentTable;
+        }
+
+        public String getTableName() {
+            return this.tableName;
+        }
+
+        public String getParentTableName() {
+            return this.parentTableName;
+        }
+
+        public String getColumnNameInParentTable() {
+            return this.columnNameInParentTable;
+        }
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundConstants.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundConstants.java
new file mode 100644 (file)
index 0000000..57ee2fc
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+
+public class HwvtepSouthboundConstants {
+
+    public static final TopologyId HWVTEP_TOPOLOGY_ID = new TopologyId(new Uri("hwvtep:1"));
+    public static final String HWVTEP_URI_PREFIX = "hwvtep";
+    public static final Integer DEFAULT_OVSDB_PORT = 6640;
+    public static final String IID_OTHER_CONFIG_KEY = "opendaylight-iid";
+    public static final String UUID = "uuid";
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundMapper.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundMapper.java
new file mode 100644 (file)
index 0000000..1c87b83
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import org.opendaylight.ovsdb.lib.OvsdbClient;
+import org.opendaylight.ovsdb.schema.hardwarevtep.Global;
+import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
+import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfoBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HwvtepSouthboundMapper {
+    private static final Logger LOG = LoggerFactory.getLogger(HwvtepSouthboundMapper.class);
+    private static final String N_CONNECTIONS_STR = "n_connections";
+
+    private static NodeId createNodeId(HwvtepConnectionInstance client) {
+        NodeKey key = client.getInstanceIdentifier().firstKeyOf(Node.class, NodeKey.class);
+        return key.getNodeId();
+
+    }
+
+    public static InstanceIdentifier<Node> createInstanceIdentifier(NodeId nodeId) {
+        InstanceIdentifier<Node> nodePath = InstanceIdentifier
+                .create(NetworkTopology.class)
+                .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
+                .child(Node.class,new NodeKey(nodeId));
+        return nodePath;
+    }
+
+    public static InstanceIdentifier<Node> createInstanceIdentifier (OvsdbClient client) {
+        return createInstanceIdentifier(createIpAddress(client.getConnectionInfo().getRemoteAddress()),
+                        new PortNumber(client.getConnectionInfo().getRemotePort()));
+    }
+
+    private static InstanceIdentifier<Node> createInstanceIdentifier(IpAddress ip, PortNumber port) {
+        String uriString = HwvtepSouthboundConstants.HWVTEP_URI_PREFIX + "://"
+                + new String(ip.getValue()) + ":" + port.getValue();
+        Uri uri = new Uri(uriString);
+        NodeId nodeId = new NodeId(uri);
+        InstanceIdentifier<Node> path = InstanceIdentifier.create(NetworkTopology.class)
+                        .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
+                        .child(Node.class,new NodeKey(nodeId));
+        LOG.debug("Created ovsdb path: {}",path);
+        return path;
+    }
+
+    public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
+        NodeKey nodeKey = iid.firstKeyOf(Node.class, NodeKey.class);
+        return nodeKey.getNodeId();
+    }
+
+    public static IpAddress createIpAddress(InetAddress address) {
+        IpAddress ip = null;
+        if (address instanceof Inet4Address) {
+            ip = createIpAddress((Inet4Address)address);
+        } else if (address instanceof Inet6Address) {
+            ip = createIpAddress((Inet6Address)address);
+        }
+        return ip;
+    }
+
+    public static IpAddress createIpAddress(Inet4Address address) {
+        Ipv4Address ipv4 = new Ipv4Address(address.getHostAddress());
+        return new IpAddress(ipv4);
+    }
+
+    public static IpAddress createIpAddress(Inet6Address address) {
+        Ipv6Address ipv6 = new Ipv6Address(address.getHostAddress());
+        return new IpAddress(ipv6);
+    }
+
+    public static ConnectionInfo createConnectionInfo(OvsdbClient client) {
+        ConnectionInfoBuilder connectionInfoBuilder = new ConnectionInfoBuilder();
+        connectionInfoBuilder.setRemoteIp(createIpAddress(client.getConnectionInfo().getRemoteAddress()));
+        connectionInfoBuilder.setRemotePort(new PortNumber(client.getConnectionInfo().getRemotePort()));
+        connectionInfoBuilder.setLocalIp(createIpAddress(client.getConnectionInfo().getLocalAddress()));
+        connectionInfoBuilder.setLocalPort(new PortNumber(client.getConnectionInfo().getLocalPort()));
+        return connectionInfoBuilder.build();
+    }
+
+    public static ConnectionInfo suppressLocalIpPort(ConnectionInfo connectionInfo) {
+        ConnectionInfoBuilder connectionInfoBuilder = new ConnectionInfoBuilder();
+        connectionInfoBuilder.setRemoteIp(connectionInfo.getRemoteIp());
+        connectionInfoBuilder.setRemotePort(connectionInfo.getRemotePort());
+        return connectionInfoBuilder.build();
+    }
+
+    public static InetAddress createInetAddress(IpAddress ip) throws UnknownHostException {
+        if (ip.getIpv4Address() != null) {
+            return InetAddress.getByName(ip.getIpv4Address().getValue());
+        } else if (ip.getIpv6Address() != null) {
+            return InetAddress.getByName(ip.getIpv6Address().getValue());
+        } else {
+            throw new UnknownHostException("IP Address has no value");
+        }
+    }
+
+    public static InstanceIdentifier<Node> getInstanceIdentifier(Global global) {
+        InstanceIdentifier<Node> iid = null;
+        String nodeString = HwvtepSouthboundConstants.HWVTEP_URI_PREFIX + "://" +
+                        HwvtepSouthboundConstants.UUID + "/" + global.getUuid().toString();
+            NodeId nodeId = new NodeId(new Uri(nodeString));
+            NodeKey nodeKey = new NodeKey(nodeId);
+            TopologyKey topoKey = new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID);
+            iid = InstanceIdentifier.builder(NetworkTopology.class)
+                            .child(Topology.class, topoKey)
+                            .child(Node.class,nodeKey)
+                            .build();
+        return iid;
+    }
+
+    public static InstanceIdentifier<Node> createInstanceIdentifier(HwvtepConnectionInstance client,
+                    PhysicalSwitch pSwitch) {
+        InstanceIdentifier<Node> iid = null;
+        String nodeString = client.getNodeKey().getNodeId().getValue() + "/physicalswitch/" + pSwitch.getName();
+        NodeId nodeId = new NodeId(new Uri(nodeString));
+        NodeKey nodeKey = new NodeKey(nodeId);
+        iid =InstanceIdentifier.builder(NetworkTopology.class)
+                        .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
+                        .child(Node.class, nodeKey).build();
+        return iid;
+    }
+
+    public static InstanceIdentifier<Node> createInstanceIdentifier(HwvtepConnectionInstance client,
+                    LogicalSwitch lSwitch) {
+        InstanceIdentifier<Node> iid = null;
+        String nodeString = client.getNodeKey().getNodeId().getValue() + "/logicalswitch/" + lSwitch.getName();
+        NodeId nodeId = new NodeId(new Uri(nodeString));
+        NodeKey nodeKey = new NodeKey(nodeId);
+        iid =InstanceIdentifier.builder(NetworkTopology.class)
+                        .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
+                        .child(Node.class, nodeKey).build();
+        return iid;
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundProvider.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundProvider.java
new file mode 100644 (file)
index 0000000..44a2789
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.hwvtepsouthbound;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
+import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipState;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.TransactionInvoker;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.TransactionInvokerImpl;
+import org.opendaylight.ovsdb.lib.OvsdbConnection;
+import org.opendaylight.ovsdb.lib.impl.OvsdbConnectionService;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+
+public class HwvtepSouthboundProvider implements BindingAwareProvider, AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(HwvtepSouthboundProvider.class);
+    private static final String ENTITY_TYPE = "ovsdb-hwvtepsouthbound-provider";
+
+    public static DataBroker getDb() {
+        return db;
+    }
+
+    private static DataBroker db;
+    private HwvtepConnectionManager cm;
+    private OvsdbConnection ovsdbConnection;
+    private TransactionInvoker txInvoker;
+    private EntityOwnershipService entityOwnershipService;
+    private EntityOwnershipCandidateRegistration registration;
+    private HwvtepsbPluginInstanceEntityOwnershipListener providerOwnershipChangeListener;
+    private HwvtepDataChangeListener hwvtepDTListener;
+
+    public HwvtepSouthboundProvider(
+            EntityOwnershipService entityOwnershipServiceDependency,
+            OvsdbConnection ovsdbConnection) {
+        this.entityOwnershipService = entityOwnershipServiceDependency;
+        registration = null;
+        this.ovsdbConnection = ovsdbConnection;
+        LOG.info("HwvtepSouthboundProvider ovsdbConnectionService: {}", ovsdbConnection);
+    }
+
+    @Override
+    public void onSessionInitiated(ProviderContext session) {
+        LOG.info("HwvtepSouthboundProvider Session Initiated");
+        db = session.getSALService(DataBroker.class);
+        txInvoker = new TransactionInvokerImpl(db);
+        cm = new HwvtepConnectionManager(db, txInvoker, entityOwnershipService);
+        hwvtepDTListener = new HwvtepDataChangeListener(db, cm);
+
+        //Register listener for entityOnwership changes
+        providerOwnershipChangeListener =
+                new HwvtepsbPluginInstanceEntityOwnershipListener(this,this.entityOwnershipService);
+        entityOwnershipService.registerListener(ENTITY_TYPE,providerOwnershipChangeListener);
+
+        //register instance entity to get the ownership of the provider
+        Entity instanceEntity = new Entity(ENTITY_TYPE, ENTITY_TYPE);
+        try {
+            Optional<EntityOwnershipState> ownershipStateOpt = entityOwnershipService.getOwnershipState(instanceEntity);
+            registration = entityOwnershipService.registerCandidate(instanceEntity);
+            if (ownershipStateOpt.isPresent()) {
+                EntityOwnershipState ownershipState = ownershipStateOpt.get();
+                if (ownershipState.hasOwner() && !ownershipState.isOwner()) {
+                    ovsdbConnection.registerConnectionListener(cm);
+                    ovsdbConnection.startOvsdbManager(HwvtepSouthboundConstants.DEFAULT_OVSDB_PORT);
+                }
+            }
+        } catch (CandidateAlreadyRegisteredException e) {
+            LOG.warn("HWVTEP Southbound Provider instance entity {} was already "
+                    + "registered for {} ownership", instanceEntity, e);
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+        LOG.info("HwvtepSouthboundProvider Closed");
+        if(cm != null){
+            cm.close();
+            cm = null;
+        }
+        if(registration != null) {
+            registration.close();
+            registration = null;
+        }
+        if(providerOwnershipChangeListener != null) {
+            providerOwnershipChangeListener.close();
+            providerOwnershipChangeListener = null;
+        }
+        if(hwvtepDTListener != null) {
+            hwvtepDTListener.close();
+            hwvtepDTListener = null;
+        }
+    }
+
+    private void initializeHwvtepTopology(LogicalDatastoreType type) {
+        InstanceIdentifier<Topology> path = InstanceIdentifier
+                .create(NetworkTopology.class)
+                .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID));
+        initializeTopology(type);
+        ReadWriteTransaction transaction = db.newReadWriteTransaction();
+        CheckedFuture<Optional<Topology>, ReadFailedException> hwvtepTp = transaction.read(type, path);
+        try {
+            if (!hwvtepTp.get().isPresent()) {
+                TopologyBuilder tpb = new TopologyBuilder();
+                tpb.setTopologyId(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID);
+                transaction.put(type, path, tpb.build());
+                transaction.submit();
+            } else {
+                transaction.cancel();
+            }
+        } catch (Exception e) {
+            LOG.error("Error initializing hwvtep topology", e);
+        }
+    }
+
+    private void initializeTopology(LogicalDatastoreType type) {
+        ReadWriteTransaction transaction = db.newReadWriteTransaction();
+        InstanceIdentifier<NetworkTopology> path = InstanceIdentifier.create(NetworkTopology.class);
+        CheckedFuture<Optional<NetworkTopology>, ReadFailedException> topology = transaction.read(type,path);
+        try {
+            if (!topology.get().isPresent()) {
+                NetworkTopologyBuilder ntb = new NetworkTopologyBuilder();
+                transaction.put(type,path,ntb.build());
+                transaction.submit();
+            } else {
+                transaction.cancel();
+            }
+        } catch (Exception e) {
+            LOG.error("Error initializing hwvtep topology {}",e);
+        }
+    }
+
+    public void handleOwnershipChange(EntityOwnershipChange ownershipChange) {
+        if (ownershipChange.isOwner()) {
+            LOG.info("*This* instance of HWVTEP southbound provider is set as a MASTER instance");
+            LOG.info("Initialize HWVTEP topology {} in operational and config data store if not already present"
+                    ,HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID);
+            initializeHwvtepTopology(LogicalDatastoreType.OPERATIONAL);
+            initializeHwvtepTopology(LogicalDatastoreType.CONFIGURATION);
+        } else {
+            LOG.info("*This* instance of HWVTEP southbound provider is set as a SLAVE instance");
+        }
+        ovsdbConnection.registerConnectionListener(cm);
+        ovsdbConnection.startOvsdbManager(HwvtepSouthboundConstants.DEFAULT_OVSDB_PORT);
+    }
+
+    private class HwvtepsbPluginInstanceEntityOwnershipListener implements EntityOwnershipListener {
+        private HwvtepSouthboundProvider hsp;
+        private EntityOwnershipListenerRegistration listenerRegistration;
+
+        HwvtepsbPluginInstanceEntityOwnershipListener(HwvtepSouthboundProvider hsp,
+                EntityOwnershipService entityOwnershipService) {
+            this.hsp = hsp;
+            listenerRegistration = entityOwnershipService.registerListener(ENTITY_TYPE, this);
+        }
+
+        public void close() {
+            this.listenerRegistration.close();
+        }
+        @Override
+        public void ownershipChanged(EntityOwnershipChange ownershipChange) {
+            hsp.handleOwnershipChange(ownershipChange);
+        }
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundUtil.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundUtil.java
new file mode 100644 (file)
index 0000000..483cf15
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalSwitchAttributes;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+
+public class HwvtepSouthboundUtil {
+
+    private static final Logger LOG = LoggerFactory.getLogger(HwvtepSouthboundUtil.class);
+
+    private static InstanceIdentifierCodec instanceIdentifierCodec;
+
+    private HwvtepSouthboundUtil() {
+        // Prevent instantiating a utility class
+    }
+
+    public static void setInstanceIdentifierCodec(InstanceIdentifierCodec iidc) {
+        instanceIdentifierCodec = iidc;
+    }
+
+    public static InstanceIdentifierCodec getInstanceIdentifierCodec() {
+        return instanceIdentifierCodec;
+    }
+
+    public static String serializeInstanceIdentifier(InstanceIdentifier<?> iid) {
+        return instanceIdentifierCodec.serialize(iid);
+    }
+
+    public static InstanceIdentifier<?> deserializeInstanceIdentifier(String iidString) {
+        InstanceIdentifier<?> result = null;
+        try {
+            result = instanceIdentifierCodec.bindingDeserializer(iidString);
+        } catch (DeserializationException e) {
+            LOG.warn("Unable to deserialize iidString", e);
+        }
+        return result;
+    }
+
+    public static <D extends org.opendaylight.yangtools.yang.binding.DataObject> Optional<D> readNode(
+                    ReadWriteTransaction transaction, final InstanceIdentifier<D> connectionIid) {
+        Optional<D> node = Optional.absent();
+        try {
+            node = transaction.read(LogicalDatastoreType.OPERATIONAL, connectionIid).checkedGet();
+        } catch (final ReadFailedException e) {
+            LOG.warn("Read Operational/DS for Node failed! {}", connectionIid, e);
+        }
+        return node;
+    }
+
+    public static <D extends org.opendaylight.yangtools.yang.binding.DataObject> boolean deleteNode(
+                    ReadWriteTransaction transaction, final InstanceIdentifier<D> connectionIid) {
+        boolean result = false;
+        transaction.delete(LogicalDatastoreType.OPERATIONAL, connectionIid);
+        CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
+        try {
+            future.checkedGet();
+            result = true;
+        } catch (TransactionCommitFailedException e) {
+            LOG.warn("Failed to delete {} ", connectionIid, e);
+        }
+        return result;
+    }
+
+    public static Optional<HwvtepGlobalAugmentation> getManagingNode(DataBroker db,
+                    HwvtepPhysicalSwitchAttributes pNode) {
+        Preconditions.checkNotNull(pNode);
+        Optional<HwvtepGlobalAugmentation> result = null;
+        HwvtepGlobalRef ref = pNode.getManagedBy();
+        if (ref != null && ref.getValue() != null) {
+            result = getManagingNode(db, ref);
+        } else {
+            LOG.warn("Cannot find client for PhysicalSwitch without a specified ManagedBy {}", pNode);
+            return Optional.absent();
+        }
+        if (!result.isPresent()) {
+            LOG.warn("Failed to find managing node for PhysicalSwitch {}", pNode);
+        }
+        return result;
+    }
+
+    public static Optional<HwvtepGlobalAugmentation> getManagingNode(DataBroker db,
+                    HwvtepLogicalSwitchAttributes lNode) {
+        Preconditions.checkNotNull(lNode);
+        Optional<HwvtepGlobalAugmentation> result = null;
+
+        HwvtepGlobalRef ref = lNode.getLogicalSwitchManagedBy();
+        if (ref != null && ref.getValue() != null) {
+            result = getManagingNode(db, ref);
+        } else {
+            LOG.warn("Cannot find client for LogicalSwitch without a specified ManagedBy {}", lNode);
+            return Optional.absent();
+        }
+        if(!result.isPresent()) {
+            LOG.warn("Failed to find managing node for PhysicalSwitch {}",lNode);
+        }
+        return result;
+    }
+
+    private static Optional<HwvtepGlobalAugmentation> getManagingNode(DataBroker db, HwvtepGlobalRef ref) {
+        try {
+            ReadOnlyTransaction transaction = db.newReadOnlyTransaction();
+            @SuppressWarnings("unchecked")
+            // Note: erasure makes this safe in combination with the typecheck
+            // below
+            InstanceIdentifier<Node> path = (InstanceIdentifier<Node>) ref.getValue();
+
+            CheckedFuture<Optional<Node>, ReadFailedException> nf =
+                            transaction.read(LogicalDatastoreType.OPERATIONAL, path);
+            transaction.close();
+            Optional<Node> optional = nf.get();
+            if (optional != null && optional.isPresent()) {
+                HwvtepGlobalAugmentation hwvtepNode = null;
+                Node node = optional.get();
+                if (node instanceof HwvtepGlobalAugmentation) {
+                    hwvtepNode = (HwvtepGlobalAugmentation) node;
+                } else if (node != null) {
+                    hwvtepNode = node.getAugmentation(HwvtepGlobalAugmentation.class);
+                }
+                if (hwvtepNode != null) {
+                    return Optional.of(hwvtepNode);
+                } else {
+                    LOG.warn("Hwvtep switch claims to be managed by {} but " + "that HwvtepNode does not exist",
+                                    ref.getValue());
+                    return Optional.absent();
+                }
+            } else {
+                LOG.warn("Mysteriously got back a thing which is *not* a topology Node: {}", optional);
+                return Optional.absent();
+            }
+        } catch (Exception e) {
+            LOG.warn("Failed to get HwvtepNode {}", ref, e);
+            return Optional.absent();
+        }
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/InstanceIdentifierCodec.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/InstanceIdentifierCodec.java
new file mode 100644 (file)
index 0000000..9444d53
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound;
+
+import java.net.URI;
+
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
+import org.opendaylight.yangtools.yang.data.util.AbstractModuleStringInstanceIdentifierCodec;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+
+public class InstanceIdentifierCodec extends AbstractModuleStringInstanceIdentifierCodec
+    implements SchemaContextListener {
+
+    private DataSchemaContextTree dataSchemaContextTree;
+    private SchemaContext context;
+    private BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer;
+
+    public InstanceIdentifierCodec(SchemaService schemaService,
+            BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer) {
+        schemaService.registerSchemaContextListener(this);
+        this.bindingNormalizedNodeSerializer = bindingNormalizedNodeSerializer;
+    }
+
+    @Override
+    protected DataSchemaContextTree getDataContextTree() {
+        return dataSchemaContextTree;
+    }
+
+    @Override
+    protected Module moduleForPrefix(final String prefix) {
+        return context.findModuleByName(prefix, null);
+    }
+
+    @Override
+    protected String prefixForNamespace(final URI namespace) {
+        final Module module = context.findModuleByNamespaceAndRevision(namespace, null);
+        return module == null ? null : module.getName();
+    }
+
+    @Override
+    public void onGlobalContextUpdated(SchemaContext context) {
+        this.context = context;
+        this.dataSchemaContextTree = DataSchemaContextTree.from(context);
+    }
+
+    public String serialize(InstanceIdentifier<?> iid) {
+        YangInstanceIdentifier normalizedIid = bindingNormalizedNodeSerializer.toYangInstanceIdentifier(iid);
+        return serialize(normalizedIid);
+    }
+
+    public YangInstanceIdentifier getYangInstanceIdentifier(InstanceIdentifier<?> iid) {
+        return bindingNormalizedNodeSerializer.toYangInstanceIdentifier(iid);
+    }
+
+    public  InstanceIdentifier<?> bindingDeserializer(String iidString) throws DeserializationException {
+        YangInstanceIdentifier normalizedYangIid = deserialize(iidString);
+        return bindingNormalizedNodeSerializer.fromYangInstanceIdentifier(normalizedYangIid);
+    }
+
+    public InstanceIdentifier<?> bindingDeserializer(YangInstanceIdentifier yangIID) {
+        return bindingNormalizedNodeSerializer.fromYangInstanceIdentifier(yangIID);
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/impl/HwvtepSouthboundProvider.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/impl/HwvtepSouthboundProvider.java
deleted file mode 100644 (file)
index 8ef25ea..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.ovsdb.hwvtepsouthbound.impl;
-
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class HwvtepSouthboundProvider implements BindingAwareProvider, AutoCloseable {
-
-    private static final Logger LOG = LoggerFactory.getLogger(HwvtepSouthboundProvider.class);
-
-    @Override
-    public void onSessionInitiated(ProviderContext session) {
-        LOG.info("HwvtepSouthboundProvider Session Initiated");
-    }
-
-    @Override
-    public void close() throws Exception {
-        LOG.info("HwvtepSouthboundProvider Closed");
-    }
-
-}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/AbstractTransactCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/AbstractTransactCommand.java
new file mode 100644 (file)
index 0000000..d766f19
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+
+public abstract class AbstractTransactCommand implements TransactCommand {
+
+    private HwvtepOperationalState operationalState;
+    private Collection<DataTreeModification<Node>> changes;
+
+    protected AbstractTransactCommand() {
+        // NO OP
+    }
+
+    public AbstractTransactCommand(HwvtepOperationalState state, Collection<DataTreeModification<Node>> changes) {
+        this.operationalState = state;
+        this.changes = changes;
+    }
+
+    public HwvtepOperationalState getOperationalState() {
+        return operationalState;
+    }
+
+    public Collection<DataTreeModification<Node>> getChanges() {
+        return changes;
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/HwvtepOperationalState.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/HwvtepOperationalState.java
new file mode 100644 (file)
index 0000000..26c515d
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorSetAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+
+public class HwvtepOperationalState {
+    private static final Logger LOG = LoggerFactory.getLogger(HwvtepOperationalState.class);
+    private Map<InstanceIdentifier<Node>, Node> operationalNodes = new HashMap<>();
+
+    public HwvtepOperationalState(DataBroker db, Collection<DataTreeModification<Node>> changes) {
+        ReadOnlyTransaction transaction = db.newReadOnlyTransaction();
+        Map<InstanceIdentifier<Node>, Node> nodeCreateOrUpdate =
+            extractCreatedOrUpdatedOrRemoved(changes, Node.class);
+            //TransactUtils.extractCreatedOrUpdatedOrRemoved(changes, Node.class);
+        if (nodeCreateOrUpdate != null) {
+            for (Entry<InstanceIdentifier<Node>, Node> entry: nodeCreateOrUpdate.entrySet()) {
+                CheckedFuture<Optional<Node>, ReadFailedException> nodeFuture =
+                        transaction.read(LogicalDatastoreType.OPERATIONAL, entry.getKey());
+                try {
+                    Optional<Node> nodeOptional = nodeFuture.get();
+                    if (nodeOptional.isPresent()) {
+                        operationalNodes.put(entry.getKey(), nodeOptional.get());
+                    }
+                } catch (InterruptedException | ExecutionException e) {
+                    LOG.warn("Error reading from datastore",e);
+                }
+            }
+        }
+        transaction.close();
+    }
+
+    private Node getCreated(DataObjectModification<Node> mod) {
+        if((mod.getModificationType() == ModificationType.WRITE)
+                        && (mod.getDataBefore() == null)){
+            return mod.getDataAfter();
+        }
+        return null;
+    }
+
+    private Node getRemoved(DataObjectModification<Node> mod) {
+        if(mod.getModificationType() == ModificationType.DELETE){
+            return mod.getDataBefore();
+        }
+        return null;
+    }
+
+    private Node getUpdated(DataObjectModification<Node> mod) {
+        Node node = null;
+        switch(mod.getModificationType()) {
+            case SUBTREE_MODIFIED:
+                node = mod.getDataAfter();
+                break;
+            case WRITE:
+                if(mod.getDataBefore() !=  null) {
+                    node = mod.getDataAfter();
+                }
+                break;
+            default:
+                break;
+        }
+        return node;
+    }
+
+    private Node getOriginal(DataObjectModification<Node> mod) {
+        Node node = null;
+        switch(mod.getModificationType()) {
+            case SUBTREE_MODIFIED:
+                node = mod.getDataBefore();
+                break;
+            case WRITE:
+                if(mod.getDataBefore() !=  null) {
+                    node = mod.getDataBefore();
+                }
+                break;
+            case DELETE:
+                node = mod.getDataBefore();
+                break;
+            default:
+                break;
+        }
+        return node;
+    }
+
+    private Map<InstanceIdentifier<Node>, Node> extractCreatedOrUpdatedOrRemoved(
+            Collection<DataTreeModification<Node>> changes, Class<Node> class1) {
+        // TODO Auto-generated method stub
+        Map<InstanceIdentifier<Node>, Node> result = new HashMap<InstanceIdentifier<Node>, Node>();
+        for (DataTreeModification<Node> change : changes) {
+            final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+            final DataObjectModification<Node> mod = change.getRootNode();
+            Node created = getCreated(mod);
+            result.put(key, created);
+            Node updated = getUpdated(mod);
+            result.put(key, updated);
+            Node deleted = getRemoved(mod);
+            result.put(key, deleted);
+        }
+        return result;
+    }
+
+    public Optional<Node> getGlobalNode(InstanceIdentifier<?> iid) {
+        InstanceIdentifier<Node> nodeIid = iid.firstIdentifierOf(Node.class);
+        return Optional.fromNullable(operationalNodes.get(nodeIid));
+    }
+
+    public Optional<HwvtepLogicalSwitchAugmentation> getLogicalSwitchAugmentation(InstanceIdentifier<?> iid) {
+        Optional<Node> nodeOptional = getGlobalNode(iid);
+        if (nodeOptional.isPresent()) {
+            return Optional.fromNullable(nodeOptional.get().getAugmentation(HwvtepLogicalSwitchAugmentation.class));
+        }
+        return Optional.absent();
+    }
+
+    public Optional<PhysicalSwitchAugmentation> getPhysicalSwitchAugmentation(InstanceIdentifier<?> iid) {
+        Optional<Node> nodeOptional = getGlobalNode(iid);
+        if (nodeOptional.isPresent()) {
+            return Optional.fromNullable(nodeOptional.get().getAugmentation(PhysicalSwitchAugmentation.class));
+        }
+        return Optional.absent();
+    }
+
+    public Optional<HwvtepPhysicalLocatorSetAugmentation> getPhysicalLocatorSetAugmentation(InstanceIdentifier<?> iid) {
+        Optional<Node> nodeOptional = getGlobalNode(iid);
+        if (nodeOptional.isPresent()) {
+            return Optional.fromNullable(nodeOptional.get().getAugmentation(HwvtepPhysicalLocatorSetAugmentation.class));
+        }
+        return Optional.absent();
+    }
+
+    public Optional<TerminationPoint> getHwvtepTerminationPoint(InstanceIdentifier<?> iid) {
+        if (iid != null) {
+            Optional<Node> nodeOptional = getGlobalNode(iid);
+            if (nodeOptional.isPresent() && nodeOptional.get().getTerminationPoint() != null) {
+                TerminationPointKey key = iid.firstKeyOf(TerminationPoint.class, TerminationPointKey.class);
+                if (key != null) {
+                    for (TerminationPoint tp:nodeOptional.get().getTerminationPoint()) {
+                        if (tp.getKey().equals(key)) {
+                            return Optional.of(tp);
+                        }
+                    }
+                }
+            }
+        }
+        return Optional.absent();
+    }
+
+    public Optional<HwvtepPhysicalLocatorAugmentation> getPhysicalLocatorAugmentation(InstanceIdentifier<?> iid) {
+        Optional<TerminationPoint> nodeOptional = getHwvtepTerminationPoint(iid);
+        if (nodeOptional.isPresent()) {
+            return Optional.fromNullable(nodeOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class));
+        }
+        return Optional.absent();
+    }
+
+    public Optional<HwvtepPhysicalPortAugmentation> getPhysycalPortAugmentation(InstanceIdentifier<?> iid) {
+        Optional<TerminationPoint> tpOptional = getHwvtepTerminationPoint(iid);
+        if (tpOptional.isPresent()) {
+            return Optional.fromNullable(tpOptional.get().getAugmentation(HwvtepPhysicalPortAugmentation.class));
+        }
+        return Optional.absent();
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalSwitchRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalSwitchRemoveCommand.java
new file mode 100644 (file)
index 0000000..6be3c44
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+
+import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.Global;
+import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+public class LogicalSwitchRemoveCommand extends AbstractTransactCommand {
+    private static final Logger LOG = LoggerFactory.getLogger(LogicalSwitchRemoveCommand.class);
+
+    public LogicalSwitchRemoveCommand(HwvtepOperationalState state,
+            Collection<DataTreeModification<Node>> changes) {
+        super(state, changes);
+    }
+
+    @Override
+    public void execute(TransactionBuilder transaction) {
+        //TODO
+        /*Set<InstanceIdentifier<HwvtepLogicalSwitchAugmentation>> removeds =
+                TransactUtils.extractRemoved(getChanges(),HwvtepLogicalSwitchAugmentation.class);
+        Map<InstanceIdentifier<HwvtepLogicalSwitchAugmentation>, HwvtepLogicalSwitchAugmentation> originals
+            = TransactUtils.extractOriginal(getChanges(),HwvtepLogicalSwitchAugmentation.class);
+        for (InstanceIdentifier<HwvtepLogicalSwitchAugmentation> removed: removeds) {
+            LOG.info("Received request to delete ovsdb node {}",removed);
+            HwvtepLogicalSwitchAugmentation original = originals.get(removed);
+            LogicalSwitch bridge = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), LogicalSwitch.class, null);
+            Optional<HwvtepLogicalSwitchAugmentation> lsAugmentationOptional = getOperationalState()
+                    .getLogicalSwitchAugmentation(removed);
+            if (lsAugmentationOptional.isPresent() && lsAugmentationOptional.get().getHwvtepLogicalSwitchExternalId() != null) {
+                UUID lsUuid = new UUID(lsAugmentationOptional.get().getHwvtepLogicalSwitchExternalId().getValue());
+                Global ovs = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
+                        Global.class,null);
+                transaction.add(op.delete(bridge.getSchema())
+                        .where(bridge.getUuidColumn().getSchema().opEqual(lsUuid)).build());
+                transaction.add(op.comment("Logical Switch: Deleting " + original.getHwvtepNodeName()));
+            } else {
+                LOG.warn("Unable to delete logical switch {} because it was not found in the operational store, "
+                        + "and thus we cannot retrieve its UUID", removed);
+            }
+
+        }*/
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalSwitchUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalSwitchUpdateCommand.java
new file mode 100644 (file)
index 0000000..730c936
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+
+import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+public class LogicalSwitchUpdateCommand extends AbstractTransactCommand {
+    private static final Logger LOG = LoggerFactory.getLogger(LogicalSwitchUpdateCommand.class);
+
+    public LogicalSwitchUpdateCommand(HwvtepOperationalState state,
+            Collection<DataTreeModification<Node>> changes) {
+        super(state, changes);
+    }
+
+    @Override
+    public void execute(TransactionBuilder transaction) {
+        Map<InstanceIdentifier<HwvtepLogicalSwitchAugmentation>, HwvtepLogicalSwitchAugmentation> created =
+                extractCreated(getChanges(),HwvtepLogicalSwitchAugmentation.class);
+        if(created != null) {
+            for(Entry<InstanceIdentifier<HwvtepLogicalSwitchAugmentation>, HwvtepLogicalSwitchAugmentation> logicalSwitchEntry:
+                created.entrySet()) {
+                updateLogicalSwitch(transaction,  logicalSwitchEntry.getKey(), logicalSwitchEntry.getValue());
+            }
+        }
+    }
+
+
+    private void updateLogicalSwitch(TransactionBuilder transaction,
+            InstanceIdentifier<HwvtepLogicalSwitchAugmentation> iid, HwvtepLogicalSwitchAugmentation logicalSwitchAugmentation) {
+        LOG.debug("Creating a logical switch named: {}", logicalSwitchAugmentation.getHwvtepNodeName());
+        Optional<HwvtepLogicalSwitchAugmentation> operationalLogicalSwitchOptional =
+                getOperationalState().getLogicalSwitchAugmentation(iid);
+        DatabaseSchema dbSchema = transaction.getDatabaseSchema();
+        LogicalSwitch logicalSwitch = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), LogicalSwitch.class);
+        if(!operationalLogicalSwitchOptional.isPresent()) {
+            setName(logicalSwitch, logicalSwitchAugmentation, operationalLogicalSwitchOptional);
+            setTunnelKey(logicalSwitch, logicalSwitchAugmentation, operationalLogicalSwitchOptional);
+            transaction.add(op.insert(logicalSwitch));
+        } else {
+            String existingLogicalSwitchName = operationalLogicalSwitchOptional.get().getHwvtepNodeName().getValue();
+            // Name is immutable, and so we *can't* update it.  So we use extraBridge for the schema stuff
+            LogicalSwitch extraLogicalSwitch = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), LogicalSwitch.class);
+            extraLogicalSwitch.setName("");
+            transaction.add(op.update(logicalSwitch)
+                    .where(extraLogicalSwitch.getNameColumn().getSchema().opEqual(existingLogicalSwitchName))
+                    .build());
+            //stampInstanceIdentifier(transaction, iid.firstIdentifierOf(Node.class),existingBridgeName);
+        }
+    }
+
+    private void setName(LogicalSwitch logicalSwitch, HwvtepLogicalSwitchAugmentation logicalSwitchAugmentation,
+            Optional<HwvtepLogicalSwitchAugmentation> operationalLogicalSwitchOptional) {
+        if(logicalSwitchAugmentation.getHwvtepNodeName() != null) {
+            logicalSwitch.setName(logicalSwitchAugmentation.getHwvtepNodeName().getValue());
+        } else if(operationalLogicalSwitchOptional.isPresent() && operationalLogicalSwitchOptional.get().getHwvtepNodeName() != null) {
+            logicalSwitch.setName(operationalLogicalSwitchOptional.get().getHwvtepNodeName().getValue());
+        }
+    }
+
+    private void setTunnelKey(LogicalSwitch logicalSwitch, HwvtepLogicalSwitchAugmentation logicalSwitchAugmentation,
+            Optional<HwvtepLogicalSwitchAugmentation> operationalLogicalSwitchOptional) {
+        if(logicalSwitchAugmentation.getTunnelKey() != null) {
+            Set<Long> tunnel = new HashSet<Long>();
+            tunnel.add(Long.valueOf(logicalSwitchAugmentation.getTunnelKey()));
+            logicalSwitch.setTunnelKey(tunnel);
+        } else if(operationalLogicalSwitchOptional.isPresent() && operationalLogicalSwitchOptional.get().getTunnelKey() != null) {
+            Set<Long> tunnel = new HashSet<Long>();
+            tunnel.add(Long.valueOf(operationalLogicalSwitchOptional.get().getTunnelKey()));
+            logicalSwitch.setTunnelKey(tunnel);
+        }
+    }
+
+    private Node getCreated(DataObjectModification<Node> mod) {
+        if((mod.getModificationType() == ModificationType.WRITE)
+                        && (mod.getDataBefore() == null)){
+            return mod.getDataAfter();
+        }
+        return null;
+    }
+
+    private Map<InstanceIdentifier<HwvtepLogicalSwitchAugmentation>, HwvtepLogicalSwitchAugmentation> extractCreated(
+            Collection<DataTreeModification<Node>> changes, Class<HwvtepLogicalSwitchAugmentation> class1) {
+        Map<InstanceIdentifier<HwvtepLogicalSwitchAugmentation>, HwvtepLogicalSwitchAugmentation> result
+            = new HashMap<InstanceIdentifier<HwvtepLogicalSwitchAugmentation>, HwvtepLogicalSwitchAugmentation>();
+        if(changes != null && !changes.isEmpty()) {
+            for(DataTreeModification<Node> change : changes) {
+                final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+                final DataObjectModification<Node> mod = change.getRootNode();
+                Node created = getCreated(mod);
+                if(created != null) {
+                    HwvtepLogicalSwitchAugmentation logicalSwitch = created.getAugmentation(HwvtepLogicalSwitchAugmentation.class);
+                    InstanceIdentifier<HwvtepLogicalSwitchAugmentation> iid = change.getRootPath().getRootIdentifier().augmentation(HwvtepLogicalSwitchAugmentation.class);
+                    if(logicalSwitch != null) {
+                        result.put(iid, logicalSwitch);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalLocatorRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalLocatorRemoveCommand.java
new file mode 100644 (file)
index 0000000..8206b4c
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PhysicalLocatorRemoveCommand extends AbstractTransactCommand {
+    private static final Logger LOG = LoggerFactory.getLogger(PhysicalLocatorRemoveCommand.class);
+
+    public PhysicalLocatorRemoveCommand(HwvtepOperationalState state,
+            Collection<DataTreeModification<Node>> changes) {
+        super(state, changes);
+    }
+
+    @Override
+    public void execute(TransactionBuilder transaction) {
+        //TODO
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalLocatorUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalLocatorUpdateCommand.java
new file mode 100644 (file)
index 0000000..113d78b
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PhysicalLocatorUpdateCommand extends AbstractTransactCommand {
+    private static final Logger LOG = LoggerFactory.getLogger(PhysicalLocatorUpdateCommand.class);
+
+    public PhysicalLocatorUpdateCommand(HwvtepOperationalState state,
+            Collection<DataTreeModification<Node>> changes) {
+        super(state, changes);
+    }
+
+    @Override
+    public void execute(TransactionBuilder transaction) {
+        //TODO
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortRemoveCommand.java
new file mode 100644 (file)
index 0000000..aafc847
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PhysicalPortRemoveCommand extends AbstractTransactCommand {
+    private static final Logger LOG = LoggerFactory.getLogger(PhysicalPortRemoveCommand.class);
+
+    public PhysicalPortRemoveCommand(HwvtepOperationalState state,
+            Collection<DataTreeModification<Node>> changes) {
+        super(state, changes);
+    }
+
+    @Override
+    public void execute(TransactionBuilder transaction) {
+        //TODO
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortUpdateCommand.java
new file mode 100644 (file)
index 0000000..caef6cb
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PhysicalPortUpdateCommand extends AbstractTransactCommand {
+    private static final Logger LOG = LoggerFactory.getLogger(PhysicalPortUpdateCommand.class);
+
+    public PhysicalPortUpdateCommand(HwvtepOperationalState state,
+            Collection<DataTreeModification<Node>> changes) {
+        super(state, changes);
+    }
+
+    @Override
+    public void execute(TransactionBuilder transaction) {
+        //TODO
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactCommand.java
new file mode 100644 (file)
index 0000000..ac9eeea
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+
+public interface TransactCommand {
+
+    void execute(TransactionBuilder transaction);
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactCommandAggregator.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactCommandAggregator.java
new file mode 100644 (file)
index 0000000..3d15f38
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+
+public class TransactCommandAggregator implements TransactCommand {
+
+    private List<TransactCommand> commands = new ArrayList<TransactCommand>();
+
+    public TransactCommandAggregator(HwvtepOperationalState state, Collection<DataTreeModification<Node>> changes) {
+        commands.add(new LogicalSwitchUpdateCommand(state,changes));
+        commands.add(new LogicalSwitchRemoveCommand(state,changes));
+        commands.add(new PhysicalLocatorUpdateCommand(state,changes));
+        commands.add(new PhysicalLocatorRemoveCommand(state,changes));
+        commands.add(new PhysicalPortUpdateCommand(state,changes));
+        commands.add(new PhysicalPortRemoveCommand(state,changes));
+    }
+
+    @Override
+    public void execute(TransactionBuilder transaction) {
+        for (TransactCommand command:commands) {
+            command.execute(transaction);
+        }
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactInvoker.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactInvoker.java
new file mode 100644 (file)
index 0000000..a077116
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+
+public interface TransactInvoker {
+    void invoke(TransactCommand command);
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactInvokerImpl.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactInvokerImpl.java
new file mode 100644 (file)
index 0000000..4402c88
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.lib.operations.OperationResult;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class TransactInvokerImpl implements TransactInvoker {
+    private static final Logger LOG = LoggerFactory.getLogger(TransactInvokerImpl.class);
+    private HwvtepConnectionInstance connectionInstance;
+    private DatabaseSchema dbSchema;
+
+    public TransactInvokerImpl(HwvtepConnectionInstance connectionInstance, DatabaseSchema dbSchema) {
+        this.connectionInstance = connectionInstance;
+        this.dbSchema = dbSchema;
+    }
+
+    @Override
+    public void invoke(TransactCommand command) {
+        TransactionBuilder tb = new TransactionBuilder(connectionInstance, dbSchema);
+        command.execute(tb);
+        ListenableFuture<List<OperationResult>> result = tb.execute();
+        LOG.debug("invoke: command: {}, tb: {}", command, tb);
+        if (tb.getOperations().size() > 0) {
+            try {
+                List<OperationResult> got = result.get();
+                LOG.debug("OVSDB transaction result: {}", got);
+            } catch (Exception e) {
+                LOG.warn("Transact execution exception: ", e);
+            }
+            LOG.trace("invoke exit command: {}, tb: {}", command, tb);
+        }
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactUtils.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactUtils.java
new file mode 100644 (file)
index 0000000..e8a01e6
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2015 China Telecom Beijing Research Institute and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TransactUtils {
+    private static final Logger LOG = LoggerFactory.getLogger(TransactUtils.class);
+
+    public static Node getCreated(DataObjectModification<Node> mod) {
+        if((mod.getModificationType() == ModificationType.WRITE)
+                        && (mod.getDataBefore() == null)){
+            return mod.getDataAfter();
+        }
+        return null;
+    }
+
+    public static Node getRemoved(DataObjectModification<Node> mod) {
+        if(mod.getModificationType() == ModificationType.DELETE){
+            return mod.getDataBefore();
+        }
+        return null;
+    }
+
+    public static Node getUpdated(DataObjectModification<Node> mod) {
+        Node node = null;
+        switch(mod.getModificationType()) {
+            case SUBTREE_MODIFIED:
+                node = mod.getDataAfter();
+                break;
+            case WRITE:
+                if(mod.getDataBefore() !=  null) {
+                    node = mod.getDataAfter();
+                }
+                break;
+            default:
+                break;
+        }
+        return node;
+    }
+
+    public static Node getOriginal(DataObjectModification<Node> mod) {
+        Node node = null;
+        switch(mod.getModificationType()) {
+            case SUBTREE_MODIFIED:
+                node = mod.getDataBefore();
+                break;
+            case WRITE:
+                if(mod.getDataBefore() !=  null) {
+                    node = mod.getDataBefore();
+                }
+                break;
+            case DELETE:
+                node = mod.getDataBefore();
+                break;
+            default:
+                break;
+        }
+        return node;
+    }
+
+    public static Map<InstanceIdentifier<Node>, Node> extractCreatedOrUpdatedOrRemoved(
+            Collection<DataTreeModification<Node>> changes, Class<Node> class1) {
+        // TODO Auto-generated method stub
+        Map<InstanceIdentifier<Node>, Node> result = new HashMap<InstanceIdentifier<Node>, Node>();
+        for(DataTreeModification<Node> change : changes) {
+            final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+            final DataObjectModification<Node> mod = change.getRootNode();
+            Node created = getCreated(mod);
+            result.put(key, created);
+            Node updated = getUpdated(mod);
+            result.put(key, updated);
+            Node deleted = getRemoved(mod);
+            result.put(key, deleted);
+        }
+        return null;
+    }
+
+    /*
+    public static <T extends Augmentation<Node>> Map<InstanceIdentifier<? extends DataObject>, T> extractCreated(
+            Collection<DataTreeModification<Node>> changes, Class<T> class1) {
+        // TODO Auto-generated method stub
+        Map<InstanceIdentifier<?>, T> result =
+            new HashMap<InstanceIdentifier<?>, T>();
+        if(changes != null && !changes.isEmpty()) {
+            for(DataTreeModification<Node> change : changes) {
+                final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+                final DataObjectModification<Node> mod = change.getRootNode();
+                Node created = getCreated(mod);
+                if(created != null) {
+                    T logicalSwitch = created.getAugmentation(class1);
+                    created.getKey().getNodeId().get
+                    logicalSwitch.
+                    InstanceIdentifier<?> iid = change.getRootPath().getRootIdentifier()..augmentation(class1);
+                    if(logicalSwitch != null) {
+                        result.put(iid, logicalSwitch);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+    */
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/AbstractTransactionCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/AbstractTransactionCommand.java
new file mode 100644 (file)
index 0000000..67f507d
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfo;
+
+public abstract class AbstractTransactionCommand implements TransactionCommand{
+
+    private TableUpdates updates;
+    private DatabaseSchema dbSchema;
+    private HwvtepConnectionInstance key;
+
+    public TableUpdates getUpdates() {
+        return updates;
+    }
+
+    public DatabaseSchema getDbSchema() {
+        return dbSchema;
+    }
+
+    public ConnectionInfo getConnectionInfo() {
+        return key.getMDConnectionInfo();
+    }
+
+    public HwvtepConnectionInstance getOvsdbConnectionInstance() {
+        return key;
+    }
+
+    protected AbstractTransactionCommand() {
+        // NO OP
+    }
+
+    public AbstractTransactionCommand(HwvtepConnectionInstance key,TableUpdates updates, DatabaseSchema dbSchema) {
+        this.updates = updates;
+        this.dbSchema = dbSchema;
+        this.key = key;
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/GlobalUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/GlobalUpdateCommand.java
new file mode 100644 (file)
index 0000000..656fd23
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.Global;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GlobalUpdateCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(GlobalUpdateCommand.class);
+    private Map<UUID, Global> updatedHwvtepRows =
+                    TyperUtils.extractRowsUpdated(Global.class, getUpdates(),getDbSchema());
+    private Map<UUID, Global> oldHwvtepRows =
+                    TyperUtils.extractRowsUpdated(Global.class, getUpdates(),getDbSchema());
+
+    public GlobalUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+                super(key, updates, dbSchema);
+            }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        for (Entry<UUID, Global> entry : updatedHwvtepRows.entrySet()) {
+            Global hwvtepGlobal = entry.getValue();
+            Global oldEntry = oldHwvtepRows.get(entry.getKey());
+            final InstanceIdentifier<Node> nodePath = getInstanceIdentifier(hwvtepGlobal);
+            LOG.trace("Processing hardware_vtep update for nodePath: {}", nodePath);
+
+            HwvtepGlobalAugmentationBuilder hwvtepGlobalBuilder = new HwvtepGlobalAugmentationBuilder();
+            hwvtepGlobalBuilder.setConnectionInfo(getConnectionInfo());
+            NodeBuilder nodeBuilder = new NodeBuilder();
+            nodeBuilder.setNodeId(getNodeId(hwvtepGlobal));
+            nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, hwvtepGlobalBuilder.build());
+            transaction.merge(LogicalDatastoreType.OPERATIONAL, nodePath, nodeBuilder.build());
+        }
+    }
+
+    private InstanceIdentifier<Node> getInstanceIdentifier(Global hwvtep) {
+        InstanceIdentifier<Node> iid = getOvsdbConnectionInstance().getInstanceIdentifier();
+        if(iid == null) {
+            LOG.warn("InstanceIdentifier was null when it shouldn't be");
+            /* This can be case for switch initiated connection */
+            iid = HwvtepSouthboundMapper.getInstanceIdentifier(hwvtep);
+            getOvsdbConnectionInstance().setInstanceIdentifier(iid);
+        }
+        return getOvsdbConnectionInstance().getInstanceIdentifier();
+    }
+
+    private NodeId getNodeId(Global hwvtep) {
+        NodeKey nodeKey = getInstanceIdentifier(hwvtep).firstKeyOf(Node.class, NodeKey.class);
+        return nodeKey.getNodeId();
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepGlobalRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepGlobalRemoveCommand.java
new file mode 100644 (file)
index 0000000..acf2ee9
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Managers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+
+public class HwvtepGlobalRemoveCommand extends AbstractTransactionCommand {
+    private static final Logger LOG = LoggerFactory.getLogger(HwvtepGlobalRemoveCommand.class);
+    private static final long ONE_CONNECTED_MANAGER = 1;
+    private static final long ONE_ACTIVE_CONNECTION_IN_PASSIVE_MODE = 1;
+
+    public HwvtepGlobalRemoveCommand(HwvtepConnectionInstance key,TableUpdates updates,DatabaseSchema dbSchema) {
+        super(key,updates,dbSchema);
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        CheckedFuture<Optional<Node>, ReadFailedException> hwvtepGlobalFuture = transaction.read(
+                LogicalDatastoreType.OPERATIONAL, getOvsdbConnectionInstance().getInstanceIdentifier());
+        Optional<Node> hwvtepGlobalOptional;
+        try {
+            hwvtepGlobalOptional = hwvtepGlobalFuture.get();
+            if (hwvtepGlobalOptional.isPresent()) {
+                Node hwvtepNode = hwvtepGlobalOptional.get();
+                HwvtepGlobalAugmentation hgAugmentation = hwvtepNode.getAugmentation(HwvtepGlobalAugmentation.class);
+                if (checkIfOnlyConnectedManager(hgAugmentation)) {
+                    if (hgAugmentation != null) {
+                        if (hgAugmentation.getSwitches() != null) {
+                            for (Switches hwSwitch : hgAugmentation.getSwitches()) {
+                                LOG.debug("Deleting hwvtep switch {}", hwSwitch);
+                                transaction.delete(
+                                        LogicalDatastoreType.OPERATIONAL, hwSwitch.getSwitchRef().getValue());
+                            }
+                        } else {
+                            LOG.debug("{} had no switches", hwvtepNode.getNodeId().getValue());
+                        }
+                    } else {
+                        LOG.warn("{} had no HwvtepGlobalAugmentation", hwvtepNode.getNodeId().getValue());
+                    }
+                    transaction.delete(LogicalDatastoreType.OPERATIONAL,
+                            getOvsdbConnectionInstance().getInstanceIdentifier());
+                } else {
+                    LOG.debug("Other southbound plugin instances in cluster are connected to the device,"
+                            + " not deleting OvsdbNode form data store.");
+                }
+            }
+        } catch (Exception e) {
+            LOG.warn("Failure to delete ovsdbNode {}",e);
+        }
+    }
+
+    private boolean checkIfOnlyConnectedManager(HwvtepGlobalAugmentation hgAugmentation) {
+        Managers onlyConnectedManager = null;
+        if (hgAugmentation != null) {
+            int connectedManager = 0;
+            if (hgAugmentation.getManagers() != null) {
+                for (Managers manager : hgAugmentation.getManagers()) {
+                    if (manager.isIsConnected()) {
+                        connectedManager++;
+                        if (connectedManager > ONE_CONNECTED_MANAGER) {
+                            return false;
+                        }
+                        onlyConnectedManager = manager;
+                    }
+                }
+            }
+            if (connectedManager == 0) {
+                return true;
+            }
+        }
+        /*When switch is listening in passive mode, this number represent number of active connection to the device
+        This is to handle the controller initiated connection scenario, where all the controller will connect, but
+        switch will have only one manager.
+        */
+        /* CLUSTERING-TODO-ITEM: For hwvtep we don't have getNumberOfConnections()
+         * FIXME: Add it to yang?
+        if (onlyConnectedManager.getNumberOfConnections() > ONE_ACTIVE_CONNECTION_IN_PASSIVE_MODE) {
+            return false;
+        }*/
+        return true;
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepManagerUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepManagerUpdateCommand.java
new file mode 100644 (file)
index 0000000..8c8710b
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.Map;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.Manager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HwvtepManagerUpdateCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(HwvtepManagerUpdateCommand.class);
+    private Map<UUID, Manager> updatedMgrRows;
+    private Map<UUID, Manager> oldMgrRows;
+
+    public HwvtepManagerUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        super(key, updates, dbSchema);
+        updatedMgrRows = TyperUtils.extractRowsUpdated(Manager.class, getUpdates(),getDbSchema());
+        oldMgrRows = TyperUtils.extractRowsOld(Manager.class, getUpdates(),getDbSchema());
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        // TODO Auto-generated method stub
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepOperationalCommandAggregator.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepOperationalCommandAggregator.java
new file mode 100644 (file)
index 0000000..2c0e963
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+
+public class HwvtepOperationalCommandAggregator implements TransactionCommand {
+
+
+    private List<TransactionCommand> commands = new ArrayList<TransactionCommand>();
+
+    public HwvtepOperationalCommandAggregator(HwvtepConnectionInstance key,TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        //TODO: Add commands in here
+        commands.add(new GlobalUpdateCommand(key, updates, dbSchema));
+        commands.add(new PhysicalSwitchUpdateCommand(key, updates, dbSchema));
+        commands.add(new PhysicalSwitchRemoveCommand(key, updates, dbSchema));
+        commands.add(new HwvtepManagerUpdateCommand(key, updates, dbSchema));
+        commands.add(new LogicalSwitchUpdateCommand(key, updates, dbSchema));
+        commands.add(new LogicalSwitchRemoveCommand(key, updates, dbSchema));
+        commands.add(new PhysicalPortUpdateCommand(key, updates, dbSchema));
+        commands.add(new PhysicalPortRemoveCommand(key, updates, dbSchema));
+        commands.add(new HwvtepTunnelUpdateCommand(key, updates, dbSchema));
+        commands.add(new PhysicalLocatorUpdateCommand(key, updates, dbSchema));
+        commands.add(new PhysicalLocatorSetUpdateCommand(key, updates, dbSchema));
+        commands.add(new UcastMacsLocalUpdateCommand(key, updates, dbSchema));
+        commands.add(new UcastMacsRemoteUpdateCommand(key, updates, dbSchema));
+        commands.add(new McastMacsLocalUpdateCommand(key, updates, dbSchema));
+        commands.add(new McastMacsRemoteUpdateCommand(key, updates, dbSchema));
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        for (TransactionCommand command: commands) {
+            command.execute(transaction);
+        }
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepTunnelUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepTunnelUpdateCommand.java
new file mode 100644 (file)
index 0000000..3c51cac
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.Tunnel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HwvtepTunnelUpdateCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(HwvtepTunnelUpdateCommand.class);
+    private Map<UUID, Tunnel> updatedTunnelRows;
+    private Map<UUID, Tunnel> oldTunnelRows;
+
+    public HwvtepTunnelUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        super(key, updates, dbSchema);
+        updatedTunnelRows = TyperUtils.extractRowsUpdated(Tunnel.class, getUpdates(),getDbSchema());
+        oldTunnelRows = TyperUtils.extractRowsOld(Tunnel.class, getUpdates(),getDbSchema());
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        // TODO Auto-generated method stub
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/LogicalSwitchRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/LogicalSwitchRemoveCommand.java
new file mode 100644 (file)
index 0000000..388d158
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.Collection;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalSwitchRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.SwitchesKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LogicalSwitchRemoveCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(LogicalSwitchRemoveCommand.class);
+
+    public LogicalSwitchRemoveCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        super(key, updates, dbSchema);
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        Collection<LogicalSwitch> deletedLSRows = TyperUtils.extractRowsRemoved(LogicalSwitch.class, getUpdates(),getDbSchema()).values();
+        if(deletedLSRows != null && !deletedLSRows.isEmpty()) {
+            for (LogicalSwitch lSwitch : deletedLSRows) {
+                InstanceIdentifier<Node> nodeIid = HwvtepSouthboundMapper.createInstanceIdentifier(
+                                getOvsdbConnectionInstance(), lSwitch);
+                /*
+                 * TODO:
+                 * Once hwvtep.yang is modified, replace HwvtepPhysicalSwitchRef with appropriate
+                 * class [HWvtepSwitchRef].
+                 */
+                InstanceIdentifier<Switches> switchIid = getOvsdbConnectionInstance().getInstanceIdentifier()
+                                .augmentation(HwvtepGlobalAugmentation.class)
+                                .child(Switches.class, new SwitchesKey(new HwvtepPhysicalSwitchRef(nodeIid)));
+                        // TODO handle removal of reference to managed switch from model
+                        transaction.delete(LogicalDatastoreType.OPERATIONAL, nodeIid);
+                        transaction.delete(LogicalDatastoreType.OPERATIONAL, switchIid);
+            }
+        }
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/LogicalSwitchUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/LogicalSwitchUpdateCommand.java
new file mode 100644 (file)
index 0000000..3725684
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalSwitchRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.SwitchesBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+public class LogicalSwitchUpdateCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(LogicalSwitchUpdateCommand.class);
+    private Map<UUID, LogicalSwitch> updatedLSRows;
+    private Map<UUID, LogicalSwitch> oldLSRows;
+
+    public LogicalSwitchUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        super(key, updates, dbSchema);
+        updatedLSRows = TyperUtils.extractRowsUpdated(LogicalSwitch.class, getUpdates(),getDbSchema());
+        oldLSRows = TyperUtils.extractRowsOld(LogicalSwitch.class, getUpdates(),getDbSchema());
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        if(updatedLSRows != null && !updatedLSRows.isEmpty()) {
+            for (Entry<UUID, LogicalSwitch> entry : updatedLSRows.entrySet()) {
+                updateLogicalSwitch(transaction, entry.getValue());
+            }
+        }
+    }
+
+    private void updateLogicalSwitch(ReadWriteTransaction transaction, LogicalSwitch lSwitch) {
+        final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
+        Optional<Node> connection = HwvtepSouthboundUtil.readNode(transaction, connectionIId);
+        if (connection.isPresent()) {
+            LOG.debug("Connection {} is present",connection);
+            Node connectionNode = buildConnectionNode(lSwitch);
+            transaction.merge(LogicalDatastoreType.OPERATIONAL, connectionIId, connectionNode);
+            // Update the Logical Switch with whatever data we are getting
+            InstanceIdentifier<Node> lsIid = getInstanceIdentifier(lSwitch);
+            Node lsNode = buildLogicalSwitchNode(lSwitch);
+            transaction.merge(LogicalDatastoreType.OPERATIONAL, lsIid, lsNode);
+//            TODO: Delete entries that are no longer needed
+        }
+    }
+
+    private Node buildLogicalSwitchNode(LogicalSwitch lSwitch) {
+        NodeBuilder lsNodeBuilder = new NodeBuilder();
+        NodeId psNodeId = getNodeId(lSwitch);
+        lsNodeBuilder.setNodeId(psNodeId);
+        HwvtepLogicalSwitchAugmentationBuilder lsAugBuilder = new HwvtepLogicalSwitchAugmentationBuilder();
+        setManagedBy(lsAugBuilder, lSwitch);
+        setLogicalSwitchId(lsAugBuilder, lSwitch);
+
+        lsNodeBuilder.addAugmentation(HwvtepLogicalSwitchAugmentation.class, lsAugBuilder.build());
+
+        LOG.trace("Built with the intent to store PhysicalSwitch data {}",
+                lsAugBuilder.build());
+        return lsNodeBuilder.build();
+    }
+
+    private void setManagedBy(HwvtepLogicalSwitchAugmentationBuilder lsAugBuilder, LogicalSwitch lSwitch) {
+        // TODO This requires change to yang file
+    }
+
+
+    private void setLogicalSwitchId(HwvtepLogicalSwitchAugmentationBuilder lsAugBuilder, LogicalSwitch lSwitch) {
+        lsAugBuilder.setHwvtepNodeName(new HwvtepNodeName(lSwitch.getName()));
+        if(lSwitch.getDescription() != null) {
+            lsAugBuilder.setHwvtepNodeDescription(lSwitch.getDescription());
+        }
+    }
+
+    private Node buildConnectionNode(LogicalSwitch lSwitch) {
+        //Update node with PhysicalSwitch reference
+        NodeBuilder connectionNode = new NodeBuilder();
+        connectionNode.setNodeId(getOvsdbConnectionInstance().getNodeId());
+
+        HwvtepGlobalAugmentationBuilder hgAugmentationBuilder = new HwvtepGlobalAugmentationBuilder();
+        List<Switches> switches = new ArrayList<>();
+        InstanceIdentifier<Node> switchIid = HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(),
+                        lSwitch);
+        hgAugmentationBuilder.setSwitches(switches);
+        /* FIXME:
+         * TODO: This need to be revisited after fix in yang file.
+         * It should ideally be HwvtepSwitchRef
+         */
+        Switches logicalSwitch = new SwitchesBuilder().setSwitchRef(
+                        new HwvtepPhysicalSwitchRef(switchIid)).build(); 
+        switches.add(logicalSwitch);
+
+        connectionNode.addAugmentation(HwvtepGlobalAugmentation.class, hgAugmentationBuilder.build());
+
+        LOG.debug("Update node with logicalswitch ref {}",
+                hgAugmentationBuilder.getSwitches().iterator().next());
+        return connectionNode.build();
+    }
+
+    private InstanceIdentifier<Node> getInstanceIdentifier(LogicalSwitch lSwitch) {
+        return HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(),
+                lSwitch);
+    }
+
+    private NodeId getNodeId(LogicalSwitch lSwitch) {
+        NodeKey nodeKey = getInstanceIdentifier(lSwitch).firstKeyOf(Node.class, NodeKey.class);
+        return nodeKey.getNodeId();
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/McastMacsLocalUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/McastMacsLocalUpdateCommand.java
new file mode 100644 (file)
index 0000000..06ab9e4
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.McastMacsLocal;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class McastMacsLocalUpdateCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(McastMacsLocalUpdateCommand.class);
+    private Map<UUID, McastMacsLocal> updatedMMacsLocalRows;
+    private Map<UUID, McastMacsLocal> oldMMacsLocalRows;
+
+    public McastMacsLocalUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        super(key, updates, dbSchema);
+        updatedMMacsLocalRows = TyperUtils.extractRowsUpdated(McastMacsLocal.class, getUpdates(),getDbSchema());
+        oldMMacsLocalRows = TyperUtils.extractRowsOld(McastMacsLocal.class, getUpdates(),getDbSchema());
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        // TODO Auto-generated method stub
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/McastMacsRemoteUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/McastMacsRemoteUpdateCommand.java
new file mode 100644 (file)
index 0000000..10ec57e
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.McastMacsRemote;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class McastMacsRemoteUpdateCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(McastMacsRemoteUpdateCommand.class);
+    private Map<UUID, McastMacsRemote> updatedMMacsRemoteRows;
+    private Map<UUID, McastMacsRemote> oldMMacsRemoteRows;
+
+    public McastMacsRemoteUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        super(key, updates, dbSchema);
+        updatedMMacsRemoteRows = TyperUtils.extractRowsUpdated(McastMacsRemote.class, getUpdates(),getDbSchema());
+        oldMMacsRemoteRows = TyperUtils.extractRowsOld(McastMacsRemote.class, getUpdates(),getDbSchema());
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        // TODO Auto-generated method stub
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalLocatorSetUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalLocatorSetUpdateCommand.java
new file mode 100644 (file)
index 0000000..9be6116
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocatorSet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PhysicalLocatorSetUpdateCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PhysicalLocatorSetUpdateCommand.class);
+    private Map<UUID, PhysicalLocatorSet> updatedPLocSetRows;
+    private Map<UUID, PhysicalLocatorSet> oldPLocSetRows;
+
+    public PhysicalLocatorSetUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        super(key, updates, dbSchema);
+        updatedPLocSetRows = TyperUtils.extractRowsUpdated(PhysicalLocatorSet.class, getUpdates(),getDbSchema());
+        oldPLocSetRows = TyperUtils.extractRowsOld(PhysicalLocatorSet.class, getUpdates(),getDbSchema());
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        // TODO Auto-generated method stub
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalLocatorUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalLocatorUpdateCommand.java
new file mode 100644 (file)
index 0000000..307da2d
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PhysicalLocatorUpdateCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PhysicalLocatorUpdateCommand.class);
+    private Map<UUID, PhysicalLocator> updatedPLocRows;
+    private Map<UUID, PhysicalLocator> oldPLocRows;
+
+    public PhysicalLocatorUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        super(key, updates, dbSchema);
+        updatedPLocRows = TyperUtils.extractRowsUpdated(PhysicalLocator.class, getUpdates(),getDbSchema());
+        updatedPLocRows = TyperUtils.extractRowsOld(PhysicalLocator.class, getUpdates(),getDbSchema());
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        // TODO Auto-generated method stub
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalPortRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalPortRemoveCommand.java
new file mode 100644 (file)
index 0000000..c9f276d
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
+import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PhysicalPortRemoveCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PhysicalPortRemoveCommand.class);
+
+    public PhysicalPortRemoveCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        super(key, updates, dbSchema);
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        String portName = null;
+        Collection<PhysicalPort> deletedPortRows = TyperUtils.extractRowsRemoved(PhysicalPort.class, getUpdates(),getDbSchema()).values();
+        Map<UUID, PhysicalSwitch> updatedPSRows = TyperUtils.extractRowsUpdated(PhysicalSwitch.class, getUpdates(),getDbSchema());
+        Map<UUID, PhysicalSwitch> oldPSRows = TyperUtils.extractRowsOld(PhysicalSwitch.class, getUpdates(),getDbSchema());
+        if(deletedPortRows != null && !deletedPortRows.isEmpty()) {
+            for (PhysicalPort pPort : deletedPortRows) {
+                PhysicalSwitch updatedPSwitchData = null;
+                for(UUID pSwitchUUID: updatedPSRows.keySet()) {
+                    PhysicalSwitch oldPSwitchData = oldPSRows.get(pSwitchUUID);
+                    if(oldPSwitchData.getPortsColumn() != null
+                            && oldPSwitchData.getPortsColumn().getData().contains(pPort.getUuidColumn().getData())
+                            && (!updatedPSRows.isEmpty())) {
+                        updatedPSwitchData = updatedPSRows.get(pSwitchUUID);
+                        break;
+                    }
+                }
+                if(updatedPSwitchData == null) {
+                    LOG.warn("PhysicalSwitch not found for port {}", pPort);
+                    continue;
+                }
+                portName = pPort.getName();
+                final InstanceIdentifier<TerminationPoint> nodePath = HwvtepSouthboundMapper
+                        .createInstanceIdentifier(getOvsdbConnectionInstance(), 
+                                updatedPSwitchData).child(
+                                TerminationPoint.class,
+                                new TerminationPointKey(new TpId(portName)));
+                transaction.delete(LogicalDatastoreType.OPERATIONAL, nodePath);
+            }
+        }
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalPortUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalPortUpdateCommand.java
new file mode 100644 (file)
index 0000000..780a49d
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
+import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
+import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.PhysicalPortIdBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindingsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindingsKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+public class PhysicalPortUpdateCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PhysicalPortUpdateCommand.class);
+    private Map<UUID, PhysicalPort> updatedPPRows;
+    private Map<UUID, PhysicalPort> oldPPRows;
+    private Map<UUID, PhysicalSwitch> switchUpdatedRows;
+    private Map<UUID, LogicalSwitch> lSwitchUpdatedRows;
+
+    public PhysicalPortUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        super(key, updates, dbSchema);
+        updatedPPRows = TyperUtils.extractRowsUpdated(PhysicalPort.class, getUpdates(),getDbSchema());
+        oldPPRows = TyperUtils.extractRowsOld(PhysicalPort.class, getUpdates(),getDbSchema());
+        switchUpdatedRows = TyperUtils.extractRowsUpdated(PhysicalSwitch.class, getUpdates(),getDbSchema());
+        lSwitchUpdatedRows = TyperUtils.extractRowsUpdated(LogicalSwitch.class, getUpdates(),getDbSchema());
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
+        if ( updatedPPRows == null
+                || updatedPPRows.isEmpty()) {
+            return;
+        }
+        LOG.trace("PhysicalPortTable updated: {}", updatedPPRows);
+        Optional<Node> node = readNode(transaction, connectionIId);
+        if (node.isPresent()) {
+            updateTerminationPoints(transaction, node.get());
+            //TODO: Handle Deletion of VLAN Bindings
+        }
+    }
+
+    private void updateTerminationPoints(ReadWriteTransaction transaction, Node node) {
+        for (Entry<UUID, PhysicalPort> pPortUpdate : updatedPPRows.entrySet()) {
+            String portName = null;
+            portName = pPortUpdate.getValue().getNameColumn().getData();
+            Optional<InstanceIdentifier<Node>> switchIid = getTerminationPointSwitch(pPortUpdate.getKey());
+            if (!switchIid.isPresent()) {
+                switchIid = getTerminationPointSwitch( transaction, node, portName);
+            }
+            if (switchIid.isPresent()) {
+                NodeId switchId = HwvtepSouthboundMapper.createManagedNodeId(switchIid.get());
+                TerminationPointKey tpKey = new TerminationPointKey(new TpId(portName));
+                TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+                tpBuilder.setKey(tpKey);
+                tpBuilder.setTpId(tpKey.getTpId());
+                InstanceIdentifier<TerminationPoint> tpPath =
+                        getInstanceIdentifier(switchIid.get(), pPortUpdate.getValue());
+                HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder =
+                        new HwvtepPhysicalPortAugmentationBuilder();
+                buildTerminationPoint(tpAugmentationBuilder,pPortUpdate.getValue());
+                tpBuilder.addAugmentation(HwvtepPhysicalPortAugmentation.class, tpAugmentationBuilder.build());
+                if (oldPPRows.containsKey(pPortUpdate.getKey())) {
+                    transaction.merge(LogicalDatastoreType.OPERATIONAL,
+                            tpPath, tpBuilder.build());
+                } else {
+                    transaction.put(LogicalDatastoreType.OPERATIONAL,
+                            tpPath, tpBuilder.build());
+                }
+            }
+        }
+    }
+
+    private void buildTerminationPoint(HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder,
+                    PhysicalPort portUpdate) {
+        updatePhysicalPortId(portUpdate, tpAugmentationBuilder);
+        updatePort(portUpdate, tpAugmentationBuilder);
+    }
+
+    private void updatePort(PhysicalPort portUpdate,
+                    HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder) {
+        updateVlanBindings(portUpdate, tpAugmentationBuilder);
+    }
+
+    private void updatePhysicalPortId(PhysicalPort portUpdate,
+                    HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder) {
+        PhysicalPortIdBuilder portIdBuilder = new PhysicalPortIdBuilder();
+        portIdBuilder.setHwvtepNodeName(new HwvtepNodeName(portUpdate.getName()));
+        if(portUpdate.getDescription() != null) {
+            portIdBuilder.setHwvtepNodeDescription(portUpdate.getDescription());
+        }
+
+        tpAugmentationBuilder.setPhysicalPortId(portIdBuilder.build());
+    }
+
+    private void updateVlanBindings(PhysicalPort portUpdate,
+                    HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder) {
+        Map<Long, UUID> vlanBindings = portUpdate.getVlanBindingsColumn().getData();
+        if(vlanBindings != null && !vlanBindings.isEmpty()) {
+            Set<Long> vlanBindingsKeys = vlanBindings.keySet();
+            List<VlanBindings> vlanBindingsList = new ArrayList<>();
+            UUID vlanBindingValue = null;
+            for(Long vlanBindingKey: vlanBindingsKeys) {
+                vlanBindingValue = vlanBindings.get(vlanBindingKey);
+                if(vlanBindingValue != null && vlanBindingKey != null) {
+                    vlanBindingsList.add(createVlanBinding(portUpdate, vlanBindingKey, vlanBindingValue));
+                }
+            }
+            tpAugmentationBuilder.setVlanBindings(vlanBindingsList);
+        }
+    }
+
+    private VlanBindings createVlanBinding(PhysicalPort portUpdate, Long key, UUID value) {
+        VlanBindingsBuilder vbBuilder = new VlanBindingsBuilder();
+        VlanBindingsKey vbKey = new VlanBindingsKey(new VlanId(key.intValue()));
+        vbBuilder.setKey(vbKey);
+        vbBuilder.setVlanIdKey(vbKey.getVlanIdKey());
+        HwvtepLogicalSwitchRef lSwitchRef = this.getLogicalSwitchRef(value, portUpdate.getUuid());
+        vbBuilder.setLogicalSwitch(lSwitchRef);
+        return vbBuilder.build();
+    }
+
+    private HwvtepLogicalSwitchRef getLogicalSwitchRef( UUID switchUUID, UUID portUUID) {
+            if (lSwitchUpdatedRows.get(switchUUID) != null) {
+                Optional<InstanceIdentifier<Node>> optSwitchIid = Optional.of(HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(),
+                        this.lSwitchUpdatedRows.get(switchUUID)));
+                if(optSwitchIid.isPresent()) {
+                    return new HwvtepLogicalSwitchRef(optSwitchIid.get());
+                }
+            }
+        return null;
+    }
+
+    private Optional<InstanceIdentifier<Node>> getTerminationPointSwitch( UUID portUUID) {
+        for (UUID switchUUID : this.switchUpdatedRows.keySet()) {
+            if (this.switchUpdatedRows.get(switchUUID).getPortsColumn().getData().contains(portUUID)) {
+                return Optional.of(HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(),
+                        this.switchUpdatedRows.get(switchUUID)));
+            }
+        }
+        return Optional.absent();
+    }
+
+    private Optional<InstanceIdentifier<Node>> getTerminationPointSwitch(
+                    final ReadWriteTransaction transaction, Node node, String tpName) {
+                HwvtepGlobalAugmentation hwvtepNode = node.getAugmentation(HwvtepGlobalAugmentation.class);
+                List<Switches> switchNodes = hwvtepNode.getSwitches();
+                for ( Switches managedNodeEntry : switchNodes ) {
+                    @SuppressWarnings("unchecked")
+                    Node switchNode = readNode(transaction,
+                            (InstanceIdentifier<Node>)managedNodeEntry.getSwitchRef().getValue()).get();
+                    TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+                    TerminationPointKey tpKey = new TerminationPointKey(new TpId(tpName));
+                    tpBuilder.setKey(tpKey);
+                    if (switchNode.getTerminationPoint() != null
+                            && switchNode.getTerminationPoint().contains(tpBuilder.build())) {
+                        PhysicalSwitchAugmentation pSwitchAugment
+                            = switchNode.getAugmentation(PhysicalSwitchAugmentation.class);
+                        return Optional.of((InstanceIdentifier<Node>)managedNodeEntry.getSwitchRef().getValue());
+                    }
+                }
+                return Optional.absent();
+            }
+
+    private Optional<Node> readNode(final ReadWriteTransaction transaction, final InstanceIdentifier<Node> nodePath) {
+        Optional<Node> node = Optional.absent();
+        try {
+            node = transaction.read(
+                    LogicalDatastoreType.OPERATIONAL, nodePath)
+                    .checkedGet();
+        } catch (final ReadFailedException e) {
+            LOG.warn("Read Operational/DS for Node fail! {}",
+                    nodePath, e);
+        }
+        return node;
+    }
+
+    private InstanceIdentifier<TerminationPoint> getInstanceIdentifier(InstanceIdentifier<Node> switchIid,
+                    PhysicalPort pPort) {
+        return switchIid.child(TerminationPoint.class, new TerminationPointKey(new TpId(pPort.getName())));
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalSwitchRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalSwitchRemoveCommand.java
new file mode 100644 (file)
index 0000000..1f2a9eb
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.Collection;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalSwitchRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.SwitchesKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PhysicalSwitchRemoveCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PhysicalSwitchRemoveCommand.class);
+
+    public PhysicalSwitchRemoveCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        super(key, updates, dbSchema);
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        Collection<PhysicalSwitch> deletedPSRows = TyperUtils.extractRowsRemoved(PhysicalSwitch.class, getUpdates(),getDbSchema()).values();
+        if(deletedPSRows != null && !deletedPSRows.isEmpty()) {
+            for (PhysicalSwitch pSwitch : deletedPSRows) {
+                InstanceIdentifier<Node> nodeIid = HwvtepSouthboundMapper.createInstanceIdentifier(
+                                getOvsdbConnectionInstance(), pSwitch);
+                InstanceIdentifier<Switches> switchIid = getOvsdbConnectionInstance().getInstanceIdentifier()
+                                .augmentation(HwvtepGlobalAugmentation.class)
+                                .child(Switches.class, new SwitchesKey(new HwvtepPhysicalSwitchRef(nodeIid)));
+                        // TODO handle removal of reference to managed switch from model
+                        transaction.delete(LogicalDatastoreType.OPERATIONAL, nodeIid);
+                        transaction.delete(LogicalDatastoreType.OPERATIONAL, switchIid);
+            }
+        }
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalSwitchUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/PhysicalSwitchUpdateCommand.java
new file mode 100644 (file)
index 0000000..54212d8
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalSwitchRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.SwitchesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIpsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIpsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.PhysicalSwitchIdBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIpsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIpsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.Tunnels;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelsBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+public class PhysicalSwitchUpdateCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PhysicalSwitchUpdateCommand.class);
+    private Map<UUID, PhysicalSwitch> updatedPSRows;
+    private Map<UUID, PhysicalSwitch> oldPSRows;
+
+    public PhysicalSwitchUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        super(key, updates, dbSchema);
+        updatedPSRows = TyperUtils.extractRowsUpdated(PhysicalSwitch.class, getUpdates(),getDbSchema());
+        oldPSRows = TyperUtils.extractRowsOld(PhysicalSwitch.class, getUpdates(),getDbSchema());
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        if(updatedPSRows != null && !updatedPSRows.isEmpty()) {
+            for (Entry<UUID, PhysicalSwitch> entry : updatedPSRows.entrySet()) {
+                updatePhysicalSwitch(transaction, entry.getValue());
+            }
+        }
+    }
+
+    private void updatePhysicalSwitch(ReadWriteTransaction transaction, PhysicalSwitch pSwitch) {
+        final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
+        Optional<Node> connection = HwvtepSouthboundUtil.readNode(transaction, connectionIId);
+        if (connection.isPresent()) {
+            LOG.debug("Connection {} is present",connection);
+            // Update the connection node to let it know it manages this Physical Switch
+            Node connectionNode = buildConnectionNode(pSwitch);
+            transaction.merge(LogicalDatastoreType.OPERATIONAL, connectionIId, connectionNode);
+
+            // Update the Physical Switch with whatever data we are getting
+            InstanceIdentifier<Node> psIid = getInstanceIdentifier(pSwitch);
+            Node psNode = buildPhysicalSwitchNode(pSwitch);
+            transaction.merge(LogicalDatastoreType.OPERATIONAL, psIid, psNode);
+//            TODO: Delete entries that are no longer needed
+        }
+    }
+
+    private Node buildPhysicalSwitchNode(PhysicalSwitch pSwitch) {
+        NodeBuilder psNodeBuilder = new NodeBuilder();
+        NodeId psNodeId = getNodeId(pSwitch);
+        psNodeBuilder.setNodeId(psNodeId);
+        PhysicalSwitchAugmentationBuilder psAugmentationBuilder = new PhysicalSwitchAugmentationBuilder();
+        setManagedBy(psAugmentationBuilder, pSwitch);
+        setPhysicalSwitchId(psAugmentationBuilder, pSwitch);
+        setManagementIps(psAugmentationBuilder, pSwitch);
+        setTunnelIps(psAugmentationBuilder, pSwitch);
+        setUcastMacsLocal(psAugmentationBuilder, pSwitch);
+        setUcastMacsRemote(psAugmentationBuilder, pSwitch);
+        setMcastMacsLocal(psAugmentationBuilder, pSwitch);
+        setMcastMacsRemote(psAugmentationBuilder, pSwitch);
+
+        psNodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, psAugmentationBuilder.build());
+
+        LOG.trace("Built with the intent to store PhysicalSwitch data {}",
+                psAugmentationBuilder.build());
+        return psNodeBuilder.build();
+    }
+
+    private void setManagedBy(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
+        InstanceIdentifier<Node> connectionNodePath = getOvsdbConnectionInstance().getInstanceIdentifier();
+        psAugmentationBuilder.setManagedBy(new HwvtepGlobalRef(connectionNodePath));
+    }
+
+    private void setPhysicalSwitchId(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
+        PhysicalSwitchIdBuilder psIdBuilder = new PhysicalSwitchIdBuilder();
+        if(pSwitch.getName() != null) {
+            psIdBuilder.setHwvtepNodeName(new HwvtepNodeName(pSwitch.getName()));
+        }
+
+        if(pSwitch.getDescription() != null) {
+            psIdBuilder.setHwvtepNodeDescription(pSwitch.getDescription());
+        }
+        psAugmentationBuilder.setPhysicalSwitchId(psIdBuilder.build());
+    }
+
+    private void setManagementIps(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
+        if(pSwitch.getManagementIpsColumn() != null 
+                && pSwitch.getManagementIpsColumn().getData() != null
+                && !pSwitch.getManagementIpsColumn().getData().isEmpty() ) {
+            List<ManagementIps> mgmtIps = new ArrayList<>();
+            for(String mgmtIp: pSwitch.getManagementIpsColumn().getData()) {
+                IpAddress ip = new IpAddress(mgmtIp.toCharArray());
+                mgmtIps.add(new ManagementIpsBuilder()
+                        .setKey(new ManagementIpsKey(ip))
+                        .setManagementIpsKey(ip)
+                        .build());
+            }
+            psAugmentationBuilder.setManagementIps(mgmtIps);
+        }
+    }
+
+    private void setTunnelIps(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
+        if(pSwitch.getTunnelIpsColumn() != null
+            && pSwitch.getTunnelIpsColumn().getData() != null
+            && !pSwitch.getTunnelIpsColumn().getData().isEmpty()) {
+            List<TunnelIps> tunnelIps = new ArrayList<>();
+            for(String tunnelIp: pSwitch.getTunnelIpsColumn().getData()) {
+                IpAddress ip = new IpAddress(tunnelIp.toCharArray());
+                tunnelIps.add(new TunnelIpsBuilder()
+                        .setKey(new TunnelIpsKey(ip))
+                        .setTunnelIpsKey(ip)
+                        .build());
+            }
+            psAugmentationBuilder.setTunnelIps(tunnelIps);
+        }
+    }
+
+    private void setUcastMacsLocal(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    private void setUcastMacsRemote(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    private void setMcastMacsLocal(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    private void setMcastMacsRemote(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    private Node buildConnectionNode(PhysicalSwitch pSwitch) {
+        //Update node with PhysicalSwitch reference
+        NodeBuilder connectionNode = new NodeBuilder();
+        connectionNode.setNodeId(getOvsdbConnectionInstance().getNodeId());
+
+        HwvtepGlobalAugmentationBuilder hgAugmentationBuilder = new HwvtepGlobalAugmentationBuilder();
+        List<Switches> switches = new ArrayList<>();
+        InstanceIdentifier<Node> switchIid = HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(),
+                        pSwitch);
+        hgAugmentationBuilder.setSwitches(switches);
+        Switches physicalSwitch = new SwitchesBuilder().setSwitchRef(
+                        new HwvtepPhysicalSwitchRef(switchIid)).build(); 
+        switches.add(physicalSwitch);
+
+        connectionNode.addAugmentation(HwvtepGlobalAugmentation.class, hgAugmentationBuilder.build());
+
+        LOG.debug("Update node with physicalswitch ref {}",
+                hgAugmentationBuilder.getSwitches().iterator().next());
+        return connectionNode.build();
+    }
+
+    private InstanceIdentifier<Node> getInstanceIdentifier(PhysicalSwitch pSwitch) {
+        return HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(),
+                pSwitch);
+    }
+
+    private NodeId getNodeId(PhysicalSwitch pSwitch) {
+        NodeKey nodeKey = getInstanceIdentifier(pSwitch).firstKeyOf(Node.class, NodeKey.class);
+        return nodeKey.getNodeId();
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/TransactionCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/TransactionCommand.java
new file mode 100644 (file)
index 0000000..89dda90
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+
+public interface TransactionCommand {
+
+    void execute(ReadWriteTransaction transaction);
+
+}
\ No newline at end of file
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/TransactionInvoker.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/TransactionInvoker.java
new file mode 100644 (file)
index 0000000..5e9fe9b
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+public interface TransactionInvoker {
+
+    void invoke(TransactionCommand command);
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/TransactionInvokerImpl.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/TransactionInvokerImpl.java
new file mode 100644 (file)
index 0000000..8f4ab70
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+
+import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
+/*  TODO:
+ * Copied over as-is from southbound plugin. Good candidate to be common
+ * when refactoring code. 
+ */
+public class TransactionInvokerImpl implements TransactionInvoker,TransactionChainListener, Runnable, AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(TransactionInvokerImpl.class);
+    private static final int QUEUE_SIZE = 10000;
+    private BindingTransactionChain chain;
+    private DataBroker db;
+    private BlockingQueue<TransactionCommand> inputQueue = new LinkedBlockingQueue<>(QUEUE_SIZE);
+    private BlockingQueue<ReadWriteTransaction> successfulTransactionQueue
+        = new LinkedBlockingQueue<>(QUEUE_SIZE);
+    private BlockingQueue<AsyncTransaction<?, ?>> failedTransactionQueue
+        = new LinkedBlockingQueue<>(QUEUE_SIZE);
+    private ExecutorService executor;
+    private Map<ReadWriteTransaction,TransactionCommand> transactionToCommand
+        = new HashMap<>();
+    private List<ReadWriteTransaction> pendingTransactions = new ArrayList<>();
+
+    public TransactionInvokerImpl(DataBroker db) {
+        this.db = db;
+        this.chain = db.createTransactionChain(this);
+        ThreadFactory threadFact = new ThreadFactoryBuilder().setNameFormat("transaction-invoker-impl-%d").build();
+        executor = Executors.newSingleThreadExecutor(threadFact);
+        executor.submit(this);
+    }
+
+    @Override
+    public void invoke(final TransactionCommand command) {
+        // TODO what do we do if queue is full?
+        inputQueue.offer(command);
+    }
+
+    @Override
+    public void onTransactionChainFailed(TransactionChain<?, ?> chain,
+            AsyncTransaction<?, ?> transaction, Throwable cause) {
+        failedTransactionQueue.offer(transaction);
+    }
+
+    @Override
+    public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
+        // NO OP
+
+    }
+
+    @Override
+    public void run() {
+        while (true) {
+            forgetSuccessfulTransactions();
+            try {
+                List<TransactionCommand> commands = extractCommands();
+                for (TransactionCommand command: commands) {
+                    final ReadWriteTransaction transaction = chain.newReadWriteTransaction();
+                    recordPendingTransaction(command, transaction);
+                    command.execute(transaction);
+                    Futures.addCallback(transaction.submit(), new FutureCallback<Void>() {
+                        @Override
+                        public void onSuccess(final Void result) {
+                            successfulTransactionQueue.offer(transaction);
+                        }
+
+                        @Override
+                        public void onFailure(final Throwable throwable) {
+                            // NOOP - handled by failure of transaction chain
+                        }
+                    });
+                }
+            } catch (Exception e) {
+                LOG.warn("Exception invoking Transaction: ", e);
+            }
+        }
+    }
+
+    private List<TransactionCommand> extractResubmitCommands() {
+        AsyncTransaction<?, ?> transaction = failedTransactionQueue.poll();
+        List<TransactionCommand> commands = new ArrayList<>();
+        if (transaction != null) {
+            int index = pendingTransactions.lastIndexOf(transaction);
+            List<ReadWriteTransaction> transactions =
+                    pendingTransactions.subList(index, pendingTransactions.size() - 1);
+            for (ReadWriteTransaction tx: transactions) {
+                commands.add(transactionToCommand.get(tx));
+            }
+            resetTransactionQueue();
+        }
+        return commands;
+    }
+
+    private void resetTransactionQueue() {
+        chain.close();
+        chain = db.createTransactionChain(this);
+        pendingTransactions = new ArrayList<>();
+        transactionToCommand = new HashMap<>();
+        failedTransactionQueue.clear();
+        successfulTransactionQueue.clear();
+    }
+
+    private void recordPendingTransaction(TransactionCommand command,
+            final ReadWriteTransaction transaction) {
+        transactionToCommand.put(transaction, command);
+        pendingTransactions.add(transaction);
+    }
+
+    private List<TransactionCommand> extractCommands() throws InterruptedException {
+        List<TransactionCommand> commands = extractResubmitCommands();
+        commands.addAll(extractCommandsFromQueue());
+        return commands;
+    }
+
+    private List<TransactionCommand> extractCommandsFromQueue() throws InterruptedException {
+        List<TransactionCommand> result = new ArrayList<>();
+        TransactionCommand command = inputQueue.take();
+        while (command != null) {
+            result.add(command);
+            command = inputQueue.poll();
+        }
+        return result;
+    }
+
+    private void forgetSuccessfulTransactions() {
+        ReadWriteTransaction transaction = successfulTransactionQueue.poll();
+        while (transaction != null) {
+            pendingTransactions.remove(transaction);
+            transactionToCommand.remove(transaction);
+            transaction = successfulTransactionQueue.poll();
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+        this.executor.shutdown();
+    }
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/UcastMacsLocalUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/UcastMacsLocalUpdateCommand.java
new file mode 100644 (file)
index 0000000..3971ccc
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsLocal;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UcastMacsLocalUpdateCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UcastMacsLocalUpdateCommand.class);
+    private Map<UUID, UcastMacsLocal> updatedUMacsLocalRows;
+    private Map<UUID, UcastMacsLocal> oldUMacsLocalRows;
+
+    public UcastMacsLocalUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        super(key, updates, dbSchema);
+        updatedUMacsLocalRows = TyperUtils.extractRowsUpdated(UcastMacsLocal.class, getUpdates(),getDbSchema());
+        oldUMacsLocalRows = TyperUtils.extractRowsOld(UcastMacsLocal.class, getUpdates(),getDbSchema());
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        // TODO Auto-generated method stub
+    }
+
+}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/UcastMacsRemoteUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/UcastMacsRemoteUpdateCommand.java
new file mode 100644 (file)
index 0000000..cac4a0a
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md;
+
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsRemote;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UcastMacsRemoteUpdateCommand extends AbstractTransactionCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UcastMacsRemoteUpdateCommand.class);
+    private Map<UUID, UcastMacsRemote> updatedUMacsRemoteRows;
+    private Map<UUID, UcastMacsRemote> oldUMacsRemoteRows;
+
+    public UcastMacsRemoteUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates,
+            DatabaseSchema dbSchema) {
+        super(key, updates, dbSchema);
+        updatedUMacsRemoteRows = TyperUtils.extractRowsUpdated(UcastMacsRemote.class, getUpdates(),getDbSchema());
+        oldUMacsRemoteRows = TyperUtils.extractRowsOld(UcastMacsRemote.class, getUpdates(),getDbSchema());
+    }
+
+    @Override
+    public void execute(ReadWriteTransaction transaction) {
+        // TODO Auto-generated method stub
+    }
+
+}
index 0a37e0155a760f7e671c34af1896ede44e8786b4..d88718838f8b8cfea6e791109dfa094127c27eb2 100644 (file)
@@ -8,7 +8,9 @@
 
 package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hwvtepsouthbound.impl.rev150901;
 
-import org.opendaylight.ovsdb.hwvtepsouthbound.impl.HwvtepSouthboundProvider;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundProvider;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
+import org.opendaylight.ovsdb.hwvtepsouthbound.InstanceIdentifierCodec;
 
 public class HwvtepSouthboundModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hwvtepsouthbound.impl.rev150901.AbstractHwvtepSouthboundModule {
     public HwvtepSouthboundModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -26,7 +28,10 @@ public class HwvtepSouthboundModule extends org.opendaylight.yang.gen.v1.urn.ope
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        HwvtepSouthboundProvider provider = new HwvtepSouthboundProvider();
+        HwvtepSouthboundUtil.setInstanceIdentifierCodec(new InstanceIdentifierCodec(getSchemaServiceDependency(),
+                        getBindingNormalizedNodeSerializerDependency()));
+        HwvtepSouthboundProvider provider = new HwvtepSouthboundProvider(getClusteringEntityOwnershipServiceDependency(),
+                        getConnectionServiceDependency());
         getBrokerDependency().registerProvider(provider);
         return provider;
     }
index 2f8aae6d0138aa75d280ba34f8b74fb1f444e2b9..f0823322d63591dfa3874857e989ab12e4f67892 100644 (file)
@@ -5,6 +5,9 @@ module hwvtepsouthbound-impl {
 
     import config { prefix config; revision-date 2013-04-05; }
     import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
+    import opendaylight-entity-ownership-service {prefix eos; revision-date 2015-08-10;}
+    import opendaylight-md-sal-dom {prefix dom; revision-date 2013-10-28;}
+    import library { prefix library; revision-date 2014-12-10; }
 
     description
         "Service definition for hwvtepsouthbound project";
@@ -30,6 +33,38 @@ module hwvtepsouthbound-impl {
                     }
                 }
             }
+            container schema-service {
+                uses config:service-ref {
+                    refine type {
+                        mandatory false;
+                        config:required-identity dom:schema-service;
+                    }
+                }
+            }
+            container clustering-entity-ownership-service {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity eos:entity-ownership-service;
+                    }
+                }
+            }
+            container binding-normalized-node-serializer {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity md-sal-binding:binding-normalized-node-serializer;
+                    }
+                }
+            }
+            container connection-service {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity library:connection-service;
+                    }
+                }
+            }
         }
     }
 }
index 3b67519fe9e0716a53997aff03304660b8ab9b28..6f49c4c9234fcead8d90dc62193da203b6365541 100644 (file)
@@ -7,12 +7,13 @@
  */
 package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hwvtepsouthbound.impl.rev150901;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.JmxAttribute;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.ovsdb.hwvtepsouthbound.impl.HwvtepSouthboundProvider;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundProvider;
 
 import javax.management.ObjectName;
 
@@ -32,6 +33,8 @@ public class HwvtepSouthboundModuleTest {
         module.customValidation();
     }
 
+    //TODO: Ignore for now, will be replaced with better UT
+    @Ignore
     @Test
     public void testCreateInstance() throws Exception {
         // configure mocks
index 55ec29e66c51539956f43a7e0d5943a6f50db94f..ecdbc05614ec4d210dda74a6b0d2bf653d10e7c0 100644 (file)
@@ -21,7 +21,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <maven>3.1.1</maven>
   </prerequisites>
   <properties>
-    <karaf.localFeature>odl-hwvtepsouthbound-ui</karaf.localFeature>
+    <karaf.localFeature>odl-ovsdb-hwvtepsouthbound-ui</karaf.localFeature>
   </properties>
   <dependencyManagement>
     <dependencies>
index 07ede6d877df0ad70685d9b5338b3c90ebb9af4e..adc575be6317be987396b3cdd7d3cf33f5d3d060 100644 (file)
@@ -10,20 +10,20 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
 <features name="odl-ovsdb-library-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
-  <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/${mdsal.model.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.yangtools/features-yangtools/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.controller/features-mdsal/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/{{VERSION}}/xml/features</repository>
   <feature name='odl-ovsdb-library' version='${project.version}' description='OpenDaylight :: library'>
     <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
     <feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
-    <bundle>mvn:org.opendaylight.ovsdb/library/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/library/{{VERSION}}</bundle>
     <!-- Test only (move to another feature) -->
-    <bundle>mvn:org.opendaylight.ovsdb/utils.servicehelper/${project.version}</bundle>
-    <bundle>mvn:org.opendaylight.ovsdb/schema.openvswitch/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/utils.servicehelper/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/schema.openvswitch/{{VERSION}}</bundle>
     <!-- Test only ends -->
-    <bundle start="true">mvn:com.fasterxml.jackson.core/jackson-annotations/${jackson.version}</bundle>
-    <bundle start="true">mvn:com.fasterxml.jackson.core/jackson-core/${jackson.version}</bundle>
-    <bundle start="true">mvn:com.fasterxml.jackson.core/jackson-databind/${jackson.version}</bundle>
-    <configfile finalname="${configfile.directory}/library.xml">mvn:org.opendaylight.ovsdb/library/${project.version}/xml/config</configfile>
+    <bundle start="true">mvn:com.fasterxml.jackson.core/jackson-annotations/{{VERSION}}</bundle>
+    <bundle start="true">mvn:com.fasterxml.jackson.core/jackson-core/{{VERSION}}</bundle>
+    <bundle start="true">mvn:com.fasterxml.jackson.core/jackson-databind/{{VERSION}}</bundle>
+    <configfile finalname="${configfile.directory}/library.xml">mvn:org.opendaylight.ovsdb/library/{{VERSION}}/xml/config</configfile>
   </feature>
 </features>
index 8112ddc1bf8813363d2eb4007d4480bcd50840b6..381de3a9b948bdf2e3f0858360badb797faf5aa7 100644 (file)
@@ -94,6 +94,20 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       </testResource>
     </testResources>
     <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Export-Package>
+              org.opendaylight.ovsdb.lib,
+              org.opendaylight.ovsdb.lib.*,
+              org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.library.impl.rev141210
+            </Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-checkstyle-plugin</artifactId>
index e8b159f436ad3b6d262b87e754c20499a12cd00d..c0b80df871f4daf919d4b2c3621132c87c619ae4 100644 (file)
@@ -25,6 +25,15 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
           </broker>
         </module>
       </modules>
+      <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+        <service>
+          <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:library:impl">prefix:connection-service</type>
+          <instance>
+            <name>connection-service</name>
+            <provider>/modules/module[type='library'][name='library-default']</provider>
+          </instance>
+        </service>
+      </services>
     </data>
   </configuration>
 </snapshot>
diff --git a/library/impl/src/main/java/org/opendaylight/ovsdb/lib/ConfigActivator.java b/library/impl/src/main/java/org/opendaylight/ovsdb/lib/ConfigActivator.java
deleted file mode 100644 (file)
index 1092ccd..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright Â© 2015 Red Hat, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.ovsdb.lib;
-
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.ovsdb.lib.impl.OvsdbConnectionService;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * "Configuration" activator for the OVSDB library.
- */
-public class ConfigActivator implements BundleActivator {
-    /**
-     * Logger.
-     */
-    private static final Logger LOG = LoggerFactory.getLogger(ConfigActivator.class);
-
-    /**
-     * Parent provider context.
-     */
-    private final BindingAwareBroker.ProviderContext providerContext;
-
-    /**
-     * Creates an instance of the activator.
-     *
-     * @param providerContext The parent provider context.
-     */
-    public ConfigActivator(BindingAwareBroker.ProviderContext providerContext) {
-        LOG.info("OVSDB library ConfigActivator created.");
-        this.providerContext = providerContext;
-    }
-
-    @Override
-    public void start(BundleContext context) throws Exception {
-        LOG.info("OVSDB library ConfigActivator starting.");
-        context.registerService(OvsdbConnection.class, new OvsdbConnectionService(), null);
-        // TODO Need to indicate that OvsdbConnectionListeners should register with the connection service
-        // (if I've understood correctly, the old dependency manager would call registerConnectionListener()
-        // whenever an instance of OvsdbConnection is retrieved, and unregisterConnectionListener() when it
-        // is no longer used)
-        // (All current users register manually...)
-    }
-
-    @Override
-    public void stop(BundleContext context) throws Exception {
-        LOG.info("OVSDB library ConfigActivator stopping.");
-    }
-}
index b2c8083c41987904b798450e4096e948d123b831..f2264a152797bd8cac96ffa20b4ac04f5385b48d 100644 (file)
@@ -65,7 +65,7 @@ public interface OvsdbClient {
      * @param callback receives the monitor response
      */
     <E extends TableSchema<E>> TableUpdates monitor(DatabaseSchema schema,
-                                                    List<MonitorRequest<E>> monitorRequests,
+                                                    List<MonitorRequest> monitorRequests,
                                                     MonitorCallBack callback);
 
     /**
@@ -76,7 +76,7 @@ public interface OvsdbClient {
      * @param callback receives the monitor response
      */
     <E extends TableSchema<E>> TableUpdates monitor(DatabaseSchema schema,
-                                                    List<MonitorRequest<E>> monitorRequests,
+                                                    List<MonitorRequest> monitorRequests,
                                                     MonitorHandle monitorHandle,
                                                     MonitorCallBack callback);
 
index 1579ae0b93be460d93862271f3f13294e8853a88..4e55685fa825ecc8c9a0e0930ff854c329f391f5 100644 (file)
@@ -22,8 +22,7 @@ public class ColumnSchemaNotFoundException extends RuntimeException {
     }
 
     public static String createMessage(String columnName, String tableName) {
-        String message = "Unable to locate ColumnSchema for " +  columnName + " in " + tableName;
-        return message;
+        return "Unable to locate ColumnSchema for " +  columnName + " in " + tableName;
     }
 
 }
index a358245e037e934ed321ee8ef4e3143171a75f04..3f710d00f7edb6e706fb28e42b114e266f2bfe04 100644 (file)
@@ -24,19 +24,8 @@ public class SchemaVersionMismatchException extends RuntimeException {
         super(message, cause);
     }
 
-    public static String createMessage(Version currentVersion, Version requiredVersion) {
-        String message =
-                "The schema version used to access this Table/Column does not match the required version.\n"
-                + "Current Version: " + currentVersion.toString() + "\n";
-
-        if (currentVersion.compareTo(requiredVersion) > 1) {
-            message += "Removed in Version: " + requiredVersion.toString();
-
-        } else {
-            message += "Added in Version: " + requiredVersion.toString();
-
-        }
-
-        return message;
+    public SchemaVersionMismatchException(Version schemaVersion, Version fromVersion, Version untilVersion) {
+        this("The schema version used to access the table/column (" + schemaVersion + ") does not match the required " +
+                "version (from " + fromVersion + " to " + untilVersion + ")");
     }
 }
index 2d66ba2e8926920a403af41b5ab13cefb89275ac..c782ce424862fe14598d83363358f4603438db4d 100644 (file)
@@ -22,8 +22,7 @@ public class TableSchemaNotFoundException extends RuntimeException {
     }
 
     public static String createMessage(String tableName, String schemaName) {
-        String message = "Unable to locate TableSchema for " +  tableName + " in " + schemaName;
-        return message;
+        return "Unable to locate TableSchema for " +  tableName + " in " + schemaName;
     }
 
 }
diff --git a/library/impl/src/main/java/org/opendaylight/ovsdb/lib/impl/LibraryProvider.java b/library/impl/src/main/java/org/opendaylight/ovsdb/lib/impl/LibraryProvider.java
deleted file mode 100644 (file)
index 63c5783..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright Â© 2015 Red Hat, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.ovsdb.lib.impl;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
-import org.opendaylight.ovsdb.lib.ConfigActivator;
-import org.opendaylight.ovsdb.lib.OvsdbConnection;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class LibraryProvider implements BindingAwareProvider, AutoCloseable {
-
-    private static final Logger LOG = LoggerFactory.getLogger(LibraryProvider.class);
-    private final BundleContext bundleContext;
-    private DataBroker dataBroker;
-    private ConfigActivator activator;
-
-    public LibraryProvider(BundleContext bundleContext) {
-        LOG.info("LibraryProvider: bundleContext: {}", bundleContext);
-        this.bundleContext = bundleContext;
-    }
-
-    @Override
-    public void onSessionInitiated(ProviderContext providerContext) {
-        LOG.info("LibraryProvider Session Initiated");
-        dataBroker = providerContext.getSALService(DataBroker.class);
-        LOG.info("LibraryProvider: onSessionInitiated dataBroker: {}", dataBroker);
-        this.activator = new ConfigActivator(providerContext);
-        try {
-            activator.start(bundleContext);
-        } catch (Exception e) {
-            LOG.warn("Failed to start LibraryProvider: ", e);
-        }
-    }
-
-    @Override
-    public void close() throws Exception {
-        LOG.info("LibraryProvider Closed");
-        if (activator != null) {
-            activator.stop(bundleContext);
-        }
-    }
-
-}
index cc7472ed671f92a6e1bca1cd2ee5b56df43ba3e3..0ea4e09365de3894c71d860b6b152f6e3ded24aa 100644 (file)
@@ -144,13 +144,13 @@ public class OvsdbClientImpl implements OvsdbClient {
 
     @Override
     public <E extends TableSchema<E>> TableUpdates monitor(final DatabaseSchema dbSchema,
-                                                            List<MonitorRequest<E>> monitorRequest,
+                                                            List<MonitorRequest> monitorRequest,
                                                             final MonitorCallBack callback) {
 
-        final ImmutableMap<String, MonitorRequest<E>> reqMap = Maps.uniqueIndex(monitorRequest,
-                new Function<MonitorRequest<E>, String>() {
+        final ImmutableMap<String, MonitorRequest> reqMap = Maps.uniqueIndex(monitorRequest,
+                new Function<MonitorRequest, String>() {
                     @Override
-                    public String apply(MonitorRequest<E> input) {
+                    public String apply(MonitorRequest input) {
                         return input.getTableName();
                     }
                 });
@@ -175,14 +175,14 @@ public class OvsdbClientImpl implements OvsdbClient {
 
     @Override
     public <E extends TableSchema<E>> TableUpdates monitor(final DatabaseSchema dbSchema,
-                                                           List<MonitorRequest<E>> monitorRequest,
+                                                           List<MonitorRequest> monitorRequest,
                                                            final MonitorHandle monitorHandle,
                                                            final MonitorCallBack callback) {
 
-        final ImmutableMap<String, MonitorRequest<E>> reqMap = Maps.uniqueIndex(monitorRequest,
-                new Function<MonitorRequest<E>, String>() {
+        final ImmutableMap<String, MonitorRequest> reqMap = Maps.uniqueIndex(monitorRequest,
+                new Function<MonitorRequest, String>() {
                     @Override
-                    public String apply(MonitorRequest<E> input) {
+                    public String apply(MonitorRequest input) {
                         return input.getTableName();
                     }
                 });
@@ -201,8 +201,7 @@ public class OvsdbClientImpl implements OvsdbClient {
         } catch (InterruptedException | ExecutionException e) {
             return null;
         }
-        TableUpdates updates = transformingCallback(result, dbSchema);
-        return updates;
+        return transformingCallback(result, dbSchema);
     }
 
     private void registerCallback(MonitorHandle monitorHandle, MonitorCallBack callback, DatabaseSchema schema) {
index ef2af7530e7a5ec32d49d4efdb5f588b4326c5ac..98ad0864d52dc6781fb640510f43e4ba9c5ce9ac 100644 (file)
@@ -74,7 +74,7 @@ import com.google.common.collect.Sets;
  * environment. Hence a single instance of the service will be active (via Service Registry in OSGi)
  * and a Singleton object in a non-OSGi environment.
  */
-public class OvsdbConnectionService implements OvsdbConnection {
+public class OvsdbConnectionService implements AutoCloseable, OvsdbConnection {
     private static final Logger LOG = LoggerFactory.getLogger(OvsdbConnectionService.class);
     private static final int NUM_THREADS = 3;
 
@@ -124,9 +124,8 @@ public class OvsdbConnectionService implements OvsdbConnection {
 
             ChannelFuture future = bootstrap.connect(address, port).sync();
             Channel channel = future.channel();
-            OvsdbClient client = getChannelClient(channel, ConnectionType.ACTIVE,
+            return getChannelClient(channel, ConnectionType.ACTIVE,
                     Executors.newFixedThreadPool(NUM_THREADS));
-            return client;
         } catch (InterruptedException e) {
             LOG.warn("Thread was interrupted during connect", e);
         } catch (Exception e) {
@@ -149,6 +148,7 @@ public class OvsdbConnectionService implements OvsdbConnection {
 
     @Override
     public void registerConnectionListener(OvsdbConnectionListener listener) {
+        LOG.info("registerConnectionListener: registering {}", listener.getClass().getSimpleName());
         connectionListeners.add(listener);
     }
 
@@ -184,6 +184,7 @@ public class OvsdbConnectionService implements OvsdbConnection {
     @Override
     public synchronized boolean startOvsdbManager(final int ovsdbListenPort) {
         if (!singletonCreated) {
+            LOG.info("startOvsdbManager: Starting");
             new Thread() {
                 @Override
                 public void run() {
@@ -389,4 +390,9 @@ public class OvsdbConnectionService implements OvsdbConnection {
     public Collection<OvsdbClient> getConnections() {
         return connections.keySet();
     }
+
+    @Override
+    public void close() throws Exception {
+        LOG.info("OvsdbConnectionService closed");
+    }
 }
index c407a1115fb201077b7a20e13d9bdf8c48eacd25..50c5c3428bb8506f7c429644467c8a15bf74f581 100644 (file)
@@ -19,10 +19,9 @@ import com.google.common.collect.Sets;
 /**
  * @author Ashwin Raveendran
  * @author Madhu Venugopal
- * @param <E> monitor
  */
 @JsonInclude(JsonInclude.Include.NON_NULL)
-public class MonitorRequest<E extends TableSchema<E>> {
+public class MonitorRequest {
     @JsonIgnore String tableName;
     Set<String> columns;
     MonitorSelect select;
@@ -65,7 +64,7 @@ public class MonitorRequest<E extends TableSchema<E>> {
 
     public void addColumn(String column) {
         if (columns == null) {
-            columns = Sets.<String>newHashSet();
+            columns = Sets.newHashSet();
         }
         columns.add(column);
     }
index a133cf392eff2d6974b1935cea141d46347e47d6..95b66c298b46c4a79e2d6bcd58d3c5aa30517c48 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.ovsdb.lib.schema.TableSchema;
 public class MonitorRequestBuilder<E extends TableSchema<E>> {
 
     E tableSchema;
-    MonitorRequest<E> monitorRequest;
+    MonitorRequest monitorRequest;
 
     MonitorRequestBuilder(E tableSchema) {
         this.tableSchema = tableSchema;
@@ -27,9 +27,9 @@ public class MonitorRequestBuilder<E extends TableSchema<E>> {
         return new MonitorRequestBuilder<>(tableSchema);
     }
 
-    MonitorRequest<E> getMonitorRequest() {
+    MonitorRequest getMonitorRequest() {
         if (monitorRequest == null) {
-            monitorRequest = new MonitorRequest<>();
+            monitorRequest = new MonitorRequest();
         }
         return monitorRequest;
     }
@@ -60,8 +60,8 @@ public class MonitorRequestBuilder<E extends TableSchema<E>> {
         return this;
     }
 
-    public MonitorRequest<E> build() {
-        MonitorRequest<E> monitorRequest = getMonitorRequest();
+    public MonitorRequest build() {
+        MonitorRequest monitorRequest = getMonitorRequest();
         if (monitorRequest.getSelect() == null) {
             monitorRequest.setSelect(new MonitorSelect());
         }
index 73497046b4c8a6a26edefa3dba266b87fd4c8258..bc688fb560d82dcab883944a80c41072f47ddd20 100644 (file)
@@ -67,7 +67,7 @@ public class TableUpdate<E extends TableSchema<E>> {
     }
 
     public void addRow(UUID uuid, Row<E> oldRow, Row<E> newRow) {
-        rows.put(uuid, new RowUpdate<E>(uuid, oldRow, newRow));
+        rows.put(uuid, new RowUpdate<>(uuid, oldRow, newRow));
     }
 
     public Row<E> getOld(UUID uuid) {
index 0875ae5e77f77fb357f64cf14c03d0362ebb3e01..efc409fe814c000b2237fe34e57187a5d65b7f1f 100644 (file)
@@ -8,18 +8,18 @@
 
 package org.opendaylight.ovsdb.lib.message;
 
-import java.util.ArrayList;
+import java.util.List;
 
 import org.opendaylight.ovsdb.lib.operations.OperationResult;
 
 public class TransactResponse extends Response {
-    ArrayList<OperationResult> result;
+    List<OperationResult> result;
 
-    public ArrayList<OperationResult> getResult() {
+    public List<OperationResult> getResult() {
         return result;
     }
 
-    public void setResult(ArrayList<OperationResult> result) {
+    public void setResult(List<OperationResult> result) {
         this.result = result;
     }
 
index 49b6e7d34be6299238133fa410e67ffe85b405d8..d106dee718fe3d39772a02d237352baba612d577 100644 (file)
@@ -18,7 +18,7 @@ public enum Function {
     INCLUDES("includes"),
     EXCLUDES("excludes");
 
-    private Function(String name) {
+    Function(String name) {
         this.name = name;
     }
 
index a3b0a493ff863025e7a6f2a5f38e63d57d606a53..410a37bc00b98a83b21e66770a3fe04e48e35b08 100644 (file)
@@ -17,7 +17,7 @@ public enum Mutator {
     INSERT("insert"),
     DELETE("delete");
 
-    private Mutator(String name) {
+    Mutator(String name) {
         this.name = name;
     }
 
index 6aaae6c3acd84066b94f97ae84cf968bb5185606..de0e844f664d6fb9a82ee20721a23ddca7954e16 100644 (file)
@@ -38,6 +38,6 @@ public class OvsdbMap<K, V> extends ForwardingMap<K, V> {
     }
 
     public static <K,V> OvsdbMap<K,V> fromMap(Map<K, V> value) {
-        return new OvsdbMap<K,V>(value);
+        return new OvsdbMap<>(value);
     }
 }
index 3c19e6afba14942338262b324457e5d12ff7aaa8..4f64ff9c7dfbad31808a226c4195f9cb998852ea 100644 (file)
@@ -8,7 +8,6 @@
 
 package org.opendaylight.ovsdb.lib.operations;
 
-import java.util.ArrayList;
 import java.util.List;
 
 import org.opendaylight.ovsdb.lib.notation.Row;
@@ -33,7 +32,7 @@ public class OperationResult {
     private int count;
     @JsonIgnore
     private UUID uuid;
-    private ArrayList<Row<GenericTableSchema>> rows;
+    private List<Row<GenericTableSchema>> rows;
     private String error;
     private String details;
 
@@ -53,7 +52,7 @@ public class OperationResult {
     public List<Row<GenericTableSchema>> getRows() {
         return rows;
     }
-    public void setRows(ArrayList<Row<GenericTableSchema>> rows) {
+    public void setRows(List<Row<GenericTableSchema>> rows) {
         this.rows = rows;
     }
     public String getError() {
index a59c749b54043577f87645d8c1b1ee7bbc817f37..d52b053cc549b7d21cce7349638834af9e79b723 100644 (file)
@@ -8,7 +8,6 @@
 
 package org.opendaylight.ovsdb.lib.operations;
 
-import java.util.ArrayList;
 import java.util.List;
 
 import org.opendaylight.ovsdb.lib.OvsdbClient;
@@ -21,7 +20,7 @@ public class TransactionBuilder {
 
     private DatabaseSchema databaseSchema;
     OvsdbClient ovs;
-    ArrayList<Operation> operations = Lists.newArrayList();
+    List<Operation> operations = Lists.newArrayList();
 
     public TransactionBuilder(OvsdbClient ovs, DatabaseSchema schema) {
         this.ovs = ovs;
index 04e8fb0ea9024376a24609f04c524a97ef1d661d..a5c5f429c3cc289442666d8a5848519d1ce559ff 100644 (file)
@@ -26,7 +26,6 @@ import org.opendaylight.ovsdb.lib.schema.ColumnType.AtomicColumnType;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.Lists;
 
 
 public abstract class TableSchema<E extends TableSchema<E>> {
@@ -138,7 +137,7 @@ public abstract class TableSchema<E extends TableSchema<E>> {
     }
 
     public Row<E> createRow(ObjectNode rowNode) {
-        List<Column<E, ?>> columns = Lists.newArrayList();
+        List<Column<E, ?>> columns = new ArrayList<>();
         for (Iterator<Map.Entry<String, JsonNode>> iter = rowNode.fields(); iter.hasNext();) {
             Map.Entry<String, JsonNode> next = iter.next();
             ColumnSchema<E, Object> schema = column(next.getKey(), Object.class);
@@ -156,8 +155,8 @@ public abstract class TableSchema<E extends TableSchema<E>> {
         return new Row<>(this, columns);
     }
 
-    public ArrayList<Row<E>> createRows(JsonNode rowsNode) {
-        ArrayList<Row<E>> rows = Lists.newArrayList();
+    public List<Row<E>> createRows(JsonNode rowsNode) {
+        List<Row<E>> rows = new ArrayList<>();
         for (JsonNode rowNode : rowsNode.get("rows")) {
             rows.add(createRow((ObjectNode)rowNode));
         }
index 4c9348a1faeaab99981e26aca3cb148fe678f091..7e647d6043e9a42c3d88c3fde3e3082cd9276135 100644 (file)
@@ -13,7 +13,7 @@ import org.opendaylight.ovsdb.lib.notation.Version;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
-import java.lang.annotation.ElementType;;
+import java.lang.annotation.ElementType;
 
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
index 8b569813bda0236de84d7bf102f25170cb54853d..881ec0b7ae92d290c65f9ebb7839135ef649048d 100644 (file)
@@ -13,7 +13,7 @@ import org.opendaylight.ovsdb.lib.notation.Version;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
-import java.lang.annotation.ElementType;;
+import java.lang.annotation.ElementType;
 
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
index d59121e0675a49f6052949c7691e30d5dc507e5c..8c9adceb13ac728e568129742912f6a9d4058b69 100644 (file)
@@ -196,13 +196,9 @@ public class TyperUtils {
     }
 
     private static void checkVersion(Version schemaVersion, Version fromVersion, Version untilVersion) {
-        if (!fromVersion.equals(Version.NULL) && schemaVersion.compareTo(fromVersion) < 0) {
-            String message = SchemaVersionMismatchException.createMessage(schemaVersion, fromVersion);
-            throw new SchemaVersionMismatchException(message);
-        }
-        if (!untilVersion.equals(Version.NULL) && schemaVersion.compareTo(untilVersion) > 0) {
-            String message = SchemaVersionMismatchException.createMessage(schemaVersion, untilVersion);
-            throw new SchemaVersionMismatchException(message);
+        if ((!fromVersion.equals(Version.NULL) && schemaVersion.compareTo(fromVersion) < 0) || (!untilVersion.equals(
+                Version.NULL) && schemaVersion.compareTo(untilVersion) > 0)) {
+            throw new SchemaVersionMismatchException(schemaVersion, fromVersion, untilVersion);
         }
     }
 
@@ -304,7 +300,7 @@ public class TyperUtils {
                 // When the row is null, that might indicate that the user maybe interested
                 // only in the ColumnSchema and not on the Data.
                 if (row == null) {
-                    return new Column<GenericTableSchema, Object>(columnSchema, null);
+                    return new Column<>(columnSchema, null);
                 }
                 return row.getColumn(columnSchema);
             }
index 8fc9039940469f5b56ce7cfa1d4e8357ac6f0e31..57b960957cab81967ce5504a6353013593b71540 100644 (file)
@@ -9,7 +9,7 @@ package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.library
 
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.ovsdb.lib.impl.LibraryProvider;
+import org.opendaylight.ovsdb.lib.impl.OvsdbConnectionService;
 import org.osgi.framework.BundleContext;
 
 import com.google.common.base.Preconditions;
@@ -33,9 +33,7 @@ public class LibraryModule extends org.opendaylight.yang.gen.v1.urn.opendaylight
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        LibraryProvider provider = new LibraryProvider(bundleContext);
-        getBrokerDependency().registerProvider(provider);
-        return provider;
+        return new OvsdbConnectionService();
     }
 
     public void setBundleContext(BundleContext bundleContext) {
index 97b0f086adcd487c221459b1b20c17dc15c5c7b2..21932fb6d09ec6b4b7a816e2cd53bc4e06e07bbc 100644 (file)
@@ -17,6 +17,12 @@ module library {
     identity library {
         base config:module-type;
         config:java-name-prefix Library;
+        config:provided-service connection-service;
+    }
+
+    identity connection-service {
+        base config:service-type;
+        config:java-class "org.opendaylight.ovsdb.lib.OvsdbConnection";
     }
 
     augment "/config:modules/config:module/config:configuration" {
index 389e33f1fe47b218a93ffa730910b32a8a0f31c7..98703b99f2de4941d5ec1e927cc3d9da6fb5039c 100644 (file)
@@ -17,7 +17,6 @@ import com.google.common.base.Charsets;
 import com.google.common.io.Resources;
 import io.netty.channel.embedded.EmbeddedChannel;
 import io.netty.handler.codec.DecoderException;
-import io.netty.handler.codec.TooLongFrameException;
 import io.netty.util.CharsetUtil;
 import java.net.URL;
 import org.junit.Before;
index fe4d007544c52b8bc75e318b155a7feadeba4250..ede3e6d0da586f3cee5c210800ea5282fa81bccf 100644 (file)
@@ -12,7 +12,6 @@ import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.JmxAttribute;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.ovsdb.lib.impl.LibraryProvider;
 import org.osgi.framework.BundleContext;
 
 import javax.management.ObjectName;
@@ -20,7 +19,6 @@ import javax.management.ObjectName;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 public class LibraryModuleTest {
@@ -49,9 +47,6 @@ public class LibraryModuleTest {
         // getInstance calls resolveInstance to get the broker dependency and then calls createInstance
         AutoCloseable closeable = module.getInstance();
 
-        // verify that the module registered the returned provider with the broker
-        verify(broker).registerProvider((LibraryProvider)closeable);
-
         // ensure no exceptions on close
         closeable.close();
     }
index 32d5f870e05fd46025d0cb3aaf7c6907b11f3911..f0cbe5a84f27fcc63e04bd7c39fac4c94e07a62a 100644 (file)
@@ -92,7 +92,7 @@ public class OvsdbClientTestIT extends LibraryIntegrationTestBase {
         Assert.assertNotNull(dbSchema);
         GenericTableSchema bridge = dbSchema.table("Bridge", GenericTableSchema.class);
 
-        List<MonitorRequest<GenericTableSchema>> monitorRequests = Lists.newArrayList();
+        List<MonitorRequest> monitorRequests = Lists.newArrayList();
         ColumnSchema<GenericTableSchema, Set<Integer>> flood_vlans = bridge.multiValuedColumn("flood_vlans", Integer.class);
         ColumnSchema<GenericTableSchema, Map<String, String>> externalIds = bridge.multiValuedColumn("external_ids", String.class, String.class);
         ColumnSchema<GenericTableSchema, String> name = bridge.column("name", String.class);
@@ -180,7 +180,7 @@ public class OvsdbClientTestIT extends LibraryIntegrationTestBase {
         Assert.assertNotNull(dbSchema);
         GenericTableSchema ovsTable = dbSchema.table("Open_vSwitch", GenericTableSchema.class);
 
-        List<MonitorRequest<GenericTableSchema>> monitorRequests = Lists.newArrayList();
+        List<MonitorRequest> monitorRequests = Lists.newArrayList();
         ColumnSchema<GenericTableSchema, UUID> _uuid = ovsTable.column("_uuid", UUID.class);
 
         List<OperationResult> results = ovs.transactBuilder(dbSchema)
index 1d07fa28d2d9e2bc0bf9ffbacab49b89319b33c9..067fcdb4bdabda78dd9d30dd34b129a9bd772f92 100644 (file)
@@ -164,7 +164,7 @@ public class HardwareVTEPIT  extends LibraryIntegrationTestBase {
      *
      * @return MonitorRequest that includes all the Bridge Columns including _uuid
      */
-    public <T extends TypedBaseTable<GenericTableSchema>> MonitorRequest<GenericTableSchema> getAllColumnsMonitorRequest (Class <T> klazz) {
+    public <T extends TypedBaseTable<GenericTableSchema>> MonitorRequest getAllColumnsMonitorRequest (Class <T> klazz) {
         TypedBaseTable<GenericTableSchema> table = getClient().createTypedRowWrapper(klazz);
         GenericTableSchema tableSchema = table.getSchema();
         Set<String> columns = tableSchema.getColumns();
@@ -175,7 +175,7 @@ public class HardwareVTEPIT  extends LibraryIntegrationTestBase {
         return bridgeBuilder.with(new MonitorSelect(true, true, true, true)).build();
     }
 
-    public <T extends TableSchema<T>> MonitorRequest<T> getAllColumnsMonitorRequest (T tableSchema) {
+    public <T extends TableSchema<T>> MonitorRequest getAllColumnsMonitorRequest (T tableSchema) {
         Set<String> columns = tableSchema.getColumns();
         MonitorRequestBuilder<T> monitorBuilder = MonitorRequestBuilder.builder(tableSchema);
         for (String column : columns) {
@@ -192,7 +192,7 @@ public class HardwareVTEPIT  extends LibraryIntegrationTestBase {
 
         assertNotNull(getDbSchema());
 
-        List<MonitorRequest<GenericTableSchema>> monitorRequests = Lists.newArrayList();
+        List<MonitorRequest> monitorRequests = Lists.newArrayList();
         Set<String> tables = getDbSchema().getTables();
         assertNotNull("ovsdb tables should not be null", tables);
 
index 8d12cd163993a92c316c2cd0e0be9f8cce452efc..d7dfe6789537dfd29cd1cecce75aeb725498aede 100644 (file)
@@ -214,7 +214,7 @@ public class OpenVSwitchIT extends LibraryIntegrationTestBase {
      *
      * @return MonitorRequest that includes all the Bridge Columns including _uuid
      */
-    public <T extends TypedBaseTable<GenericTableSchema>> MonitorRequest<GenericTableSchema> getAllColumnsMonitorRequest (Class <T> klazz) {
+    public <T extends TypedBaseTable<GenericTableSchema>> MonitorRequest getAllColumnsMonitorRequest (Class <T> klazz) {
         TypedBaseTable<GenericTableSchema> table = getClient().createTypedRowWrapper(klazz);
         GenericTableSchema tableSchema = table.getSchema();
         Set<String> columns = tableSchema.getColumns();
@@ -225,7 +225,7 @@ public class OpenVSwitchIT extends LibraryIntegrationTestBase {
         return bridgeBuilder.with(new MonitorSelect(true, true, true, true)).build();
     }
 
-    public <T extends TableSchema<T>> MonitorRequest<T> getAllColumnsMonitorRequest (T tableSchema) {
+    public <T extends TableSchema<T>> MonitorRequest getAllColumnsMonitorRequest (T tableSchema) {
         Set<String> columns = tableSchema.getColumns();
         MonitorRequestBuilder<T> monitorBuilder = MonitorRequestBuilder.builder(tableSchema);
         for (String column : columns) {
@@ -242,7 +242,7 @@ public class OpenVSwitchIT extends LibraryIntegrationTestBase {
 
         assertNotNull(getDbSchema());
 
-        List<MonitorRequest<GenericTableSchema>> monitorRequests = Lists.newArrayList();
+        List<MonitorRequest> monitorRequests = Lists.newArrayList();
         Set<String> tables = getDbSchema().getTables();
         assertNotNull("ovsdb tables should not be null", tables);
 
@@ -470,18 +470,12 @@ public class OpenVSwitchIT extends LibraryIntegrationTestBase {
         bridgeDelete(testBridgeUuid);
     }
 
-    @Test
+    @Test(expected = SchemaVersionMismatchException.class)
     public void testFlowSampleCollectorSetTableNotSupported () {
         // Don't run this test if the table is not supported
         assumeTrue(schemaVersion.compareTo(flowSampleCollectorSetFromVersion) < 0);
 
-        boolean isExceptionRaised = false;
-        try {
-            getClient().createTypedRowWrapper(FlowSampleCollectorSet.class);
-        } catch (SchemaVersionMismatchException e) {
-            isExceptionRaised = true;
-        }
-        assertTrue(isExceptionRaised);
+        getClient().createTypedRowWrapper(FlowSampleCollectorSet.class);
     }
 
     public void flowSampleCollectorSetInsert () throws ExecutionException, InterruptedException {
@@ -540,18 +534,12 @@ public class OpenVSwitchIT extends LibraryIntegrationTestBase {
         bridgeDelete(testBridgeUuid);
     }
 
-    @Test
+    @Test(expected = SchemaVersionMismatchException.class)
     public void testFlowTableTableNotSupported () {
         // Don't run this test if the table is not supported
         assumeTrue(schemaVersion.compareTo(flowTableFromVersion) < 0);
 
-        boolean isExceptionRaised = false;
-        try {
-            getClient().createTypedRowWrapper(FlowTable.class);
-        } catch (SchemaVersionMismatchException e) {
-            isExceptionRaised = true;
-        }
-        assertTrue(isExceptionRaised);
+        getClient().createTypedRowWrapper(FlowTable.class);
     }
 
     public void flowTableInsert () throws ExecutionException, InterruptedException {
@@ -632,18 +620,12 @@ public class OpenVSwitchIT extends LibraryIntegrationTestBase {
         bridgeDelete(testBridgeUuid);
     }
 
-    @Test
+    @Test(expected = SchemaVersionMismatchException.class)
     public void testIpfixTableNotSupported () {
         // Don't run this test if the table is not supported
         assumeTrue(schemaVersion.compareTo(ipfixFromVersion) < 0);
 
-        boolean isExceptionRaised = false;
-        try {
-            getClient().createTypedRowWrapper(IPFIX.class);
-        } catch (SchemaVersionMismatchException e) {
-            isExceptionRaised = true;
-        }
-        assertTrue(isExceptionRaised);
+        getClient().createTypedRowWrapper(IPFIX.class);
     }
 
     public void ipfixInsert () throws ExecutionException, InterruptedException {
index 43fbb78ef9f7a7774e635453ece2139a7204aaec..c49173d9d6a6dc13a85089086641c1cb11ebae89 100644 (file)
@@ -7,19 +7,22 @@
  */
 package org.opendaylight.ovsdb.openstack.netvirt.it;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 import static org.ops4j.pax.exam.CoreOptions.composite;
 import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
 import static org.ops4j.pax.exam.CoreOptions.vmOption;
 import static org.ops4j.pax.exam.CoreOptions.when;
+import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
+import static org.ops4j.pax.exam.MavenUtils.asInProject;
 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
-import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features;
 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
 
 import com.google.common.collect.ImmutableBiMap;
 import com.google.common.collect.Lists;
-import com.google.common.collect.ObjectArrays;
 
 import java.io.File;
 import java.net.InetAddress;
@@ -28,6 +31,7 @@ import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.atomic.AtomicBoolean;
 import javax.inject.Inject;
@@ -39,10 +43,17 @@ import org.junit.runner.RunWith;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.PipelineOrchestrator;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+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.params.xml.ns.yang.ovsdb.rev150105.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
@@ -126,6 +137,10 @@ public class NetvirtIT extends AbstractMdsalTestBase {
 
     private Option[] getOtherOptions() {
         return new Option[] {
+                wrappedBundle(
+                        mavenBundle("org.opendaylight.ovsdb", "utils.mdsal-openflow")
+                                .version(asInProject())
+                                .type("jar")),
                 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
                 keepRuntimeFolder()
         };
@@ -143,12 +158,12 @@ public class NetvirtIT extends AbstractMdsalTestBase {
 
     @Override
     public String getModuleName() {
-        return "openstack.net-virt-providers";
+        return "netvirt-providers-impl";
     }
 
     @Override
     public String getInstanceName() {
-        return "net-virt-providers-default";
+        return "netvirt-providers-default";
     }
 
     @Override
@@ -177,14 +192,11 @@ public class NetvirtIT extends AbstractMdsalTestBase {
         return composite(
                 editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
                         "log4j.logger.org.opendaylight.ovsdb",
-                        LogLevelOption.LogLevel.DEBUG.name()),
+                        LogLevelOption.LogLevel.TRACE.name()),
                 editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
                         "log4j.logger.org.opendaylight.ovsdb.lib",
                         LogLevelOption.LogLevel.INFO.name()),
                 super.getLoggingOption());
-            /*editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
-                    "log4j.logger.org.opendaylight.ovsdb.openstack.net-virt",
-                    LogLevelOption.LogLevel.DEBUG.name())*/
     }
 
     private Option[] getPropertiesOptions() {
@@ -199,7 +211,7 @@ public class NetvirtIT extends AbstractMdsalTestBase {
         LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
                 connectionType, addressStr, portStr);
 
-        Option[] options = new Option[] {
+        return new Option[] {
                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
                         NetvirtITConstants.SERVER_IPADDRESS, addressStr),
                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
@@ -207,7 +219,6 @@ public class NetvirtIT extends AbstractMdsalTestBase {
                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
                         NetvirtITConstants.CONNECTION_TYPE, connectionType),
         };
-        return options;
     }
 
     @Before
@@ -308,9 +319,8 @@ public class NetvirtIT extends AbstractMdsalTestBase {
     }
 
     private Node getOvsdbNode(final ConnectionInfo connectionInfo) {
-        Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
+        return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
                 SouthboundMapper.createInstanceIdentifier(connectionInfo));
-        return node;
     }
 
     private boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
@@ -342,10 +352,10 @@ public class NetvirtIT extends AbstractMdsalTestBase {
         try{
             for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
                  ifaces.hasMoreElements();) {
-                NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
+                NetworkInterface iface = ifaces.nextElement();
 
                 for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
-                    InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
+                    InetAddress inetAddr = inetAddrs.nextElement();
                     if (!inetAddr.isLoopbackAddress()) {
                         if (inetAddr.isSiteLocalAddress()) {
                             ipaddress = inetAddr.getHostAddress();
@@ -440,11 +450,11 @@ public class NetvirtIT extends AbstractMdsalTestBase {
     }
 
     private List<ProtocolEntry> createMdsalProtocols() {
-        List<ProtocolEntry> protocolList = new ArrayList<ProtocolEntry>();
+        List<ProtocolEntry> protocolList = new ArrayList<>();
         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
                 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
         protocolList.add(new ProtocolEntryBuilder().
-                setProtocol((Class<? extends OvsdbBridgeProtocolBase>) mapper.get("OpenFlow13")).build());
+                setProtocol(mapper.get("OpenFlow13")).build());
         return protocolList;
     }
 
@@ -684,8 +694,34 @@ public class NetvirtIT extends AbstractMdsalTestBase {
     @Test
     public void testNetVirt() throws InterruptedException {
         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
+        Node ovsdbNode = connectOvsdbNode(connectionInfo);
+
         Thread.sleep(10000);
+        // Verify the pipeline flows were installed
+        PipelineOrchestrator pipelineOrchestrator =
+                (PipelineOrchestrator) ServiceHelper.getGlobalInstance(PipelineOrchestrator.class, this);
+        assertNotNull("Could not find PipelineOrchestrator Service", pipelineOrchestrator);
+        Node bridgeNode = southbound.getBridgeNode(ovsdbNode, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
+        assertNotNull("bridge " + NetvirtITConstants.INTEGRATION_BRIDGE_NAME + " was not found", bridgeNode);
+        long datapathId = southbound.getDataPathId(bridgeNode);
+        org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder nodeBuilder =
+                FlowUtils.createNodeBuilder(datapathId);
+
+        List<Service> staticPipeline = pipelineOrchestrator.getStaticPipeline();
+        List<Service> staticPipelineFound = Lists.newArrayList();
+        for (Service service : pipelineOrchestrator.getServiceRegistry().keySet()) {
+            if (staticPipeline.contains(service)) {
+                staticPipelineFound.add(service);
+            }
+            FlowBuilder flowBuilder = FlowUtils.getPipelineFlow(service.getTable(), (short)0);
+            Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
+            assertNotNull("Could not find flow in config", flow);
+            flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
+            assertNotNull("Could not find flow in operational", flow);
+        }
+        assertEquals("did not find all expected flows in static pipeline",
+                staticPipeline.size(), staticPipelineFound.size());
+
         netVirtAddPort(connectionInfo);
         Thread.sleep(10000);
         Assert.assertTrue(deleteBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME));
@@ -707,4 +743,22 @@ public class NetvirtIT extends AbstractMdsalTestBase {
             LOG.info(">>>>> node: {}", node);
         }
     }
+
+    private Flow getFlow (
+            FlowBuilder flowBuilder,
+            org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder nodeBuilder,
+            LogicalDatastoreType store)
+            throws InterruptedException {
+
+        Flow flow = null;
+        for (int i = 0; i < 10; i++) {
+            flow = FlowUtils.getFlow(flowBuilder, nodeBuilder, dataBroker.newReadOnlyTransaction(), store);
+            if (flow != null) {
+                LOG.info("getFlow: flow({}): {}", store, flow);
+                break;
+            }
+            Thread.sleep(1000);
+        }
+        return flow;
+    }
 }
index e302c2b42a70afbc1abeb2c9e012d32ab90a7fcf..29109865b18d2e098e0347be2eec8093b88546dc 100755 (executable)
@@ -89,7 +89,7 @@ public class SouthboundConstants {
             .build();
     public static final String IID_EXTERNAL_ID_KEY = "opendaylight-iid";
 
-    public static enum VLANMODES {
+    public enum VLANMODES {
         ACCESS("access"),
         NATIVE_TAGGED("native-tagged"),
         NATIVE_UNTAGGED("native-untagged"),
@@ -97,7 +97,7 @@ public class SouthboundConstants {
 
         private final String mode;
 
-        private VLANMODES(String mode) {
+        VLANMODES(String mode) {
             this.mode = mode;
         }
         @Override
index 0ca89b042fca2ac984727b8f087ae409a44a9cb3..7c7f43493c0dfd691cb1b74459d6b0b2fa34ddc2 100644 (file)
@@ -154,12 +154,10 @@ public class SouthboundMapper {
     public static String createDatapathType(OvsdbBridgeAugmentation mdsalbridge) {
         String datapathtype = SouthboundConstants.DATAPATH_TYPE_MAP.get(DatapathTypeSystem.class);
 
-        if (mdsalbridge.getDatapathType() != null) {
-            if (SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType()) != null) {
-                datapathtype = SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType());
-            } else {
-                throw new IllegalArgumentException("Unknown datapath type "
-                        + SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType()));
+        if (mdsalbridge.getDatapathType() != null && !mdsalbridge.getDatapathType().equals(DatapathTypeBase.class)) {
+            datapathtype = SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType());
+            if (datapathtype == null) {
+                throw new IllegalArgumentException("Unknown datapath type " + mdsalbridge.getDatapathType().getName());
             }
         }
         return datapathtype;
@@ -190,7 +188,7 @@ public class SouthboundMapper {
     }
 
     public static Set<String> createOvsdbBridgeProtocols(OvsdbBridgeAugmentation ovsdbBridgeNode) {
-        Set<String> protocols = new HashSet<String>();
+        Set<String> protocols = new HashSet<>();
         if (ovsdbBridgeNode.getProtocolEntry() != null && ovsdbBridgeNode.getProtocolEntry().size() > 0) {
             for (ProtocolEntry protocol : ovsdbBridgeNode.getProtocolEntry()) {
                 if (SouthboundConstants.OVSDB_PROTOCOL_MAP.get(protocol.getProtocol()) != null) {
index 76ca876bdd34368c4b7c57b54e54730bf4038838..dfef38d55431f8a6c579369b2f1f57ce9b3381d7 100644 (file)
@@ -259,7 +259,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
             <Embed-Dependency>utils.config,utils.mdsal-openflow;type=!pom;inline=false</Embed-Dependency>
             <Embed-Transitive>true</Embed-Transitive>
             <Export-Package>
-              org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.*
+              org.opendaylight.ovsdb.openstack.netvirt.providers,
+              org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13
             </Export-Package>
           </instructions>
         </configuration>
index 32d43df895e5035906a6c247d3c509435088e0c1..f748ee76a4100bd81f991b71324cc638f59650b6 100644 (file)
@@ -3,16 +3,6 @@
 <snapshot>
   <required-capabilities>
     <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
-    <!--<capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&amp;revision=2013-10-28</capability>
-    <capability>
-      urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&amp;revision=2013-10-28
-    </capability>
-    <capability>
-      urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&amp;revision=2013-10-28
-    </capability>
-    <capability>
-      urn:opendaylight:params:xml:ns:yang:controller:config?module=config&amp;revision=2013-04-05
-    </capability>-->
     <capability>urn:opendaylight:params:xml:ns:yang:southbound:impl?module=southbound-impl&amp;revision=2014-12-10</capability>
     <capability>urn:opendaylight:params:xml:ns:yang:netvirt:impl?module=netvirt-impl&amp;revision=2015-05-13</capability>
     <capability>urn:opendaylight:params:xml:ns:yang:netvirt:providers:impl?module=netvirt-providers-impl&amp;revision=2015-05-13</capability>
index 02d6815f6c74f27953d41adb297813b54d86c477..b2861c35d53b9a2b6443d67a402b40aa9974b081 100644 (file)
@@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory;
 
 public class ConfigActivator implements BundleActivator {
     private static final Logger LOG = LoggerFactory.getLogger(ConfigActivator.class);
-    private List<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
+    private List<ServiceRegistration<?>> registrations = new ArrayList<>();
     private ProviderContext providerContext;
 
     public ConfigActivator(ProviderContext providerContext) {
index f66669e756d8dcd13bbf665da70f9c9af53d8b40..e6037c09aa8e06e8667d9a0f803518488b0c0a5e 100644 (file)
@@ -40,6 +40,7 @@ public class NetvirtProvidersProvider implements BindingAwareProvider, AutoClose
 
     @Override
     public void close() throws Exception {
+        LOG.info("NetvirtProvidersProvider closed");
         activator.stop(bundleContext);
     }
 
index c354d2dcefe32bc8d504ac8144a6c9fc0089b921..05b16236b05d5116480215932612bcf21b97d136 100644 (file)
@@ -1020,9 +1020,9 @@ public class OF13Provider implements ConfigInterface, NetworkingProvider {
                     return;
                 }
             }
-            ingressAclProvider.programFixedSecurityAcl(dpid, segmentationId, dhcpPort.getMacAddress(), localPort,
+            ingressAclProvider.programFixedSecurityGroup(dpid, segmentationId, dhcpPort.getMacAddress(), localPort,
                                                        isLastPortinSubnet, isComputePort, write);
-            egressAclProvider.programFixedSecurityAcl(dpid, segmentationId, attachedMac, localPort,
+            egressAclProvider.programFixedSecurityGroup(dpid, segmentationId, attachedMac, localPort,
                                                       srcAddressList, isLastPortinBridge, isComputePort,write);
             /* If the network type is tunnel based (VXLAN/GRRE/etc) with Neutron Port Security ACLs */
             /* TODO SB_MIGRATION */
@@ -1033,11 +1033,13 @@ public class OF13Provider implements ConfigInterface, NetworkingProvider {
                 //Associate the security group flows.
                 List<NeutronSecurityGroup> securityGroupListInPort = securityServicesManager
                         .getSecurityGroupInPortList(intf);
+                String neutronPortId = southbound.getInterfaceExternalIdsValue(intf,
+                                                                               Constants.EXTERNAL_ID_INTERFACE_ID);
                 for (NeutronSecurityGroup securityGroupInPort:securityGroupListInPort) {
-                    ingressAclProvider.programPortSecurityAcl(dpid, segmentationId, attachedMac, localPort,
-                                                              securityGroupInPort,srcAddressList, write);
-                    egressAclProvider.programPortSecurityAcl(dpid, segmentationId, attachedMac, localPort,
-                                                             securityGroupInPort,srcAddressList, write);
+                    ingressAclProvider.programPortSecurityGroup(dpid, segmentationId, attachedMac, localPort,
+                                                              securityGroupInPort, neutronPortId, write);
+                    egressAclProvider.programPortSecurityGroup(dpid, segmentationId, attachedMac, localPort,
+                                                             securityGroupInPort, neutronPortId, write);
                 }
             }
         } else {
index e6e0fd0396bf0a638685381f762206ec73d015ec..6f8a19728298cec71d23d9fdeb0e77af6ad60d2d 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13;
 
+import java.util.List;
+import java.util.Map;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.osgi.framework.ServiceReference;
 
@@ -21,6 +23,8 @@ import org.osgi.framework.ServiceReference;
 public interface PipelineOrchestrator {
     Service getNextServiceInPipeline(Service service);
     AbstractServiceInstance getServiceInstance(Service service);
+    Map<Service, AbstractServiceInstance> getServiceRegistry();
+    List<Service> getStaticPipeline();
     void enqueue(Node node);
     void registerService(final ServiceReference ref, AbstractServiceInstance serviceInstance);
     void unregisterService(final ServiceReference ref);
index edea48c26cdc122d5e2c6cbd29dd478f62e90075..299ab21a08b76f4261a5fceee18f5e49cf8c7046 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.BlockingQueue;
@@ -32,6 +33,11 @@ import com.google.common.collect.Maps;
 
 public class PipelineOrchestratorImpl implements ConfigInterface, NodeCacheListener, PipelineOrchestrator {
     private static final Logger LOG = LoggerFactory.getLogger(PipelineOrchestratorImpl.class);
+
+    public List<Service> getStaticPipeline() {
+        return staticPipeline;
+    }
+
     private List<Service> staticPipeline = Lists.newArrayList(
             Service.CLASSIFIER,
             Service.ARP_RESPONDER,
@@ -45,6 +51,11 @@ public class PipelineOrchestratorImpl implements ConfigInterface, NodeCacheListe
             Service.OUTBOUND_NAT,
             Service.L2_FORWARDING
     );
+
+    public Map<Service, AbstractServiceInstance> getServiceRegistry() {
+        return serviceRegistry;
+    }
+
     Map<Service, AbstractServiceInstance> serviceRegistry = Maps.newConcurrentMap();
     private volatile BlockingQueue<Node> queue;
     private ExecutorService eventHandler;
@@ -61,6 +72,23 @@ public class PipelineOrchestratorImpl implements ConfigInterface, NodeCacheListe
         Service service = (Service)ref.getProperty(AbstractServiceInstance.SERVICE_PROPERTY);
         LOG.info("registerService {} - {}", serviceInstance, service);
         serviceRegistry.put(service, serviceInstance);
+        // insert the service if not already there. The list is ordered based of table ID.
+        if (!staticPipeline.contains(service) && !isTableInPipeline(service.getTable())) {
+            staticPipeline.add(service);
+            Collections.sort(staticPipeline, Service.insertComparator);
+        }
+        LOG.info("registerService: {}", staticPipeline);
+    }
+
+    private boolean isTableInPipeline (short tableId) {
+        boolean found = false;
+        for (Service service : staticPipeline) {
+            if (service.getTable() == tableId) {
+                found = true;
+                break;
+            }
+        }
+        return found;
     }
 
     public void unregisterService(final ServiceReference ref) {
index 30bec35cdaf0fe620babc66ed073b6ad3d2b1a87..25177441218ed005b4c4788254738b7c1bb0608a 100644 (file)
@@ -8,11 +8,14 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13;
 
+import java.util.Comparator;
+
 public enum Service {
 
     CLASSIFIER ((short) 0, "Classifier"),
     GATEWAY_RESOLVER((short) 0, "External Network Gateway Resolver"),
     DIRECTOR ((short) 10, "Director"),
+    SFC_CLASSIFIER ((short) 10, "SFC Classifier"),
     ARP_RESPONDER ((short) 20, "Distributed ARP Responder"),
     INBOUND_NAT ((short) 30, "DNAT for inbound floating-ip traffic"),
     EGRESS_ACL ((short) 40, "Egress Acces-control"),
@@ -27,7 +30,7 @@ public enum Service {
     short table;
     String description;
 
-    private Service (short table, String description)  {
+    Service(short table, String description)  {
         this.table = table;
         this.description = description;
     }
@@ -39,4 +42,12 @@ public enum Service {
     public String getDescription() {
         return description;
     }
+
+    public static Comparator<Service> insertComparator = new Comparator<Service>() {
+
+        @Override
+        public int compare(Service service1, Service service2) {
+            return service1.getTable() - service2.getTable();
+        }
+    };
 }
index 126db01610f634c0e3c93be3623879994811f292..e9ee40045016ddc607b1401ebda15c14553178c9 100644 (file)
@@ -108,6 +108,7 @@ public class ClassifierService extends AbstractServiceInstance implements Classi
                     BigInteger.valueOf(REG_VALUE_FROM_LOCAL)));
             ab.setOrder(1);
             ab.setKey(new ActionKey(1));
+
             actionList.add(ab.build());
 
             ib.setOrder(0);
index 7faf6b048f84070a686195f433868ad595de3caf..350f9cf478e18d8c3543449ca71d3adf8cffbbc4 100644 (file)
@@ -8,18 +8,18 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
 
-import java.math.BigInteger;
-import java.util.List;
+import com.google.common.collect.Lists;
 
-import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
-import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
-import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EgressAclProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityGroupCacheManger;
 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
@@ -40,12 +40,14 @@ import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Lists;
+import java.math.BigInteger;
+import java.util.List;
 
 public class EgressAclService extends AbstractServiceInstance implements EgressAclProvider, ConfigInterface {
 
     private static final Logger LOG = LoggerFactory.getLogger(EgressAclService.class);
     private volatile SecurityServicesManager securityServicesManager;
+    private volatile SecurityGroupCacheManger securityGroupCacheManger;
     private static final int DHCP_SOURCE_PORT = 67;
     private static final int DHCP_DESTINATION_PORT = 68;
     private static final String HOST_MASK = "/32";
@@ -61,11 +63,10 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
     }
 
     @Override
-    public void programPortSecurityAcl(Long dpid, String segmentationId, String attachedMac, long localPort,
-                                       NeutronSecurityGroup securityGroup,
-                                       List<Neutron_IPs> srcAddressList, boolean write) {
+    public void programPortSecurityGroup(Long dpid, String segmentationId, String attachedMac, long localPort,
+                                       NeutronSecurityGroup securityGroup, String portUuid, boolean write) {
 
-        LOG.trace("programPortSecurityAcl: neutronSecurityGroup: {} ", securityGroup);
+        LOG.trace("programPortSecurityGroup: neutronSecurityGroup: {} ", securityGroup);
         if (securityGroup == null || securityGroup.getSecurityRules() == null) {
             return;
         }
@@ -73,6 +74,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         List<NeutronSecurityRule> portSecurityList = securityGroup.getSecurityRules();
         /* Iterate over the Port Security Rules in the Port Security Group bound to the port*/
         for (NeutronSecurityRule portSecurityRule : portSecurityList) {
+
             /**
              * Neutron Port Security Acl "egress" and "IPv4"
              * Check that the base conditions for flow based Port Security are true:
@@ -81,219 +83,126 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
              * http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
              *
              */
+
+            if (portSecurityRule == null ||
+                    portSecurityRule.getSecurityRuleEthertype() == null ||
+                    portSecurityRule.getSecurityRuleDirection() == null) {
+                continue;
+            }
+
             if ("IPv4".equals(portSecurityRule.getSecurityRuleEthertype())
                     && portSecurityRule.getSecurityRuleDirection().equals("egress")) {
-                LOG.debug("programPortSecurityAcl: Acl Rule matching IPv4 and ingress is: {} ", portSecurityRule);
-                if (null == portSecurityRule.getSecurityRuleProtocol()) {
-                    /* TODO Rework on the priority values */
-                    egressAclIPv4(dpid, segmentationId, attachedMac,
-                                  write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                } else if (null != portSecurityRule.getSecurityRemoteGroupID()) {
-                  //Remote Security group is selected
+                LOG.debug("programPortSecurityGroup: Acl Rule matching IPv4 and ingress is: {} ", portSecurityRule);
+                if (null != portSecurityRule.getSecurityRemoteGroupID()) {
+                    //Remote Security group is selected
                     List<Neutron_IPs> remoteSrcAddressList = securityServicesManager
-                            .getVmListForSecurityGroup(srcAddressList,portSecurityRule.getSecurityRemoteGroupID());
+                            .getVmListForSecurityGroup(portUuid,portSecurityRule.getSecurityRemoteGroupID());
                     if (null != remoteSrcAddressList) {
                         for (Neutron_IPs vmIp :remoteSrcAddressList ) {
-                            switch (portSecurityRule.getSecurityRuleProtocol()) {
-                                case MatchUtils.TCP:
-                                    egressAclTcp(dpid, segmentationId, attachedMac,
-                                                 portSecurityRule,vmIp.getIpAddress(), write,
-                                                 Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                                    break;
-                                case MatchUtils.UDP:
-                                    egressAclUdp(dpid, segmentationId, attachedMac,
-                                                 portSecurityRule,vmIp.getIpAddress(), write,
-                                                 Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                                    break;
-                                case MatchUtils.ICMP:
-                                    egressAclIcmp(dpid, segmentationId, attachedMac,
-                                                   portSecurityRule, vmIp.getIpAddress(),write,
-                                                   Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                                    break;
-                                default:
-                                    LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
-                                    break;
-                            }
+
+                            programPortSecurityRule(dpid, segmentationId, attachedMac,
+                                                    localPort, portSecurityRule, vmIp, write);
+                        }
+                        if (write) {
+                            securityGroupCacheManger.addToCache(portSecurityRule.getSecurityRemoteGroupID(), portUuid);
+                        } else {
+                            securityGroupCacheManger.removeFromCache(portSecurityRule.getSecurityRemoteGroupID(),
+                                                                     portUuid);
                         }
                     }
                 } else {
-                    //CIDR is selected
-                    switch (portSecurityRule.getSecurityRuleProtocol()) {
-                        case MatchUtils.TCP:
-                            egressAclTcp(dpid, segmentationId, attachedMac,
-                                         portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                            break;
-                        case MatchUtils.UDP:
-                            egressAclUdp(dpid, segmentationId, attachedMac,
-                                         portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                            break;
-                        case MatchUtils.ICMP:
-                            egressAclIcmp(dpid, segmentationId, attachedMac,
-                                           portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                            break;
-                        default:
-                            LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
-                    }
-                }
-            }
-            /*
-             * Code is refactored to handle all the protocols. More
-             * protocols  will be added incrementrally
-             * TODO Connection tracking will be used to track active TCP connections This code
-             * may be reused then.
-             */
-            /* if (portSecurityRule.getSecurityRuleEthertype().equalsIgnoreCase("IPv4") &&
-                portSecurityRule.getSecurityRuleDirection().equalsIgnoreCase("egress")) {
-                LOG.debug("Egress IPV4 ACL  Port Security Rule: {} ", portSecurityRule);
-                // ToDo: Implement Port Range
-
-             *//**
-             * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (True)
-             *//*
-                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
-                    !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                    !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
-                    (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
-                     !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
-                             .equalsIgnoreCase("0.0.0.0/0"))) {
-                    LOG.debug(
-                            "Rule #1 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
-                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRulePortMax(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
-                    egressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
-                                            Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
-                                            true);
-                    egressACLTcpPortWithPrefix(dpid, segmentationId,
-                                               attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
-                                               portSecurityRule.getSecurityRuleRemoteIpPrefix(),
-                                               Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                    continue;
-                }
-              *//**
-              * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (True)
-              *//*
-                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
-                    !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                    String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
-                    (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
-                     !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
-                             .equalsIgnoreCase("0.0.0.0/0"))) {
-                    LOG.debug(
-                            "Rule #2 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
-                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRulePortMax(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
-                    egressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
-                                            Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
-                                            true);
-                    egressACLTcpPortWithPrefix(dpid, segmentationId,
-                                               attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
-                                               portSecurityRule.getSecurityRuleRemoteIpPrefix(),
-                                               Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                    continue;
+                    programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
+                                            portSecurityRule, null, write);
                 }
-               *//**
-               * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
-               *//*
-                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
-                    String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                    String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
-                    !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
-                    LOG.debug(
-                            "Rule #3 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
-                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRulePortMax(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
-                    egressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PROTO_PREFIX_MATCH_PRIORITY_DROP,
-                                            true);
-                    egressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
-                                            portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PREFIX_MATCH_PRIORITY);
-                    continue;
-                }
-                *//**
-                * TCP Proto (False), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
-                *//*
-                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("null") &&
-                    String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                    String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                    (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
-                     !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
-                             .equalsIgnoreCase("0.0.0.0/0"))) {
-                    LOG.debug(
-                            "Rule #4 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
-                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRulePortMax(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
-                    egressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PREFIX_MATCH_PRIORITY_DROP, true);
-                    egressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
-                                            portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PREFIX_MATCH_PRIORITY);
-                    continue;
-                }
-                 *//**
-                 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (False)
-                 *//*
-                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
-                    !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                    !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
-                    String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
-                    LOG.debug(
-                            "Rule #5 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
-                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRulePortMax(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
-                    egressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PROTO_PORT_MATCH_PRIORITY_DROP,
-                                            true);
-                    egressACLTcpSyn(dpid, segmentationId,
-                                    attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
-                                    Constants.PROTO_PORT_MATCH_PRIORITY);
-                    continue;
-                }
-                  *//**
-                  * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (False)
-                  *//*
-                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
-                    !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                    String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
-                    String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
-                    LOG.debug(
-                            "Rule #6 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
-                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRulePortMax(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
-                    egressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
-                                            Constants.PROTO_PORT_MATCH_PRIORITY_DROP, true);
-                    egressACLTcpSyn(dpid, segmentationId, attachedMac, true,
-                                    portSecurityRule.getSecurityRulePortMin(), Constants.PROTO_PORT_MATCH_PRIORITY);
-                    continue;
-                }
-                   *//**
-                   * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (False or 0.0.0.0/0)
-                   *//*
-                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
-                    String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                    String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
-                    ((String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) ||
-                     String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
-                             .equalsIgnoreCase("0.0.0.0/0"))) {
-                    LOG.debug(
-                            "Rule #7 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
-                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRulePortMax(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
-                    // No need to drop until UDP/ICMP are implemented
-                    // egressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, PROTO_MATCH_PRIORITY_DROP, true);
-                    egressAllowProto(dpid, segmentationId, attachedMac, true,
-                                     portSecurityRule.getSecurityRuleProtocol(), Constants.PROTO_MATCH_PRIORITY);
-                    continue;
+                if (write) {
+                    securityGroupCacheManger.portAdded(securityGroup.getSecurityGroupUUID(), portUuid);
+                } else {
+                    securityGroupCacheManger.portRemoved(securityGroup.getSecurityGroupUUID(), portUuid);
                 }
-                LOG.debug("ACL Match combination not found for rule: {}", portSecurityRule);
-            }*/
+            }
         }
     }
 
     @Override
-    public void programFixedSecurityAcl(Long dpid, String segmentationId, String attachedMac,
+    public void programPortSecurityRule(Long dpid, String segmentationId, String attachedMac,
+                                        long localPort, NeutronSecurityRule portSecurityRule,
+                                        Neutron_IPs vmIp, boolean write) {
+        if (null == portSecurityRule.getSecurityRuleProtocol()) {
+            /* TODO Rework on the priority values */
+            egressAclIPv4(dpid, segmentationId, attachedMac,
+                          write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+        } else {
+            String ipaddress = null;
+            if (null != vmIp) {
+                ipaddress = vmIp.getIpAddress();
+            }
+            switch (portSecurityRule.getSecurityRuleProtocol()) {
+              case MatchUtils.TCP:
+                  LOG.debug("programPortSecurityRule: Rule matching TCP", portSecurityRule);
+                  egressAclTcp(dpid, segmentationId, attachedMac,
+                               portSecurityRule,ipaddress, write,
+                               Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                  break;
+              case MatchUtils.UDP:
+                  LOG.debug("programPortSecurityRule: Rule matching UDP", portSecurityRule);
+                  egressAclUdp(dpid, segmentationId, attachedMac,
+                               portSecurityRule, ipaddress, write,
+                               Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                  break;
+              case MatchUtils.ICMP:
+                  LOG.debug("programPortSecurityRule: Rule matching ICMP", portSecurityRule);
+                  egressAclIcmp(dpid, segmentationId, attachedMac,
+                                portSecurityRule, ipaddress,write,
+                                Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                  break;
+              default:
+                  LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other " +
+                          "protocol = ", portSecurityRule.getSecurityRuleProtocol());
+                  egressOtherProtocolAclHandler(dpid, segmentationId, attachedMac,
+                                      portSecurityRule, ipaddress, write,
+                                      Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                  break;
+            }
+        }
+
+    }
+
+    private void egressOtherProtocolAclHandler(Long dpidLong, String segmentationId, String srcMac,
+         NeutronSecurityRule portSecurityRule, String dstAddress,
+         boolean write, Integer protoPortMatchPriority) {
+
+         MatchBuilder matchBuilder = new MatchBuilder();
+         String flowId = "Egress_Other_" + segmentationId + "_" + srcMac + "_";
+         matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,srcMac,null);
+
+         short proto = 0;
+         try {
+             Integer protocol = new Integer(portSecurityRule.getSecurityRuleProtocol());
+             proto = protocol.shortValue();
+             flowId = flowId + proto;
+         } catch (NumberFormatException e) {
+             LOG.error("Protocol vlaue conversion failure", e);
+         }
+         matchBuilder = MatchUtils.createIpProtocolMatch(matchBuilder, proto);
+
+         if (null != dstAddress) {
+             flowId = flowId + dstAddress;
+             matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
+                                                         MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
+
+         } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+             flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+             matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder, null,new Ipv4Prefix(portSecurityRule
+                                                                        .getSecurityRuleRemoteIpPrefix()));
+         }
+         flowId = flowId + "_Permit";
+         String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+         syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+ }
+
+    @Override
+    public void programFixedSecurityGroup(Long dpid, String segmentationId, String attachedMac,
                                         long localPort, List<Neutron_IPs> srcAddressList,
                                         boolean isLastPortinBridge, boolean isComputePort ,boolean write) {
         // If it is the only port in the bridge add the rule to allow any DHCP client traffic
@@ -357,10 +266,10 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                                      portSecurityRule.getSecurityRulePortMin());
         } else {
             /* All TCP Match */
-            if(portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
+            if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
                     && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
-                flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_" +
-                    portSecurityRule.getSecurityRulePortMax()+ "_";
+                flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
+                            + portSecurityRule.getSecurityRulePortMax() + "_";
                 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
             }
             /*TODO TCP PortRange Match*/
@@ -370,13 +279,12 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         if (null != dstAddress) {
             flowId = flowId + dstAddress;
             matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
-                                                        MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
+                                      MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
 
         } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
             flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
             matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
-                                                        new Ipv4Prefix(portSecurityRule
-                                                                       .getSecurityRuleRemoteIpPrefix()));
+                                      new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
         }
         flowId = flowId + "_Permit";
         String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
@@ -400,14 +308,23 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
     private void egressAclIcmp(Long dpidLong, String segmentationId, String srcMac,
                                NeutronSecurityRule portSecurityRule, String dstAddress,
                                boolean write, Integer protoPortMatchPriority) {
+
         MatchBuilder matchBuilder = new MatchBuilder();
-        String flowId = "Egress_ICMP_" + segmentationId + "_" + srcMac + "_"
-                    + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
-                    + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
+        String flowId = "Egress_ICMP_" + segmentationId + "_" + srcMac + "_";
         matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,srcMac,null);
-        matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
-                                                    portSecurityRule.getSecurityRulePortMin().shortValue(),
-                                                    portSecurityRule.getSecurityRulePortMax().shortValue());
+        /*Custom ICMP Match */
+        if (portSecurityRule.getSecurityRulePortMin() != null &&
+                             portSecurityRule.getSecurityRulePortMax() != null) {
+            flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
+                    + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
+            matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
+                    portSecurityRule.getSecurityRulePortMin().shortValue(),
+                    portSecurityRule.getSecurityRulePortMax().shortValue());
+        } else {
+            /* All ICMP Match */ // We are getting from neutron NULL for both min and max
+            flowId = flowId + "all" + "_" ;
+            matchBuilder = MatchUtils.createICMPv4Match(matchBuilder, MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
+        }
         if (null != dstAddress) {
             flowId = flowId + dstAddress;
             matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
@@ -451,10 +368,10 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                                      portSecurityRule.getSecurityRulePortMin());
         } else {
             /* All UDP Match */
-            if(portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
+            if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
                     && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
-                flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_" +
-                    portSecurityRule.getSecurityRulePortMax()+ "_";
+                flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
+                    + portSecurityRule.getSecurityRulePortMax() + "_";
                 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0, 0);
             }
             /*TODO UDP PortRange Match*/
@@ -846,6 +763,8 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         super.setDependencies(bundleContext.getServiceReference(EgressAclProvider.class.getName()), this);
         securityServicesManager =
                 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
+        securityGroupCacheManger =
+                (SecurityGroupCacheManger) ServiceHelper.getGlobalInstance(SecurityGroupCacheManger.class, this);
     }
 
     @Override
index e8fa6b14c65f7496463e1b5ba4a29f874fd1f10d..d100f4e6daf96205aeae722195e0f07623a382e6 100644 (file)
@@ -8,18 +8,19 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
 
-import java.math.BigInteger;
-import java.util.List;
 
-import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
-import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
-import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
+import com.google.common.collect.Lists;
+
 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityGroupCacheManger;
 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
@@ -40,12 +41,16 @@ import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Lists;
+import java.math.BigInteger;
+import java.util.List;
+
+
 
 public class IngressAclService extends AbstractServiceInstance implements IngressAclProvider, ConfigInterface {
 
     private static final Logger LOG = LoggerFactory.getLogger(IngressAclService.class);
     private volatile SecurityServicesManager securityServicesManager;
+    private volatile SecurityGroupCacheManger securityGroupCacheManger;
     private static final int PORT_RANGE_MIN = 1;
     private static final int PORT_RANGE_MAX = 65535;
 
@@ -58,11 +63,11 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
     }
 
     @Override
-    public void programPortSecurityAcl(Long dpid, String segmentationId, String attachedMac,
+    public void programPortSecurityGroup(Long dpid, String segmentationId, String attachedMac,
                                        long localPort, NeutronSecurityGroup securityGroup,
-                                       List<Neutron_IPs> srcAddressList, boolean write) {
+                                       String portUuid, boolean write) {
 
-        LOG.trace("programLocalBridgeRulesWithSec neutronSecurityGroup: {} ", securityGroup);
+        LOG.trace("programPortSecurityGroup neutronSecurityGroup: {} ", securityGroup);
         if (securityGroup == null || securityGroup.getSecurityRules() == null) {
             return;
         }
@@ -70,6 +75,7 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         List<NeutronSecurityRule> portSecurityList = securityGroup.getSecurityRules();
         /* Iterate over the Port Security Rules in the Port Security Group bound to the port*/
         for (NeutronSecurityRule portSecurityRule : portSecurityList) {
+
             /**
              * Neutron Port Security Acl "ingress" and "IPv4"
              * Check that the base conditions for flow based Port Security are true:
@@ -79,196 +85,115 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
              *
              */
 
+            if (portSecurityRule == null ||
+                    portSecurityRule.getSecurityRuleEthertype() == null ||
+                    portSecurityRule.getSecurityRuleDirection() == null) {
+                continue;
+            }
+
             if ("IPv4".equals(portSecurityRule.getSecurityRuleEthertype())
                     && "ingress".equals(portSecurityRule.getSecurityRuleDirection())) {
-                LOG.debug("Acl Rule matching IPv4 and ingress is: {} ", portSecurityRule);
-                if (null == portSecurityRule.getSecurityRuleProtocol()) {
-                    ingressAclIPv4(dpid, segmentationId, attachedMac,
-                                   write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                } else if (null != portSecurityRule.getSecurityRemoteGroupID()) {
+                LOG.debug("programPortSecurityGroup: Rule matching IPv4 and ingress is: {} ", portSecurityRule);
+                if (null != portSecurityRule.getSecurityRemoteGroupID()) {
                     //Remote Security group is selected
                     List<Neutron_IPs> remoteSrcAddressList = securityServicesManager
-                            .getVmListForSecurityGroup(srcAddressList,portSecurityRule.getSecurityRemoteGroupID());
+                            .getVmListForSecurityGroup(portUuid,portSecurityRule.getSecurityRemoteGroupID());
                     if (null != remoteSrcAddressList) {
                         for (Neutron_IPs vmIp :remoteSrcAddressList ) {
-                            switch (portSecurityRule.getSecurityRuleProtocol()) {
-                                case MatchUtils.TCP:
-                                    ingressAclTcp(dpid, segmentationId, attachedMac, portSecurityRule,
-                                                vmIp.getIpAddress(),write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                                    break;
-                                case MatchUtils.UDP:
-                                    ingressAclUdp(dpid, segmentationId, attachedMac, portSecurityRule,
-                                                vmIp.getIpAddress(), write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                                    break;
-                                case MatchUtils.ICMP:
-                                    ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule,
-                                                vmIp.getIpAddress(), write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                                    break;
-                                default:
-                                    LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
-                                    break;
-                            }
+                            programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
+                                                    portSecurityRule, vmIp, write);
+                        }
+                        if (write) {
+                            securityGroupCacheManger.addToCache(portSecurityRule.getSecurityRemoteGroupID(), portUuid);
+                        } else {
+                            securityGroupCacheManger.removeFromCache(portSecurityRule.getSecurityRemoteGroupID(),
+                                                                     portUuid);
                         }
                     }
                 } else {
-                    //CIDR is selected
-                    switch (portSecurityRule.getSecurityRuleProtocol()) {
-                        case MatchUtils.TCP:
-                            ingressAclTcp(dpid, segmentationId, attachedMac,
-                                          portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                            break;
-                        case MatchUtils.UDP:
-                            ingressAclUdp(dpid, segmentationId, attachedMac,
-                                          portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                            break;
-                        case MatchUtils.ICMP:
-                            ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, null,
-                                           write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                            break;
-                        default:
-                            LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
-                    }
-                }
-
-                /**
-                 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (True)
-                 * TODO Some part of the code will be  used when conntrack is supported
-
-                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
-                        !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                        !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
-                        (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
-                                !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
-                                        .equalsIgnoreCase("0.0.0.0/0"))) {
-                    LOG.debug("Rule #1 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
-                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRulePortMax(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
-                    ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
-                            Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
-                            true);
-                    ingressACLTcpPortWithPrefix(dpid, segmentationId,
-                            attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                    continue;
-                }
-                /**
-                 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (True)
-                 */
-                /*if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
-                        !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                        String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
-                        (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
-                                !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
-                                        .equalsIgnoreCase("0.0.0.0/0"))) {
-                    LOG.debug("Rule #2 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
-                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRulePortMax(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
-                    ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
-                                             Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
-                            true);
-                    ingressACLTcpPortWithPrefix(dpid, segmentationId,
-                            attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                    continue;
-                }
-                 *//**
-                 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
-                 *//*
-                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
-                        String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                        String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
-                        !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
-                    LOG.debug("Rule #3 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
-                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRulePortMax(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
-                    ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PROTO_PREFIX_MATCH_PRIORITY_DROP,
-                            true);
-                    ingressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PREFIX_MATCH_PRIORITY);
-                    continue;
-                }
-                  *//**
-                  * TCP Proto (False), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
-                  *//*
-                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("null") &&
-                        String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                        String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                        (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
-                                !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
-                                        .equalsIgnoreCase("0.0.0.0/0"))) {
-                    LOG.debug("Rule #4 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
-                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRulePortMax(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
-                    ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PREFIX_MATCH_PRIORITY_DROP, true);
-                    ingressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PREFIX_MATCH_PRIORITY);
-                    continue;
+                    programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
+                                            portSecurityRule, null, write);
                 }
-                   *//**
-                   * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (False)
-                   *//*
-                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
-                        !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                        !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
-                        String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
-                    LOG.debug("Rule #5 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
-                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRulePortMax(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
-                    ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, Constants.PROTO_PORT_MATCH_PRIORITY_DROP,
-                            true);
-                    ingressACLTcpSyn(dpid, segmentationId,
-                            attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
-                            Constants.PREFIX_PORT_MATCH_PRIORITY_DROP);
-                    continue;
-                }
-                    *//**
-                    * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (False)
-                    *//*
-                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
-                        !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                        String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
-                        String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
-                    LOG.debug("Rule #6 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
-                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRulePortMax(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
-                    ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
-                                             Constants.PROTO_PORT_MATCH_PRIORITY_DROP, true);
-                    ingressACLTcpSyn(dpid, segmentationId, attachedMac, true,
-                            portSecurityRule.getSecurityRulePortMin(), Constants.PROTO_PORT_MATCH_PRIORITY);
-                    continue;
+                if (write) {
+                    securityGroupCacheManger.portAdded(securityGroup.getSecurityGroupUUID(), portUuid);
+                } else {
+                    securityGroupCacheManger.portRemoved(securityGroup.getSecurityGroupUUID(), portUuid);
                 }
-                     *//**
-                     * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (False or 0.0.0.0/0)
-                     *//*
-                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
-                        String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
-                        String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
-                        ((String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) ||
-                                String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
-                                        .equalsIgnoreCase("0.0.0.0/0"))) {
-                    LOG.debug("Rule #7 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
-                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
-                            portSecurityRule.getSecurityRulePortMax(),
-                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
-                    // No need to drop until UDP/ICMP are implemented
-                    // ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, PROTO_MATCH_PRIORITY_DROP, true);
-                    handleIngressAllowProto(dpid, segmentationId, attachedMac, true,
-                            portSecurityRule.getSecurityRuleProtocol(), Constants.PROTO_MATCH_PRIORITY);
-                    continue;
-                }*/
-                LOG.debug("Ingress Acl Match combination not found for rule: {}", portSecurityRule);
             }
         }
     }
 
     @Override
-    public void programFixedSecurityAcl(Long dpid, String segmentationId, String dhcpMacAddress,
+    public void programPortSecurityRule(Long dpid, String segmentationId, String attachedMac,
+                                        long localPort, NeutronSecurityRule portSecurityRule,
+                                        Neutron_IPs vmIp, boolean write) {
+        if (null == portSecurityRule.getSecurityRuleProtocol()) {
+            ingressAclIPv4(dpid, segmentationId, attachedMac,
+                           write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+        } else {
+            String ipaddress = null;
+            if (null != vmIp) {
+                ipaddress = vmIp.getIpAddress();
+            }
+            switch (portSecurityRule.getSecurityRuleProtocol()) {
+              case MatchUtils.TCP:
+                  LOG.debug("programPortSecurityRule: Rule matching TCP", portSecurityRule);
+                  ingressAclTcp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
+                              write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                  break;
+              case MatchUtils.UDP:
+                  LOG.debug("programPortSecurityRule: Rule matching UDP", portSecurityRule);
+                  ingressAclUdp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
+                                write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                  break;
+              case MatchUtils.ICMP:
+                  LOG.debug("programPortSecurityRule: Rule matching ICMP", portSecurityRule);
+                  ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
+                                 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                  break;
+              default:
+                  LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other " +
+                          "protocol = ", portSecurityRule.getSecurityRuleProtocol());
+                  ingressOtherProtocolAclHandler(dpid, segmentationId, attachedMac, portSecurityRule,
+                              null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                  break;
+            }
+        }
+    }
+
+    private void ingressOtherProtocolAclHandler(Long dpidLong, String segmentationId, String dstMac,
+          NeutronSecurityRule portSecurityRule, String srcAddress,
+          boolean write, Integer protoPortMatchPriority) {
+
+          MatchBuilder matchBuilder = new MatchBuilder();
+          String flowId = "Ingress_Other_" + segmentationId + "_" + dstMac + "_";
+          matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
+          short proto = 0;
+          try {
+              Integer protocol = new Integer(portSecurityRule.getSecurityRuleProtocol());
+              proto = protocol.shortValue();
+              flowId = flowId + proto;
+          } catch (NumberFormatException e) {
+              LOG.error("Protocol vlaue conversion failure", e);
+          }
+          matchBuilder = MatchUtils.createIpProtocolMatch(matchBuilder, proto);
+          if (null != srcAddress) {
+              flowId = flowId + srcAddress;
+              matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+                                        MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
+          } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+              flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+              matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+                                        new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
+          }
+          String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+          NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+          flowId = flowId + "_Permit";
+          syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+    }
+
+    @Override
+    public void programFixedSecurityGroup(Long dpid, String segmentationId, String dhcpMacAddress,
                                         long localPort, boolean isLastPortinSubnet,
                                         boolean isComputePort, boolean write) {
         //If this port is the only port in the compute node add the DHCP server rule.
@@ -287,7 +212,7 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
      * @param protoPortMatchPriority the protocol match priority.
      */
     private void ingressAclIPv4(Long dpidLong, String segmentationId, String dstMac,
-                               boolean write, Integer protoPortMatchPriority ) {
+                                boolean write, Integer protoPortMatchPriority ) {
         String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
         MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
@@ -309,8 +234,8 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
      * @param protoPortMatchPriority the protocol match priroty
      */
     private void ingressAclTcp(Long dpidLong, String segmentationId, String dstMac,
-                              NeutronSecurityRule portSecurityRule, String srcAddress, boolean write,
-                              Integer protoPortMatchPriority ) {
+                               NeutronSecurityRule portSecurityRule, String srcAddress, boolean write,
+                               Integer protoPortMatchPriority ) {
 
         MatchBuilder matchBuilder = new MatchBuilder();
         FlowBuilder flowBuilder = new FlowBuilder();
@@ -321,13 +246,13 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
             flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
             matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
-                                                    portSecurityRule.getSecurityRulePortMin());
+                                                     portSecurityRule.getSecurityRulePortMin());
         } else {
             /* All TCP Match */
-            if(portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
+            if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
                     && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
-                flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_" +
-                    portSecurityRule.getSecurityRulePortMax()+ "_";
+                flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
+                    + portSecurityRule.getSecurityRulePortMax() + "_";
                 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
             }
             /*TODO TCP PortRange Match*/
@@ -365,8 +290,8 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
      * @param protoPortMatchPriority the protocol match priroty
      */
     private void ingressAclUdp(Long dpidLong, String segmentationId, String dstMac,
-                              NeutronSecurityRule portSecurityRule, String srcAddress,
-                              boolean write, Integer protoPortMatchPriority ) {
+                               NeutronSecurityRule portSecurityRule, String srcAddress,
+                               boolean write, Integer protoPortMatchPriority ) {
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Ingress_UDP_" + segmentationId + "_" + dstMac + "_";
         matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
@@ -375,13 +300,13 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
             flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
             matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
-                                                    portSecurityRule.getSecurityRulePortMin());
+                                                     portSecurityRule.getSecurityRulePortMin());
         } else {
             /* All UDP Match */
-            if(portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
+            if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
                     && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
-                flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_" +
-                    portSecurityRule.getSecurityRulePortMax()+ "_";
+                flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
+                    + portSecurityRule.getSecurityRulePortMax() + "_";
                 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0, 0);
             }
             /*TODO TCP PortRange Match*/
@@ -396,7 +321,8 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
             flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
             matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
-                                      new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
+                                                        new Ipv4Prefix(portSecurityRule
+                                                                       .getSecurityRuleRemoteIpPrefix()),null);
         }
         String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
@@ -422,23 +348,31 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
                                 boolean write, Integer protoPortMatchPriority) {
 
         MatchBuilder matchBuilder = new MatchBuilder();
-        FlowBuilder flowBuilder = new FlowBuilder();
-        String flowId = "Ingress_ICMP_" + segmentationId + "_" + dstMac + "_"
-                    + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
-                    + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";;
+        String flowId = "Ingress_ICMP_" + segmentationId + "_" + dstMac + "_";
         matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
-        matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
-                        portSecurityRule.getSecurityRulePortMin().shortValue(),
-                        portSecurityRule.getSecurityRulePortMax().shortValue());
+
+        /* Custom ICMP Match */
+        if (portSecurityRule.getSecurityRulePortMin() != null &&
+                portSecurityRule.getSecurityRulePortMax() != null) {
+            flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
+                    + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
+            matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
+                    portSecurityRule.getSecurityRulePortMin().shortValue(),
+                    portSecurityRule.getSecurityRulePortMax().shortValue());
+        } else {
+            /* All ICMP Match */
+            flowId = flowId + "all" + "_";
+            matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
+        }
         if (null != srcAddress) {
             flowId = flowId + srcAddress;
             matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
-                    MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
-
+                                                        MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
         } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
             flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
             matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
-                    new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
+                                                        new Ipv4Prefix(portSecurityRule
+                                                                       .getSecurityRuleRemoteIpPrefix()),null);
         }
         String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
@@ -446,6 +380,7 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
     }
 
+
     public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
                                  Integer securityRulePortMin, Integer protoPortMatchPriority) {
 
@@ -770,6 +705,8 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         super.setDependencies(bundleContext.getServiceReference(IngressAclProvider.class.getName()), this);
         securityServicesManager =
                 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
+        securityGroupCacheManger =
+                (SecurityGroupCacheManger) ServiceHelper.getGlobalInstance(SecurityGroupCacheManger.class, this);
     }
 
     @Override
index 717473e83abd486739319eac804ac7c8cebc5f55..dbe50a862b8cf0baff1e0598c073705f1d633e66 100644 (file)
@@ -61,7 +61,7 @@ public class Arp extends Packet {
 
     public Arp() {
         payload = null;
-        hdrFieldsMap = new HashMap<String, byte[]>(ARP_FIELDS_COUNT);
+        hdrFieldsMap = new HashMap<>(ARP_FIELDS_COUNT);
         setHardwareLength((short) 6); // MAC address length
         setProtocolLength((short) 4); // IPv4 address length
         setHardwareType(ETHERNET_HW_TYPE);
index 9699a518efc2600e59d6f9a8803a6dbca843c8f7..991095b555fcf2e23a60dba28f98846f0f3b09c2 100644 (file)
@@ -40,7 +40,7 @@ public class ArpFlowFactory {
      */
     public static EthernetMatch createEthernetMatch(MacAddress destinationMacAddress) {
         return new EthernetMatchBuilder().setEthernetType(
-                new EthernetTypeBuilder().setType(new EtherType(Long.valueOf(EtherTypes.ARP.intValue()))).build())
+                new EthernetTypeBuilder().setType(new EtherType((long) EtherTypes.ARP.intValue())).build())
             .setEthernetDestination(new EthernetDestinationBuilder().setAddress(destinationMacAddress).build())
             .build();
     }
index b65e5a26946421c577b53c99c1a745d10c48ce8f..5eb5bff6622029555378a192b76713894b23cdd5 100644 (file)
@@ -16,7 +16,7 @@ public enum ArpOperation {
 
     private final int intOperation;
 
-    private ArpOperation(int operationNumber) {
+    ArpOperation(int operationNumber) {
         this.intOperation = operationNumber;
     }
 
index d6990521c53a6678a005be8deca41e9f996df4f2..d196fcaed8f1c6ebc563cd9a7b5affc9c5af3578 100644 (file)
@@ -197,7 +197,7 @@ public class AbstractServiceInstanceTest {
     @Test
     public void testProgramDefaultPipelineRule() {
         when(southbound.getBridgeName(any(Node.class))).thenReturn(Constants.INTEGRATION_BRIDGE);
-        when(southbound.getDataPathId(any(Node.class))).thenReturn(Long.valueOf(261));
+        when(southbound.getDataPathId(any(Node.class))).thenReturn(261L);
 
         when(orchestrator.getNextServiceInPipeline(any(Service.class))).thenReturn(Service.ARP_RESPONDER);
 
index e72b4ce687635d3b1d01dc68f69f4da3b512a8b0..c21b60fa0bbde363e34bdfde92fe71e68db7dfed 100644 (file)
@@ -34,7 +34,7 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFaile
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
-import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityGroupCacheManger;
 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.PipelineOrchestrator;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
@@ -71,12 +71,13 @@ public class EgressAclServiceTest {
     @Mock private NeutronSecurityRule portSecurityRule;
 
     @Mock private SecurityServicesManager securityServices;
+    @Mock private SecurityGroupCacheManger securityGroupCacheManger;
 
     private Neutron_IPs neutron_ip_src;
     private Neutron_IPs neutron_ip_dest_1;
     private Neutron_IPs neutron_ip_dest_2;
-    private List<Neutron_IPs> neutronSrcIpList = new ArrayList<Neutron_IPs>();
-    private List<Neutron_IPs> neutronDestIpList = new ArrayList<Neutron_IPs>();
+    private List<Neutron_IPs> neutronSrcIpList = new ArrayList<>();
+    private List<Neutron_IPs> neutronDestIpList = new ArrayList<>();
     private static final String HOST_ADDRESS = "127.0.0.1/32";
     private static final String MAC_ADDRESS = "87:1D:5E:02:40:B7";
     private static final String SRC_IP = "192.168.0.1";
@@ -85,6 +86,7 @@ public class EgressAclServiceTest {
     private static final String DEST_IP_1_WITH_MASK = "192.169.0.1/32";
     private static final String DEST_IP_2_WITH_MASK = "192.169.0.2/32";
     private static final String SECURITY_GROUP_UUID = "85cc3048-abc3-43cc-89b3-377341426ac5";
+    private static final String PORT_UUID = "95cc3048-abc3-43cc-89b3-377341426ac5";
     private static final String SEGMENT_ID = "2";
     private static final Long DP_ID_LONG = (long) 1554;
     private static final Long LOCAL_PORT = (long) 124;
@@ -120,7 +122,7 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRuleEthertype()).thenReturn("IPv4");
         when(portSecurityRule.getSecurityRuleDirection()).thenReturn("egress");
 
-        List<NeutronSecurityRule> portSecurityList = new ArrayList<NeutronSecurityRule>();
+        List<NeutronSecurityRule> portSecurityList = new ArrayList<>();
         portSecurityList.add(portSecurityRule);
 
         neutron_ip_src = new Neutron_IPs();
@@ -136,7 +138,7 @@ public class EgressAclServiceTest {
         neutronDestIpList.add(neutron_ip_dest_2);
 
         when(securityGroup.getSecurityRules()).thenReturn(portSecurityList);
-        when(securityServices.getVmListForSecurityGroup(neutronSrcIpList, SECURITY_GROUP_UUID)).thenReturn(neutronDestIpList);
+        when(securityServices.getVmListForSecurityGroup(PORT_UUID, SECURITY_GROUP_UUID)).thenReturn(neutronDestIpList);
     }
 
     /**
@@ -264,17 +266,54 @@ public class EgressAclServiceTest {
         verify(commitFuture, times(1)).get();
     }
 */
+    /**
+     * Test method {@link EgressAclService#programPortSecurityGroup(java.lang.Long, java.lang.String,
+     * java.lang.String, long, org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup,
+     * java.lang.String, boolean)} when portSecurityRule is incomplete
+     */
+    @Test
+    public void testProgramPortSecurityGroupWithIncompleteRule() throws Exception {
+        NeutronSecurityRule portSecurityRule1 = mock(NeutronSecurityRule.class);
+        when(portSecurityRule1.getSecurityRuleEthertype()).thenReturn("IPv4");
+        when(portSecurityRule1.getSecurityRuleDirection()).thenReturn("not_egress");  // other direction
+
+        NeutronSecurityRule portSecurityRule2 = mock(NeutronSecurityRule.class);
+        when(portSecurityRule2.getSecurityRuleEthertype()).thenReturn(null);
+        when(portSecurityRule2.getSecurityRuleDirection()).thenReturn("egress");
+
+        NeutronSecurityRule portSecurityRule3 = mock(NeutronSecurityRule.class);
+        when(portSecurityRule3.getSecurityRuleEthertype()).thenReturn("IPv4");
+        when(portSecurityRule3.getSecurityRuleDirection()).thenReturn(null);
+
+        NeutronSecurityRule portSecurityRule4 = mock(NeutronSecurityRule.class);
+        when(portSecurityRule4.getSecurityRuleEthertype()).thenReturn(null);
+        when(portSecurityRule4.getSecurityRuleDirection()).thenReturn(null);
+
+        List<NeutronSecurityRule> portSecurityList = new ArrayList<>();
+        portSecurityList.add(null);
+        portSecurityList.add(portSecurityRule1);
+        portSecurityList.add(portSecurityRule2);
+        portSecurityList.add(portSecurityRule3);
+        portSecurityList.add(portSecurityRule4);
+
+        NeutronSecurityGroup localSecurityGroup = mock(NeutronSecurityGroup.class);
+        when(localSecurityGroup.getSecurityRules()).thenReturn(portSecurityList);
+
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT,
+                localSecurityGroup, PORT_UUID, true);
+    }
+
     /**
      * Test method {@link EgressAclService#egressACLDefaultTcpDrop(Long, String, String, int, boolean)}
      */
     @Test
     public void testEgressACLDefaultTcpDrop() throws Exception {
-        egressAclService.egressACLDefaultTcpDrop(Long.valueOf(123), "2", MAC_ADDRESS, 1, true);
+        egressAclService.egressACLDefaultTcpDrop(123L, "2", MAC_ADDRESS, 1, true);
         verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), anyBoolean());
         verify(writeTransaction, times(1)).submit();
         verify(commitFuture, times(1)).get();
 
-        egressAclService.egressACLDefaultTcpDrop(Long.valueOf(123), "2", MAC_ADDRESS, 1, false);
+        egressAclService.egressACLDefaultTcpDrop(123L, "2", MAC_ADDRESS, 1, false);
         verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(2)).submit();
         verify(commitFuture, times(2)).get(); // 1 + 1 above
@@ -290,7 +329,7 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(null);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn(null);
 
-        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,true);
+        egressAclServiceSpy.programPortSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,PORT_UUID,true);
 
         verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
         verify(writeTransaction, times(1)).submit();
@@ -307,7 +346,7 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(null);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn(null);
 
-        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
+        egressAclServiceSpy.programPortSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,PORT_UUID,false);
         verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(1)).submit();
         verify(commitFuture, times(1)).get();
@@ -324,8 +363,8 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -351,8 +390,8 @@ public class EgressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -377,8 +416,8 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -411,8 +450,8 @@ public class EgressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -444,8 +483,8 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
@@ -466,8 +505,8 @@ public class EgressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -489,8 +528,8 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -521,8 +560,8 @@ public class EgressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -552,8 +591,8 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -578,8 +617,8 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -605,8 +644,8 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -640,8 +679,8 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -675,8 +714,8 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -698,8 +737,8 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -721,8 +760,8 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -752,8 +791,8 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -784,8 +823,8 @@ public class EgressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         Icmpv4Match icmpv4Match = match.getIcmpv4Match();
@@ -811,8 +850,8 @@ public class EgressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         Icmpv4Match icmpv4Match = match.getIcmpv4Match();
@@ -839,8 +878,8 @@ public class EgressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         Icmpv4Match icmpv4Match = match.getIcmpv4Match();
@@ -859,7 +898,7 @@ public class EgressAclServiceTest {
             Assert.assertTrue(true);
         } else {
             Assert.assertTrue(false);
-        };
+        }
     }
 
     /**
@@ -874,8 +913,8 @@ public class EgressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        egressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         Icmpv4Match icmpv4Match = match.getIcmpv4Match();
@@ -904,7 +943,7 @@ public class EgressAclServiceTest {
     public void testProgramPortSecurityACLRuleInvalidEther() throws Exception {
         when(portSecurityRule.getSecurityRuleEthertype()).thenReturn("IPV6");
 
-        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
+        egressAclServiceSpy.programPortSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,PORT_UUID,false);
 
         verify(writeTransaction, times(0)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(0)).submit();
@@ -918,7 +957,7 @@ public class EgressAclServiceTest {
     public void testProgramPortSecurityACLRuleInvalidDirection() throws Exception {
         when(portSecurityRule.getSecurityRuleDirection()).thenReturn("ingress");
 
-        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
+        egressAclServiceSpy.programPortSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,PORT_UUID,false);
 
         verify(writeTransaction, times(0)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(0)).submit();
@@ -930,7 +969,7 @@ public class EgressAclServiceTest {
      */
     @Test
     public void testProgramFixedSecurityACLAdd1() throws Exception {
-        egressAclServiceSpy.programFixedSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, false, false, true);
+        egressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, false, false, true);
 
         verify(writeTransaction, times(0)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
         verify(writeTransaction, times(0)).submit();
@@ -942,7 +981,7 @@ public class EgressAclServiceTest {
     @Test
     public void testProgramFixedSecurityACLRemove1() throws Exception {
 
-        egressAclServiceSpy.programFixedSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, false, false, false);
+        egressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, false, false, false);
 
         verify(writeTransaction, times(0)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(0)).submit();
@@ -955,7 +994,7 @@ public class EgressAclServiceTest {
     @Test
     public void testProgramFixedSecurityACLAdd2() throws Exception {
 
-        egressAclServiceSpy.programFixedSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, false, true, true);
+        egressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, false, true, true);
 
         verify(writeTransaction, times(6)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
         verify(writeTransaction, times(3)).submit();
@@ -968,7 +1007,7 @@ public class EgressAclServiceTest {
     @Test
     public void testProgramFixedSecurityACLRemove2() throws Exception {
 
-        egressAclServiceSpy.programFixedSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, false, true, false);
+        egressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, false, true, false);
 
         verify(writeTransaction, times(3)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(3)).submit();
@@ -981,7 +1020,7 @@ public class EgressAclServiceTest {
     @Test
     public void testProgramFixedSecurityACLAdd3() throws Exception {
 
-        egressAclServiceSpy.programFixedSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, true, false, true);
+        egressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, true, false, true);
 
         verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
         verify(writeTransaction, times(1)).submit();
@@ -994,7 +1033,7 @@ public class EgressAclServiceTest {
     @Test
     public void testProgramFixedSecurityACLRemove3() throws Exception {
 
-        egressAclServiceSpy.programFixedSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, true, false, false);
+        egressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, true, false, false);
 
         verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(1)).submit();
@@ -1007,7 +1046,7 @@ public class EgressAclServiceTest {
     @Test
     public void testProgramFixedSecurityACLAdd4() throws Exception {
 
-        egressAclServiceSpy.programFixedSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, true, true, true);
+        egressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, true, true, true);
 
         verify(writeTransaction, times(8)).put(any(LogicalDatastoreType.class),
                                                any(InstanceIdentifier.class), any(Node.class), eq(true));
@@ -1021,7 +1060,7 @@ public class EgressAclServiceTest {
     @Test
     public void testProgramFixedSecurityACLRemove4() throws Exception {
 
-        egressAclServiceSpy.programFixedSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, true, true, false);
+        egressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, true, true, false);
 
         verify(writeTransaction, times(4)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(4)).submit();
@@ -1033,12 +1072,12 @@ public class EgressAclServiceTest {
      */
     @Test
     public void testEgressACLTcpPortWithPrefix() throws Exception {
-        egressAclService.egressACLTcpPortWithPrefix(Long.valueOf(123), "2", MAC_ADDRESS, true, 1, HOST_ADDRESS, 1);
+        egressAclService.egressACLTcpPortWithPrefix(123L, "2", MAC_ADDRESS, true, 1, HOST_ADDRESS, 1);
         verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), anyBoolean());
         verify(writeTransaction, times(1)).submit();
         verify(commitFuture, times(1)).get();
 
-        egressAclService.egressACLTcpPortWithPrefix(Long.valueOf(123), "2", MAC_ADDRESS, false, 1, HOST_ADDRESS, 1);
+        egressAclService.egressACLTcpPortWithPrefix(123L, "2", MAC_ADDRESS, false, 1, HOST_ADDRESS, 1);
         verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(2)).submit();
         verify(commitFuture, times(2)).get(); // 1 + 1 above
@@ -1049,12 +1088,12 @@ public class EgressAclServiceTest {
      */
     @Test
     public void testEgressAllowProto() throws Exception {
-        egressAclService.egressAllowProto(Long.valueOf(123), "2", MAC_ADDRESS, true, HOST_ADDRESS, 1);
+        egressAclService.egressAllowProto(123L, "2", MAC_ADDRESS, true, HOST_ADDRESS, 1);
         verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), anyBoolean());
         verify(writeTransaction, times(1)).submit();
         verify(commitFuture, times(1)).get();
 
-        egressAclService.egressAllowProto(Long.valueOf(123), "2", MAC_ADDRESS, false, HOST_ADDRESS, 1);
+        egressAclService.egressAllowProto(123L, "2", MAC_ADDRESS, false, HOST_ADDRESS, 1);
         verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(2)).submit();
         verify(commitFuture, times(2)).get(); // 1 + 1 above
@@ -1065,12 +1104,12 @@ public class EgressAclServiceTest {
      */
     @Test
     public void testEgressACLPermitAllProto() throws Exception {
-        egressAclService.egressACLPermitAllProto(Long.valueOf(123), "2", MAC_ADDRESS, true, HOST_ADDRESS, 1);
+        egressAclService.egressACLPermitAllProto(123L, "2", MAC_ADDRESS, true, HOST_ADDRESS, 1);
         verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), anyBoolean());
         verify(writeTransaction, times(1)).submit();
         verify(commitFuture, times(1)).get();
 
-        egressAclService.egressACLPermitAllProto(Long.valueOf(123), "2", MAC_ADDRESS, false, HOST_ADDRESS, 1);
+        egressAclService.egressACLPermitAllProto(123L, "2", MAC_ADDRESS, false, HOST_ADDRESS, 1);
         verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(2)).submit();
         verify(commitFuture, times(2)).get(); // 1 + 1 above
@@ -1081,12 +1120,12 @@ public class EgressAclServiceTest {
      */
     @Test
     public void testEgressACLTcpSyn() throws Exception {
-        egressAclService.egressACLTcpSyn(Long.valueOf(123), "2", MAC_ADDRESS, true, 1, 1);
+        egressAclService.egressACLTcpSyn(123L, "2", MAC_ADDRESS, true, 1, 1);
         verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), anyBoolean());
         verify(writeTransaction, times(1)).submit();
         verify(commitFuture, times(1)).get();
 
-        egressAclService.egressACLTcpSyn(Long.valueOf(123), "2", MAC_ADDRESS, false, 1, 1);
+        egressAclService.egressACLTcpSyn(123L, "2", MAC_ADDRESS, false, 1, 1);
         verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(2)).submit();
         verify(commitFuture, times(2)).get(); // 1 + 1 above
index 51734e827eafd4939a295928bd381d400b1f7ccf..e2b41f68bcdb995d3d02cb121a023a36e94802af 100644 (file)
@@ -10,9 +10,6 @@ package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
@@ -28,10 +25,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.Spy;
 import org.mockito.invocation.InvocationOnMock;
-import org.mockito.runners.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
@@ -40,7 +34,7 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFaile
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
-import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityGroupCacheManger;
 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.PipelineOrchestrator;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
@@ -77,9 +71,10 @@ public class IngressAclServiceTest {
     @Mock private NeutronSecurityGroup securityGroup;
     @Mock private NeutronSecurityRule portSecurityRule;
     @Mock private SecurityServicesManager securityServices;
+    @Mock private SecurityGroupCacheManger securityGroupCacheManger;
 
-    private List<Neutron_IPs> neutronSrcIpList = new ArrayList<Neutron_IPs>();
-    private List<Neutron_IPs> neutronDestIpList = new ArrayList<Neutron_IPs>();
+    private List<Neutron_IPs> neutronSrcIpList = new ArrayList<>();
+    private List<Neutron_IPs> neutronDestIpList = new ArrayList<>();
     private Neutron_IPs neutron_ip_src;
     private Neutron_IPs neutron_ip_dest_1;
     private Neutron_IPs neutron_ip_dest_2;
@@ -92,6 +87,7 @@ public class IngressAclServiceTest {
     private static final String DEST_IP_1 = "192.169.0.1";
     private static final String DEST_IP_2 = "192.169.0.2";
     private static final String SECURITY_GROUP_UUID = "85cc3048-abc3-43cc-89b3-377341426ac5";
+    private static final String PORT_UUID = "95cc3048-abc3-43cc-89b3-377341426ac5";
     private static final String SEGMENT_ID = "2";
     private static final Long DP_ID_LONG = (long) 1554;
     private static final Long LOCAL_PORT = (long) 124;
@@ -126,7 +122,7 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRuleEthertype()).thenReturn("IPv4");
         when(portSecurityRule.getSecurityRuleDirection()).thenReturn("ingress");
 
-        List<NeutronSecurityRule> portSecurityList = new ArrayList<NeutronSecurityRule>();
+        List<NeutronSecurityRule> portSecurityList = new ArrayList<>();
         portSecurityList.add(portSecurityRule);
 
         neutron_ip_src = new Neutron_IPs();
@@ -144,7 +140,7 @@ public class IngressAclServiceTest {
 
         when(securityGroup.getSecurityRules()).thenReturn(portSecurityList);
         when(securityServices.getVmListForSecurityGroup
-             (neutronSrcIpList, SECURITY_GROUP_UUID)).thenReturn(neutronDestIpList);
+             (PORT_UUID, SECURITY_GROUP_UUID)).thenReturn(neutronDestIpList);
     }
 
    /* *//**
@@ -273,6 +269,43 @@ public class IngressAclServiceTest {
         verify(commitFuture, times(1)).get();
     }
 */
+    /**
+     * Test method {@link EgressAclService#programPortSecurityGroup(java.lang.Long, java.lang.String,
+     * java.lang.String, long, org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup,
+     * java.lang.String, boolean)} when portSecurityRule is incomplete
+     */
+    @Test
+    public void testProgramPortSecurityGroupWithIncompleteRule() throws Exception {
+        NeutronSecurityRule portSecurityRule1 = mock(NeutronSecurityRule.class);
+        when(portSecurityRule1.getSecurityRuleEthertype()).thenReturn("IPv4");
+        when(portSecurityRule1.getSecurityRuleDirection()).thenReturn("not_ingress");  // other direction
+
+        NeutronSecurityRule portSecurityRule2 = mock(NeutronSecurityRule.class);
+        when(portSecurityRule2.getSecurityRuleEthertype()).thenReturn(null);
+        when(portSecurityRule2.getSecurityRuleDirection()).thenReturn("ingress");
+
+        NeutronSecurityRule portSecurityRule3 = mock(NeutronSecurityRule.class);
+        when(portSecurityRule3.getSecurityRuleEthertype()).thenReturn("IPv4");
+        when(portSecurityRule3.getSecurityRuleDirection()).thenReturn(null);
+
+        NeutronSecurityRule portSecurityRule4 = mock(NeutronSecurityRule.class);
+        when(portSecurityRule4.getSecurityRuleEthertype()).thenReturn(null);
+        when(portSecurityRule4.getSecurityRuleDirection()).thenReturn(null);
+
+        List<NeutronSecurityRule> portSecurityList = new ArrayList<>();
+        portSecurityList.add(null);
+        portSecurityList.add(portSecurityRule1);
+        portSecurityList.add(portSecurityRule2);
+        portSecurityList.add(portSecurityRule3);
+        portSecurityList.add(portSecurityRule4);
+
+        NeutronSecurityGroup localSecurityGroup = mock(NeutronSecurityGroup.class);
+        when(localSecurityGroup.getSecurityRules()).thenReturn(portSecurityList);
+
+        ingressAclServiceSpy.programPortSecurityGroup(
+                Long.valueOf(1554), "2", MAC_ADDRESS, 124, localSecurityGroup, PORT_UUID, false);
+    }
+
     /**
      *  Test IPv4 add test case.
      */
@@ -283,7 +316,7 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(null);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn(null);
 
-        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,true);
+        ingressAclServiceSpy.programPortSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,PORT_UUID,true);
 
         verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
         verify(writeTransaction, times(1)).submit();
@@ -300,7 +333,7 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(null);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn(null);
 
-        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
+        ingressAclServiceSpy.programPortSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,PORT_UUID,false);
 
         verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(1)).submit();
@@ -319,8 +352,8 @@ public class IngressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -346,8 +379,8 @@ public class IngressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -373,8 +406,8 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -409,8 +442,8 @@ public class IngressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -445,8 +478,8 @@ public class IngressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -469,8 +502,8 @@ public class IngressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -492,8 +525,8 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -524,8 +557,8 @@ public class IngressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -557,8 +590,8 @@ public class IngressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -584,8 +617,8 @@ public class IngressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -611,8 +644,8 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -646,8 +679,8 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -681,8 +714,8 @@ public class IngressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -705,8 +738,8 @@ public class IngressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -729,8 +762,8 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, true);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -761,8 +794,8 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
-                                                   neutronSrcIpList, false);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
 
         Match match = flowBuilder.getMatch();
         EthernetMatch ethMatch = match.getEthernetMatch();
@@ -793,8 +826,8 @@ public class IngressAclServiceTest {
 
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID,
-                                                    MAC_ADDRESS, LOCAL_PORT, securityGroup, neutronSrcIpList, true);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID,
+                                                    MAC_ADDRESS, LOCAL_PORT, securityGroup, PORT_UUID, true);
         Match match = flowBuilder.getMatch();
         Icmpv4Match icmpv4Match = match.getIcmpv4Match();
         Assert.assertEquals(10, icmpv4Match.getIcmpv4Type().shortValue());
@@ -820,8 +853,8 @@ public class IngressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID,
-                                                    MAC_ADDRESS, LOCAL_PORT, securityGroup, neutronSrcIpList, false);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID,
+                                                    MAC_ADDRESS, LOCAL_PORT, securityGroup, PORT_UUID, false);
         Match match = flowBuilder.getMatch();
         Icmpv4Match icmpv4Match = match.getIcmpv4Match();
         Assert.assertEquals(20, icmpv4Match.getIcmpv4Type().shortValue());
@@ -847,8 +880,8 @@ public class IngressAclServiceTest {
         PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
                                              any(NodeBuilder.class));
 
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID,
-                                                    MAC_ADDRESS, LOCAL_PORT, securityGroup, neutronSrcIpList, true);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID,
+                                                    MAC_ADDRESS, LOCAL_PORT, securityGroup, PORT_UUID, true);
         Match match = flowBuilder.getMatch();
         Icmpv4Match icmpv4Match =match.getIcmpv4Match();
         Assert.assertEquals(30, icmpv4Match.getIcmpv4Type().shortValue());
@@ -881,8 +914,8 @@ public class IngressAclServiceTest {
         PowerMockito.doAnswer(answer())
         .when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class), any(NodeBuilder.class));
 
-        ingressAclServiceSpy.programPortSecurityAcl(DP_ID_LONG, SEGMENT_ID,
-                                                    MAC_ADDRESS, LOCAL_PORT, securityGroup, neutronSrcIpList, false);
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID,
+                                                    MAC_ADDRESS, LOCAL_PORT, securityGroup, PORT_UUID, false);
         Match match = flowBuilder.getMatch();
         Icmpv4Match icmpv4Match = match.getIcmpv4Match();
         Assert.assertEquals(40, icmpv4Match.getIcmpv4Type().shortValue());
@@ -910,7 +943,7 @@ public class IngressAclServiceTest {
     public void testProgramPortSecurityACLRuleInvalidEther() throws Exception {
         when(portSecurityRule.getSecurityRuleEthertype()).thenReturn("IPV6");
 
-        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
+        ingressAclServiceSpy.programPortSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,PORT_UUID,false);
 
         verify(writeTransaction, times(0)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(0)).submit();
@@ -924,7 +957,7 @@ public class IngressAclServiceTest {
     public void testProgramPortSecurityACLRuleInvalidDirection() throws Exception {
         when(portSecurityRule.getSecurityRuleDirection()).thenReturn("edgress");
 
-        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
+        ingressAclServiceSpy.programPortSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,PORT_UUID,false);
 
         verify(writeTransaction, times(0)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(0)).submit();
@@ -936,7 +969,7 @@ public class IngressAclServiceTest {
      */
     @Test
     public void testProgramFixedSecurityACLAdd1() throws Exception {
-        ingressAclServiceSpy.programFixedSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 1, false, false, true);
+        ingressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, false, false, true);
 
         verify(writeTransaction, times(0)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
         verify(writeTransaction, times(0)).submit();
@@ -948,7 +981,7 @@ public class IngressAclServiceTest {
     @Test
     public void testProgramFixedSecurityACLRemove1() throws Exception {
 
-        ingressAclServiceSpy.programFixedSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 1, false, false, false);
+        ingressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, false, false, false);
 
         verify(writeTransaction, times(0)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(0)).submit();
@@ -960,12 +993,12 @@ public class IngressAclServiceTest {
      */
     @Test
     public void testIgressACLDefaultTcpDrop() throws Exception {
-        ingressAclService.ingressACLDefaultTcpDrop(Long.valueOf(123), SEGMENTATION_ID, MAC_ADDRESS, PRIORITY, true);
+        ingressAclService.ingressACLDefaultTcpDrop(123L, SEGMENTATION_ID, MAC_ADDRESS, PRIORITY, true);
         verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), anyBoolean());
         verify(writeTransaction, times(1)).submit();
         verify(commitFuture, times(1)).get();
 
-        ingressAclService.ingressACLDefaultTcpDrop(Long.valueOf(123), SEGMENTATION_ID, MAC_ADDRESS, PRIORITY, false);
+        ingressAclService.ingressACLDefaultTcpDrop(123L, SEGMENTATION_ID, MAC_ADDRESS, PRIORITY, false);
         verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(2)).submit();
         verify(commitFuture, times(2)).get(); // 1 + 1 above
@@ -976,12 +1009,12 @@ public class IngressAclServiceTest {
      */
     @Test
     public void testIngressACLTcpPortWithPrefix() throws Exception {
-        ingressAclService.ingressACLTcpPortWithPrefix(Long.valueOf(123), SEGMENTATION_ID, MAC_ADDRESS, true, 1, HOST_ADDRESS, PRIORITY);
+        ingressAclService.ingressACLTcpPortWithPrefix(123L, SEGMENTATION_ID, MAC_ADDRESS, true, 1, HOST_ADDRESS, PRIORITY);
         verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), anyBoolean());
         verify(writeTransaction, times(1)).submit();
         verify(commitFuture, times(1)).get();
 
-        ingressAclService.ingressACLTcpPortWithPrefix(Long.valueOf(123), SEGMENTATION_ID, MAC_ADDRESS, false, 1, HOST_ADDRESS, PRIORITY);
+        ingressAclService.ingressACLTcpPortWithPrefix(123L, SEGMENTATION_ID, MAC_ADDRESS, false, 1, HOST_ADDRESS, PRIORITY);
         verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(2)).submit();
         verify(commitFuture, times(2)).get(); // 1 + 1 above
@@ -992,12 +1025,12 @@ public class IngressAclServiceTest {
      */
     @Test
     public void testIngressAllowProto() throws Exception {
-        ingressAclService.handleIngressAllowProto(Long.valueOf(123), SEGMENTATION_ID, MAC_ADDRESS, true, HOST_ADDRESS, PRIORITY);
+        ingressAclService.handleIngressAllowProto(123L, SEGMENTATION_ID, MAC_ADDRESS, true, HOST_ADDRESS, PRIORITY);
         verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), anyBoolean());
         verify(writeTransaction, times(1)).submit();
         verify(commitFuture, times(1)).get();
 
-        ingressAclService.handleIngressAllowProto(Long.valueOf(123), SEGMENTATION_ID, MAC_ADDRESS, false, HOST_ADDRESS, PRIORITY);
+        ingressAclService.handleIngressAllowProto(123L, SEGMENTATION_ID, MAC_ADDRESS, false, HOST_ADDRESS, PRIORITY);
         verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(2)).submit();
         verify(commitFuture, times(2)).get(); // 1 + 1 above
@@ -1008,12 +1041,12 @@ public class IngressAclServiceTest {
      */
     @Test
     public void testIngressACLPermitAllProto() throws Exception {
-        ingressAclService.ingressACLPermitAllProto(Long.valueOf(123), SEGMENTATION_ID, MAC_ADDRESS, true, HOST_ADDRESS, PRIORITY);
+        ingressAclService.ingressACLPermitAllProto(123L, SEGMENTATION_ID, MAC_ADDRESS, true, HOST_ADDRESS, PRIORITY);
         verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), anyBoolean());
         verify(writeTransaction, times(1)).submit();
         verify(commitFuture, times(1)).get();
 
-        ingressAclService.ingressACLPermitAllProto(Long.valueOf(123), SEGMENTATION_ID, MAC_ADDRESS, false, HOST_ADDRESS, PRIORITY);
+        ingressAclService.ingressACLPermitAllProto(123L, SEGMENTATION_ID, MAC_ADDRESS, false, HOST_ADDRESS, PRIORITY);
         verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(2)).submit();
         verify(commitFuture, times(2)).get(); // 1 + 1 above
@@ -1024,12 +1057,12 @@ public class IngressAclServiceTest {
      */
     @Test
     public void testIngressACLTcpSyn() throws Exception {
-        ingressAclService.ingressACLTcpSyn(Long.valueOf(123), SEGMENTATION_ID, MAC_ADDRESS, true, 1, PRIORITY);
+        ingressAclService.ingressACLTcpSyn(123L, SEGMENTATION_ID, MAC_ADDRESS, true, 1, PRIORITY);
         verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), anyBoolean());
         verify(writeTransaction, times(1)).submit();
         verify(commitFuture, times(1)).get();
 
-        ingressAclService.ingressACLTcpSyn(Long.valueOf(123), SEGMENTATION_ID, MAC_ADDRESS, false, 1, PRIORITY);
+        ingressAclService.ingressACLTcpSyn(123L, SEGMENTATION_ID, MAC_ADDRESS, false, 1, PRIORITY);
         verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(2)).submit();
         verify(commitFuture, times(2)).get(); // 1 + 1 above
index 214e9d5aca3bdebaf0c3eb52c610ca00987297db..34e5658eaef399d46ebc47aded2f660eb6b36eaf 100644 (file)
@@ -53,10 +53,10 @@ public class L2FowardingServiceTest {
 
     private static final String SEGMENTATION_ID = "2";
     private static final String MAC_ADDRESS = "87:1D:5E:02:40:B8";
-    private static final Long DPID = Long.valueOf(122);
-    private static final Long LOCAL_PORT = Long.valueOf(451);
-    private static final Long ETH_PORT = Long.valueOf(564);
-    private static final Long OF_PORT_OUT = Long.valueOf(5698);
+    private static final Long DPID = 122L;
+    private static final Long LOCAL_PORT = 451L;
+    private static final Long ETH_PORT = 564L;
+    private static final Long OF_PORT_OUT = 5698L;
 
     @Before
     public void setUp() throws Exception {
index 95ed7d7f561888143570483c2055025d43821703..d5d92d75acbd190115211f63fff3f0d337ee3b76 100644 (file)
@@ -89,7 +89,7 @@ public class LoadBalancerServiceTest {
         when(member.getMAC()).thenReturn(MAC_ADDRESS);
 
         Southbound southbound = mock(Southbound.class);
-        when(southbound.getDataPathId(any(Node.class))).thenReturn(Long.valueOf(123));
+        when(southbound.getDataPathId(any(Node.class))).thenReturn(123L);
         MemberModifier.field(LoadBalancerService.class, "southbound").set(loadBalancerService, southbound);
     }
     /**
index 8b4e1874ad956373aa21efa1338cab398d51685b..75049d0d0e309d3f466bae15a6b5206749848ece 100644 (file)
@@ -22,6 +22,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <version>1.2.1-SNAPSHOT</version>
   <packaging>bundle</packaging>
 
+  <properties>
+    <sfc.project.version>0.2.0-SNAPSHOT</sfc.project.version>
+  </properties>
+
   <dependencies>
     <dependency>
       <groupId>org.opendaylight.mdsal.model</groupId>
@@ -35,6 +39,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <groupId>org.opendaylight.mdsal.model</groupId>
       <artifactId>yang-ext</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.sfc</groupId>
+      <artifactId>sfc-model</artifactId>
+      <version>${sfc.project.version}</version>
+    </dependency>
   </dependencies>
 
   <build>
@@ -46,9 +55,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
         <configuration>
           <instructions>
             <Export-Package>
-              org.opendaylight.yang.gen.v1.*;
+              org.opendaylight.yang.gen.v1.*,
+              org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105,
+              org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105,
+              org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105,
             </Export-Package>
-            <!--<Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>-->
           </instructions>
         </configuration>
       </plugin>
diff --git a/openstack/net-virt-sfc/api/src/main/yang/ietf-acl.yang b/openstack/net-virt-sfc/api/src/main/yang/ietf-acl.yang
deleted file mode 100644 (file)
index 3549cb4..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-module ietf-acl {
-  yang-version 1;
-
-  namespace "urn:ietf:params:xml:ns:yang:ietf-acl";
-
-  prefix acl;
-
-  import ietf-yang-types {
-      prefix "ietf";
-  }
-
-  import packet-fields {
-      prefix "packet-fields";
-  }
-
-  organization
-    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
-
-  contact
-    "WG Web: http://tools.ietf.org/wg/netmod/
-    WG List: netmod@ietf.org
-
-    WG Chair: Juergen Schoenwaelder
-    j.schoenwaelder@jacobs-university.de
-
-    WG Chair: Tom Nadeau
-    tnadeau@lucidvision.com
-
-    Editor: Dean Bogdanovic
-    deanb@juniper.net
-
-    Editor: Kiran Agrahara Sreenivasa
-    kkoushik@brocade.com
-
-    Editor: Lisa Huang
-    yihuan@cisco.com
-
-    Editor: Dana Blair
-    dblair@cisco.com";
-
-  description
-    "This YANG module defines a component that describing the
-    configuration of Access Control Lists (ACLs).";
-
-  revision 2014-10-10 {
-    description "Creating base model for netmod.";
-    reference
-      "RFC 6020: YANG - A Data Modeling Language for the
-      Network Configuration Protocol (NETCONF)";
-  }
-
-  identity acl-base {
-    description "Base acl type for all ACL type identifiers.";
-  }
-
-  identity ip-acl {
-    base "acl:acl-base";
-    description "layer 3 ACL type";
-  }
- identity eth-acl {
-    base "acl:acl-base";
-    description "layer 2 ACL type";
-  }
-
-  typedef acl-type {
-    type identityref {
-      base "acl-base";
-    }
-    description
-      "This type is used to refer to an Access Control List
-      (ACL) type";
-  }
-
-  typedef acl-ref {
-    type leafref {
-      path "/acl:access-lists/acl:access-list/acl:acl-name";
-    }
-    description "This type is used by data models that
-    need to referenced an acl";
-  }
-
-  container access-lists {
-    description
-      "Access control lists.";
-
-    list access-list {
-      key acl-name;
-      description "
-        An access list (acl) is an ordered list of
-        access list entries (ace). Each ace has a
-        sequence number to define the order, list
-        of match criteria, and a list of actions.
-        Since there are several kinds of acls
-        implementeded with different attributes for
-        each and different for each vendor, this
-        model accomodates customizing acls for
-        each kind and for each vendor.
-        ";
-
-      leaf acl-name {
-        type string;
-        description "The name of access-list.
-        A device MAY restrict the length and value of
-        this name, possibly space and special
-        characters are not allowed.";
-      }
-
-      leaf acl-type {
-        type acl-type;
-        description "Type of ACL";
-      }
-
-      container acl-oper-data {
-        config false;
-
-        description "Overall ACL operational data";
-        leaf match-counter {
-          type ietf:counter64;
-          description "Total match count for ACL";
-        }
-
-        leaf-list targets {
-          type string;
-          description "List of targets where ACL is applied";
-        }
-      }
-
-      container access-list-entries {
-        description "The access-list-entries container contains
-          a list of access-list-entry(ACE).";
-
-          list access-list-entry {
-            key rule-name;
-            ordered-by user;
-
-            description "List of access list entries(ACE)";
-            leaf rule-name {
-              type string;
-              description "Entry name.";
-            }
-
-            container matches {
-              description "Define match criteria";
-              choice ace-type {
-                description "Type of ace.";
-                case ace-ip {
-                  uses packet-fields:acl-ip-header-fields;
-                  choice ace-ip-version {
-                    description "Choice of IP version.";
-                    case ace-ipv4 {
-                      uses packet-fields:acl-ipv4-header-fields;
-                    }
-                    case ace-ipv6 {
-                      uses packet-fields:acl-ipv6-header-fields;
-                    }
-                  }
-                }
-                case ace-eth {
-                  uses packet-fields:acl-eth-header-fields;
-                }
-              }
-              uses packet-fields:metadata;
-          }
-
-          container actions {
-            description "Define action criteria";
-            choice packet-handling {
-              default deny;
-
-              description "Packet handling action.";
-              case deny {
-                leaf deny {
-                  type empty;
-                  description "Deny action.";
-                }
-              }
-              case permit {
-                leaf permit {
-                  type empty;
-                  description "Permit action.";
-                }
-              }
-            }
-          }
-
-          container ace-oper-data {
-            config false;
-
-            description "Per ace operational data";
-            leaf match-counter {
-              type ietf:counter64;
-              description "Number of matches for an ace";
-            }
-          }
-        }
-      }
-    }
-  }
-}
index 50b90bdb449e44c35f276a8804b491ed3069f3d9..44fa5a1847ce303d084f01e108f6af4c3ee190fb 100644 (file)
@@ -3,27 +3,32 @@ module netvirt-sfc-acl {
     namespace "urn:opendaylight:params:xml:ns:yang:netvirt:sfc:acl";
     prefix "acl";
 
-    import ietf-acl { prefix ietf-acl;}
+    import ietf-access-control-list { prefix ietf-acl;}
     import yang-ext { prefix ext; }
 
     revision "2015-01-05" {
         description "Initial revision of netvirt extensions to ietf-acl model";
     }
 
-    // TODO: Add choice for Neutron and add fields there instead of at the root of matches
-    augment "/ietf-acl:access-lists/ietf-acl:access-list/ietf-acl:access-list-entries" +
-            "/ietf-acl:access-list-entry/ietf-acl:matches" {
+  //augment "/ietf-acl:access-lists/ietf-acl:access-list/ietf-acl:access-list-entries/ietf-acl:access-list-entry/ietf-acl:matches" {
+    augment "/ietf-acl:access-lists/ietf-acl:acl/ietf-acl:access-list-entries/ietf-acl:ace/ietf-acl:matches" {
         description "Neutron network uuid";
+        ext:augment-identifier "neutron-network";
         leaf network-uuid {
             type string;
         }
     }
 
-    // TODO: Add choice for Neutron and add fields there instead of at the root of matches
-    augment "/ietf-acl:access-lists/ietf-acl:access-list/ietf-acl:access-list-entries" +
-            "/ietf-acl:access-list-entry/ietf-acl:actions" {
-        description "Redirect traffic to SFC identified by SFC Path ID";
-        leaf redirect-sfc {
+    augment "/ietf-acl:access-lists/ietf-acl:acl/ietf-acl:access-list-entries/ietf-acl:ace/ietf-acl:actions" {
+        description "Redirect traffic to SFC identified by either SFC, SFP or RSP";
+        ext:augment-identifier "redirect-to-sfc";
+        leaf sfc-name {
+            type string;
+        }
+        leaf sfp-name {
+            type string;
+        }
+        leaf rsp-name {
             type string;
         }
     }
index c0aec3a3698c1e7c8b6d242b21ac235c47f18ac5..5e01309128afde1990aa54d2e891ba0da8875c7a 100644 (file)
@@ -32,6 +32,20 @@ module netvirt-sfc-classifier {
                     }
                 }
             }
+            container bridges {
+                list bridge {
+                    key "name";
+                    leaf name {
+                        type string;
+                    }
+                    leaf direction {
+                        type enumeration {
+                            enum ingress;
+                            enum egress;
+                        }
+                    }
+                }
+            }
         }
     }
 }
diff --git a/openstack/net-virt-sfc/api/src/main/yang/packet-fields.yang b/openstack/net-virt-sfc/api/src/main/yang/packet-fields.yang
deleted file mode 100644 (file)
index bea6777..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-module packet-fields {
-    yang-version 1;
-
-    namespace "urn:ietf:params:xml:ns:yang:packet-fields";
-
-    prefix packet-fields;
-
-    import ietf-inet-types {
-        prefix "inet";
-    }
-
-    import ietf-yang-types {
-        prefix "yang";
-    }
-
-    revision 2014-06-25 {
-        description "Initial version of packet fields used by access-lists";
-    }
-
-    grouping acl-transport-header-fields {
-        description "Transport header fields";
-
-        container source-port-range {
-             description "inclusive range of source ports";
-             leaf lower-port {
-                 mandatory true;
-                 type inet:port-number;
-             }
-             leaf upper-port {
-                 type inet:port-number;
-             }
-        }
-
-        container destination-port-range {
-             description "inclusive range of destination ports";
-             leaf lower-port {
-                 mandatory true;
-                 type inet:port-number;
-             }
-             leaf upper-port {
-                 type inet:port-number;
-             }
-        }
-    }
-
-    grouping acl-ip-header-fields {
-        description "Header fields common to ipv4 and ipv6";
-
-        uses acl-transport-header-fields;
-
-        leaf dscp {
-            type inet:dscp;
-        }
-
-        leaf ip-protocol {
-            type uint8;
-        }
-
-    }
-
-    grouping acl-ipv4-header-fields {
-        description "fields in IPv4 header";
-
-        leaf destination-ipv4-address {
-            type inet:ipv4-prefix;
-        }
-
-        leaf source-ipv4-address {
-            type inet:ipv4-prefix;
-        }
-
-    }
-
-    grouping acl-ipv6-header-fields {
-        description "fields in IPv6 header";
-
-        leaf destination-ipv6-address {
-            type inet:ipv6-prefix;
-        }
-
-        leaf source-ipv6-address {
-            type inet:ipv6-prefix;
-        }
-
-        leaf flow-label {
-            type inet:ipv6-flow-label;
-        }
-
-    }
-
-    grouping acl-eth-header-fields {
-        description "fields in ethernet header";
-
-        leaf destination-mac-address {
-            type yang:mac-address;
-        }
-
-        leaf destination-mac-address-mask {
-            type yang:mac-address;
-        }
-
-        leaf source-mac-address {
-            type yang:mac-address;
-        }
-
-        leaf source-mac-address-mask {
-            type yang:mac-address;
-        }
-    }
-
-    grouping timerange {
-        description "Define time range entries to restrict
-            the access. The time range is identified by a name
-            and then referenced by a function, so that those
-            time restrictions are imposed on the function itself.";
-
-        container absolute {
-            description
-                "Absolute time and date that
-                the associated function starts
-                going into effect.";
-
-            leaf start {
-                type yang:date-and-time;
-                description
-                "Start time and date";
-            }
-            leaf end {
-                type yang:date-and-time;
-                description "Absolute end time and date";
-            }
-            leaf active {
-                type boolean;
-                default "true";
-                description
-                    "Specify the associated function
-                    active or inactive state when
-                    starts going into effect";
-            }
-        } // container absolute
-    } //grouping timerange
-
-    grouping metadata {
-        description "Fields associated with a packet but not in the header";
-
-        leaf input-interface {
-             description "Packet was received on this interface";
-             type string;
-        }
-        uses timerange;
-    }
-}
index 01fb239e0a0b09ca4db7f278c487135641b09322..684d59a55fb868a9aad0b34cb11d748f57a384a3 100644 (file)
@@ -116,16 +116,15 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <type>xml</type>
     </dependency>
     <dependency>
-      <groupId>org.opendaylight.sfc</groupId>
-      <artifactId>features-sfc</artifactId>
-      <version>${sfc.version}</version>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>features-openflowplugin-extension</artifactId>
+      <version>${openflowplugin.version}</version>
       <classifier>features</classifier>
       <type>xml</type>
-      <scope>runtime</scope>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.sfc</groupId>
-      <artifactId>features-sfc-ovs</artifactId>
+      <artifactId>features-sfc</artifactId>
       <version>${sfc.version}</version>
       <classifier>features</classifier>
       <type>xml</type>
index 1b4ca16239b492ef20782f1e8df8308edc3bf561..cce550aa05e70bcfb09a3bffd79598a66e19c802 100644 (file)
@@ -10,33 +10,34 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
 <features name="odl-ovsdb-sfc-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
-  <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.dlux/features-dlux/${dlux.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/${mdsal.model.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.netconf/features-restconf/${restconf.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/${openflowplugin.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.ovsdb/features-ovsdb/${project.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.ovsdb/southbound-features/${project.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.sfc/features-sfc/${sfc.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.sfc/features-sfc-ovs/${sfc.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.controller/features-mdsal/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.dlux/features-dlux/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.netconf/features-restconf/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin-extension/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.ovsdb/features-ovsdb/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.ovsdb/southbound-features/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.sfc/features-sfc/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.yangtools/features-yangtools/{{VERSION}}/xml/features</repository>
   <feature name='odl-ovsdb-sfc-api' version='${project.version}' description='OpenDaylight :: ovsdb-sfc :: api'>
     <feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
-    <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt-sfc-api/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt-sfc-api/{{VERSION}}</bundle>
   </feature>
   <feature name='odl-ovsdb-sfc' version='${project.version}' description='OpenDaylight :: ovsdb-sfc'>
     <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
     <feature version="${openflowplugin.version}">odl-openflowplugin-nsf-model</feature>
+    <feature version="${openflowplugin.version}">odl-openflowplugin-flow-services</feature>
+    <feature version='${openflowplugin.version}'>odl-openflowplugin-nxm-extensions</feature>
     <feature version='${project.version}'>odl-ovsdb-southbound-impl</feature>
     <feature version='${project.version}'>odl-ovsdb-openstack</feature>
-    <feature version='${sfc.version}'>odl-sfc-core</feature>
-    <feature version='${sfc.version}'>odl-sfc-ovs</feature>
-    <feature version="${openflowplugin.version}">odl-openflowplugin-flow-services</feature>
+    <feature version='${sfc.version}'>odl-sfc-provider</feature>
+    <feature version='${sfc.version}'>odl-sfcofl2</feature>
     <feature version='${project.version}'>odl-ovsdb-sfc-api</feature>
-    <bundle>mvn:org.opendaylight.ovsdb/utils.mdsal-utils/${project.version}</bundle>
-    <bundle>mvn:org.opendaylight.ovsdb/utils.servicehelper/${project.version}</bundle>
-    <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt-sfc-impl/${project.version}</bundle>
-    <configfile finalname="${configfile.directory}/openstack.net-virt-sfc.xml">mvn:org.opendaylight.ovsdb/openstack.net-virt-sfc-impl/${project.version}/xml/config</configfile>
+    <bundle>mvn:org.opendaylight.ovsdb/utils.mdsal-utils/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/utils.servicehelper/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/openstack.net-virt-sfc-impl/{{VERSION}}</bundle>
+    <configfile finalname="${configfile.directory}/openstack.net-virt-sfc.xml">mvn:org.opendaylight.ovsdb/openstack.net-virt-sfc-impl/{{VERSION}}/xml/config</configfile>
   </feature>
   <feature name='odl-ovsdb-sfc-rest' version='${project.version}' description='OpenDaylight :: ovsdb-sfc :: REST'>
     <feature version="${project.version}">odl-ovsdb-sfc</feature>
index 9dd3154362cc4931297cf5646899143e490bb89a..0f8b724bd82a9b68cf191587670c64fafdd27370 100644 (file)
@@ -12,8 +12,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
   <repository>mvn:org.opendaylight.ovsdb/openstack.net-virt-sfc-features/1.2.1-SNAPSHOT/xml/features</repository>
   <feature name='odl-ovsdb-sfc-test' version='${project.version}' description='OpenDaylight :: ovsdb-sfc-test'>
-    <bundle>mvn:org.opendaylight.ovsdb/utils.mdsal-utils/${project.version}</bundle>
-    <bundle>mvn:org.opendaylight.ovsdb/utils.southbound-utils/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/utils.mdsal-utils/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/utils.southbound-utils/{{VERSION}}</bundle>
     <feature version='${project.version}'>odl-ovsdb-sfc-ui</feature>
   </feature>
 </features>
index 7795793b612ea2b6079ced16c06f8581327b7683..27c3ab73097acb581025a68ff1aa9b0227f6262c 100644 (file)
@@ -27,6 +27,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <properties>
     <networkconfig.neutron.version>0.6.0-SNAPSHOT</networkconfig.neutron.version>
     <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
+    <powermock.version>1.5.2</powermock.version>
     <sonar.jacoco.itReportPath>../it/target/jacoco-it.exec</sonar.jacoco.itReportPath>
     <sfc.project.version>0.2.0-SNAPSHOT</sfc.project.version>
   </properties>
@@ -47,6 +48,16 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>openstack.net-virt-providers</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>southbound-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>southbound-impl</artifactId>
+      <version>${project.version}</version>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>utils.mdsal-utils</artifactId>
@@ -86,6 +97,20 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-common-api</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller.model</groupId>
+      <artifactId>model-inventory</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>openflowplugin-extension-nicira</artifactId>
+      <version>${openflowplugin.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>openflowjava-extension-nicira</artifactId>
+      <version>${openflowplugin.version}</version>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.openflowplugin.model</groupId>
       <artifactId>model-flow-base</artifactId>
@@ -105,11 +130,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>sfc-model</artifactId>
       <version>${sfc.project.version}</version>
     </dependency>
-    <dependency>
-      <groupId>org.opendaylight.sfc</groupId>
-      <artifactId>sfc-ovs</artifactId>
-      <version>${sfc.project.version}</version>
-    </dependency>
     <dependency>
       <groupId>org.opendaylight.sfc</groupId>
       <artifactId>sfc-provider</artifactId>
@@ -134,12 +154,35 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>mockito-all</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-core</artifactId>
+      <version>${powermock.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-module-junit4</artifactId>
+      <version>${powermock.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-api-mockito</artifactId>
+      <version>${powermock.version}</version>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>org.codehaus.sonar-plugins.java</groupId>
       <artifactId>sonar-jacoco-listeners</artifactId>
       <version>${sonar-jacoco-listeners.version}</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.mdsal.model</groupId>
+      <artifactId>iana-if-type-2014-05-08</artifactId>
+      <version>2014.05.08.8-SNAPSHOT</version>
+    </dependency>
   </dependencies>
 
   <build>
@@ -155,13 +198,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
           </instructions>
         </configuration>
       </plugin>
-      <plugin>
+      <!--<plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-checkstyle-plugin</artifactId>
         <configuration>
-          <propertyExpansion>checkstyle.checker.severity=error</propertyExpansion>
+          <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
         </configuration>
-      </plugin>
+      </plugin>-->
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
index 1aa106ae18a911d76b08b871f2e182aa6f9ba65a..a794e579218c8e05d2352cad7e5c369af812b445 100644 (file)
@@ -21,6 +21,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
         <module>
           <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:netvirt:sfc">prefix:netvirt-sfc</type>
           <name>netvirt-sfc-default</name>
+          <of13provider>workaround</of13provider>
           <broker>
             <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
             <name>binding-osgi-broker</name>
index dfbe6f0eb790506b9b3e487ca20dc4ae31dba555..87a9db615cdd7ffb3e9cd672e73ed574ce7f414d 100644 (file)
@@ -14,7 +14,6 @@ import com.google.common.base.Preconditions;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13.INetvirtSfcOF13Provider;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -6,10 +6,14 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13;
+package org.opendaylight.ovsdb.openstack.netvirt.sfc;
 
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.AccessList;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services.SfcClassifierService;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.Acl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.Bridges;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.bridges.Bridge;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
+import org.osgi.framework.ServiceReference;
 
 /**
  * Open vSwitch OpenFlow 1.3 Networking Provider for Netvirt SFC
@@ -21,10 +25,11 @@ public interface INetvirtSfcOF13Provider {
      * Method installs the OF rules corresponding to rules within ACL
      * on a given Service Function Forwarder. DataObject which is identified by InstanceIdentifier.
      *
-     * @param sff - Service Function Forwarder
+     * @param bridge - Service Function Forwarder
      * @param acl - Access list includes rules that need to be installed in a SFF.
      */
-    public void addClassifierRules(Sff sff, AccessList acl);
+    void addClassifierRules(Bridge bridge, Acl acl);
+    void addClassifierRules(Bridges bridges, Acl acl);
 
     /**
      * Method removes the OF rules corresponding to rules within ACL
@@ -33,5 +38,11 @@ public interface INetvirtSfcOF13Provider {
      * @param sff - Service Function Forwarder
      * @param acl - Access list includes rules that need to be installed in a SFF.
      */
-    public void removeClassifierRules(Sff sff, AccessList acl);
+    void removeClassifierRules(Sff sff, Acl acl);
+
+    void addClassifierRules(Acl acl);
+    void removeClassifierRules(Acl acl);
+
+    void setSfcClassifierService(ISfcClassifierService sfcClassifierService);
+    public void setDependencies(ServiceReference serviceReference);
 }
diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/ISfcClassifierService.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/ISfcClassifierService.java
new file mode 100644 (file)
index 0000000..008339e
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright Â© 2015 Red Hat, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc;
+
+import java.net.InetAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+
+public interface ISfcClassifierService {
+    void programIngressClassifier(long dataPathId, String ruleName, Matches matches,
+                                  NshUtils nshHeader, long vxGpeOfPort, boolean write);
+
+    void programSfcTable(long dataPathId, long vxGpeOfPort, short goToTableId, boolean write);
+
+    void programEgressClassifier1(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+                                  int tunnelOfPort, int tunnelId, short gotoTableId, boolean write);
+
+    void programEgressClassifier(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+                                 long sfOfPort, int tunnelId, boolean write);
+
+    void programEgressClassifierBypass(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+                                       long sfOfPort, int tunnelId, boolean write);
+
+    void program_sfEgress(long dataPathId, int dstPort, boolean write);
+
+    void program_sfIngress(long dataPathId, int dstPort, long sfOfPort,
+                           String ipAddress, String sfDplName, boolean write);
+
+    void programStaticArpEntry(long dataPathId, long ofPort, String macAddressStr,
+                               String ipAddress, boolean write);
+}
index 302be54ae402e7d8f80144f16436ee66d7cb0c55..74776698cb219d469a354acd76910172fd8556a4 100644 (file)
@@ -12,17 +12,9 @@ import com.google.common.base.Preconditions;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13.INetvirtSfcOF13Provider;
 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.AccessLists;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.AccessList;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.AccessListKey;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.AccessListEntries;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.AccessListEntry;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.AccessListEntryKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.Classifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.AccessLists;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.Acl;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -31,10 +23,9 @@ import org.slf4j.LoggerFactory;
 /**
  * Data tree listener for AccessList.
  */
-public class NetvirtSfcAclListener extends AbstractDataTreeListener<AccessList> {
+public class NetvirtSfcAclListener extends AbstractDataTreeListener<Acl> {
     private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcAclListener.class);
     private ListenerRegistration<NetvirtSfcAclListener> listenerRegistration;
-    private MdsalUtils dbutils;
 
     /**
      * {@link NetvirtSfcAclListener} constructor.
@@ -42,23 +33,21 @@ public class NetvirtSfcAclListener extends AbstractDataTreeListener<AccessList>
      * @param db MdSal {@link DataBroker}
      */
     public NetvirtSfcAclListener(final INetvirtSfcOF13Provider provider, final DataBroker db) {
-        super(provider, AccessList.class);
+        super(provider, Acl.class);
         Preconditions.checkNotNull(db, "DataBroker can not be null!");
 
-        dbutils = new MdsalUtils(db);
         registrationListener(db);
     }
 
     private void registrationListener(final DataBroker db) {
-        final DataTreeIdentifier<AccessList> treeId =
+        final DataTreeIdentifier<Acl> treeId =
                 new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, getIetfAclIid());
         try {
-            LOG.info("Registering Data Change Listener for Netvirt AccesList configuration.");
+            LOG.info("Registering Data Change Listener for NetvirtSfc AccessList configuration.");
             listenerRegistration = db.registerDataTreeChangeListener(treeId, this);
         } catch (final Exception e) {
             LOG.warn("Netvirt AccesList DataChange listener registration fail!");
-            LOG.debug("Netvirt AccesList DataChange listener registration fail!", e);
-            throw new IllegalStateException("NetvirtSfcAccesListListener startup fail! System needs restart.", e);
+            throw new IllegalStateException("NetvirtSfcAccessListListener startup fail! System needs restart.", e);
         }
     }
 
@@ -76,67 +65,26 @@ public class NetvirtSfcAclListener extends AbstractDataTreeListener<AccessList>
     }
 
     @Override
-    public void remove(final InstanceIdentifier<AccessList> identifier,
-                       final AccessList removeDataObj) {
+    public void remove(final InstanceIdentifier<Acl> identifier,
+                       final Acl removeDataObj) {
         Preconditions.checkNotNull(removeDataObj, "Removed object can not be null!");
-        String aclName = removeDataObj.getAclName();
-
-        Classifiers classifiers = dbutils.read(LogicalDatastoreType.CONFIGURATION, getClassifierIid());
-        if (classifiers != null) {
-            for (Classifier classifier : classifiers.getClassifier()) {
-                if (classifier.getAcl().equalsIgnoreCase(aclName)) {
-                    if (classifier.getSffs() != null) {
-                        for (Sff sff : classifier.getSffs().getSff()) {
-                            provider.removeClassifierRules(sff, removeDataObj);
-                        }
-                    }
-                }
-            }
-        }
+        provider.removeClassifierRules(removeDataObj);
     }
 
     @Override
-    public void update(final InstanceIdentifier<AccessList> identifier,
-                       final AccessList original, final AccessList update) {
+    public void update(final InstanceIdentifier<Acl> identifier,
+                       final Acl original, final Acl update) {
     }
 
     @Override
-    public void add(final InstanceIdentifier<AccessList> identifier,
-                    final AccessList addDataObj) {
+    public void add(final InstanceIdentifier<Acl> identifier,
+                    final Acl addDataObj) {
         Preconditions.checkNotNull(addDataObj, "Added object can not be null!");
-        String aclName = addDataObj.getAclName();
-        LOG.debug("Adding accesslist = {}", identifier);
-        Classifiers classifiers = dbutils.read(LogicalDatastoreType.CONFIGURATION, getClassifierIid());
-        if (classifiers != null) {
-            for (Classifier classifier : classifiers.getClassifier()) {
-                if (classifier.getAcl().equalsIgnoreCase(aclName)) {
-                    if (classifier.getSffs() != null) {
-                        for (Sff sff : classifier.getSffs().getSff()) {
-                            provider.addClassifierRules(sff, addDataObj);
-                        }
-                    }
-                }
-            }
-        }
+        LOG.debug("Adding accesslist iid = {}, dataObj = {}", identifier, addDataObj);
+        provider.addClassifierRules(addDataObj);
     }
 
-    private InstanceIdentifier<Classifiers> getClassifierIid() {
-        return InstanceIdentifier.create(Classifiers.class);
-    }
-
-    public InstanceIdentifier<AccessList> getIetfAclIid() {
-        return InstanceIdentifier.create(AccessLists.class).child(AccessList.class);
-    }
-
-    /**
-     * Create an {@link AccessListEntry} {@link InstanceIdentifier}.
-     * @param aclName is the name of the ACL
-     * @param ruleName is the name of the rule
-     * @return the {@link AccessListEntry} {@link InstanceIdentifier}
-     */
-    public InstanceIdentifier<AccessListEntry> getIetfAclEntryIid(String aclName, String ruleName) {
-        return InstanceIdentifier.create(AccessLists.class).child(AccessList.class,
-                new AccessListKey(aclName)).child(AccessListEntries.class).child(AccessListEntry.class,
-                new AccessListEntryKey(ruleName));
+    public InstanceIdentifier<Acl> getIetfAclIid() {
+        return InstanceIdentifier.create(AccessLists.class).child(Acl.class);
     }
 }
index df1102f83c5dfe2b371bcd58ccd1e56009295703..1562a41f0fd461505fc4366bd949982255c93c50 100644 (file)
@@ -12,11 +12,10 @@ import com.google.common.base.Preconditions;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13.INetvirtSfcOF13Provider;
 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.AccessLists;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.AccessList;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.AccessListKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.AccessLists;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.Acl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.AclKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.Classifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
@@ -32,7 +31,7 @@ import org.slf4j.LoggerFactory;
  */
 public class NetvirtSfcClassifierListener extends AbstractDataTreeListener<Classifier> {
     private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcClassifierListener.class);
-    private MdsalUtils dbutils;
+    private MdsalUtils mdsalUtils;
     private ListenerRegistration<NetvirtSfcClassifierListener> listenerRegistration;
 
     /**
@@ -43,7 +42,7 @@ public class NetvirtSfcClassifierListener extends AbstractDataTreeListener<Class
     public NetvirtSfcClassifierListener(final INetvirtSfcOF13Provider provider, final DataBroker db) {
         super(provider, Classifier.class);
         Preconditions.checkNotNull(db, "DataBroker can not be null!");
-        dbutils = new MdsalUtils(db);
+        mdsalUtils = new MdsalUtils(db);
         registrationListener(db);
     }
 
@@ -51,11 +50,10 @@ public class NetvirtSfcClassifierListener extends AbstractDataTreeListener<Class
         final DataTreeIdentifier<Classifier> treeId =
                 new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, getClassifierIid());
         try {
-            LOG.info("Registering Data Change Listener for Netvirt Classifier configuration.");
+            LOG.info("Registering Data Change Listener for NetvirtSfc Classifier configuration.");
             listenerRegistration = db.registerDataTreeChangeListener(treeId, this);
         } catch (final Exception e) {
             LOG.warn("Netvirt Classifier DataChange listener registration fail!");
-            LOG.debug("Netvirt Classifier DataChange listener registration fail!", e);
             throw new IllegalStateException("NetvirtSfcClassifierListener startup fail! System needs restart.", e);
         }
     }
@@ -67,7 +65,6 @@ public class NetvirtSfcClassifierListener extends AbstractDataTreeListener<Class
                 listenerRegistration.close();
             } catch (final Exception e) {
                 LOG.warn("Error to stop Netvirt Classifier DataChange listener: {}", e.getMessage());
-                LOG.debug("Error to stop Netvirt Classifier DataChange listener..", e);
             }
             listenerRegistration = null;
         }
@@ -79,20 +76,13 @@ public class NetvirtSfcClassifierListener extends AbstractDataTreeListener<Class
         Preconditions.checkNotNull(removeDataObj, "Added object can not be null!");
         String aclName = removeDataObj.getAcl();
         // Read the ACL information from data store and make sure it exists.
-        AccessList acl = dbutils.read(LogicalDatastoreType.CONFIGURATION,getIetfAclIid(aclName));
+        Acl acl = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, getIetfAclIid(aclName));
         if (acl == null) {
             LOG.debug("IETF ACL with name ={} is not yet configured. skip this operation", aclName);
             return;
         }
 
-        if (removeDataObj.getSffs() != null) {
-            for (Sff sff : removeDataObj.getSffs().getSff()) {
-                // Netvirt classifier binds an ACL with service function forwarder that is identified by SFF name.
-                // SFF validation can be done with SFC Provider APIs, as SFF is configured within SFC project.  
-                // Netvirt SFC provider will validate the SFF using SFC provider APIs.
-                provider.removeClassifierRules(sff, acl);
-            }
-        }
+        provider.removeClassifierRules(acl);
     }
 
     @Override
@@ -107,28 +97,22 @@ public class NetvirtSfcClassifierListener extends AbstractDataTreeListener<Class
                     final Classifier addDataObj) {
         Preconditions.checkNotNull(addDataObj, "Added object can not be null!");
         String aclName = addDataObj.getAcl();
+        LOG.debug("Adding classifier iid = {}, dataObj = {}", identifier, addDataObj);
         // Read the ACL information from data store and make sure it exists.
-        AccessList acl = dbutils.read(LogicalDatastoreType.CONFIGURATION,getIetfAclIid(aclName));
+        Acl acl = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, getIetfAclIid(aclName));
         if (acl == null) {
             LOG.debug("IETF ACL with name ={} is not yet configured. skip this operation", aclName);
             return;
         }
 
-        if (addDataObj.getSffs() != null) {
-            for (Sff sff : addDataObj.getSffs().getSff()) {
-                // Netvirt classifier binds an ACL with service function forwarder that is identified by SFF name.
-                // SFF validation can be done with SFC Provider APIs, as SFF is configured within SFC project.  
-                // Netvirt SFC provider will validate the SFF using SFC provider APIs.
-                provider.addClassifierRules(sff, acl);
-            }
-        }
+        provider.addClassifierRules(acl);
     }
 
     public InstanceIdentifier<Classifier> getClassifierIid() {
         return InstanceIdentifier.create(Classifiers.class).child(Classifier.class);
     }
 
-    private InstanceIdentifier<AccessList> getIetfAclIid(String aclName) {
-        return InstanceIdentifier.create(AccessLists.class).child(AccessList.class, new AccessListKey(aclName));
+    private InstanceIdentifier<Acl> getIetfAclIid(String aclName) {
+        return InstanceIdentifier.create(AccessLists.class).child(Acl.class, new AclKey(aclName));
     }
 }
index 3dba7b4b57b779a62eaaf99b687ed665b8ea5ce9..a77b8cf560f795bb44a5567279ec320160569cee 100644 (file)
 
 package org.opendaylight.ovsdb.openstack.netvirt.sfc;
 
+import java.util.Dictionary;
+import java.util.Hashtable;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
-import org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13.INetvirtSfcOF13Provider;
-import org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13.NetvirtSfcOF13Provider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.OF13Provider;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13.NetvirtSfcStandaloneOF13Provider;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13.services.SfcClassifierService;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.NetvirtSfcWorkaroundOF13Provider;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class NetvirtSfcProvider implements BindingAwareProvider, AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcProvider.class);
     private NetvirtSfcAclListener aclListener;
-    private NetvirtSfcClassifierListener classfierListener;
+    private NetvirtSfcClassifierListener classifierListener;
+
+    public void setOf13Provider(String of13Provider) {
+        LOG.info("of13Provider is: {}", of13Provider);
+        this.of13Provider = of13Provider;
+    }
+
+    private String of13Provider;
+
+    public void setBundleContext(BundleContext bundleContext) {
+        LOG.info("bundleContext is: {}", bundleContext);
+        this.bundleContext = bundleContext;
+    }
+
+    private BundleContext bundleContext;
+
+    public NetvirtSfcProvider(BundleContext bundleContext) {
+        LOG.info("NetvirtSfcProvider: bundleContext: {}", bundleContext);
+        this.bundleContext = bundleContext;
+    }
 
     @Override
     public void onSessionInitiated(ProviderContext session) {
         LOG.info("NetvirtSfcProvider Session Initiated");
         DataBroker dataBroker = session.getSALService(DataBroker.class);
 
-        INetvirtSfcOF13Provider provider = new NetvirtSfcOF13Provider(dataBroker);
+        MdsalUtils mdsalUtils = new MdsalUtils(dataBroker);
+        SfcUtils sfcUtils = new SfcUtils(mdsalUtils);
+
+        // Allocate provider based on config
+        INetvirtSfcOF13Provider provider;
+        if (of13Provider.equals("standalone")) {
+            provider = new NetvirtSfcStandaloneOF13Provider(dataBroker);
+        } else {
+            provider = new NetvirtSfcWorkaroundOF13Provider(dataBroker, mdsalUtils, sfcUtils);
+        }
         aclListener = new NetvirtSfcAclListener(provider, dataBroker);
-        classfierListener = new NetvirtSfcClassifierListener(provider, dataBroker);
+        classifierListener = new NetvirtSfcClassifierListener(provider, dataBroker);
+
+        addToPipeline(provider);
+        provider.setDependencies(null);
     }
 
     @Override
     public void close() throws Exception {
         LOG.info("NetvirtSfcProvider Closed");
         aclListener.close();
-        classfierListener.close();
+        classifierListener.close();
+    }
+
+    private void addToPipeline(INetvirtSfcOF13Provider provider) {
+        if (provider instanceof NetvirtSfcStandaloneOF13Provider) {
+            SfcClassifierService sfcClassifierService =
+                    new org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13.services.SfcClassifierService();
+            registerService(bundleContext, ISfcClassifierService.class.getName(),
+                    sfcClassifierService, Service.SFC_CLASSIFIER);
+            sfcClassifierService.setDependencies(bundleContext, null);
+        } else {
+            org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services.SfcClassifierService sfcClassifierService =
+                    new org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services.SfcClassifierService();
+            registerService(bundleContext, ISfcClassifierService.class.getName(),
+                    sfcClassifierService, Service.SFC_CLASSIFIER);
+            sfcClassifierService.setDependencies(bundleContext, null);
+        }
+
+        //provider.setSfcClassifierService(sfcClassifierService);
+    }
+
+    private ServiceRegistration<?> registerService(BundleContext bundleContext, String[] interfaces,
+                                                   Dictionary<String, Object> properties, Object impl) {
+        ServiceRegistration<?> serviceRegistration = bundleContext.registerService(interfaces, impl, properties);
+        return serviceRegistration;
+    }
+
+    private ServiceRegistration<?> registerService(BundleContext bundleContext, String interfaceClassName,
+                                                       Object impl, Object serviceProperty) {
+        Dictionary<String, Object> properties = new Hashtable<>();
+        properties.put(AbstractServiceInstance.SERVICE_PROPERTY, serviceProperty);
+        properties.put(Constants.PROVIDER_NAME_PROPERTY, OF13Provider.NAME);
+        return registerService(bundleContext,
+                new String[] {AbstractServiceInstance.class.getName(),interfaceClassName},
+                properties, impl);
     }
 }
diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/NshUtils.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/NshUtils.java
new file mode 100644 (file)
index 0000000..f28f030
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2015 Dell, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc;
+
+import com.google.common.net.InetAddresses;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+
+/**
+ * Open Vswitch DB OpenFlow 1.3 Networking Provider for Netvirt SFC Utilities.
+ * @author Arun Yerra
+ */
+public class NshUtils {
+    private Ipv4Address nshTunIpDst;
+    private PortNumber nshTunUdpPort;
+    private long nshNsp;
+    private short nshNsi;
+    private long nshMetaC1;
+    private long nshMetaC2;
+
+    public NshUtils() {
+        super();
+    }
+
+    /**
+     * {@link NshUtils} constructor.
+     * @param nshTunIpDst Tunnel Destination IP
+     * @param nshTunUdpPort Tunnel Transport Port
+     * @param nshNsp Service Path Id
+     * @param nshNsi Service Path Index
+     * @param nshMetaC1 End point ID
+     * @param nshMetaC2 Tunnel Id.
+     */
+    public NshUtils(Ipv4Address nshTunIpDst, PortNumber nshTunUdpPort,
+            long nshNsp, short nshNsi, long nshMetaC1,
+            long nshMetaC2) {
+        super();
+        this.nshTunIpDst = nshTunIpDst;
+        this.nshTunUdpPort = nshTunUdpPort;
+        this.nshNsp = nshNsp;
+        this.nshNsi = nshNsi;
+        this.nshMetaC1 = nshMetaC1;
+        this.nshMetaC2 = nshMetaC2;
+    }
+
+    /*
+     * @return the nshTunIpDst
+     */
+    public Ipv4Address getNshTunIpDst() {
+        return nshTunIpDst;
+    }
+
+    /*
+     * @param nshTunIpDst the nshTunIpDst to set
+     */
+    public void setNshTunIpDst(Ipv4Address nshTunIpDst) {
+        this.nshTunIpDst = nshTunIpDst;
+    }
+
+    /*
+     * @return the nshTunUdpPort
+     */
+    public PortNumber getNshTunUdpPort() {
+        return nshTunUdpPort;
+    }
+
+    /*
+     * @param nshTunUdpPort the nshTunUdpPort to set
+     */
+    public void setNshTunUdpPort(PortNumber nshTunUdpPort) {
+        this.nshTunUdpPort = nshTunUdpPort;
+    }
+
+    /*
+     * @return the nshNsp
+     */
+    public long getNshNsp() {
+        return nshNsp;
+    }
+
+    /*
+     * @param nshNsp the nshNsp to set
+     */
+    public void setNshNsp(long nshNsp) {
+        this.nshNsp = nshNsp;
+    }
+
+    /*
+     * @return the nshNsi
+     */
+    public short getNshNsi() {
+        return nshNsi;
+    }
+
+    /*
+     * @param nshNsi the nshNsi to set
+     */
+    public void setNshNsi(short nshNsi) {
+        this.nshNsi = nshNsi;
+    }
+
+    /*
+     * @return the nshMetaC1
+     */
+    public long getNshMetaC1() {
+        return nshMetaC1;
+    }
+
+    /*
+     * @param nshMetaC1 the nshMetaC1 to set
+     */
+    public void setNshMetaC1(long nshMetaC1) {
+        this.nshMetaC1 = nshMetaC1;
+    }
+
+    /*
+     * @return the nshMetaC2
+     */
+    public long getNshMetaC2() {
+        return nshMetaC2;
+    }
+
+    /*
+     * @param nshMetaC2 the nshMetaC2 to set
+     */
+    public void setNshMetaC2(long nshMetaC2) {
+        this.nshMetaC2 = nshMetaC2;
+    }
+
+    public static Long convertIpAddressToLong(Ipv4Address ipv4Address) {
+        return (InetAddresses.coerceToInteger(InetAddresses.forString(ipv4Address.getValue()))) & 0xFFFFFFFFL;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "NshUtils [nshTunIpDst=" + nshTunIpDst + ", nshTunUdpPort=" + nshTunUdpPort + ", nshNsp=" + nshNsp
+                + ", nshNsi=" + nshNsi + ", nshMetaC1=" + nshMetaC1 + ", nshMetaC2=" + nshMetaC2 + "]";
+    }
+}
diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/SfcUtils.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/SfcUtils.java
new file mode 100644 (file)
index 0000000..40b8172
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright Â© 2015 Red Hat, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+import org.opendaylight.sfc.provider.api.SfcProviderServiceFunctionAPI;
+import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RspName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.RenderedServicePaths;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePathKey;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctions;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunctionKey;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.Ip;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SfcUtils {
+    private static final Logger LOG = LoggerFactory.getLogger(SfcUtils.class);
+    private MdsalUtils mdsalUtils;
+
+    public SfcUtils(MdsalUtils mdsalUtils) {
+        this.mdsalUtils = mdsalUtils;
+    }
+
+    public InstanceIdentifier<Classifiers> getClassifierIid() {
+        return InstanceIdentifier.create(Classifiers.class);
+    }
+
+    public InstanceIdentifier<RenderedServicePaths> getRspsId() {
+        return InstanceIdentifier.builder(RenderedServicePaths.class).build();
+    }
+
+    public InstanceIdentifier<RenderedServicePath> getRspId(String rspName) {
+        return InstanceIdentifier.builder(RenderedServicePaths.class)
+                .child(RenderedServicePath.class, new RenderedServicePathKey(new RspName(rspName))).build();
+    }
+
+    public InstanceIdentifier<ServiceFunction> getSfId(String sfName) {
+        return InstanceIdentifier.builder(ServiceFunctions.class)
+                .child(ServiceFunction.class, new ServiceFunctionKey(SfName.getDefaultInstance(sfName))).build();
+    }
+
+    public RenderedServicePath getRsp(String rspName) {
+        return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, getRspId(rspName));
+    }
+
+    public RenderedServicePath getRspforSfp(String sfpName) {
+        RenderedServicePath rspFound = null;
+        RenderedServicePaths rsps = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, this.getRspsId());
+        if (rsps != null) {
+            for (RenderedServicePath rsp : rsps.getRenderedServicePath()) {
+                if (rsp.getParentServiceFunctionPath() != null) {
+                    if (rsp.getParentServiceFunctionPath().getValue().equals(sfpName)) {
+                        rspFound = rsp;
+                    }
+                }
+            }
+        }
+        return rspFound;
+    }
+
+    public ServiceFunctionPath getSfp(String redirectSfc) {
+        ServiceFunctionPath sfpFound = null;
+        ServiceFunctionPaths sfps = SfcProviderServicePathAPI.readAllServiceFunctionPaths();
+        if (sfps != null) {
+            for (ServiceFunctionPath sfp: sfps.getServiceFunctionPath()) {
+                if (sfp.getServiceChainName().getValue().equalsIgnoreCase(redirectSfc)) {
+                    sfpFound = sfp;
+                }
+            }
+        }
+        return sfpFound;
+    }
+
+    public IpAddress getSfIpAddress(String sfname) {
+        ServiceFunction serviceFunction =
+                SfcProviderServiceFunctionAPI.readServiceFunction(SfName.getDefaultInstance(sfname));
+
+        if (serviceFunction == null) {
+            LOG.info("Failed to read ServiceFunction: {}", sfname);
+            return null;
+        }
+
+        return getSfIpAddress(serviceFunction);
+    }
+
+    public IpAddress getSfIpAddress(ServiceFunction serviceFunction) {
+        if (serviceFunction == null) {
+            LOG.info("getSfIp: Servicefunction is null");
+            return null;
+        }
+
+        Ip ipLocator = (Ip) serviceFunction.getSfDataPlaneLocator().get(0).getLocatorType();
+        return ipLocator.getIp();
+    }
+
+    public PortNumber getSfPort(ServiceFunction serviceFunction) {
+        if (serviceFunction == null) {
+            LOG.info("getSfIp: Servicefunction is null");
+            return null;
+        }
+
+        Ip ipLocator = (Ip) serviceFunction.getSfDataPlaneLocator().get(0).getLocatorType();
+        return ipLocator.getPort();
+    }
+
+    public Ip getSfIp(ServiceFunction serviceFunction) {
+        if (serviceFunction == null) {
+            LOG.info("getSfIp: Servicefunction is null");
+            return null;
+        }
+
+        return (Ip)serviceFunction.getSfDataPlaneLocator().get(0).getLocatorType();
+    }
+
+    public String getSfDplName(ServiceFunction serviceFunction) {
+        String sfDplName = null;
+        if (serviceFunction == null) {
+            LOG.warn("getSfDplName: Servicefunction is null");
+            return null;
+        }
+
+        sfDplName = serviceFunction.getSfDataPlaneLocator().get(0).getName().getValue();
+        return sfDplName;
+    }
+
+    public Ip getSffIp(ServiceFunctionForwarder serviceFunctionForwarder) {
+        if (serviceFunctionForwarder == null) {
+            LOG.info("getSfIp: ServicefunctionForwarder is null");
+            return null;
+        }
+
+        return (Ip)serviceFunctionForwarder.getSffDataPlaneLocator().get(0).getDataPlaneLocator().getLocatorType();
+    }
+}
diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/openflow13/NetvirtSfcOF13Provider.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/openflow13/NetvirtSfcOF13Provider.java
deleted file mode 100644 (file)
index 1621e72..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (c) 2015 Dell, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13;
-
-import java.util.Iterator;
-import java.util.List;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
-import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
-import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
-import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.PipelineOrchestrator;
-import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
-import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
-import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
-import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
-import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
-import org.opendaylight.sfc.sfc_ovs.provider.SfcOvsUtil;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.AccessList;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.AccessListEntry;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.Actions;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.Matches;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.actions.packet.handling.Deny;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.actions.packet.handling.Permit;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.matches.ace.type.AceEth;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.matches.ace.type.AceIp;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.matches.ace.type.ace.ip.ace.ip.version.AceIpv4;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.osgi.framework.ServiceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Open vSwitch OpenFlow 1.3 Networking Provider for Netvirt SFC
- * @author Arun Yerra
- */
-public class NetvirtSfcOF13Provider implements INetvirtSfcOF13Provider{
-    private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcOF13Provider.class);
-    private static final int DEFAULT_FLOW_PRIORITY = 32768;
-    private volatile NodeCacheManager nodeCacheManager;
-    private volatile Southbound southbound;
-    private MdsalUtils dbutils;
-    private PipelineOrchestrator orchestrator;
-
-    /**
-     * {@link NetvirtSfcOF13Provider} constructor.
-     * @param dataBroker MdSal {@link DataBroker}
-     */
-    public NetvirtSfcOF13Provider(final DataBroker dataBroker) {
-        Preconditions.checkNotNull(dataBroker, "Input dataBroker cannot be NULL!");
-
-        //this.dataService = dataBroker;
-        dbutils = new MdsalUtils(dataBroker);
-
-        this.setDependencies(null);
-    }
-
-    @Override
-    public void addClassifierRules(Sff sff, AccessList acl) {
-        Preconditions.checkNotNull(sff, "Input service function forwarder cannot be NULL!");
-        Preconditions.checkNotNull(acl, "Input accesslist cannot be NULL!");
-
-        // Validate if any service function forwarder exists by the name, using SFC provider APIs.
-        ServiceFunctionForwarder serviceForwarder =
-                SfcProviderServiceForwarderAPI.readServiceFunctionForwarder(sff.getName());
-        if (serviceForwarder == null) {
-            LOG.debug("Service Function Forwarder = {} not yet configured. Skip processing !!", sff.getName());
-            return;
-        }
-
-        // If a service function forwarder exists, then get the corresponding OVS Bridge details and Openflow NodeId.
-        // If OVS Bridge augmentation is configured, the following API returns NULL.
-        String datapathId = SfcOvsUtil.getOpenFlowNodeIdForSff(serviceForwarder);
-        if (datapathId == null) {
-            LOG.debug("Service Function Forwarder = {} is not augemented with "
-                    + "OVS Bridge Information. Skip processing!!", sff.getName());
-        }
-        // If openflow Node Id is NULL, get all the bridge nodes using southbound apis and fetch
-        // SFF with matching name. From this bridge name, get the openflow data path ID.
-        if (datapathId == null) {
-            Node node = null;
-            final List<Node> nodes = nodeCacheManager.getBridgeNodes();
-            if (nodes.isEmpty()) {
-                LOG.debug("Noop with Classifier Creation on SFF={}. No Bridges configured YET!!", sff.getName());
-            } else {
-                for (Node dstNode : nodes) {
-                    LOG.debug("Processing Node={}, sff={}", dstNode.getNodeId().getValue(), sff.getName());
-                    if (dstNode.getNodeId().getValue().equalsIgnoreCase(sff.getName())) {
-                        LOG.debug("Found matching OVSDB Bridge Name!!= {}", dstNode.getNodeId().getValue());
-                        node = dstNode;
-                        break;
-                    }
-                }
-            }
-        }
-
-        LOG.debug("Processing the Classifier rules on Node={}", datapathId);
-        if (datapathId != null) {
-            // Program the OF flow on the corresponding open flow node.
-            Iterator<AccessListEntry> itr = acl.getAccessListEntries().getAccessListEntry().iterator();
-            while (itr.hasNext()) {
-                AccessListEntry entry = itr.next();
-                programOFRules(entry, datapathId, true);
-            }
-        }
-    }
-
-    private void programOFRules(AccessListEntry entry, String datapathId, boolean write) {
-        NodeBuilder nodeBuilder = new NodeBuilder();
-        nodeBuilder.setId(new NodeId(Constants.OPENFLOW_NODE_PREFIX + datapathId));
-        nodeBuilder.setKey(new NodeKey(nodeBuilder.getId()));
-
-        //Create the match using match builder, by parsing the Accesslist Entry Match.
-        MatchBuilder matchBuilder = null;
-        matchBuilder = buildMatch(entry.getRuleName(), entry.getMatches(), datapathId);
-
-        InstructionsBuilder isb = null;
-        isb = buildActions(entry.getRuleName(), entry.getActions(), datapathId);
-
-        String flowId = "NETVIRT_SFC_FLOW" + "_" + entry.getRuleName();
-
-        FlowBuilder flowBuilder = new FlowBuilder();
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setMatch(matchBuilder.build());
-        flowBuilder.setPriority(DEFAULT_FLOW_PRIORITY);
-        flowBuilder.setBarrier(true);
-        flowBuilder.setTableId(this.getTable());
-        flowBuilder.setKey(key);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
-
-        flowBuilder.setInstructions(isb.build());
-
-        if (write) {
-            writeFlow(flowBuilder, nodeBuilder);
-        } else {
-            removeFlow(flowBuilder, nodeBuilder);
-        }
-    }
-
-    private InstructionsBuilder buildActions(String ruleName, Actions actions, String datapathId) {
-        InstructionBuilder ib = new InstructionBuilder();
-
-        if (actions.getPacketHandling() instanceof Deny) {
-            InstructionUtils.createDropInstructions(ib);
-        } else if (actions.getPacketHandling() instanceof Permit) {
-            //Permit actPermit = (Permit) actions.getPacketHandling();
-        } else {
-            InstructionUtils.createDropInstructions(ib);
-        }
-
-        ib.setOrder(0);
-        ib.setKey(new InstructionKey(0));
-        // Instructions List Stores Individual Instructions
-        List<Instruction> instructions = Lists.newArrayList();
-        instructions.add(ib.build());
-
-        // Call the InstructionBuilder Methods Containing Actions
-        ib = this.getMutablePipelineInstructionBuilder();
-        ib.setOrder(1);
-        ib.setKey(new InstructionKey(1));
-        instructions.add(ib.build());
-
-        // Add InstructionBuilder to the Instruction(s)Builder List
-        InstructionsBuilder isb = new InstructionsBuilder();
-        isb.setInstruction(instructions);
-        return isb;
-    }
-
-    private MatchBuilder buildMatch(String ruleName, Matches matches, String dpId) {
-        MatchBuilder matchBuilder = new MatchBuilder();
-
-        if (matches.getAceType() instanceof AceIp) {
-            AceIp aceIp = (AceIp)matches.getAceType();
-            if (aceIp.getAceIpVersion() instanceof AceIpv4) {
-                AceIpv4 aceIpv4 = (AceIpv4) aceIp.getAceIpVersion();
-                MatchUtils.createSrcL3IPv4Match(matchBuilder, aceIpv4.getSourceIpv4Address());
-                MatchUtils.createDstL3IPv4Match(matchBuilder, aceIpv4.getDestinationIpv4Address());
-                MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getIpProtocol());
-                MatchUtils.addLayer4Match(matchBuilder, aceIp.getIpProtocol().intValue(),
-                        aceIp.getSourcePortRange().getLowerPort().getValue().intValue(),
-                        aceIp.getDestinationPortRange().getLowerPort().getValue().intValue());
-            }
-        } else if (matches.getAceType() instanceof AceEth) {
-            AceEth aceEth = (AceEth) matches.getAceType();
-            MatchUtils.createEthSrcMatch(matchBuilder, new MacAddress(aceEth.getSourceMacAddress().getValue()));
-            MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(aceEth.getDestinationMacAddress().getValue()),
-                    new MacAddress(aceEth.getDestinationMacAddressMask().getValue()));
-        }
-
-        //MatchUtils.createInPortMatch(matchBuilder, Long.getLong(dpId), Long.getLong(matches.getInputInterface()));
-        return matchBuilder;
-    }
-
-    @Override
-    public void removeClassifierRules(Sff sff, AccessList acl) {
-        // TODO Auto-generated method stub
-
-    }
-
-
-    protected void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
-        LOG.debug("writeFlow: flowBuilder: {}, nodeBuilder: {}",
-                flowBuilder.build(), nodeBuilder.build());
-        dbutils.merge(LogicalDatastoreType.CONFIGURATION, createNodePath(nodeBuilder), nodeBuilder.build());
-        dbutils.put(LogicalDatastoreType.CONFIGURATION, createFlowPath(flowBuilder, nodeBuilder), flowBuilder.build());
-    }
-
-    protected void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
-        dbutils.delete(LogicalDatastoreType.CONFIGURATION, createFlowPath(flowBuilder, nodeBuilder));
-    }
-
-    private String getDpid(Node node) {
-        long dpid = southbound.getDataPathId(node);
-        if (dpid == 0) {
-            LOG.warn("getDpid: DPID could not be found for node: {}", node.getNodeId().getValue());
-        }
-        return String.valueOf(dpid);
-    }
-
-    private static InstanceIdentifier<Flow> createFlowPath(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
-        return InstanceIdentifier.builder(Nodes.class)
-                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
-                        nodeBuilder.getKey())
-                .augmentation(FlowCapableNode.class)
-                .child(Table.class, new TableKey(flowBuilder.getTableId()))
-                .child(Flow.class, flowBuilder.getKey()).build();
-    }
-
-    private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node>
-        createNodePath(NodeBuilder nodeBuilder) {
-        return InstanceIdentifier.builder(Nodes.class)
-                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
-                        nodeBuilder.getKey()).build();
-    }
-
-    private short getTable() {
-        return Service.INGRESS_ACL.getTable();
-    }
-
-    private final InstructionBuilder getMutablePipelineInstructionBuilder() {
-        Service nextService = orchestrator.getNextServiceInPipeline(Service.INGRESS_ACL);
-        if (nextService != null) {
-            return InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), nextService.getTable());
-        } else {
-            return InstructionUtils.createDropInstructions(new InstructionBuilder());
-        }
-    }
-
-    private void setDependencies(ServiceReference serviceReference) {
-        nodeCacheManager = (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
-        southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
-        orchestrator = (PipelineOrchestrator) ServiceHelper.getGlobalInstance(PipelineOrchestrator.class, this);
-    }
-}
diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/standalone/openflow13/NetvirtSfcStandaloneOF13Provider.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/standalone/openflow13/NetvirtSfcStandaloneOF13Provider.java
new file mode 100644 (file)
index 0000000..77ec178
--- /dev/null
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2015 Dell, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13;
+
+import com.google.common.base.Preconditions;
+
+import com.google.common.collect.Iterables;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.INetvirtSfcOF13Provider;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.ISfcClassifierService;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
+import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
+import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RspName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.RenderedServicePaths;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.path.first.hop.info.RenderedServicePathFirstHop;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePathKey;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHop;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.Acl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.Ace;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.RedirectToSfc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.Classifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.Bridges;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.bridges.Bridge;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Open vSwitch OpenFlow 1.3 Networking Provider for Netvirt SFC
+ * @author Arun Yerra
+ */
+public class NetvirtSfcStandaloneOF13Provider implements INetvirtSfcOF13Provider {
+    private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcStandaloneOF13Provider.class);
+    private static final short TABLE_0_CLASSIFIER = 0;
+    private static final short TABLE_3_INGR_ACL = 50;
+
+    private volatile NodeCacheManager nodeCacheManager;
+    private volatile Southbound southbound;
+    private MdsalUtils mdsalUtils;
+    private SfcClassifier sfcClassifier;
+
+    // TBD:: Remove these constants after integrating with openstack.
+    private static final String TUNNEL_DST = "192.168.50.75";
+    private static final String TUNNEL_VNID = "10";
+    private static final String CLIENT_PORT_NAME = "vethl-h35_2";
+    private static final String SERVER_PORT_NAME = "vethl-h35_4";
+    private static final String CLIENT_GPE_PORT_NAME = "sw1-vxlangpe-0";
+    private static final String SERVER_GPE_PORT_NAME = "sw6-vxlangpe-0";
+    private static final String INTERFACE_TYPE_VXLAN_GPE = "vxlangpe";
+
+    /**
+     * {@link NetvirtSfcStandaloneOF13Provider} constructor.
+     * @param dataBroker MdSal {@link DataBroker}
+     */
+    public NetvirtSfcStandaloneOF13Provider(final DataBroker dataBroker) {
+        Preconditions.checkNotNull(dataBroker, "Input dataBroker cannot be NULL!");
+        mdsalUtils = new MdsalUtils(dataBroker);
+        //this.setDependencies(null);
+        sfcClassifier = new SfcClassifier(dataBroker, southbound, mdsalUtils);
+    }
+
+    public void removeClassifierRules(Sff sff, Acl acl) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void addClassifierRules(Acl acl) {
+        String aclName = acl.getAclName();
+        Classifiers classifiers = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, getClassifierIid());
+        if (classifiers == null) {
+            LOG.debug("add: No Classifiers found");
+            return;
+        }
+
+        LOG.debug("add: Classifiers: {}", classifiers);
+        for (Classifier classifier : classifiers.getClassifier()) {
+            if (classifier.getAcl().equals(aclName)) {
+                if (classifier.getBridges() != null) {
+                    addClassifierRules(classifier.getBridges(), acl);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void removeClassifierRules(Acl acl) {
+        String aclName = acl.getAclName();
+        Classifiers classifiers = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, getClassifierIid());
+        if (classifiers != null) {
+            for (Classifier classifier : classifiers.getClassifier()) {
+                if (classifier.getAcl().equalsIgnoreCase(aclName)) {
+                    if (classifier.getSffs() != null) {
+                        for (Sff sff : classifier.getSffs().getSff()) {
+                            removeClassifierRules(sff, acl);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setSfcClassifierService(ISfcClassifierService sfcClassifierService) {
+
+    }
+
+    @Override
+    public void addClassifierRules(Bridge bridge, Acl acl) {
+
+    }
+
+    @Override
+    public void addClassifierRules(Bridges bridges, Acl acl) {
+        Preconditions.checkNotNull(bridges, "Input bridges cannot be NULL!");
+        Preconditions.checkNotNull(acl, "Input accesslist cannot be NULL!");
+
+        for (Ace ace : acl.getAccessListEntries().getAce()) {
+            processAclEntry(ace, bridges, true);
+        }
+    }
+
+    private void processAclEntry(Ace entry, Bridges bridges, boolean write) {
+        Matches matches = entry.getMatches();
+        if (matches == null) {
+            LOG.warn("processAclEntry: matches not found");
+            return;
+        }
+
+        RenderedServicePath rsp = getRenderedServicePath(entry);
+        if (rsp == null) {
+            LOG.warn("Failed to get renderedServicePatch for entry: {}", entry);
+            return;
+        }
+
+        LOG.info("processAclEntry: RSP: {}", rsp);
+        List<RenderedServicePathHop> pathHopList = rsp.getRenderedServicePathHop();
+        if (pathHopList.isEmpty()) {
+            LOG.warn("Service Path = {} has empty hops!!", rsp.getName());
+            return;
+        }
+
+        for (Bridge bridge : bridges.getBridge()) {
+            if (bridge.getDirection().getIntValue() == 0) {
+                Node bridgeNode = getBridgeNode(bridge.getName());
+                if (bridgeNode == null) {
+                    LOG.debug("processAclEntry: bridge {} not yet configured. Skip processing !!", bridge.getName());
+                    continue;
+                }
+
+                long tunnelOfPort = southbound.getOFPort(bridgeNode, CLIENT_GPE_PORT_NAME);
+                if (tunnelOfPort == 0L) {
+                    LOG.error("programAclEntry: Could not identify tunnel port {} -> OF ({}) on {}",
+                            CLIENT_GPE_PORT_NAME, tunnelOfPort, bridgeNode);
+                    return;
+                }
+
+                long localOfPort = southbound.getOFPort(bridgeNode, CLIENT_PORT_NAME);
+                if (localOfPort == 0L) {
+                    LOG.error("programAclEntry: Could not identify local port {} -> OF ({}) on {}",
+                            CLIENT_GPE_PORT_NAME, localOfPort, bridgeNode);
+                    return;
+                }
+
+                // Find the first Hop within an RSP.
+                // The classifier flow needs to send all matched traffic to this first hop SFF.
+                RenderedServicePathFirstHop firstRspHop = SfcProviderRenderedPathAPI
+                        .readRenderedServicePathFirstHop(new RspName(rsp.getName()));
+
+                LOG.debug("First Hop IPAddress = {}, Port = {}", firstRspHop.getIp().getIpv4Address().getValue(),
+                        firstRspHop.getPort().getValue());
+
+                NshUtils nshHeader = new NshUtils();
+                // C1 is the normal overlay dest ip and c2 is the vnid
+                // Hardcoded for now, netvirt integration will have those values
+                nshHeader.setNshMetaC1(NshUtils.convertIpAddressToLong(new Ipv4Address(TUNNEL_DST)));
+                nshHeader.setNshMetaC2(Long.parseLong(TUNNEL_VNID));
+                nshHeader.setNshNsp(rsp.getPathId());
+
+                RenderedServicePathHop firstHop = pathHopList.get(0);
+                nshHeader.setNshNsi(firstHop.getServiceIndex());
+                nshHeader.setNshTunIpDst(firstRspHop.getIp().getIpv4Address());
+                nshHeader.setNshTunUdpPort(firstRspHop.getPort());
+                LOG.debug("The Nsh Header = {}", nshHeader);
+
+                handleLocalInPort(southbound.getDataPathId(bridgeNode), rsp.getPathId().toString(), localOfPort,
+                        TABLE_0_CLASSIFIER, TABLE_3_INGR_ACL, matches, true);
+
+                handleSfcClassiferFlows(southbound.getDataPathId(bridgeNode), TABLE_3_INGR_ACL, entry.getRuleName(),
+                        matches, nshHeader, tunnelOfPort, true);
+            } else {
+                Node bridgeNode = getBridgeNode(bridge.getName());
+                if (bridgeNode == null) {
+                    LOG.debug("processAclEntry: bridge {} not yet configured. Skip processing !!", bridge.getName());
+                    continue;
+                }
+
+                long tunnelOfPort = southbound.getOFPort(bridgeNode, SERVER_GPE_PORT_NAME);
+                if (tunnelOfPort == 0L) {
+                    LOG.error("programAclEntry: Could not identify tunnel port {} -> OF ({}) on {}",
+                            CLIENT_GPE_PORT_NAME, tunnelOfPort, bridgeNode);
+                    return;
+                }
+
+                long localOfPort = southbound.getOFPort(bridgeNode, SERVER_PORT_NAME);
+                if (localOfPort == 0L) {
+                    LOG.error("programAclEntry: Could not identify local port {} -> OF ({}) on {}",
+                            CLIENT_GPE_PORT_NAME, localOfPort, bridgeNode);
+                    return;
+                }
+
+                RenderedServicePathHop lastRspHop = Iterables.getLast(rsp.getRenderedServicePathHop());
+
+                LOG.debug("programAclEntry: Last Hop #: {}, nsi: {}", lastRspHop.getHopNumber().intValue(),
+                        lastRspHop.getServiceIndex().intValue() - 1);
+
+                NshUtils nshHeader = new NshUtils();
+                nshHeader.setNshNsp(rsp.getPathId());
+                nshHeader.setNshNsi((short)(lastRspHop.getServiceIndex().intValue() - 1));
+                nshHeader.setNshMetaC2(Long.parseLong(TUNNEL_VNID));
+                LOG.debug("programAclEntry: The Nsh Header = {}", nshHeader);
+
+                //handleLocalEgressPort(southbound.getDataPathId(bridgeNode), rsp.getPathId().toString(), localOfPort,
+                //        TABLE_0_CLASSIFIER, TABLE_3_INGR_ACL, true);
+
+                handleEgressSfcClassiferFlows(southbound.getDataPathId(bridgeNode),
+                        TABLE_0_CLASSIFIER, entry.getRuleName(), matches, nshHeader, tunnelOfPort, localOfPort, true);
+            }
+        }
+    }
+
+    private RenderedServicePath getRenderedServicePath (Ace entry) {
+        RenderedServicePath rsp = null;
+        RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
+        LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
+        if (sfcRedirect == null) {
+            LOG.warn("processAClEntry: sfcRedirect is null");
+            return null;
+        }
+
+        if (sfcRedirect.getRspName() != null) {
+            rsp = getRenderedServicePathFromRsp(sfcRedirect.getRspName());
+        } else if (sfcRedirect.getSfpName() != null) {
+            LOG.warn("getRenderedServicePath: sfp not handled yet");
+        } else {
+            rsp = getRenderedServicePathFromSfc(entry);
+        }
+        LOG.info("getRenderedServicePath: rsp: {}", rsp);
+        return rsp;
+    }
+
+    private RenderedServicePath getRenderedServicePathFromRsp(String rspName) {
+        return null;//getRsp(rspName);
+    }
+
+    private RenderedServicePath getRenderedServicePathFromSfc (Ace entry) {
+        RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
+        LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
+        if (sfcRedirect == null) {
+            LOG.warn("processAClEntry: sfcRedirect is null");
+            return null;
+        }
+
+        String sfcName = sfcRedirect.getSfcName();
+        ServiceFunctionPath sfp = getSfp(sfcName);
+        if (sfp == null || sfp.getName() == null) {
+            LOG.warn("There is no configured SFP with sfcName = {}; so skip installing the ACL entry!!", sfcName);
+            return null;
+        }
+
+        LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcName, sfp);
+        // If RSP doesn't exist, create an RSP.
+        String sfpName = sfp.getName().getValue();
+        RenderedServicePath rsp = getRspforSfp(sfpName);
+        String rspName = sfp.getName().getValue() + "_rsp";
+        if (rsp == null) {
+            LOG.info("No configured RSP corresponding to SFP = {}, Creating new RSP = {}", sfpName, rspName);
+            CreateRenderedPathInput rspInput = new CreateRenderedPathInputBuilder()
+                    .setParentServiceFunctionPath(sfpName)
+                    .setName(rspName)
+                    .setSymmetric(sfp.isSymmetric())
+                    .build();
+            rsp = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, rspInput);
+            if (rsp == null) {
+                LOG.warn("failed to add RSP");
+                return null;
+            }
+
+            // If SFP is symmetric, create RSP in the reverse direction.
+            if (sfp.isSymmetric()) {
+                LOG.info("SFP = {} is symmetric, installing RSP in the reverse direction!!", sfpName);
+                String rspNameRev = rspName + "-Reverse";
+                RenderedServicePath rspReverse = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
+                        getRspId(rspNameRev));
+                if (rspReverse == null) {
+                    rspReverse = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp);
+                    if (rspReverse == null) {
+                        LOG.warn("failed to add reverse RSP");
+                        return null;
+                    }
+                }
+            }
+        }
+        return rsp;
+    }
+
+    private void handleLocalEgressPort(long dataPathId, String s, long localOfPort, short writeTable,
+                                       short gotoTable, boolean write) {
+
+    }
+
+    private void handleEgressSfcClassiferFlows(long dataPathId, short writeTable, String ruleName,
+                                               Matches matches, NshUtils nshHeader, long tunnelOfPort,
+                                               long outOfPort, boolean write) {
+        sfcClassifier.programEgressSfcClassiferFlows(dataPathId, writeTable, ruleName, matches, nshHeader,
+                tunnelOfPort, outOfPort, write);
+    }
+
+    private void handleSfcClassiferFlows(long dataPathId, short writeTable, String ruleName,
+                                         Matches matches, NshUtils nshHeader, long tunnelOfPort,
+                                         boolean write) {
+        sfcClassifier.programSfcClassiferFlows(dataPathId, writeTable, ruleName, matches, nshHeader,
+                tunnelOfPort, write);
+    }
+
+    private InstanceIdentifier<RenderedServicePaths> getRspsId() {
+        return InstanceIdentifier.builder(RenderedServicePaths.class).build();
+    }
+
+    private InstanceIdentifier<RenderedServicePath> getRspId(String rspName) {
+        return InstanceIdentifier.builder(RenderedServicePaths.class)
+                .child(RenderedServicePath.class, new RenderedServicePathKey(new RspName(rspName))).build();
+    }
+
+    public Node getBridgeNode(String bridgeName) {
+        Node nodeFound = null;
+        final List<Node> nodes = nodeCacheManager.getBridgeNodes();
+        if (nodes != null && !nodes.isEmpty()) {
+            for (Node node : nodes) {
+                if (southbound.getBridge(node, bridgeName) != null) {
+                    nodeFound = node;
+                    break;
+                }
+            }
+        }
+        return nodeFound;
+    }
+
+    public RenderedServicePath getRspforSfp(String sfpName) {
+        RenderedServicePath rspFound = null;
+        RenderedServicePaths rsps = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, this.getRspsId());
+        if (rsps != null) {
+            for (RenderedServicePath rsp : rsps.getRenderedServicePath()) {
+                if (rsp.getParentServiceFunctionPath() != null) {
+                    if (rsp.getParentServiceFunctionPath().getValue().equals(sfpName)) {
+                        rspFound = rsp;
+                    }
+                }
+            }
+        }
+        return rspFound;
+    }
+
+    public ServiceFunctionPath getSfp(String redirectSfc) {
+        ServiceFunctionPath sfpFound = null;
+        ServiceFunctionPaths sfps = SfcProviderServicePathAPI.readAllServiceFunctionPaths();
+        if (sfps != null) {
+            for (ServiceFunctionPath sfp: sfps.getServiceFunctionPath()) {
+                if (sfp.getServiceChainName().getValue().equalsIgnoreCase(redirectSfc)) {
+                    sfpFound = sfp;
+                }
+            }
+        }
+        return sfpFound;
+    }
+
+/*
+ * (TABLE:0) EGRESS VM TRAFFIC TOWARDS TEP
+ * MATCH: DESTINATION ETHERNET ADDR AND OPENFLOW INPORT
+ * INSTRUCTION: SET TUNNELID AND GOTO TABLE TUNNEL TABLE (N)
+ * TABLE=0,IN_PORT=2,DL_SRC=00:00:00:00:00:01 \
+ * ACTIONS=SET_FIELD:5->TUN_ID,GOTO_TABLE=1"
+ */
+    public String getDestIp(Matches match) {
+        if (match.getAceType() instanceof AceIp) {
+            AceIp aceIp = (AceIp)match.getAceType();
+            if (aceIp.getAceIpVersion() instanceof AceIpv4) {
+                AceIpv4 aceIpv4 = (AceIpv4) aceIp.getAceIpVersion();
+                if (aceIpv4.getDestinationIpv4Network() != null) {
+                    String ipAddrPrefix = aceIpv4.getDestinationIpv4Network().getValue();
+                    return new StringTokenizer(ipAddrPrefix, "/").nextToken();
+                }
+            }
+        }
+        return null;
+    }
+
+    public String getSourceIp(Matches match) {
+        if (match.getAceType() instanceof AceIp) {
+            AceIp aceIp = (AceIp)match.getAceType();
+            if (aceIp.getAceIpVersion() instanceof AceIpv4) {
+                AceIpv4 aceIpv4 = (AceIpv4) aceIp.getAceIpVersion();
+                if (aceIpv4.getSourceIpv4Network() != null) {
+                    //String ipAddr = new StringTokenizer(ipAddrPrefix, "/").nextToken();
+                    return aceIpv4.getSourceIpv4Network().getValue();
+                }
+            }
+        }
+        return null;
+    }
+
+    private InstanceIdentifier<Classifiers> getClassifierIid() {
+        return InstanceIdentifier.create(Classifiers.class);
+    }
+
+    public void handleLocalInPort(long dpidLong, String segmentationId, Long inPort,
+                                  short writeTable, short goToTableId, Matches matches, boolean write) {
+        sfcClassifier.programLocalInPort(dpidLong, segmentationId, inPort, writeTable, goToTableId, matches, write);
+    }
+
+    @Override
+    public void setDependencies(ServiceReference serviceReference) {
+        nodeCacheManager = (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
+        southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
+    }
+}
diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/standalone/openflow13/SfcClassifier.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/standalone/openflow13/SfcClassifier.java
new file mode 100644 (file)
index 0000000..20b4fbc
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * Copyright Â© 2015 Red Hat, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13;
+
+import com.google.common.collect.Lists;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
+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.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SfcClassifier {
+    private static final Logger LOG = LoggerFactory.getLogger(SfcClassifier.class);
+    private DataBroker dataBroker;
+    private Southbound southbound;
+    private MdsalUtils mdsalUtils;
+    public final static long REG_VALUE_FROM_LOCAL = 0x1L;
+    public final static long REG_VALUE_FROM_REMOTE = 0x2L;
+    public static final Class<? extends NxmNxReg> REG_FIELD = NxmNxReg0.class;
+    private static final String OPENFLOW = "openflow:";
+
+    public SfcClassifier(DataBroker dataBroker, Southbound southbound, MdsalUtils mdsalUtils) {
+        this.dataBroker = dataBroker;
+        this.southbound = southbound;
+        this.mdsalUtils = mdsalUtils;
+    }
+
+    /*
+     * (TABLE:50) EGRESS VM TRAFFIC TOWARDS TEP with NSH header
+     * MATCH: Match fields passed through ACL entry
+     * INSTRUCTION: SET TUNNELID AND GOTO TABLE TUNNEL TABLE (N)
+     * TABLE=0,IN_PORT=2,DL_SRC=00:00:00:00:00:01 \
+     * ACTIONS=SET_FIELD:5->TUN_ID,GOTO_TABLE=1"
+     */
+    public void programSfcClassiferFlows(Long dpidLong, short writeTable, String ruleName, Matches match,
+                                         NshUtils nshHeader, long tunnelOfPort, boolean write) {
+        String nodeName = OPENFLOW + dpidLong;
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(nodeName);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = buildMatch(match);
+        flowBuilder.setMatch(matchBuilder.build());
+
+        String flowId = "sfcClass_" + ruleName + "_" + nshHeader.getNshNsp();
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(writeTable);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            List<Action> actionList = getNshAction(nshHeader);
+            ActionBuilder ab = new ActionBuilder();
+
+            ab.setAction(ActionUtils.outputAction(FlowUtils.getNodeConnectorId(tunnelOfPort, nodeName)));
+            ab.setOrder(actionList.size());
+            ab.setKey(new ActionKey(actionList.size()));
+            actionList.add(ab.build());
+
+            ApplyActionsBuilder aab = new ApplyActionsBuilder();
+            aab.setAction(actionList);
+
+            InstructionBuilder ib = new InstructionBuilder();
+            ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            List<Instruction> instructions = Lists.newArrayList();
+            instructions.add(ib.build());
+
+            InstructionsBuilder isb = new InstructionsBuilder();
+            isb.setInstruction(instructions);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    public void programEgressSfcClassiferFlows(Long dpidLong, short writeTable, String ruleName,
+                                               Matches match, NshUtils nshHeader,
+                                               long tunnelOfPort, long outOfPort, boolean write) {
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, tunnelOfPort).build());
+        flowBuilder.setMatch(
+                MatchUtils.createTunnelIDMatch(matchBuilder, BigInteger.valueOf(nshHeader.getNshMetaC2())).build());
+        flowBuilder.setMatch(MatchUtils.addNxNspMatch(matchBuilder, nshHeader.getNshNsp()).build());
+        flowBuilder.setMatch(MatchUtils.addNxNsiMatch(matchBuilder, nshHeader.getNshNsi()).build());
+
+        String flowId = "egressSfcClass_" + ruleName + "_" + nshHeader.getNshNsp() + "_" + nshHeader.getNshNsi();
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(writeTable);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            List<Action> actionList = new ArrayList<>();
+            ActionBuilder ab = new ActionBuilder();
+
+            ab.setAction(ActionUtils.nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(REG_FIELD).build(),
+                    BigInteger.valueOf(REG_VALUE_FROM_REMOTE)));
+            ab.setOrder(0);
+            ab.setKey(new ActionKey(0));
+            actionList.add(ab.build());
+
+            ab.setAction(ActionUtils.outputAction(FlowUtils.getNodeConnectorId(dpidLong, outOfPort)));
+            ab.setOrder(1);
+            ab.setKey(new ActionKey(1));
+            actionList.add(ab.build());
+
+            ApplyActionsBuilder aab = new ApplyActionsBuilder();
+            aab.setAction(actionList);
+
+            InstructionBuilder ib = new InstructionBuilder();
+            ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            List<Instruction> instructions = new ArrayList<>();
+            instructions.add(ib.build());
+
+            InstructionsBuilder isb = new InstructionsBuilder();
+            isb.setInstruction(instructions);
+
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    private List<Action> getNshAction(NshUtils header) {
+        // Build the Actions to Add the NSH Header
+        org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC1Load =
+                ActionUtils.nxLoadNshc1RegAction(header.getNshMetaC1());
+        org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC2Load =
+                ActionUtils.nxLoadNshc2RegAction(header.getNshMetaC2());
+        org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nspLoad =
+                ActionUtils.nxSetNspAction(header.getNshNsp());
+        org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nsiLoad =
+                ActionUtils.nxSetNsiAction(header.getNshNsi());
+        org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunVnid =
+                ActionUtils.nxLoadTunIdAction(BigInteger.valueOf(header.getNshNsp()), false);
+        org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunDest =
+                ActionUtils.nxLoadTunIPv4Action(header.getNshTunIpDst().getValue(), false);
+
+        int count = 0;
+        List<Action> actionList = Lists.newArrayList();
+        actionList.add(new ActionBuilder().setOrder(count++).setAction(nshC1Load).build());
+        actionList.add(new ActionBuilder().setOrder(count++).setAction(nshC2Load).build());
+        actionList.add(new ActionBuilder().setOrder(count++).setAction(nspLoad).build());
+        actionList.add(new ActionBuilder().setOrder(count++).setAction(nsiLoad).build());
+        actionList.add(new ActionBuilder().setOrder(count++).setAction(loadChainTunDest).build());
+        actionList.add(new ActionBuilder().setOrder(count++).setAction(loadChainTunVnid).build());
+        return actionList;
+    }
+
+    public void programLocalInPort(Long dpidLong, String segmentationId, Long inPort,
+                                   short writeTable, short goToTableId, Matches match, boolean write) {
+        String nodeName = OPENFLOW + dpidLong;
+
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(nodeName);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = buildMatch(match);
+        flowBuilder.setMatch(matchBuilder.build());
+        flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, inPort).build());
+        String flowId = "sfcIngress_" + segmentationId + "_" + inPort;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(true);
+        flowBuilder.setBarrier(false);
+        flowBuilder.setTableId(writeTable);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructions = Lists.newArrayList();
+
+            InstructionUtils.createSetTunnelIdInstructions(ib, new BigInteger(segmentationId));
+            ApplyActionsCase aac = (ApplyActionsCase) ib.getInstruction();
+            List<Action> actionList = aac.getApplyActions().getAction();
+
+            // TODO: Mark the packets as sfc classified?
+
+            ActionBuilder ab = new ActionBuilder();
+            ab.setAction(ActionUtils.nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(REG_FIELD).build(),
+                    BigInteger.valueOf(REG_VALUE_FROM_LOCAL)));
+            ab.setOrder(1);
+            ab.setKey(new ActionKey(1));
+            actionList.add(ab.build());
+
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructions.add(ib.build());
+
+            // Next service GOTO Instructions Need to be appended to the List
+            ib = InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), goToTableId);
+            ib.setOrder(1);
+            ib.setKey(new InstructionKey(1));
+            instructions.add(ib.build());
+
+            isb.setInstruction(instructions);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    public MatchBuilder buildMatch(Matches matches) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+
+        if (matches.getAceType() instanceof AceIp) {
+            AceIp aceIp = (AceIp)matches.getAceType();
+            if (aceIp.getAceIpVersion() instanceof AceIpv4) {
+                //AceIpv4 aceIpv4 = (AceIpv4) aceIp.getAceIpVersion();
+                //MatchUtils.createSrcL3IPv4Match(matchBuilder, aceIpv4.getSourceIpv4Network());
+                //MatchUtils.createDstL3IPv4Match(matchBuilder, aceIpv4.getDestinationIpv4Network());
+                MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
+                MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(), 0,
+                        aceIp.getDestinationPortRange().getLowerPort().getValue().intValue());
+            }
+        } else if (matches.getAceType() instanceof AceEth) {
+            AceEth aceEth = (AceEth) matches.getAceType();
+            MatchUtils.createEthSrcMatch(matchBuilder, new MacAddress(aceEth.getSourceMacAddress().getValue()));
+            MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(aceEth.getDestinationMacAddress().getValue()),
+                    new MacAddress(aceEth.getDestinationMacAddressMask().getValue()));
+        }
+
+        LOG.info("buildMatch: {}", matchBuilder.build());
+        return matchBuilder;
+    }
+
+    protected void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
+        LOG.debug("writeFlow: flowBuilder: {}, nodeBuilder: {}", flowBuilder.build(), nodeBuilder.build());
+        mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, FlowUtils.createNodePath(nodeBuilder),
+                nodeBuilder.build());
+        mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, FlowUtils.createFlowPath(flowBuilder, nodeBuilder),
+                flowBuilder.build());
+    }
+
+    protected void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
+        mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, FlowUtils.createFlowPath(flowBuilder, nodeBuilder));
+    }
+}
diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/standalone/openflow13/services/SfcClassifierService.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/standalone/openflow13/services/SfcClassifierService.java
new file mode 100644 (file)
index 0000000..f725c24
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright Â© 2015 Red Hat, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13.services;
+
+import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.ISfcClassifierService;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SfcClassifierService extends AbstractServiceInstance implements ConfigInterface, ISfcClassifierService {
+    private static final Logger LOG = LoggerFactory.getLogger(SfcClassifierService.class);
+
+    public SfcClassifierService(Service service) {
+        super(service);
+    }
+
+    public SfcClassifierService() {
+        super(Service.SFC_CLASSIFIER);
+    }
+
+    @Override
+    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+        super.setDependencies(bundleContext.getServiceReference(SfcClassifierService.class.getName()), this);
+    }
+
+    @Override
+    public void setDependencies(Object impl) {}
+
+    @Override
+    public void programIngressClassifier(long dataPathId, String ruleName, Matches matches, NshUtils nshHeader, long vxGpeOfPort, boolean write) {
+
+    }
+
+    @Override
+    public void programSfcTable(long dataPathId, long vxGpeOfPort, short goToTableId, boolean write) {
+
+    }
+
+    @Override
+    public void programEgressClassifier1(long dataPathId, long vxGpeOfPort, long nsp, short nsi, int tunnelOfPort, int tunnelId, short gotoTableId, boolean write) {
+
+    }
+
+    @Override
+    public void programEgressClassifier(long dataPathId, long vxGpeOfPort, long nsp, short nsi, long sfOfPort, int tunnelId, boolean write) {
+
+    }
+
+    @Override
+    public void programEgressClassifierBypass(long dataPathId, long vxGpeOfPort, long nsp, short nsi, long sfOfPort, int tunnelId, boolean write) {
+
+    }
+
+    @Override
+    public void program_sfEgress(long dataPathId, int dstPort, boolean write) {
+
+    }
+
+    @Override
+    public void program_sfIngress(long dataPathId, int dstPort, long sfOfPort, String ipAddress, String sfDplName, boolean write) {
+
+    }
+
+    @Override
+    public void programStaticArpEntry(long dataPathId, long ofPort, String macAddressStr, String ipAddress, boolean write) {
+
+    }
+}
diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/NetvirtSfcWorkaroundOF13Provider.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/NetvirtSfcWorkaroundOF13Provider.java
new file mode 100644 (file)
index 0000000..a69e801
--- /dev/null
@@ -0,0 +1,572 @@
+/*
+ * Copyright Â© 2015 Red Hat, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround;
+
+import com.google.common.base.Preconditions;
+import java.util.List;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
+import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbTables;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.INetvirtSfcOF13Provider;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.ISfcClassifierService;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.SfcUtils;
+import org.opendaylight.ovsdb.southbound.SouthboundConstants;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
+import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
+import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
+import org.opendaylight.sfc.provider.api.SfcProviderServiceFunctionAPI;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.Ip;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.path.first.hop.info.RenderedServicePathFirstHop;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHop;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.Acl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.Ace;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.RedirectToSfc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.Classifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.Bridges;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.bridges.Bridge;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider {
+    private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcWorkaroundOF13Provider.class);
+    private volatile NodeCacheManager nodeCacheManager;
+    private volatile Southbound southbound;
+    private volatile ISfcClassifierService sfcClassifierService;
+    private static final short SFC_TABLE = 150;
+    private static final int GPE_PORT = 6633;
+    private static final String NETWORK_TYPE_VXLAN = "vxlan";
+    private MdsalUtils mdsalUtils;
+    private SfcUtils sfcUtils;
+    private static final String VXGPE = "vxgpe";
+    private static final String TUNNEL_DST = "192.168.120.31";
+    private static final String TUNNEL_VNID = "10";
+    public static final String TUNNEL_ENDPOINT_KEY = "local_ip";
+
+    public NetvirtSfcWorkaroundOF13Provider(final DataBroker dataBroker, MdsalUtils mdsalUtils, SfcUtils sfcUtils) {
+        Preconditions.checkNotNull(dataBroker, "Input dataBroker cannot be NULL!");
+        Preconditions.checkNotNull(mdsalUtils, "Input mdsalUtils cannot be NULL!");
+        Preconditions.checkNotNull(sfcUtils, "Input sfcUtils cannot be NULL!");
+
+        this.mdsalUtils = mdsalUtils;
+        this.sfcUtils = sfcUtils;
+        //this.setDependencies(null);
+    }
+
+    public void setSfcClassifierService(ISfcClassifierService sfcClassifierService) {
+        this.sfcClassifierService = sfcClassifierService;
+    }
+
+    @Override
+    public void addClassifierRules(Bridge bridge, Acl acl) {
+
+    }
+
+    @Override
+    public void addClassifierRules(Bridges bridges, Acl acl) {
+        Preconditions.checkNotNull(bridges, "Input bridges cannot be NULL!");
+        Preconditions.checkNotNull(acl, "Input acl cannot be NULL!");
+    }
+
+    @Override
+    public void removeClassifierRules(Sff sff, Acl acl) {
+
+    }
+
+    @Override
+    public void addClassifierRules(Acl acl) {
+        String aclName = acl.getAclName();
+        Classifiers classifiers = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, sfcUtils.getClassifierIid());
+        if (classifiers == null) {
+            LOG.debug("addClassifierRules: No Classifiers found");
+            return;
+        }
+
+        LOG.debug("addClassifierRules: Classifiers: {}", classifiers);
+        for (Classifier classifier : classifiers.getClassifier()) {
+            if (classifier.getAcl().equals(aclName)) {
+                for (Ace ace : acl.getAccessListEntries().getAce()) {
+                    processAclEntry(ace);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void removeClassifierRules(Acl acl) {
+
+    }
+
+    private void processAclEntry(Ace entry) {
+        Matches matches = entry.getMatches();
+        Preconditions.checkNotNull(matches, "Input bridges cannot be NULL!");
+
+        RenderedServicePath rsp = getRenderedServicePath(entry);
+        if (rsp == null) {
+            LOG.warn("Failed to get renderedServicePatch for entry: {}", entry);
+            return;
+        }
+
+        handleRenderedServicePath(rsp, entry);
+    }
+
+    private void handleRenderedServicePathOld(RenderedServicePath rsp, Ace entry) {
+        LOG.info("handleRenderedServicePath: RSP: {}", rsp);
+
+        Matches matches = entry.getMatches();
+        if (matches == null) {
+            LOG.warn("processAclEntry: matches not found");
+            return;
+        }
+
+        List<RenderedServicePathHop> pathHopList = rsp.getRenderedServicePathHop();
+        if (pathHopList.isEmpty()) {
+            LOG.warn("handleRenderedServicePath: RSP {} has empty hops!!", rsp.getName());
+            return;
+        }
+        LOG.info("handleRenderedServicePath: pathHopList: {}", pathHopList);
+
+        final List<Node> bridgeNodes = nodeCacheManager.getBridgeNodes();
+        if (bridgeNodes == null || bridgeNodes.isEmpty()) {
+            LOG.warn("handleRenderedServicePath: There are no bridges to process");
+            return;
+        }
+        for (Node bridgeNode : bridgeNodes) {
+            OvsdbBridgeAugmentation ovsdbBridgeAugmentation = southbound.getBridge(bridgeNode, "br-int");
+            if (ovsdbBridgeAugmentation == null) {
+                continue;
+            }
+            long vxGpeOfPort = getOFPort(bridgeNode, VXGPE);
+            if (vxGpeOfPort == 0L) {
+                LOG.warn("programAclEntry: Could not identify tunnel port {} -> OF ({}) on {}",
+                        VXGPE, vxGpeOfPort, bridgeNode);
+                continue;
+            }
+            long dataPathId = southbound.getDataPathId(bridgeNode);
+            if (dataPathId == 0L) {
+                LOG.warn("programAclEntry: Could not identify datapathId on {}", bridgeNode);
+                continue;
+            }
+
+            // Find the first Hop within an RSP.
+            // The classifier flow needs to send all matched traffic to this first hop SFF.
+            RenderedServicePathFirstHop firstRspHop = SfcProviderRenderedPathAPI
+                    .readRenderedServicePathFirstHop(rsp.getName());
+
+            LOG.info("handleRenderedServicePath: firstRspHop: {}", firstRspHop);
+            LOG.debug("handleRenderedServicePath: First Hop IPAddress = {}, Port = {}",
+                    firstRspHop.getIp().getIpv4Address().getValue(),
+                    firstRspHop.getPort().getValue());
+
+            NshUtils nshHeader = new NshUtils();
+            nshHeader.setNshMetaC1(NshUtils.convertIpAddressToLong(new Ipv4Address(TUNNEL_DST)));
+            nshHeader.setNshMetaC2(Long.parseLong(TUNNEL_VNID)); // get from register //get from
+            nshHeader.setNshNsp(rsp.getPathId());
+
+            RenderedServicePathHop firstHop = pathHopList.get(0);
+            RenderedServicePathHop lastHop = pathHopList.get(pathHopList.size()-1);
+            ServiceFunction serviceFunction =
+                    SfcProviderServiceFunctionAPI.readServiceFunction(
+                            SfName.getDefaultInstance(firstHop.getServiceFunctionName().getValue()));
+            if (serviceFunction == null) {
+                LOG.warn("programAclEntry: Could not identify ServiceFunction {} on {}",
+                        firstHop.getServiceFunctionName().getValue(), bridgeNode);
+                continue;
+            }
+
+            nshHeader.setNshNsi(firstHop.getServiceIndex());
+            // workaround: bypass sff and got directly to sf
+            //nshHeader.setNshTunIpDst(firstRspHop.getIp().getIpv4Address());
+            IpAddress sfIpAddress = sfcUtils.getSfIpAddress(serviceFunction);
+            String sfDplName = sfcUtils.getSfDplName(serviceFunction);
+            //sfcUtils.getSfIp(firstHop.getServiceFunctionName().getValue());
+            nshHeader.setNshTunIpDst(sfIpAddress.getIpv4Address());
+            nshHeader.setNshTunUdpPort(firstRspHop.getPort());
+            LOG.debug("handleRenderedServicePath: NSH Header = {}", nshHeader);
+
+            sfcClassifierService.programIngressClassifier(dataPathId, entry.getRuleName(), matches,
+                    nshHeader, vxGpeOfPort, true);
+
+            sfcClassifierService.program_sfEgress(dataPathId, GPE_PORT, true);
+            long sfOfPort = getSfPort(bridgeNode, sfDplName);
+
+            String sfMac = getMacFromExternalIds(bridgeNode, sfDplName);
+            String sfIpString = new String(sfIpAddress.getValue());
+            LOG.info("handleRenderedServicePath: sfDplName: {}, sfMac: {}, sfOfPort: {}, sfIpAddress: {}",
+                    sfDplName, sfMac, sfOfPort, sfIpString);
+            if (sfMac != null) { // install if the sf is on this bridge, expand when using multiple bridges
+                sfcClassifierService.program_sfIngress(dataPathId, GPE_PORT, sfOfPort, sfIpString, sfDplName, true);
+                sfcClassifierService.programStaticArpEntry(dataPathId, 0L, sfMac, sfIpString, true);
+            }
+
+            short lastServiceindex = (short)((lastHop.getServiceIndex()).intValue() - 1);
+            sfcClassifierService.programEgressClassifier(dataPathId, vxGpeOfPort, rsp.getPathId(),
+                    lastServiceindex, sfOfPort, 0, true);
+            sfcClassifierService.programEgressClassifierBypass(dataPathId, vxGpeOfPort, rsp.getPathId(),
+                    lastServiceindex, sfOfPort, 0, true);
+
+            sfcClassifierService.programSfcTable(dataPathId, vxGpeOfPort, SFC_TABLE, true);
+        }
+    }
+
+    private void handleRenderedServicePath(RenderedServicePath rsp, Ace entry) {
+        LOG.info("handleRenderedServicePath: RSP: {}", rsp);
+
+        Matches matches = entry.getMatches();
+        if (matches == null) {
+            LOG.warn("processAclEntry: matches not found");
+            return;
+        }
+
+        List<RenderedServicePathHop> pathHopList = rsp.getRenderedServicePathHop();
+        if (pathHopList.isEmpty()) {
+            LOG.warn("handleRenderedServicePath: RSP {} has empty hops!!", rsp.getName());
+            return;
+        }
+        LOG.info("handleRenderedServicePath: pathHopList: {}", pathHopList);
+
+        RenderedServicePathFirstHop firstRspHop = SfcProviderRenderedPathAPI
+                .readRenderedServicePathFirstHop(rsp.getName());
+        LOG.info("handleRenderedServicePath: firstRspHop: {}", firstRspHop);
+
+        RenderedServicePathHop firstHop = pathHopList.get(0);
+        RenderedServicePathHop lastHop = pathHopList.get(pathHopList.size()-1);
+
+        final List<Node> bridgeNodes = nodeCacheManager.getBridgeNodes();
+        if (bridgeNodes == null || bridgeNodes.isEmpty()) {
+            LOG.warn("handleRenderedServicePath: There are no bridges to process");
+            return;
+        }
+        for (RenderedServicePathHop hop : pathHopList) {
+            for (Node bridgeNode : bridgeNodes) {
+                // ignore bridges other than br-int
+                OvsdbBridgeAugmentation ovsdbBridgeAugmentation = southbound.getBridge(bridgeNode, "br-int");
+                if (ovsdbBridgeAugmentation == null) {
+                    continue;
+                }
+                long vxGpeOfPort = getOFPort(bridgeNode, VXGPE);
+                if (vxGpeOfPort == 0L) {
+                    LOG.warn("programAclEntry: Could not identify gpe vtep {} -> OF ({}) on {}",
+                            VXGPE, vxGpeOfPort, bridgeNode);
+                    continue;
+                }
+                long dataPathId = southbound.getDataPathId(bridgeNode);
+                if (dataPathId == 0L) {
+                    LOG.warn("programAclEntry: Could not identify datapathId on {}", bridgeNode);
+                    continue;
+                }
+
+                ServiceFunction serviceFunction =
+                        SfcProviderServiceFunctionAPI.readServiceFunction(firstHop.getServiceFunctionName());
+                if (serviceFunction == null) {
+                    LOG.warn("programAclEntry: Could not identify ServiceFunction {} on {}",
+                            firstHop.getServiceFunctionName().getValue(), bridgeNode);
+                    continue;
+                }
+                ServiceFunctionForwarder serviceFunctionForwarder =
+                        SfcProviderServiceForwarderAPI
+                                .readServiceFunctionForwarder(hop.getServiceFunctionForwarder());
+                if (serviceFunctionForwarder == null) {
+                    LOG.warn("programAclEntry: Could not identify ServiceFunctionForwarder {} on {}",
+                            firstHop.getServiceFunctionName().getValue(), bridgeNode);
+                    continue;
+                }
+
+                handleSf(bridgeNode, serviceFunction);
+                handleSff(bridgeNode, serviceFunctionForwarder, serviceFunction, hop, firstHop, lastHop,
+                        entry.getRuleName(), matches, vxGpeOfPort, rsp);
+                if (firstHop == lastHop) {
+                    handleSff(bridgeNode, serviceFunctionForwarder, serviceFunction, hop, null, lastHop,
+                            entry.getRuleName(), matches, vxGpeOfPort, rsp);
+                }
+            }
+        }
+    }
+
+    private void handleSff(Node bridgeNode, ServiceFunctionForwarder serviceFunctionForwarder,
+                           ServiceFunction serviceFunction,
+                           RenderedServicePathHop hop,
+                           RenderedServicePathHop firstHop,
+                           RenderedServicePathHop lastHop,
+                           String ruleName, Matches matches,
+                           long vxGpeOfPort, RenderedServicePath rsp) {
+        long dataPathId = southbound.getDataPathId(bridgeNode);
+
+        if (hop == firstHop) {
+            LOG.info("handleSff: first hop processing {} - {}",
+                    bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
+            NshUtils nshHeader = new NshUtils();
+            nshHeader.setNshNsp(rsp.getPathId());
+            nshHeader.setNshNsi(firstHop.getServiceIndex());
+            if (isSffOnBridge(bridgeNode, serviceFunctionForwarder)) {
+                LOG.info("handleSff: sff and bridge are the same: {} - {}, skipping first sff",
+                        bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
+                Ip ip = sfcUtils.getSfIp(serviceFunction);
+                nshHeader.setNshTunIpDst(ip.getIp().getIpv4Address());
+                nshHeader.setNshTunUdpPort(ip.getPort());
+            } else {
+                LOG.info("handleSff: sff and bridge are not the same: {} - {}, sending to first sff",
+                        bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
+                Ip ip = sfcUtils.getSffIp(serviceFunctionForwarder);
+                nshHeader.setNshTunIpDst(ip.getIp().getIpv4Address());
+                nshHeader.setNshTunUdpPort(ip.getPort());
+            }
+            sfcClassifierService.programIngressClassifier(dataPathId, ruleName, matches,
+                    nshHeader, vxGpeOfPort, true);
+        } else if (hop == lastHop) {
+            LOG.info("handleSff: last hop processing {} - {}",
+                    bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
+            short lastServiceindex = (short)((lastHop.getServiceIndex()).intValue() - 1);
+            String sfDplName = sfcUtils.getSfDplName(serviceFunction);
+            long sfOfPort = getSfPort(bridgeNode, sfDplName);
+            sfcClassifierService.programEgressClassifier(dataPathId, vxGpeOfPort, rsp.getPathId(),
+                    lastServiceindex, sfOfPort, 0, true);
+            sfcClassifierService.programEgressClassifierBypass(dataPathId, vxGpeOfPort, rsp.getPathId(),
+                    lastServiceindex, sfOfPort, 0, true);
+        } else {
+            // add typical sff flows
+        }
+
+        sfcClassifierService.programSfcTable(dataPathId, vxGpeOfPort, SFC_TABLE, true);
+    }
+
+    void handleSf(Node bridgeNode, ServiceFunction serviceFunction) {
+        if (isSfOnBridge(bridgeNode, serviceFunction)) {
+            LOG.info("handleSf: sf and bridge are on the same node: {} - {}, adding workaround and arp",
+                    bridgeNode.getNodeId(), serviceFunction.getName());
+            long dataPathId = southbound.getDataPathId(bridgeNode);
+            Ip ip = sfcUtils.getSfIp(serviceFunction);
+            String sfIpAddr = String.valueOf(ip.getIp().getValue());
+            int sfIpPort = ip.getPort().getValue(); //GPE_PORT
+            String sfDplName = sfcUtils.getSfDplName(serviceFunction);
+            long sfOfPort = getSfPort(bridgeNode, sfDplName);
+            String sfMac = getMacFromExternalIds(bridgeNode, sfDplName);
+            if (sfMac == null) {
+                LOG.warn("handleSff: could not find mac for {} on {}", sfDplName, bridgeNode);
+                return;
+            }
+            //should be sffdplport, but they should all be the same 6633/4790
+            sfcClassifierService.program_sfEgress(dataPathId, sfIpPort, true);
+            sfcClassifierService.program_sfIngress(dataPathId, sfIpPort, sfOfPort, sfIpAddr, sfDplName, true);
+            sfcClassifierService.programStaticArpEntry(dataPathId, 0L, sfMac, sfIpAddr, true);
+        }
+    }
+
+    private boolean isSffOnBridge(Node bridgeNode, ServiceFunctionForwarder serviceFunctionForwarder) {
+        String local_ip = "";
+        Ip ip = sfcUtils.getSffIp(serviceFunctionForwarder);
+        Node ovsdbNode = southbound.readOvsdbNode(bridgeNode);
+        if (ovsdbNode != null) {
+            OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
+            if (ovsdbNodeAugmentation != null && ovsdbNodeAugmentation.getOpenvswitchOtherConfigs() != null) {
+                southbound.getOtherConfig(ovsdbNode, OvsdbTables.OPENVSWITCH, TUNNEL_ENDPOINT_KEY);
+            }
+
+        }
+        return local_ip.equals(String.valueOf(ip.getIp().getValue()));
+    }
+
+    private boolean isSfOnBridge(Node bridgeNode, ServiceFunction serviceFunction) {
+        String sfDplName = sfcUtils.getSfDplName(serviceFunction);
+        long sfOfPort = getSfPort(bridgeNode, sfDplName);
+        return sfOfPort != 0L;
+    }
+
+    private RenderedServicePath getRenderedServicePath (Ace entry) {
+        RenderedServicePath rsp = null;
+        RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
+        LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
+        if (sfcRedirect == null) {
+            LOG.warn("processAClEntry: sfcRedirect is null");
+            return null;
+        }
+
+        if (sfcRedirect.getRspName() != null) {
+            rsp = getRenderedServicePathFromRsp(sfcRedirect.getRspName());
+        } else if (sfcRedirect.getSfpName() != null) {
+            LOG.warn("getRenderedServicePath: sfp not handled yet");
+        } else {
+            rsp = getRenderedServicePathFromSfc(entry);
+        }
+        LOG.info("getRenderedServicePath: rsp: {}", rsp);
+        return rsp;
+    }
+
+    private RenderedServicePath getRenderedServicePathFromRsp(String rspName) {
+        return sfcUtils.getRsp(rspName);
+    }
+
+    private RenderedServicePath getRenderedServicePathFromSfc (Ace entry) {
+        RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
+        LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
+        if (sfcRedirect == null) {
+            LOG.warn("processAClEntry: sfcRedirect is null");
+            return null;
+        }
+
+        String sfcName = sfcRedirect.getSfcName();
+        ServiceFunctionPath sfp = sfcUtils.getSfp(sfcName);
+        if (sfp == null || sfp.getName() == null) {
+            LOG.warn("There is no configured SFP with sfcName = {}; so skip installing the ACL entry!!", sfcName);
+            return null;
+        }
+
+        LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcName, sfp);
+        // If RSP doesn't exist, create an RSP.
+        String sfpName = sfp.getName().getValue();
+        RenderedServicePath rsp = sfcUtils.getRspforSfp(sfpName);
+        String rspName = sfp.getName().getValue() + "_rsp";
+        if (rsp == null) {
+            LOG.info("No configured RSP corresponding to SFP = {}, Creating new RSP = {}", sfpName, rspName);
+            CreateRenderedPathInput rspInput = new CreateRenderedPathInputBuilder()
+                    .setParentServiceFunctionPath(sfpName)
+                    .setName(rspName)
+                    .setSymmetric(sfp.isSymmetric())
+                    .build();
+            rsp = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, rspInput);
+            if (rsp == null) {
+                LOG.warn("failed to add RSP");
+                return null;
+            }
+
+            // If SFP is symmetric, create RSP in the reverse direction.
+            if (sfp.isSymmetric()) {
+                LOG.info("SFP = {} is symmetric, installing RSP in the reverse direction!!", sfpName);
+                String rspNameRev = rspName + "-Reverse";
+                RenderedServicePath rspReverse = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
+                        sfcUtils.getRspId(rspNameRev));
+                if (rspReverse == null) {
+                    rspReverse = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp);
+                    if (rspReverse == null) {
+                        LOG.warn("failed to add reverse RSP");
+                        return null;
+                    }
+                }
+            }
+        }
+        return rsp;
+    }
+
+    // loop through all ports looking for vxlan types, skip vxgpe, keep the rest
+    // first pass we only have two tunnels: one for normal vxlan and the other for gpe
+    // so just return the first non-gpe vxlan port
+    private long getTunnelOfPort(Node bridgeNode, String vxGpePortName) {
+        long port = 0L;
+        List<OvsdbTerminationPointAugmentation> ovsdbTerminationPointAugmentations =
+                southbound.getTerminationPointsOfBridge(bridgeNode);
+        if (!ovsdbTerminationPointAugmentations.isEmpty()) {
+            for (OvsdbTerminationPointAugmentation terminationPointAugmentation :
+                    ovsdbTerminationPointAugmentations) {
+                if (terminationPointAugmentation.getInterfaceType() ==
+                        SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get(NETWORK_TYPE_VXLAN)) {
+                    if (!terminationPointAugmentation.getName().equals(vxGpePortName)) {
+                        port = terminationPointAugmentation.getOfport();
+                        break;
+                    }
+                }
+            }
+        }
+        return port;
+    }
+
+    private long getSfPort(Node bridgeNode, String sfPortName) {
+        long port = 0L;
+        port = getOFPort(bridgeNode, sfPortName);
+        return port;
+    }
+
+    private long getOFPort(Node bridgeNode, String portName) {
+        long ofPort = 0L;
+        OvsdbTerminationPointAugmentation port =
+                southbound.extractTerminationPointAugmentation(bridgeNode, portName);
+        if (port != null) {
+            ofPort = southbound.getOFPort(port);
+        }
+        if (ofPort == 0L) {
+            for (int i = 0; i < 5; i++) {
+                LOG.info("Looking for ofPort {}, try: {}", portName, i);
+                if (ofPort == 0L) {
+                    TerminationPoint tp = southbound.readTerminationPoint(bridgeNode, null, portName);
+                    if (tp != null) {
+                        port = tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
+                        if (port != null) {
+                            ofPort = southbound.getOFPort(port);
+                            break;
+                        }
+                    }
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return ofPort;
+    }
+
+    private String getMacFromOptions(Node bridgeNode, String portName) {
+        String mac = null;
+        OvsdbTerminationPointAugmentation port = southbound.extractTerminationPointAugmentation(bridgeNode, portName);
+        LOG.info("getMac: portName: {}, bridgeNode: {},,, port: {}", portName, bridgeNode, port);
+        if (port != null && port.getOptions() != null) {
+            //mac = southbound.getOptionsValue(port.getOptions(), EXTERNAL_ID_VM_MAC);
+            for (Options option : port.getOptions()) {
+                LOG.info("getMac: option: {}", option);
+                if (option.getOption().equals(Constants.EXTERNAL_ID_VM_MAC)) {
+                    mac = option.getValue();
+                    break;
+                }
+            }
+        }
+        return mac;
+    }
+
+    private String getMacFromExternalIds(Node bridgeNode, String portName) {
+        String mac = null;
+        OvsdbTerminationPointAugmentation port = southbound.getTerminationPointOfBridge(bridgeNode, portName);
+        LOG.info("getMac: portName: {}, bridgeNode: {},,, port: {}", portName, bridgeNode, port);
+        if (port != null && port.getInterfaceExternalIds() != null) {
+            mac = southbound.getInterfaceExternalIdsValue(port, Constants.EXTERNAL_ID_VM_MAC);
+        }
+        return mac;
+    }
+
+    @Override
+    public void setDependencies(ServiceReference serviceReference) {
+        nodeCacheManager = (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
+        southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
+        sfcClassifierService =
+                (ISfcClassifierService) ServiceHelper.getGlobalInstance(ISfcClassifierService.class, this);
+        LOG.info("sfcClassifierService= {}", sfcClassifierService);
+    }
+}
diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/services/SfcClassifierService.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/services/SfcClassifierService.java
new file mode 100644 (file)
index 0000000..947dcec
--- /dev/null
@@ -0,0 +1,604 @@
+/*
+ * Copyright Â© 2015 Red Hat, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services;
+
+import com.google.common.collect.Lists;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.ISfcClassifierService;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
+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.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SfcClassifierService extends AbstractServiceInstance implements ConfigInterface, ISfcClassifierService {
+    private static final Logger LOG = LoggerFactory.getLogger(SfcClassifierService.class);
+    private static final short TABLE_0 = 0;
+    private static final short UDP_SHORT = 17;
+    static int cookieIndex = 0;
+
+    private enum FlowID {
+        FLOW_INGRESSCLASS(1), FLOW_SFINGRESS(2), FLOW_SFEGRESS(3), FLOW_SFARP(4),
+        FLOW_EGRESSCLASSUNUSED(5), FLOW_EGRESSCLASS(6), FLOW_EGRESSCLASSBYPASS(7), FLOW_SFCTABLE(8);
+
+        private int value;
+        FlowID(int value) {
+            this.value = value;
+        }
+
+    }
+
+    //private AtomicLong flowCookieInc = new AtomicLong(0x1L);
+    private BigInteger getCookie(FlowID flowID) {
+        String cookieString = new String().format("1110%02d%010d", flowID.value, cookieIndex++);
+                //new String().format("1100%02d00%04d", flowID.value, flowCookieInc.getAndIncrement());
+                // "1100%02000000d%04d"
+        return new BigInteger(cookieString, 16);
+    }
+
+    public SfcClassifierService(Service service) {
+        super(service);
+    }
+
+    public SfcClassifierService() {
+        super(Service.SFC_CLASSIFIER);
+    }
+
+    @Override
+    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+        super.setDependencies(bundleContext.getServiceReference(ISfcClassifierService.class.getName()), this);
+    }
+
+    @Override
+    public void setDependencies(Object impl) {}
+
+    @Override
+    public void programIngressClassifier(long dataPathId, String ruleName, Matches matches,
+                                         NshUtils nshHeader, long vxGpeOfPort, boolean write) {
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = buildMatch(matches);
+        MatchUtils.addNxRegMatch(matchBuilder,
+                MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
+        MatchUtils.addNxRegMatch(matchBuilder,
+                MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
+        flowBuilder.setMatch(matchBuilder.build());
+
+        String flowId = "sfcIngressClass_" + ruleName;// + "_" + nshHeader.getNshNsp();
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(getTable());
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_INGRESSCLASS)));
+
+        if (write) {
+            ActionBuilder ab = new ActionBuilder();
+            List<Action> actionList = new ArrayList<>();
+
+            ab.setAction(ActionUtils.nxMoveTunIdtoNshc2());
+            ab.setOrder(actionList.size());
+            ab.setKey(new ActionKey(actionList.size()));
+            actionList.add(ab.build());
+
+            getNshAction(nshHeader, actionList);
+
+            ab.setAction(ActionUtils.outputAction(FlowUtils.getNodeConnectorId(dataPathId, vxGpeOfPort)));
+            ab.setOrder(actionList.size());
+            ab.setKey(new ActionKey(actionList.size()));
+            actionList.add(ab.build());
+
+            ApplyActionsBuilder aab = new ApplyActionsBuilder();
+            aab.setAction(actionList);
+
+            InstructionBuilder ib = new InstructionBuilder();
+            ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            List<Instruction> instructions = Lists.newArrayList();
+            instructions.add(ib.build());
+
+            InstructionsBuilder isb = new InstructionsBuilder();
+            isb.setInstruction(instructions);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    @Override
+    public void programSfcTable(long dataPathId, long vxGpeOfPort, short goToTableId, boolean write) {
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
+        flowBuilder.setMatch(matchBuilder.build());
+
+        String flowId = "sfcTable_" + vxGpeOfPort;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(TABLE_0);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        flowBuilder.setPriority(1000);
+        flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFCTABLE)));
+        flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFCTABLE)));
+
+        if (write) {
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructions = Lists.newArrayList();
+            InstructionBuilder ib =
+                    InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), goToTableId);
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructions.add(ib.build());
+
+            isb.setInstruction(instructions);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    @Override
+    public void programEgressClassifier1(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+                                         int tunnelOfPort, int tunnelId, short gotoTableId, boolean write) {
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
+        MatchUtils.addNxNspMatch(matchBuilder, nsp);
+        MatchUtils.addNxNsiMatch(matchBuilder, nsi);
+        flowBuilder.setMatch(matchBuilder.build());
+
+        String flowId = "sfcEgressClass1_" + vxGpeOfPort;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(TABLE_0);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSUNUSED)));
+        flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSUNUSED)));
+
+        if (write) {
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructions = Lists.newArrayList();
+            InstructionBuilder ib = new InstructionBuilder();
+
+            /*List<Action> actionList = Lists.newArrayList();
+
+            ActionBuilder ab = new ActionBuilder();
+            ab.setAction(ActionUtils.nxMoveNshc2ToTunId());
+            ab.setOrder(0);
+            ab.setKey(new ActionKey(0));
+            actionList.add(ab.build());
+
+            ApplyActionsBuilder aab = new ApplyActionsBuilder();
+            aab.setAction(actionList);
+            ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+
+            ib.setOrder(instructions.size());
+            ib.setKey(new InstructionKey(instructions.size()));
+            instructions.add(ib.build());*/
+
+            ib = InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), getTable());
+            ib.setOrder(instructions.size());
+            ib.setKey(new InstructionKey(instructions.size()));
+            instructions.add(ib.build());
+
+            isb.setInstruction(instructions);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    @Override
+    public void programEgressClassifier(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+                                        long sfOfPort, int tunnelId, boolean write) {
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
+        MatchUtils.addNxNspMatch(matchBuilder, nsp);
+        MatchUtils.addNxNsiMatch(matchBuilder, nsi);
+        flowBuilder.setMatch(matchBuilder.build());
+
+        String flowId = "sfcEgressClass_" + nsp + "_" + + nsi + "_"  + vxGpeOfPort;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(TABLE_0);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASS)));
+        flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASS)));
+
+        if (write) {
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructions = Lists.newArrayList();
+            List<Action> actionList = Lists.newArrayList();
+
+            ActionBuilder ab = new ActionBuilder();
+
+            ab.setAction(
+                    ActionUtils.nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(FlowUtils.REG_FIELD).build(),
+                    BigInteger.valueOf(FlowUtils.REG_VALUE_FROM_LOCAL)));
+            ab.setOrder(actionList.size());
+            ab.setKey(new ActionKey(actionList.size()));
+            actionList.add(ab.build());
+
+            ab.setAction(ActionUtils.nxMoveNshc2ToTunId());
+            ab.setOrder(actionList.size());
+            ab.setKey(new ActionKey(actionList.size()));
+            actionList.add(ab.build());
+
+            ab.setAction(ActionUtils.nxResubmitAction((int)sfOfPort, TABLE_0));
+            ab.setOrder(actionList.size());
+            ab.setKey(new ActionKey(actionList.size()));
+            actionList.add(ab.build());
+
+            ApplyActionsBuilder aab = new ApplyActionsBuilder();
+            aab.setAction(actionList);
+            InstructionBuilder ib = new InstructionBuilder();
+            ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructions.add(ib.build());
+
+            isb.setInstruction(instructions);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    @Override
+    public void programEgressClassifierBypass(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+                                              long sfOfPort, int tunnelId, boolean write) {
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.createInPortMatch(matchBuilder, dataPathId, sfOfPort);
+        MatchUtils.addNxRegMatch(matchBuilder,
+                MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
+        MatchUtils.addNxNspMatch(matchBuilder, nsp);
+        MatchUtils.addNxNsiMatch(matchBuilder, nsi);
+        flowBuilder.setMatch(matchBuilder.build());
+
+        String flowId = "sfcEgressClassBypass_" + nsp + "_" + + nsi + "_"  + sfOfPort;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(TABLE_0);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSBYPASS)));
+        flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSBYPASS)));
+        flowBuilder.setPriority(40000); //Needs to be above default priority of 32768
+
+        if (write) {
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructions = Lists.newArrayList();
+
+            InstructionBuilder ib;
+            ib = this.getMutablePipelineInstructionBuilder();
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructions.add(ib.build());
+
+            isb.setInstruction(instructions);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    // packet from sf to sff that need to go out local
+    @Override
+    public void program_sfEgress(long dataPathId, int dstPort, boolean write) {
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
+        MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort);
+        MatchUtils.addNxRegMatch(matchBuilder,
+                MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
+        flowBuilder.setMatch(matchBuilder.build());
+
+        String flowId = "sfEgress_" + dstPort;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(getTable());
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFEGRESS)));
+        flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFEGRESS)));
+
+        if (write) {
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructions = Lists.newArrayList();
+            InstructionUtils.createLocalInstructions(ib, dataPathId);
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructions.add(ib.build());
+
+            isb.setInstruction(instructions);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    // looped back sff to sf packets
+    @Override
+    public void program_sfIngress(long dataPathId, int dstPort, long sfOfPort,
+                                  String ipAddress, String sfDplName, boolean write) {
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
+        Ipv4Prefix ipCidr = MatchUtils.iPv4PrefixFromIPv4Address(ipAddress);
+        MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(ipCidr));
+        MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort);
+        flowBuilder.setMatch(matchBuilder.build());
+
+        String flowId = "sfIngress_" + dstPort + "_" + ipAddress;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(TABLE_0);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFINGRESS)));
+        flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFINGRESS)));
+
+        if (write) {
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructions = Lists.newArrayList();
+            InstructionUtils.createOutputPortInstructions(ib, dataPathId, sfOfPort);
+
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructions.add(ib.build());
+
+            isb.setInstruction(instructions);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    @Override
+    public void programStaticArpEntry(long dataPathId, long ofPort, String macAddressStr,
+                                      String ipAddress, boolean write) {
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MacAddress macAddress = new MacAddress(macAddressStr);
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.createInPortReservedMatch(matchBuilder, dataPathId, OutputPortValues.LOCAL.toString());
+        MatchUtils.createEtherTypeMatch(matchBuilder, new EtherType(Constants.ARP_ETHERTYPE));
+        MatchUtils.createArpDstIpv4Match(matchBuilder, MatchUtils.iPv4PrefixFromIPv4Address(ipAddress));
+        flowBuilder.setMatch(matchBuilder.build());
+
+        String flowId = "ArpResponder_" + ipAddress;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(TABLE_0);
+        flowBuilder.setKey(key);
+        flowBuilder.setPriority(1024);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFARP)));
+        flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFARP)));
+
+        if (write == true) {
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructions = Lists.newArrayList();
+            ApplyActionsBuilder aab = new ApplyActionsBuilder();
+            ActionBuilder ab = new ActionBuilder();
+            List<Action> actionList = Lists.newArrayList();
+
+            // Move Eth Src to Eth Dst
+            ab.setAction(ActionUtils.nxMoveEthSrcToEthDstAction());
+            ab.setOrder(0);
+            ab.setKey(new ActionKey(0));
+            actionList.add(ab.build());
+
+            // Set Eth Src
+            ab.setAction(ActionUtils.setDlSrcAction(new MacAddress(macAddress)));
+            ab.setOrder(1);
+            ab.setKey(new ActionKey(1));
+            actionList.add(ab.build());
+
+            // Set ARP OP
+            ab.setAction(ActionUtils.nxLoadArpOpAction(BigInteger.valueOf(FlowUtils.ARP_OP_REPLY)));
+            ab.setOrder(2);
+            ab.setKey(new ActionKey(2));
+            actionList.add(ab.build());
+
+            // Move ARP SHA to ARP THA
+            ab.setAction(ActionUtils.nxMoveArpShaToArpThaAction());
+            ab.setOrder(3);
+            ab.setKey(new ActionKey(3));
+            actionList.add(ab.build());
+
+            // Move ARP SPA to ARP TPA
+            ab.setAction(ActionUtils.nxMoveArpSpaToArpTpaAction());
+            ab.setOrder(4);
+            ab.setKey(new ActionKey(4));
+            actionList.add(ab.build());
+
+            // Load Mac to ARP SHA
+            ab.setAction(ActionUtils.nxLoadArpShaAction(macAddress));
+            ab.setOrder(5);
+            ab.setKey(new ActionKey(5));
+            actionList.add(ab.build());
+
+            // Load IP to ARP SPA
+            ab.setAction(ActionUtils.nxLoadArpSpaAction(ipAddress));
+            ab.setOrder(6);
+            ab.setKey(new ActionKey(6));
+            actionList.add(ab.build());
+
+            // Output of InPort
+            ab.setAction(ActionUtils.outputAction(
+                    FlowUtils.getSpecialNodeConnectorId(dataPathId, OutputPortValues.INPORT.toString())));
+            ab.setOrder(7);
+            ab.setKey(new ActionKey(7));
+            actionList.add(ab.build());
+
+            // Create Apply Actions Instruction
+            aab.setAction(actionList);
+            ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructions.add(ib.build());
+
+            isb.setInstruction(instructions);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    private List<Action> getNshAction(NshUtils header, List<Action> actionList) {
+        // Build the Actions to Add the NSH Header
+        org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC1Load =
+                ActionUtils.nxLoadNshc1RegAction(header.getNshMetaC1());
+        org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC2Load =
+                ActionUtils.nxLoadNshc2RegAction(header.getNshMetaC2());
+        org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nspLoad =
+                ActionUtils.nxSetNspAction(header.getNshNsp());
+        org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nsiLoad =
+                ActionUtils.nxSetNsiAction(header.getNshNsi());
+        org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunVnid =
+                ActionUtils.nxLoadTunIdAction(BigInteger.valueOf(header.getNshNsp()), false);
+        org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunDest =
+                ActionUtils.nxLoadTunIPv4Action(header.getNshTunIpDst().getValue(), false);
+
+        int count = actionList.size();
+        actionList.add(new ActionBuilder()
+                .setKey(new ActionKey(count)).setOrder(count++).setAction(nshC1Load).build());
+        //actionList.add(new ActionBuilder()
+        // .setKey(new ActionKey(count)).setOrder(count++).setAction(nshC2Load).build());
+        actionList.add(new ActionBuilder()
+                .setKey(new ActionKey(count)).setOrder(count++).setAction(nspLoad).build());
+        actionList.add(new ActionBuilder()
+                .setKey(new ActionKey(count)).setOrder(count++).setAction(nsiLoad).build());
+        actionList.add(new ActionBuilder()
+                .setKey(new ActionKey(count)).setOrder(count++).setAction(loadChainTunDest).build());
+        actionList.add(new ActionBuilder()
+                .setKey(new ActionKey(count)).setOrder(count).setAction(loadChainTunVnid).build());
+        return actionList;
+    }
+
+    public MatchBuilder buildMatch(Matches matches) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+
+        if (matches.getAceType() instanceof AceIp) {
+            AceIp aceIp = (AceIp)matches.getAceType();
+            if (aceIp.getAceIpVersion() instanceof AceIpv4) {
+                //AceIpv4 aceIpv4 = (AceIpv4) aceIp.getAceIpVersion();
+                //MatchUtils.createSrcL3IPv4Match(matchBuilder, aceIpv4.getSourceIpv4Network());
+                //MatchUtils.createDstL3IPv4Match(matchBuilder, aceIpv4.getDestinationIpv4Network());
+                MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
+                MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(), 0,
+                        aceIp.getDestinationPortRange().getLowerPort().getValue().intValue());
+            } else {
+                MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
+                MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(), 0,
+                        aceIp.getDestinationPortRange().getLowerPort().getValue().intValue());
+            }
+        } else if (matches.getAceType() instanceof AceEth) {
+            AceEth aceEth = (AceEth) matches.getAceType();
+            MatchUtils.createEthSrcMatch(matchBuilder, new MacAddress(aceEth.getSourceMacAddress().getValue()));
+            MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(aceEth.getDestinationMacAddress().getValue()),
+                    new MacAddress(aceEth.getDestinationMacAddressMask().getValue()));
+        }
+
+        LOG.info("buildMatch: {}", matchBuilder.build());
+        return matchBuilder;
+    }
+}
index 137b77f8ae2a49aa2406a8219f7ba7b4aea0d694..34dfd96c547b3cbc0cd9c91212b70b39500754a9 100644 (file)
@@ -1,19 +1,30 @@
+/*
+ * Copyright Â© 2015 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev141210;
 
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.ovsdb.openstack.netvirt.sfc.NetvirtSfcProvider;
+import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.osgi.framework.BundleContext;
-
-public class NetvirtSfcModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev141210.AbstractNetvirtSfcModule {
 
+public class NetvirtSfcModule extends AbstractNetvirtSfcModule {
     private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcModule.class);
+    private BundleContext bundleContext;
 
-    public NetvirtSfcModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+    public NetvirtSfcModule(ModuleIdentifier identifier, DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
     }
 
-    public NetvirtSfcModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev141210.NetvirtSfcModule oldModule, java.lang.AutoCloseable oldInstance) {
+    public NetvirtSfcModule(ModuleIdentifier identifier, DependencyResolver dependencyResolver,
+                            NetvirtSfcModule oldModule, java.lang.AutoCloseable oldInstance) {
         super(identifier, dependencyResolver, oldModule, oldInstance);
     }
 
@@ -25,8 +36,13 @@ public class NetvirtSfcModule extends org.opendaylight.yang.gen.v1.urn.opendayli
     @Override
     public java.lang.AutoCloseable createInstance() {
         LOG.info("Netvirt SFC module initialization.");
-        NetvirtSfcProvider sfcProvider = new NetvirtSfcProvider();
+        NetvirtSfcProvider sfcProvider = new NetvirtSfcProvider(bundleContext);
+        sfcProvider.setOf13Provider(getOf13provider());
         getBrokerDependency().registerProvider(sfcProvider);
         return sfcProvider;
     }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
 }
index 8468b165e55c84a501f16482e6eb837ab5c15257..276a14aa20b5561f3a20ab37114fdf3c03a1b4c3 100644 (file)
@@ -1,20 +1,32 @@
 /*
-* Generated file
-*
-* Generated from: yang module name: netvirt-sfc yang module local name: netvirt-sfc
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Wed Sep 23 15:18:24 EDT 2015
-*
-* Do not modify this file unless it is present under src/main directory
-*/
+ * Copyright Â© 2015 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev141210;
 
 import org.opendaylight.controller.config.api.DependencyResolver;
-import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
-import org.opendaylight.controller.config.spi.Module;
 import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-public class NetvirtSfcModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev141210.AbstractNetvirtSfcModuleFactory {
+public class NetvirtSfcModuleFactory extends AbstractNetvirtSfcModuleFactory {
+    @Override
+    public NetvirtSfcModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+                                              BundleContext bundleContext) {
+        NetvirtSfcModule module = super.instantiateModule(instanceName, dependencyResolver, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
+
+    @Override
+    public NetvirtSfcModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+                                              NetvirtSfcModule oldModule, AutoCloseable oldInstance,
+                                              BundleContext bundleContext) {
+        NetvirtSfcModule module = super.instantiateModule(instanceName, dependencyResolver,
+                oldModule, oldInstance, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 }
index 46b6a5f8379e912ce68fb8aa9b1ca6351f8c5610..2f5d016da2cb08e2412da489d337465083113c1a 100644 (file)
@@ -30,6 +30,10 @@ module netvirt-sfc {
                     }
                 }
             }
+
+            leaf of13provider {
+                type string;
+            }
         }
     }
 }
index c5b03f0ed7eb72ee5f9d1a6f86e3639221b98531..ecc9c11f116fe42a1906e6762f2e8811fadcedac 100644 (file)
@@ -5,26 +5,42 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
+
 package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev141210;
 
+import java.util.Dictionary;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.JmxAttribute;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.PipelineOrchestrator;
 import org.opendaylight.ovsdb.openstack.netvirt.sfc.NetvirtSfcProvider;
-import org.osgi.framework.BundleContext;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 
 import javax.management.ObjectName;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13.services.SfcClassifierService;
+import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+@PrepareForTest(ServiceHelper.class)
+@RunWith(PowerMockRunner.class)
 public class NetvirtSfcModuleTest {
     @Test
     public void testCustomValidation() {
@@ -34,6 +50,7 @@ public class NetvirtSfcModuleTest {
         module.customValidation();
     }
 
+    @SuppressWarnings("unchecked")
     @Test
     public void testCreateInstance() throws Exception {
         // configure mocks
@@ -41,13 +58,33 @@ public class NetvirtSfcModuleTest {
         BindingAwareBroker broker = mock(BindingAwareBroker.class);
         ProviderContext session = mock(ProviderContext.class);
         DataBroker dataBroker = mock(DataBroker.class);
-        when(dependencyResolver.resolveInstance(eq(BindingAwareBroker.class), any(ObjectName.class), any(JmxAttribute.class))).thenReturn(broker);
+        when(dependencyResolver.resolveInstance(eq(BindingAwareBroker.class),
+                any(ObjectName.class), any(JmxAttribute.class))).thenReturn(broker);
         when(session.getSALService(eq(DataBroker.class))).thenReturn(dataBroker);
 
         // create instance of module with injected mocks
         NetvirtSfcModule module = new NetvirtSfcModule(mock(ModuleIdentifier.class), dependencyResolver);
         // getInstance calls resolveInstance to get the broker dependency and then calls createInstance
+        BundleContext bundleContext = mock(BundleContext.class);
+        PowerMockito.mockStatic(ServiceHelper.class);
+        PipelineOrchestrator pipelineOrchestrator = mock(PipelineOrchestrator.class);
+        PowerMockito.when(ServiceHelper.getGlobalInstance(eq(PipelineOrchestrator.class), any(AbstractServiceInstance.class)))
+                .thenReturn(pipelineOrchestrator);
+        PowerMockito.when(ServiceHelper.getGlobalInstance(eq(Southbound.class), any(AbstractServiceInstance.class)))
+                .thenReturn(mock(Southbound.class));
+
+        doNothing().when(pipelineOrchestrator).registerService(any(ServiceReference.class),
+                any(AbstractServiceInstance.class));
+        when(bundleContext.registerService(
+                eq(new String[]{AbstractServiceInstance.class.getName(), SfcClassifierService.class.getName()}),
+                any(),
+                any(Dictionary.class)))
+                .thenReturn(mock(ServiceRegistration.class));
+        when(bundleContext.getServiceReference(SfcClassifierService.class.getName()))
+                .thenReturn(mock(ServiceReference.class));
         AutoCloseable closeable = module.getInstance();
+        ((NetvirtSfcProvider)closeable).setBundleContext(bundleContext);
+        ((NetvirtSfcProvider)closeable).setOf13Provider("standalone");
         ((NetvirtSfcProvider)closeable).onSessionInitiated(session);
         // verify that the module registered the returned provider with the broker
         verify(broker).registerProvider((NetvirtSfcProvider)closeable);
index d8467c53487c9711d9032c9b0f47f4effefcfe1c..67b04335ea4996eb339b72c38423e5b922297b12 100644 (file)
@@ -29,7 +29,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <karaf.distro.artifactId>openstack.net-virt-sfc-karaf</karaf.distro.artifactId>
     <karaf.distro.version>${project.version}</karaf.distro.version>
     <karaf.distro.type>zip</karaf.distro.type>
-  </properties>
+   </properties>
 
   <dependencyManagement>
     <dependencies>
@@ -49,6 +49,12 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>openstack.net-virt-sfc-features-test</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.mdsal-openflow</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>utils.mdsal-utils</artifactId>
@@ -79,6 +85,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
         <groupId>org.jacoco</groupId>
         <artifactId>jacoco-maven-plugin</artifactId>
       </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <configuration>
+          <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+        </configuration>
+      </plugin>
       <plugin>
         <artifactId>maven-failsafe-plugin</artifactId>
         <configuration>
index ee023bef086a783510b9e551f4049e9d591bc011..08a1f0069560fc98dc0c3f1d555de973ea8876bb 100644 (file)
@@ -9,45 +9,92 @@
 package org.opendaylight.ovsdb.openstack.netvirt.sfc;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.ops4j.pax.exam.CoreOptions.composite;
 import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
 import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperties;
 import static org.ops4j.pax.exam.CoreOptions.vmOption;
+import static org.ops4j.pax.exam.CoreOptions.when;
+import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
+import static org.ops4j.pax.exam.MavenUtils.asInProject;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
 
+import com.google.common.collect.Maps;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.atomic.AtomicBoolean;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13.SfcClassifier;
 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.AclUtils;
 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ClassifierUtils;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionChainUtils;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionPathUtils;
 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.SfcUtils;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionForwarderUtils;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionUtils;
 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.AccessLists;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.AccessListsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.AccessListBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.AccessListEntriesBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.AccessListEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.ActionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.MatchesBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctions;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunctionBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.ServiceFunctionChains;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.ServiceFunctionChainsBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChain;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChainBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunction;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunctionBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.ServiceFunctionForwarders;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.ServiceFunctionForwardersBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPathsBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.Firewall;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.AccessLists;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.AccessListsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.AclBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.AccessListEntriesBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.AceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.ActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.MatchesBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+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.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.ClassifiersBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.ClassifierBuilder;
@@ -85,12 +132,19 @@ public class NetvirtSfcIT extends AbstractMdsalTestBase {
     private static AclUtils aclUtils = new AclUtils();
     private static ClassifierUtils classifierUtils = new ClassifierUtils();
     private static SfcUtils sfcUtils = new SfcUtils();
+    private static ServiceFunctionUtils serviceFunctionUtils = new ServiceFunctionUtils();
+    private static ServiceFunctionForwarderUtils serviceFunctionForwarderUtils = new ServiceFunctionForwarderUtils();
+    private static ServiceFunctionChainUtils serviceFunctionChainUtils = new ServiceFunctionChainUtils();
+    private static ServiceFunctionPathUtils serviceFunctionPathUtils = new ServiceFunctionPathUtils();
     private static MdsalUtils mdsalUtils;
     private static AtomicBoolean setup = new AtomicBoolean(false);
     private static SouthboundUtils southboundUtils;
     private static String addressStr;
     private static String portStr;
     private static String connectionType;
+    private static Southbound southbound;
+    private static DataBroker dataBroker;
+    public static final String CONTROLLER_IPADDRESS = "ovsdb.controller.address";
     public static final String SERVER_IPADDRESS = "ovsdbserver.ipaddress";
     public static final String SERVER_PORT = "ovsdbserver.port";
     public static final String CONNECTION_TYPE = "ovsdbserver.connection";
@@ -99,6 +153,26 @@ public class NetvirtSfcIT extends AbstractMdsalTestBase {
     public static final String DEFAULT_SERVER_PORT = "6640";
     public static final String INTEGRATION_BRIDGE_NAME = "br-int";
     private static final String NETVIRT_TOPOLOGY_ID = "netvirt:1";
+    private static final String OVSDB_TRACE = "ovsdb.trace";
+    private static final String SF1NAME = "firewall-72";
+    private static final String SF2NAME = "dpi-72";
+    private static final String SF1IP = "10.2.1.1";//"192.168.50.70";//"192.168.120.31";
+    private static final String SF2IP = "10.2.1.2";
+    private static final String SF1DPLNAME = "sf1";
+    private static final String SF2DPLNAME = "sf2";
+    private static final String SFF1IP = "127.0.0.1"; //"192.168.1.129"
+    private static final String SFF2IP = "192.168.1.129";//"127.0.0.1";
+    private static final String SFF1NAME = "SFF1";
+    private static final String SFF2NAME = "SFF2";
+    private static final String SFFDPL1NAME = "vxgpe";
+    private static final String SFFDPL2NAME = "vxgpe";
+    private static final String SN1NAME = "OVSDB1";
+    private static final String SN2NAME = "OVSDB2";
+    private static final String BRIDGE1NAME= "br-int";
+    private static final String BRIDGE2NAME= "br-int";
+    private static final String ACLNAME= "httpAcl";
+    private static final String SFCNAME = "SFC";
+    private static final int GPEPORT = 6633;
 
     @Override
     public String getModuleName() {
@@ -141,29 +215,45 @@ public class NetvirtSfcIT extends AbstractMdsalTestBase {
 
     private Option[] getOtherOptions() {
         return new Option[] {
+                wrappedBundle(
+                        mavenBundle("org.opendaylight.ovsdb", "utils.mdsal-openflow")
+                                .version(asInProject())
+                                .type("jar")),
+                configureConsole().startLocalConsole(),
                 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
-                keepRuntimeFolder()
+                        keepRuntimeFolder()
         };
     }
 
     public Option[] getPropertiesOptions() {
         return new Option[] {
-                propagateSystemProperties(SERVER_IPADDRESS, SERVER_PORT, CONNECTION_TYPE),
+                propagateSystemProperties(SERVER_IPADDRESS, SERVER_PORT, CONNECTION_TYPE,
+                        CONTROLLER_IPADDRESS, OVSDB_TRACE),
         };
     }
 
     @Override
     public Option getLoggingOption() {
         return composite(
+                when(Boolean.getBoolean(OVSDB_TRACE)).useOptions(
+                        editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+                                "log4j.logger.org.opendaylight.ovsdb",
+                                LogLevelOption.LogLevel.TRACE.name())),
+                //editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+                //        "log4j.logger.org.opendaylight.ovsdb",
+                //        LogLevelOption.LogLevel.TRACE.name()),
                 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
                         logConfiguration(NetvirtSfcIT.class),
                         LogLevel.INFO.name()),
                 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
                         "log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.sfc",
-                        LogLevel.INFO.name()),
-                /*editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
-                        "log4j.logger.org.opendaylight.ovsdb",
-                        LogLevelOption.LogLevel.TRACE.name()),*/
+                        LogLevel.TRACE.name()),
+                editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+                        "log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13",
+                        LogLevel.TRACE.name()),
+                editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+                        "log4j.logger.org.opendaylight.sfc",
+                        LogLevel.TRACE.name()),
                 super.getLoggingOption());
     }
 
@@ -185,6 +275,7 @@ public class NetvirtSfcIT extends AbstractMdsalTestBase {
                 fail(usage());
             }
         }
+        LOG.info("getProperties {}: {}", OVSDB_TRACE, props.getProperty(OVSDB_TRACE));
     }
 
     @Before
@@ -204,11 +295,13 @@ public class NetvirtSfcIT extends AbstractMdsalTestBase {
 
         getProperties();
 
-        DataBroker dataBroker = getDatabroker(getProviderContext());
+        dataBroker = getDatabroker(getProviderContext());
         mdsalUtils = new MdsalUtils(dataBroker);
         assertNotNull("mdsalUtils should not be null", mdsalUtils);
         southboundUtils = new SouthboundUtils(mdsalUtils);
         assertTrue("Did not find " + NETVIRT_TOPOLOGY_ID, getNetvirtTopology());
+        southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
+        assertNotNull("southbound should not be null", southbound);
         setup.set(true);
     }
 
@@ -271,83 +364,322 @@ public class NetvirtSfcIT extends AbstractMdsalTestBase {
         assertTrue(true);
     }
 
-    private AccessListsBuilder setAccessLists () {
-        MatchesBuilder matchesBuilder = aclUtils.createMatches(new MatchesBuilder(), 80);
-        ActionsBuilder actionsBuilder = aclUtils.createActions(new ActionsBuilder(), Boolean.TRUE);
-        AccessListEntryBuilder accessListEntryBuilder = aclUtils.createAccessListEntryBuilder(
-                new AccessListEntryBuilder(), "http", matchesBuilder, actionsBuilder);
-        AccessListEntriesBuilder accessListEntriesBuilder = aclUtils.createAccessListEntries(
-                new AccessListEntriesBuilder(), accessListEntryBuilder);
-        AccessListBuilder accessListBuilder = aclUtils.createAccessList(new AccessListBuilder(),
-                "http", accessListEntriesBuilder);
-        AccessListsBuilder accessListsBuilder = aclUtils.createAccessLists(new AccessListsBuilder(),
-                accessListBuilder);
+    private AccessListsBuilder accessListsBuilder() {
+        MatchesBuilder matchesBuilder = aclUtils.matchesBuilder(new MatchesBuilder(), 80);
+        LOG.info("Matches: {}", matchesBuilder.build());
+        //ActionsBuilder actionsBuilder = aclUtils.actionsBuilder(new ActionsBuilder(), Boolean.TRUE);
+        ActionsBuilder actionsBuilder = aclUtils.actionsBuilder(new ActionsBuilder(), SFCNAME);
+        AceBuilder accessListEntryBuilder =
+                aclUtils.aceBuilder(new AceBuilder(), "httpRule", matchesBuilder, actionsBuilder);
+        AccessListEntriesBuilder accessListEntriesBuilder =
+                aclUtils.accessListEntriesBuidler(new AccessListEntriesBuilder(), accessListEntryBuilder);
+        AclBuilder accessListBuilder =
+                aclUtils.aclBuilder(new AclBuilder(), ACLNAME, accessListEntriesBuilder);
+        AccessListsBuilder accessListsBuilder =
+                aclUtils.accesslistsbuilder(new AccessListsBuilder(), accessListBuilder);
         LOG.info("AccessLists: {}", accessListsBuilder.build());
         return accessListsBuilder;
     }
 
     @Test
-    public void testAccessLists() {
-        testModel(setAccessLists(), AccessLists.class);
+    public void testAccessLists() throws InterruptedException {
+        testModel(accessListsBuilder(), AccessLists.class, 0);
     }
 
-    private ClassifiersBuilder setClassifiers() {
-        SffBuilder sffBuilder = classifierUtils.createSff(new SffBuilder(), "sffname");
-        SffsBuilder sffsBuilder = classifierUtils.createSffs(new SffsBuilder(), sffBuilder);
-        ClassifierBuilder classifierBuilder = classifierUtils.createClassifier(new ClassifierBuilder(),
-                "classifierName", "aclName", sffsBuilder);
-        ClassifiersBuilder classifiersBuilder = classifierUtils.createClassifiers(new ClassifiersBuilder(),
+    private ClassifiersBuilder classifiersBuilder() {
+        SffBuilder sffBuilder = classifierUtils.sffBuilder(new SffBuilder(), SFF1NAME);
+        SffsBuilder sffsBuilder = classifierUtils.sffsBuilder(new SffsBuilder(), sffBuilder);
+        ClassifierBuilder classifierBuilder = classifierUtils.classifierBuilder(new ClassifierBuilder(),
+                "classifierName", ACLNAME, sffsBuilder);
+        ClassifiersBuilder classifiersBuilder = classifierUtils.ClassifiersBuilder(new ClassifiersBuilder(),
                 classifierBuilder);
         LOG.info("Classifiers: {}", classifiersBuilder.build());
         return classifiersBuilder;
     }
 
     @Test
-    public void testClassifiers() {
-        testModel(setClassifiers(), Classifiers.class);
+    public void testClassifiers() throws InterruptedException {
+        testModel(classifiersBuilder(), Classifiers.class, 0);
     }
 
-    private SfcBuilder setSfc() {
-        SfcBuilder sfcBuilder = sfcUtils.createSfc(new SfcBuilder(), "sfc");
-        return sfcBuilder;
+    private SfcBuilder netvirtSfcBuilder() {
+        return sfcUtils.sfcBuilder(new SfcBuilder(), "sfc");
     }
 
     @Test
-    public void testSfc() {
-        testModel(setSfc(), Sfc.class);
+    public void testNetvirtSfcModel() throws InterruptedException {
+        testModel(netvirtSfcBuilder(), Sfc.class, 0);
     }
 
-    private <T extends DataObject> void testModel(Builder<T> builder, Class<T> clazz) {
+    private <T extends DataObject> void testModelPut(Builder<T> builder, Class<T> clazz) {
         InstanceIdentifier<T> path = InstanceIdentifier.create(clazz);
         assertTrue(mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, path, builder.build()));
         T result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
         assertNotNull(clazz.getSimpleName() + " should not be null", result);
+    }
+
+    private <T extends DataObject> void testModelDelete(Builder<T> builder, Class<T> clazz)
+            throws InterruptedException {
+        InstanceIdentifier<T> path = InstanceIdentifier.create(clazz);
         assertTrue("Failed to remove " + clazz.getSimpleName(),
                 mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, path));
-        result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
+        result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
         assertNull(clazz.getSimpleName() + " should be null", result);
     }
 
+    private <T extends DataObject> void testModel(Builder<T> builder, Class<T> clazz, long wait)
+            throws InterruptedException {
+        testModelPut(builder, clazz);
+        Thread.sleep(wait);
+        testModelDelete(builder, clazz);
+    }
+
+    private ServiceFunctionsBuilder serviceFunctionsBuilder() {
+        String sf1Name = SF1NAME;
+        String sf1Ip = SF1IP;
+        String sff1Ip = SF1IP;
+        String sff1Name = SFF1NAME;
+        String sf1DplName = SF1DPLNAME;
+        String sn1Name = SN1NAME;
+        String bridge1Name= BRIDGE1NAME;
+        String sf2Name = SF2NAME;
+        String sf2Ip = SF2IP;
+        String sff2Ip = SF2IP;
+        String sff2Name = SFF2NAME;
+        String sf2DplName = SF2DPLNAME;
+        String sn2Name = SN2NAME;
+        String bridge2Name= BRIDGE2NAME;
+        int port = GPEPORT;
+
+        ServiceFunctionBuilder serviceFunctionBuilder =
+                serviceFunctionUtils.serviceFunctionBuilder(sf1Ip, port, sf1DplName, sff1Name, sf1Name);
+        List<ServiceFunction> serviceFunctionList = serviceFunctionUtils.list(
+                new ArrayList<ServiceFunction>(), serviceFunctionBuilder);
+
+        //serviceFunctionBuilder =
+        //        serviceFunctionUtils.serviceFunctionBuilder(sf2Ip, port, sffDpl2Name, sff2Name, sf2Name);
+        //serviceFunctionList = serviceFunctionUtils.list(
+        //        serviceFunctionList, serviceFunctionBuilder);
+
+        ServiceFunctionsBuilder serviceFunctionsBuilder =
+                serviceFunctionUtils.serviceFunctionsBuilder(new ServiceFunctionsBuilder(),
+                        serviceFunctionList);
+        LOG.info("ServiceFunctions: {}", serviceFunctionsBuilder.build());
+        return serviceFunctionsBuilder;
+    }
+
+    private ServiceFunctionForwardersBuilder serviceFunctionForwardersBuilder() {
+        String sf1Name = SF1NAME;
+        String sf1Ip = SF1IP;
+        String sff1Ip = SFF1IP;
+        String sff1Name = SFF1NAME;
+        String sffDpl1Name = SFFDPL1NAME;
+        String sn1Name = SN1NAME;
+        String bridge1Name= BRIDGE1NAME;
+        String sf2Name = SF2NAME;
+        String sf2Ip = SF2IP;
+        String sff2Ip = SFF2IP;
+        String sff2Name = SFF2NAME;
+        String sffDpl2Name = SFFDPL2NAME;
+        String sn2Name = SN2NAME;
+        String bridge2Name= BRIDGE2NAME;
+        String aclName = ACLNAME;
+        int port = GPEPORT;
+
+        ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder =
+                serviceFunctionForwarderUtils.serviceFunctionForwarderBuilder(
+                        sff1Name, sff1Ip, port, sffDpl1Name, sf1Name, sf1Ip, sn1Name, bridge1Name, Firewall.class);
+        List<ServiceFunctionForwarder>  serviceFunctionForwarderList = serviceFunctionForwarderUtils.list(
+                new ArrayList<ServiceFunctionForwarder>(), serviceFunctionForwarderBuilder);
+
+        //serviceFunctionForwarderBuilder =
+        //        serviceFunctionForwarderUtils.serviceFunctionForwarderBuilder(
+        //                sff2Name, sff2Ip, port, sffDpl2Name, sf2Name, sff2Ip, sn2Name, bridge2Name, Dpi.class);
+        //serviceFunctionForwarderList = serviceFunctionForwarderUtils.list(
+        //        serviceFunctionForwarderList, serviceFunctionForwarderBuilder);
+
+        ServiceFunctionForwardersBuilder serviceFunctionForwardersBuilder =
+                serviceFunctionForwarderUtils.serviceFunctionForwardersBuilder(
+                        new ServiceFunctionForwardersBuilder(), serviceFunctionForwarderList);
+        LOG.info("ServiceFunctionForwarders: {}", serviceFunctionForwardersBuilder.build());
+        return serviceFunctionForwardersBuilder;
+    }
+
+    private ServiceFunctionChainsBuilder serviceFunctionChainsBuilder() {
+        String sf1Name = "firewall-abstract1";
+        String sf2Name = "dpi-abstract1";
+        String sfcName = SFCNAME;
+
+        SfcServiceFunctionBuilder sfcServiceFunctionBuilder = serviceFunctionChainUtils.sfcServiceFunctionBuilder(
+                new SfcServiceFunctionBuilder(), sf1Name, Firewall.class);
+        List<SfcServiceFunction> sfcServiceFunctionList =
+                serviceFunctionChainUtils.list(new ArrayList<SfcServiceFunction>(), sfcServiceFunctionBuilder);
+
+        //sfcServiceFunctionBuilder = serviceFunctionChainUtils.sfcServiceFunctionBuilder(
+        //        sfcServiceFunctionBuilder, sf2Name, Dpi.class);
+        //sfcServiceFunctionList = serviceFunctionChainUtils.list(sfcServiceFunctionList, sfcServiceFunctionBuilder);
+
+        ServiceFunctionChainBuilder serviceFunctionChainBuilder =
+                serviceFunctionChainUtils.serviceFunctionChainBuilder(
+                        new ServiceFunctionChainBuilder(), sfcName, false, sfcServiceFunctionList);
+        ServiceFunctionChainsBuilder serviceFunctionChainsBuilder =
+                serviceFunctionChainUtils.serviceFunctionChainsBuilder(
+                        new ServiceFunctionChainsBuilder(),
+                        serviceFunctionChainUtils.list(new ArrayList<ServiceFunctionChain>(),
+                                serviceFunctionChainBuilder));
+        LOG.info("ServiceFunctionChains: {}", serviceFunctionChainBuilder.build());
+        return serviceFunctionChainsBuilder;
+    }
+
+    private ServiceFunctionPathsBuilder serviceFunctionPathsBuilder() {
+        String sfpName = "SFC-Path";
+        String sfcName = "SFC";
+        short startingIndex = 255;
+
+        ServiceFunctionPathBuilder serviceFunctionPathBuilder =
+                serviceFunctionPathUtils.serviceFunctionPathBuilder(
+                        new ServiceFunctionPathBuilder(), sfpName, sfcName, startingIndex, false);
+        ServiceFunctionPathsBuilder serviceFunctionPathsBuilder =
+                serviceFunctionPathUtils.serviceFunctionPathsBuilder(
+                        serviceFunctionPathUtils.list(new ArrayList<ServiceFunctionPath>(),
+                                serviceFunctionPathBuilder));
+        LOG.info("ServiceFunctionPaths: {}", serviceFunctionPathsBuilder.build());
+        return serviceFunctionPathsBuilder;
+    }
+
+    @Test
+    public void testSfcModel() throws InterruptedException {
+        testModel(serviceFunctionsBuilder(), ServiceFunctions.class, 3000);
+        testModel(serviceFunctionForwardersBuilder(), ServiceFunctionForwarders.class, 3000);
+        testModel(serviceFunctionChainsBuilder(), ServiceFunctionChains.class, 3000);
+        testModel(serviceFunctionPathsBuilder(), ServiceFunctionPaths.class, 3000);
+    }
+
+    @Test
+    public void testSfcModels() throws InterruptedException {
+        String bridgeName = INTEGRATION_BRIDGE_NAME;
+        ConnectionInfo connectionInfo = southboundUtils.getConnectionInfo(addressStr, portStr);
+        assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
+        Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
+        assertNotNull("node is not connected", ovsdbNode);
+
+        Thread.sleep(5000);
+        Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
+        assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
+        long datapathId = southbound.getDataPathId(bridgeNode);
+
+        Map<String, String> externalIds = Maps.newHashMap();
+        externalIds.put("attached-mac", "f6:00:00:0f:00:01");
+        southboundUtils.addTerminationPoint(bridgeNode, null, SF1DPLNAME, "internal", null, externalIds);
+        southboundUtils.addTerminationPoint(bridgeNode, null, "vm1", "internal");
+        southboundUtils.addTerminationPoint(bridgeNode, null, "vm2", "internal");
+        Map<String, String> options = Maps.newHashMap();
+        options.put("key", "flow");
+        options.put("remote_ip", "192.168.120.32");
+        southboundUtils.addTerminationPoint(bridgeNode, null, "vx", "vxlan", options, null);
+        Thread.sleep(1000);
+
+        testModelPut(serviceFunctionsBuilder(), ServiceFunctions.class);
+        testModelPut(serviceFunctionForwardersBuilder(), ServiceFunctionForwarders.class);
+        testModelPut(serviceFunctionChainsBuilder(), ServiceFunctionChains.class);
+        testModelPut(serviceFunctionPathsBuilder(), ServiceFunctionPaths.class);
+
+        Thread.sleep(5000);
+
+        testModelPut(accessListsBuilder(), AccessLists.class);
+        testModelPut(classifiersBuilder(), Classifiers.class);
+
+        Thread.sleep(10000);
+
+        ISfcClassifierService sfcClassifierService = (ISfcClassifierService) ServiceHelper.getGlobalInstance(ISfcClassifierService.class, this);
+        LOG.info("SfcClassifierService: {}", sfcClassifierService);
+        readwait();
+        //sfcClassifierService.programIngressClassifier(datapathId);
+
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
+        FlowBuilder flowBuilder = getSfcIngressClassifierFlowBuilder();
+        Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
+        assertNotNull("Could not find flow in config", flow);
+        flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
+        assertNotNull("Could not find flow in operational", flow);
+
+        assertTrue(southboundUtils.deleteBridge(connectionInfo, bridgeName));
+        Thread.sleep(1000);
+        assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
+    }
+
     /*
      * Connect to an ovsdb node. Netvirt should add br-int, add the controller address
      * and program the pipeline flows.
      */
     @Test
-    public void testDoIt() throws InterruptedException {
+    public void testNetvirtSfc() throws InterruptedException {
+        String bridgeName = INTEGRATION_BRIDGE_NAME;
         ConnectionInfo connectionInfo = southboundUtils.getConnectionInfo(addressStr, portStr);
         assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
-        assertNotNull("node is not connected", southboundUtils.getOvsdbNode(connectionInfo));
+        Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
+        assertNotNull("node is not connected", ovsdbNode);
         ControllerEntry controllerEntry;
         // Loop 10s checking if the controller was added
         for (int i = 0; i < 10; i++) {
-            Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
+            ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
             assertNotNull("ovsdb node not found", ovsdbNode);
             String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
             assertNotNull("Failed to get controller target", controllerTarget);
-            OvsdbBridgeAugmentation bridge = southboundUtils.getBridge(connectionInfo, INTEGRATION_BRIDGE_NAME);
+            OvsdbBridgeAugmentation bridge = southboundUtils.getBridge(connectionInfo, bridgeName);
+            if (bridge != null) {
+                assertNotNull("Failed to read bridge", bridge);
+                assertNotNull("Failed to extract controllerEntry", bridge.getControllerEntry());
+                controllerEntry = bridge.getControllerEntry().iterator().next();
+                assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
+                if (controllerEntry.isIsConnected()) {
+                    Assert.assertTrue("switch is not connected to the controller", controllerEntry.isIsConnected());
+                    break;
+                }
+            }
+            Thread.sleep(1000);
+        }
+
+        Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
+        assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
+        long datapathId = southbound.getDataPathId(bridgeNode);
+
+        //Thread.sleep(10000);
+
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
+        FlowBuilder flowBuilder = FlowUtils.getPipelineFlow(Service.SFC_CLASSIFIER.getTable(), (short)0);
+        Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
+        assertNotNull("Could not find flow in config", flow);
+        flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
+        assertNotNull("Could not find flow in operational", flow);
+
+        assertTrue(southboundUtils.deleteBridge(connectionInfo, bridgeName));
+        Thread.sleep(1000);
+        assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
+    }
+
+    @Ignore
+    @Test
+    public void testStandalone() throws InterruptedException {
+        String bridgeName = "sw1";
+        ConnectionInfo connectionInfo = southboundUtils.getConnectionInfo(addressStr, portStr);
+        assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
+        Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
+        assertNotNull("node is not connected", ovsdbNode);
+        String controllerTarget = "tcp:192.168.50.1:6653";
+        List<ControllerEntry> setControllerEntry = southboundUtils.createControllerEntry(controllerTarget);
+        Assert.assertTrue(southboundUtils.addBridge(connectionInfo, null, bridgeName, null, true,
+                SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
+                setControllerEntry, null, "00:00:00:00:00:00:00:01"));
+        // Loop 10s checking if the controller was added
+        for (int i = 0; i < 10; i++) {
+            ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
+            assertNotNull("ovsdb node not found", ovsdbNode);
+            assertNotNull("Failed to get controller target", controllerTarget);
+            OvsdbBridgeAugmentation bridge = southboundUtils.getBridge(connectionInfo, bridgeName);
             assertNotNull(bridge);
             assertNotNull(bridge.getControllerEntry());
-            controllerEntry = bridge.getControllerEntry().iterator().next();
+            ControllerEntry controllerEntry = bridge.getControllerEntry().iterator().next();
             assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
             if (controllerEntry.isIsConnected()) {
                 Assert.assertTrue(controllerEntry.isIsConnected());
@@ -356,13 +688,152 @@ public class NetvirtSfcIT extends AbstractMdsalTestBase {
             Thread.sleep(1000);
         }
 
-        /* TODO: add code to write to mdsal to exercise the sfc dataChangeListener */
-        /* allow some time to let the impl code do it's work to push flows */
-        /* or just comment out below lines and just manually verify on the bridges and reset them */
-        //Thread.sleep(10000);
-
+        Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
+        assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
+        long datapathId = southbound.getDataPathId(bridgeNode);
+
+        SfcClassifier sfcClassifier = new SfcClassifier(dataBroker, southbound, mdsalUtils);
+        //sfcClassifier.programLocalInPort(datapathId, "4096", (long)1, (short)0, (short)50, true);
+
+        NshUtils nshUtils = new NshUtils(new Ipv4Address("192.168.50.71"), new PortNumber(6633),
+                (long)10, (short)255, (long)4096, (long)4096);
+        MatchesBuilder matchesBuilder = aclUtils.matchesBuilder(new MatchesBuilder(), 80);
+        sfcClassifier.programSfcClassiferFlows(datapathId, (short)0, "test", matchesBuilder.build(),
+                nshUtils, (long)2, true);
+
+        nshUtils = new NshUtils(null, null, (long)10, (short)253, 0, 0);
+        //sfcClassifier.programEgressSfcClassiferFlows(datapathId, (short)0, "test", null,
+        //        nshUtils, (long)2, (long)3, true);
+
+        //try {
+        //    System.in.read();
+        //} catch (IOException e) {
+        //    e.printStackTrace();
+        //}
+
+        //NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
+        //FlowBuilder flowBuilder = getLocalInPortFlow(datapathId, "4096", (long) 1, (short) 0);
+        //Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
+        //assertNotNull("Could not find flow in config", flow);
+        //flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
+        //assertNotNull("Could not find flow in operational", flow);
+
+        MatchBuilder matchBuilder = sfcClassifier.buildMatch(matchesBuilder.build());
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
+        FlowBuilder flowBuilder = getSfcClassifierFlow(datapathId, (short) 0, "test", null,
+                nshUtils, (long) 2, matchBuilder);
+        Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
+        assertNotNull("Could not find flow in config", flow);
+        flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
+        assertNotNull("Could not find flow in operational", flow);
+
+        //nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
+        //flowBuilder = getEgressSfcClassifierFlow(datapathId, (short) 0, "test", nshUtils, (long) 2);
+        //flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
+        //assertNotNull("Could not find flow in config", flow);
+        //flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
+        //assertNotNull("Could not find flow in operational", flow);
+
+        LOG.info("***** Go look for flows *****");
+        Thread.sleep(30000);
+        assertTrue(southboundUtils.deleteBridge(connectionInfo, bridgeName));
+        Thread.sleep(1000);
         assertTrue(southboundUtils.deleteBridge(connectionInfo, INTEGRATION_BRIDGE_NAME));
         Thread.sleep(1000);
         assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
     }
+
+    private FlowBuilder getLocalInPortFlow(long dpidLong, String segmentationId, long inPort, short writeTable) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, inPort).build());
+        String flowId = "sfcIngress_" + segmentationId + "_" + inPort;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(true);
+        flowBuilder.setBarrier(false);
+        flowBuilder.setTableId(writeTable);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        return flowBuilder;
+    }
+
+    public FlowBuilder getSfcClassifierFlow(long dpidLong, short writeTable, String ruleName, Matches match,
+                                             NshUtils nshHeader, long tunnelOfPort, MatchBuilder matchBuilder) {
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        flowBuilder.setMatch(matchBuilder.build());
+
+        String flowId = "sfcClass_" + ruleName + "_" + nshHeader.getNshNsp();
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(writeTable);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        return flowBuilder;
+    }
+
+    private FlowBuilder getEgressSfcClassifierFlow(long dpidLong, short writeTable, String ruleName,
+                                                   NshUtils nshHeader, long tunnelOfPort) {
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, tunnelOfPort).build());
+        flowBuilder.setMatch(
+                MatchUtils.createTunnelIDMatch(matchBuilder, BigInteger.valueOf(nshHeader.getNshNsp())).build());
+        flowBuilder.setMatch(MatchUtils.addNxNspMatch(matchBuilder, nshHeader.getNshNsp()).build());
+        flowBuilder.setMatch(MatchUtils.addNxNsiMatch(matchBuilder, nshHeader.getNshNsi()).build());
+
+        String flowId = "egressSfcClass_" + ruleName + "_" + nshHeader.getNshNsp() + "_" + nshHeader.getNshNsi();
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(true);
+        flowBuilder.setBarrier(false);
+        flowBuilder.setTableId(writeTable);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        return flowBuilder;
+    }
+
+    private FlowBuilder getSfcIngressClassifierFlowBuilder() {
+        FlowBuilder flowBuilder = new FlowBuilder();
+        String flowId = "sfcClass_" + "httpRule";
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setTableId((short)10);
+        return flowBuilder;
+    }
+
+    private Flow getFlow (FlowBuilder flowBuilder, NodeBuilder nodeBuilder, LogicalDatastoreType store)
+            throws InterruptedException {
+        Flow flow = null;
+        for (int i = 0; i < 10; i++) {
+            flow = FlowUtils.getFlow(flowBuilder, nodeBuilder, dataBroker.newReadOnlyTransaction(), store);
+            if (flow != null) {
+                LOG.info("getFlow: flow: {}: {}", store, flow);
+                break;
+            }
+            Thread.sleep(1000);
+        }
+        return flow;
+    }
+
+    private void readwait() {
+        try {
+            System.in.read();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
 }
diff --git a/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/AbstractUtils.java b/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/AbstractUtils.java
new file mode 100644 (file)
index 0000000..5258547
--- /dev/null
@@ -0,0 +1,29 @@
+package org.opendaylight.ovsdb.openstack.netvirt.sfc.utils;
+
+import java.util.List;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.sff.data.plane.locator.DataPlaneLocatorBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.VxlanGpe;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.IpBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+import org.opendaylight.yangtools.concepts.Builder;
+
+public abstract class AbstractUtils {
+    public <T> List<T> list(List<T> list, Builder<T> builder) {
+        list.add(builder.build());
+        return list;
+    }
+
+    public IpBuilder ipBuilder(String ip, int port) {
+        return new IpBuilder()
+                .setIp(new IpAddress(ip.toCharArray()))
+                .setPort(new PortNumber(port));
+    }
+
+    public DataPlaneLocatorBuilder dataPlaneLocatorBuilder(DataPlaneLocatorBuilder dataPlaneLocatorBuilder,
+                                                           String ip, int port) {
+        return dataPlaneLocatorBuilder
+                .setLocatorType(ipBuilder(ip, port).build())
+                .setTransport(VxlanGpe.class);
+    }
+}
index ac214bb98f3717c664396f54caf3f7d463fff0f5..7657f2eee31f6ee07089e16679a761ba7d4d3544 100644 (file)
@@ -10,75 +10,78 @@ package org.opendaylight.ovsdb.openstack.netvirt.sfc.utils;
 
 import java.util.ArrayList;
 import java.util.List;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.AccessListsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.AccessList;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.AccessListBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.AccessListEntriesBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.AccessListEntry;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.AccessListEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.ActionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.MatchesBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.actions.packet.handling.PermitBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.matches.ace.type.AceIpBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.AccessListsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.Acl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.AclBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.AccessListEntriesBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.Ace;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.AceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.ActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.MatchesBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.actions.packet.handling.PermitBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4Builder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.packet.fields.rev140625.acl.transport.header.fields.DestinationPortRangeBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev150611.acl.transport.header.fields.DestinationPortRangeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.RedirectToSfc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.RedirectToSfcBuilder;
 
-public class AclUtils {
-    public MatchesBuilder createMatches (MatchesBuilder matchesBuilder, int destPort) {
+public class AclUtils extends AbstractUtils {
+    public MatchesBuilder matchesBuilder(MatchesBuilder matchesBuilder, int destPort) {
         PortNumber portNumber = new PortNumber(destPort);
-        DestinationPortRangeBuilder destinationPortRangeBuilder = new DestinationPortRangeBuilder();
-        destinationPortRangeBuilder.setLowerPort(portNumber);
-        destinationPortRangeBuilder.setUpperPort(portNumber);
+        DestinationPortRangeBuilder destinationPortRangeBuilder = new DestinationPortRangeBuilder()
+                .setLowerPort(portNumber)
+                .setUpperPort(portNumber);
 
-        AceIpBuilder aceIpBuilder = new AceIpBuilder();
-        aceIpBuilder.setDestinationPortRange(destinationPortRangeBuilder.build());
-        matchesBuilder.setAceType(aceIpBuilder.build());
+        AceIpBuilder aceIpBuilder = new AceIpBuilder()
+                .setDestinationPortRange(destinationPortRangeBuilder.build())
+                .setProtocol((short)6)
+                .setAceIpVersion(new AceIpv4Builder().build());
 
-        return matchesBuilder;
+        return matchesBuilder.setAceType(aceIpBuilder.build());
     }
 
-    public ActionsBuilder createActions (ActionsBuilder actionsBuilder, Boolean permit) {
-        PermitBuilder permitBuilder = new PermitBuilder();
-        permitBuilder.setPermit(Boolean.TRUE);
-        actionsBuilder.setPacketHandling(permitBuilder.build());
-
-        return actionsBuilder;
+    public ActionsBuilder actionsBuilder(ActionsBuilder actionsBuilder, Boolean permit) {
+        return actionsBuilder.setPacketHandling(new PermitBuilder().setPermit(permit).build());
     }
 
-    public AccessListEntryBuilder createAccessListEntryBuilder(AccessListEntryBuilder accessListEntryBuilder,
-                                                               String ruleName,
-                                                               MatchesBuilder matchesBuilder,
-                                                               ActionsBuilder actionsBuilder) {
-        accessListEntryBuilder.setRuleName(ruleName);
-        accessListEntryBuilder.setMatches(matchesBuilder.build());
-        accessListEntryBuilder.setActions(actionsBuilder.build());
+    public ActionsBuilder actionsBuilder(ActionsBuilder actionsBuilder, String sfcName) {
+        RedirectToSfcBuilder redirectToSfcBuilder = new RedirectToSfcBuilder().setSfcName(sfcName);
 
-        return accessListEntryBuilder;
+        return actionsBuilder.addAugmentation(RedirectToSfc.class, redirectToSfcBuilder.build());
     }
 
-    public AccessListEntriesBuilder createAccessListEntries(AccessListEntriesBuilder accessListEntriesBuilder,
-                                                            AccessListEntryBuilder accessListEntryBuilder) {
-        List<AccessListEntry> accessListEntriesList = new ArrayList<>();
-        accessListEntriesList.add(accessListEntryBuilder.build());
-
-        return accessListEntriesBuilder;
+    public AceBuilder aceBuilder(AceBuilder accessListEntryBuilder,
+                                 String ruleName,
+                                 MatchesBuilder matchesBuilder,
+                                 ActionsBuilder actionsBuilder) {
+        return accessListEntryBuilder
+                .setRuleName(ruleName)
+                .setMatches(matchesBuilder.build())
+                .setActions(actionsBuilder.build());
     }
 
-    public AccessListBuilder createAccessList(AccessListBuilder accessListBuilder,
-                                              String aclName,
-                                              AccessListEntriesBuilder accessListEntriesBuilder) {
-        accessListBuilder.setAclName(aclName);
-        accessListBuilder.setAccessListEntries(accessListEntriesBuilder.build());
+    public AccessListEntriesBuilder accessListEntriesBuidler(AccessListEntriesBuilder accessListEntriesBuilder,
+                                                             AceBuilder aceBuilder) {
+        List<Ace> aceList = new ArrayList<>();
+        aceList.add(aceBuilder.build());
+
+        return accessListEntriesBuilder.setAce(aceList);
+    }
 
-        return accessListBuilder;
+    public AclBuilder aclBuilder(AclBuilder aclBuilder,
+                                 String aclName,
+                                 AccessListEntriesBuilder accessListEntriesBuilder) {
+        return aclBuilder
+                .setAclName(aclName)
+                .setAccessListEntries(accessListEntriesBuilder.build());
     }
 
-    public AccessListsBuilder createAccessLists(AccessListsBuilder accessListsBuilder,
-                                                AccessListBuilder accessListBuilder) {
-        List<AccessList> accessListList = new ArrayList<>();
-        accessListList.add(accessListBuilder.build());
-        accessListsBuilder.setAccessList(accessListList);
+    public AccessListsBuilder accesslistsbuilder(AccessListsBuilder accessListsBuilder,
+                                                 AclBuilder aclBuilder) {
+        List<Acl> aclList = new ArrayList<>();
+        aclList.add(aclBuilder.build());
 
-        return accessListsBuilder;
+        return accessListsBuilder.setAcl(aclList);
     }
 }
index f99ca664cf46acb49839cdd7a84bdf8360c17349..54d31dbab720b96ac853517e539cead1c817bed1 100644 (file)
@@ -17,14 +17,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.SffBuilder;
 
-public class ClassifierUtils {
-    public SffBuilder createSff(SffBuilder sffBuilder, String sffName) {
-        sffBuilder.setName(sffName);
-
-        return sffBuilder;
+public class ClassifierUtils extends AbstractUtils {
+    public SffBuilder sffBuilder(SffBuilder sffBuilder, String sffName) {
+        return sffBuilder.setName(sffName);
     }
 
-    public SffsBuilder createSffs(SffsBuilder sffsBuilder, SffBuilder sffBuilder) {
+    public SffsBuilder sffsBuilder(SffsBuilder sffsBuilder, SffBuilder sffBuilder) {
         List<Sff> sffList = new ArrayList<>();
         sffList.add(sffBuilder.build());
         sffsBuilder.setSff(sffList);
@@ -32,17 +30,16 @@ public class ClassifierUtils {
         return sffsBuilder;
     }
 
-    public ClassifierBuilder createClassifier(ClassifierBuilder classifierBuilder,
-                                       String classifierName, String aclName,
-                                       SffsBuilder sffsBuilder) {
-        classifierBuilder.setName(classifierName);
-        classifierBuilder.setAcl(aclName);
-
-        return classifierBuilder;
+    public ClassifierBuilder classifierBuilder(ClassifierBuilder classifierBuilder,
+                                               String classifierName, String aclName,
+                                               SffsBuilder sffsBuilder) {
+        return classifierBuilder
+                .setName(classifierName)
+                .setAcl(aclName);
     }
 
-    public ClassifiersBuilder createClassifiers(ClassifiersBuilder classifiersBuilder,
-                                                ClassifierBuilder classifierBuilder) {
+    public ClassifiersBuilder ClassifiersBuilder(ClassifiersBuilder classifiersBuilder,
+                                                 ClassifierBuilder classifierBuilder) {
         List<Classifier> classifierList = new ArrayList<>();
         classifierList.add(classifierBuilder.build());
         classifiersBuilder.setClassifier(classifierList);
diff --git a/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ServiceFunctionChainUtils.java b/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ServiceFunctionChainUtils.java
new file mode 100644 (file)
index 0000000..3ad69c4
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright Â© 2015 Red Hat, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc.utils;
+
+import java.util.List;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
+
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.ServiceFunctionChainsBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChain;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChainBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunction;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunctionBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.ServiceFunctionTypeIdentity;
+
+public class ServiceFunctionChainUtils extends AbstractUtils {
+    public SfcServiceFunctionBuilder sfcServiceFunctionBuilder(SfcServiceFunctionBuilder sfcServiceFunctionBuilder,
+                                                               String name,
+                                                               Class<? extends ServiceFunctionTypeIdentity> type) {
+        return sfcServiceFunctionBuilder
+                .setName(name)
+                .setType(type);
+    }
+
+    public ServiceFunctionChainBuilder serviceFunctionChainBuilder(
+            ServiceFunctionChainBuilder serviceFunctionChainBuilder, String name, Boolean symmetric,
+            List<SfcServiceFunction> sfcServiceFunctionList) {
+
+        return serviceFunctionChainBuilder
+                .setName(SfcName.getDefaultInstance(name))
+                .setSymmetric(symmetric)
+                .setSfcServiceFunction(sfcServiceFunctionList);
+    }
+
+    public ServiceFunctionChainsBuilder serviceFunctionChainsBuilder(
+            ServiceFunctionChainsBuilder serviceFunctionChainsBuilder,
+            List<ServiceFunctionChain> serviceFunctionChainBuilderList) {
+
+        return serviceFunctionChainsBuilder.setServiceFunctionChain(serviceFunctionChainBuilderList);
+    }
+}
diff --git a/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ServiceFunctionForwarderUtils.java b/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ServiceFunctionForwarderUtils.java
new file mode 100644 (file)
index 0000000..79f3a69
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright Â© 2015 Red Hat, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffDataPlaneLocatorName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SnName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.SffOvsBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.SffOvsBridgeAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.SffOvsLocatorOptionsAugmentation;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.SffOvsLocatorOptionsAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.bridge.OvsBridgeBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.options.OvsOptionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.ServiceFunctionForwardersBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.ServiceFunctionDictionary;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.ServiceFunctionDictionaryBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.SffDataPlaneLocator;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.SffDataPlaneLocatorBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.service.function.dictionary.SffSfDataPlaneLocatorBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.sff.data.plane.locator.DataPlaneLocatorBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.ServiceFunctionTypeIdentity;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.VxlanGpe;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
+
+public class ServiceFunctionForwarderUtils extends AbstractUtils {
+    public OvsOptionsBuilder ovsOptionsBuilder(OvsOptionsBuilder ovsOptionsBuilder, int port) {
+        String flow = "flow";
+        return ovsOptionsBuilder
+                .setDstPort(String.valueOf(port))
+                .setRemoteIp(flow)
+                .setKey(flow)
+                .setNsi(flow)
+                .setNsp(flow)
+                .setNshc1(flow)
+                .setNshc2(flow)
+                .setNshc3(flow)
+                .setNshc4(flow);
+    }
+
+    public SffDataPlaneLocatorBuilder sffDataPlaneLocatorBuilder(SffDataPlaneLocatorBuilder sffDataPlaneLocatorBuilder,
+                                                                 DataPlaneLocatorBuilder dataPlaneLocatorBuilder,
+                                                                 String dplName) {
+        SffOvsLocatorOptionsAugmentationBuilder sffOvsLocatorOptionsAugmentationBuilder =
+                new SffOvsLocatorOptionsAugmentationBuilder();
+        sffOvsLocatorOptionsAugmentationBuilder.setOvsOptions(
+                ovsOptionsBuilder(new OvsOptionsBuilder(), 6633).build());
+
+        return sffDataPlaneLocatorBuilder
+                .setName(new SffDataPlaneLocatorName(dplName))
+                .setDataPlaneLocator(dataPlaneLocatorBuilder.build())
+                .addAugmentation(SffOvsLocatorOptionsAugmentation.class,
+                        sffOvsLocatorOptionsAugmentationBuilder.build());
+    }
+
+    public SffSfDataPlaneLocatorBuilder sffSfDataPlaneLocatorBuilder(
+            SffSfDataPlaneLocatorBuilder sffSfDataPlaneLocatorBuilder, String ip, int port) {
+        return sffSfDataPlaneLocatorBuilder
+                .setLocatorType(ipBuilder(ip, port).build())
+                .setTransport(VxlanGpe.class);
+    }
+
+    public ServiceFunctionDictionaryBuilder serviceFunctionDictionaryBuilder(
+            ServiceFunctionDictionaryBuilder serviceFunctionDictionaryBuilder,
+            String sfName, Class<? extends ServiceFunctionTypeIdentity> type,
+            SffSfDataPlaneLocatorBuilder sffSfDataPlaneLocatorBuilder) {
+
+        return serviceFunctionDictionaryBuilder
+                .setName(new SfName(sfName))
+                .setType(type)
+                .setSffSfDataPlaneLocator(sffSfDataPlaneLocatorBuilder.build());
+    }
+
+    public OvsBridgeBuilder ovsBridgeBuilder(OvsBridgeBuilder ovsBridgeBuilder, String bridgeNme) {
+        return ovsBridgeBuilder.setBridgeName(bridgeNme);
+    }
+
+    public ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder(
+            ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder,
+            String sffName, String serviceNodeName, String bridgeName,
+            List<SffDataPlaneLocator> sffDataPlaneLocatorList,
+            List<ServiceFunctionDictionary> serviceFunctionDictionaryList) {
+
+        SffOvsBridgeAugmentationBuilder sffOvsBridgeAugmentationBuilder = new SffOvsBridgeAugmentationBuilder();
+        sffOvsBridgeAugmentationBuilder.setOvsBridge(ovsBridgeBuilder(new OvsBridgeBuilder(), bridgeName).build());
+
+        return serviceFunctionForwarderBuilder
+                .setName(new SffName(sffName))
+                .setServiceNode(new SnName(serviceNodeName))
+                .setServiceFunctionDictionary(serviceFunctionDictionaryList)
+                .setSffDataPlaneLocator(sffDataPlaneLocatorList)
+                .addAugmentation(SffOvsBridgeAugmentation.class, sffOvsBridgeAugmentationBuilder.build());
+    }
+
+    public ServiceFunctionForwardersBuilder serviceFunctionForwardersBuilder(
+            ServiceFunctionForwardersBuilder serviceFunctionForwardersBuilder,
+            List<ServiceFunctionForwarder> serviceFunctionForwarderList) {
+        return serviceFunctionForwardersBuilder.setServiceFunctionForwarder(serviceFunctionForwarderList);
+    }
+
+    public ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder(
+            String sffName, String sffIp, int port, String sffDplName,
+            String sfName, String sfIp, String snName, String bridgeName,
+            Class<? extends ServiceFunctionTypeIdentity> type) {
+
+        DataPlaneLocatorBuilder dataPlaneLocatorBuilder =
+                dataPlaneLocatorBuilder(new DataPlaneLocatorBuilder(), sffIp, port);
+        SffDataPlaneLocatorBuilder sffDataPlaneLocatorBuilder =
+                sffDataPlaneLocatorBuilder( new SffDataPlaneLocatorBuilder(), dataPlaneLocatorBuilder, sffDplName);
+        List<SffDataPlaneLocator> sffDataPlaneLocatorList =
+                list(new ArrayList<SffDataPlaneLocator>(), sffDataPlaneLocatorBuilder);
+
+        SffSfDataPlaneLocatorBuilder sffSfDataPlaneLocatorBuilder =
+                sffSfDataPlaneLocatorBuilder(new SffSfDataPlaneLocatorBuilder(), sffIp, port);
+        ServiceFunctionDictionaryBuilder serviceFunctionDictionaryBuilder =
+                serviceFunctionDictionaryBuilder(new ServiceFunctionDictionaryBuilder(), sfName, type,
+                        sffSfDataPlaneLocatorBuilder);
+        List<ServiceFunctionDictionary> serviceFunctionDictionaryList =
+                list(new ArrayList<ServiceFunctionDictionary>(), serviceFunctionDictionaryBuilder);
+
+        ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder =
+                serviceFunctionForwarderBuilder(
+                        new ServiceFunctionForwarderBuilder(), sffName, snName, bridgeName,
+                        sffDataPlaneLocatorList, serviceFunctionDictionaryList);
+        return serviceFunctionForwarderBuilder;
+    }
+}
diff --git a/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ServiceFunctionPathUtils.java b/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ServiceFunctionPathUtils.java
new file mode 100644 (file)
index 0000000..4f9dfd9
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright Â© 2015 Red Hat, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc.utils;
+
+import java.util.List;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfpName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPathsBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathBuilder;
+
+public class ServiceFunctionPathUtils extends AbstractUtils {
+    public ServiceFunctionPathBuilder serviceFunctionPathBuilder(
+            ServiceFunctionPathBuilder serviceFunctionPathBuilder,
+            String sfpName, String sfcName, short startingIndex, Boolean symmetric) {
+
+        return serviceFunctionPathBuilder
+                .setSymmetric(symmetric)
+                .setName(SfpName.getDefaultInstance(sfpName))
+                .setServiceChainName(SfcName.getDefaultInstance(sfcName))
+                .setStartingIndex(startingIndex);
+    }
+
+    public ServiceFunctionPathsBuilder serviceFunctionPathsBuilder(
+            List<ServiceFunctionPath> serviceFunctionPathList) {
+
+        return new ServiceFunctionPathsBuilder().setServiceFunctionPath(serviceFunctionPathList);
+    }
+}
diff --git a/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ServiceFunctionUtils.java b/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ServiceFunctionUtils.java
new file mode 100644 (file)
index 0000000..39f3838
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright Â© 2015 Red Hat, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfDataPlaneLocatorName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.function.entry.SfDataPlaneLocator;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.function.entry.SfDataPlaneLocatorBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunctionBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.Firewall;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.ServiceFunctionTypeIdentity;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.VxlanGpe;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+
+public class ServiceFunctionUtils extends AbstractUtils {
+    public SfDataPlaneLocatorBuilder sfDataPlaneLocatorBuilder(SfDataPlaneLocatorBuilder sfDataPlaneLocatorBuilder,
+                                                               String ip, int port, String dplName, String sffName) {
+        return sfDataPlaneLocatorBuilder
+                .setLocatorType(ipBuilder(ip, port).build())
+                .setName(new SfDataPlaneLocatorName(dplName))
+                .setTransport(VxlanGpe.class)
+                .setServiceFunctionForwarder(new SffName(sffName));
+    }
+
+    public ServiceFunctionBuilder serviceFunctionBuilder(ServiceFunctionBuilder serviceFunctionBuilder,
+                                                         String ip, String sfName,
+                                                         List<SfDataPlaneLocator> sfDataPlaneLocatorList,
+                                                         Class<? extends ServiceFunctionTypeIdentity> type) {
+        return serviceFunctionBuilder
+                .setSfDataPlaneLocator(sfDataPlaneLocatorList)
+                .setName(new SfName(sfName))
+                .setIpMgmtAddress(new IpAddress(ip.toCharArray()))
+                .setType(type)
+                .setNshAware(true);
+    }
+
+    public ServiceFunctionsBuilder serviceFunctionsBuilder(ServiceFunctionsBuilder serviceFunctionsBuilder,
+                                                           List<ServiceFunction> serviceFunctionList) {
+        return serviceFunctionsBuilder.setServiceFunction(serviceFunctionList);
+    }
+
+    public ServiceFunctionBuilder serviceFunctionBuilder(String sfIp, int port, String sf1DplName,
+                                                         String sffname, String sfName) {
+        SfDataPlaneLocatorBuilder sfDataPlaneLocator =
+                sfDataPlaneLocatorBuilder(new SfDataPlaneLocatorBuilder(), sfIp, port, sf1DplName, sffname);
+        List<SfDataPlaneLocator> sfDataPlaneLocatorList =
+                list(new ArrayList<SfDataPlaneLocator>(), sfDataPlaneLocator);
+        return serviceFunctionBuilder(
+                new ServiceFunctionBuilder(), sfIp, sfName, sfDataPlaneLocatorList, Firewall.class);
+    }
+
+
+}
index 99fd35e1ce250723968dfa3e3776c48ebf24f4da..5b24ef437a6e73ed5bf2c4ae513e688d99fefba0 100644 (file)
@@ -11,9 +11,7 @@ package org.opendaylight.ovsdb.openstack.netvirt.sfc.utils;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.SfcBuilder;
 
 public class SfcUtils {
-    public SfcBuilder createSfc(SfcBuilder sfcBuilder, String sfcName) {
-        sfcBuilder.setName(sfcName);
-
-        return sfcBuilder;
+    public SfcBuilder sfcBuilder(SfcBuilder sfcBuilder, String sfcName) {
+        return sfcBuilder.setName(sfcName);
     }
 }
index 3b5584c3e3002a12c2ac69dcedb248d3b60636c4..fdc004d35affc3a121e9e4560908bf64394394bd 100644 (file)
@@ -120,6 +120,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>utils.servicehelper</artifactId>
       <version>${ovsdb.utils.servicehelper.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.mdsal-utils</artifactId>
+      <version>${project.version}</version>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yang-common</artifactId>
index e37b853b83d41b4a4dcd60e37fca71910ea89441..ee392fbea3950f98c0092b6ea785c5efd98890dd 100644 (file)
@@ -16,7 +16,44 @@ import java.util.List;
 import org.apache.commons.lang3.tuple.Pair;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.ovsdb.openstack.netvirt.translator.*;
+import org.opendaylight.ovsdb.openstack.netvirt.api.ArpProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
+import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+import org.opendaylight.ovsdb.openstack.netvirt.api.EgressAclProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
+import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolver;
+import org.opendaylight.ovsdb.openstack.netvirt.api.InboundNatProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.L3ForwardingProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.MultiTenantAwareRouter;
+import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProviderManager;
+import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheListener;
+import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
+import org.opendaylight.ovsdb.openstack.netvirt.api.OutboundNatProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbInventoryListener;
+import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbInventoryService;
+import org.opendaylight.ovsdb.openstack.netvirt.api.RoutingProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityGroupCacheManger;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
+import org.opendaylight.ovsdb.openstack.netvirt.api.VlanConfigurationCache;
+import org.opendaylight.ovsdb.openstack.netvirt.impl.BridgeConfigurationManagerImpl;
+import org.opendaylight.ovsdb.openstack.netvirt.impl.ConfigurationServiceImpl;
+import org.opendaylight.ovsdb.openstack.netvirt.impl.EventDispatcherImpl;
+import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
+import org.opendaylight.ovsdb.openstack.netvirt.impl.NodeCacheManagerImpl;
+import org.opendaylight.ovsdb.openstack.netvirt.impl.OpenstackRouter;
+import org.opendaylight.ovsdb.openstack.netvirt.impl.OvsdbInventoryServiceImpl;
+import org.opendaylight.ovsdb.openstack.netvirt.impl.ProviderNetworkManagerImpl;
+import org.opendaylight.ovsdb.openstack.netvirt.impl.SecurityGroupCacheManagerImpl;
+import org.opendaylight.ovsdb.openstack.netvirt.impl.SecurityServicesImpl;
+import org.opendaylight.ovsdb.openstack.netvirt.impl.SouthboundImpl;
+import org.opendaylight.ovsdb.openstack.netvirt.impl.TenantNetworkManagerImpl;
+import org.opendaylight.ovsdb.openstack.netvirt.impl.VlanConfigurationCacheImpl;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronFloatingIPCRUD;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronLoadBalancerCRUD;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronLoadBalancerPoolCRUD;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronNetworkCRUD;
@@ -50,8 +87,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronRouter
 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSecurityGroupAware;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSecurityRuleAware;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSubnetAware;
-import org.opendaylight.ovsdb.openstack.netvirt.api.*;
-import org.opendaylight.ovsdb.openstack.netvirt.impl.*;
+import org.opendaylight.ovsdb.utils.mdsal.utils.NeutronModelsDataStoreHelper;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -62,7 +98,7 @@ import org.slf4j.LoggerFactory;
 
 public class ConfigActivator implements BundleActivator {
     private static final Logger LOG = LoggerFactory.getLogger(ConfigActivator.class);
-    private List<ServiceRegistration<?>> translatorCRUDRegistrations = new ArrayList<ServiceRegistration<?>>();
+    private List<ServiceRegistration<?>> translatorCRUDRegistrations = new ArrayList<>();
     private List<Pair<Object, ServiceRegistration>> servicesAndRegistrations = new ArrayList<>();
     private ProviderContext providerContext;
 
@@ -136,6 +172,13 @@ public class ConfigActivator implements BundleActivator {
         registerService(context,
                 new String[]{SecurityServicesManager.class.getName()}, null, securityServices);
 
+        final SecurityGroupCacheManger securityGroupCacheManger = new SecurityGroupCacheManagerImpl();
+        registerService(context,
+                        new String[]{SecurityGroupCacheManger.class.getName()}, null, securityGroupCacheManger);
+
+        registerService(context,
+                new String[]{SecurityServicesManager.class.getName()}, null, securityServices);
+
         FWaasHandler fWaasHandler = new FWaasHandler();
         registerAbstractHandlerService(context,
                 new Class[] {INeutronFirewallAware.class, INeutronFirewallRuleAware.class, INeutronFirewallPolicyAware.class},
@@ -149,7 +192,8 @@ public class ConfigActivator implements BundleActivator {
         registerService(context,
                 new String[]{EventDispatcher.class.getName()}, null, eventDispatcher);
 
-        final NeutronL3Adapter neutronL3Adapter = new NeutronL3Adapter();
+        final NeutronL3Adapter neutronL3Adapter = new NeutronL3Adapter(
+                new NeutronModelsDataStoreHelper(this.providerContext.getSALService(DataBroker.class)));
         registerService(context,
                 new String[]{NeutronL3Adapter.class.getName()}, null, neutronL3Adapter);
 
@@ -194,6 +238,7 @@ public class ConfigActivator implements BundleActivator {
                 securityServices, neutronL3Adapter);
         trackService(context, INeutronPortCRUD.class, tenantNetworkManager, lBaaSHandler, lBaaSPoolHandler,
                 lBaaSPoolMemberHandler, securityServices, neutronL3Adapter);
+        trackService(context, INeutronFloatingIPCRUD.class, neutronL3Adapter);
         trackService(context, INeutronLoadBalancerCRUD.class, lBaaSHandler, lBaaSPoolHandler, lBaaSPoolMemberHandler);
         trackService(context, INeutronLoadBalancerPoolCRUD.class, lBaaSHandler, lBaaSPoolMemberHandler);
         trackService(context, LoadBalancerProvider.class, lBaaSHandler, lBaaSPoolHandler, lBaaSPoolMemberHandler);
@@ -263,15 +308,9 @@ public class ConfigActivator implements BundleActivator {
 
     @Override
     public void stop(BundleContext context) throws Exception {
-        LOG.info("Stop Translator CRUD service provides");
+        LOG.info("ConfigActivator stop");
         // ServiceTrackers and services are already released when bundle stops,
         // so we don't need to close the trackers or unregister the services
-        for (ServiceRegistration registration : translatorCRUDRegistrations) {
-            if (registration != null) {
-                registration.unregister();
-            }
-        }
-
     }
 
     private ServiceRegistration<?> registerService(BundleContext bundleContext, String[] interfaces,
index 87fc3e0c2f47f2caa8745fd9a49ef7e7c72d6410..28cc30f9b02d50a094a03508c8a0e087e0db6dd6 100644 (file)
@@ -58,6 +58,7 @@ public class MdsalHelper {
     public static final String OVSDB_URI_PREFIX = "ovsdb";
     public static final String BRIDGE_URI_PREFIX = "bridge";
     public static final String TP_URI_PREFIX = "termination-point";
+    public static final String DISABLE_IN_BAND = "disable-in-band";
 
     public static final ImmutableBiMap<Class<? extends OvsdbBridgeProtocolBase>,String> OVSDB_PROTOCOL_MAP
             = new ImmutableBiMap.Builder<Class<? extends OvsdbBridgeProtocolBase>,String>()
index ecd89ff1ddf2be9e86a384757f2589eca6458883..43c637c88087cf5e17d06249f009b006b182ecd7 100644 (file)
@@ -31,6 +31,7 @@ public class NetvirtProvider implements BindingAwareProvider, AutoCloseable {
 
     @Override
     public void close() throws Exception {
+        LOG.info("NetvirtProvider closed");
         activator.stop(bundleContext);
     }
 
index f6c2342558c9ed3d2d064feaa887a370c208e651..c0e48e37f5be97139d4400c8832217983381368f 100755 (executable)
@@ -17,7 +17,6 @@ import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD
 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSubnetCRUD;
 
 import java.util.AbstractMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -36,19 +35,11 @@ public class NeutronCacheUtils {
             return null;
         }
 
-        List<Neutron_IPs> fixedIPs;
-        Iterator<Neutron_IPs> fixedIPIterator;
-        Neutron_IPs ip;
-
         List<NeutronPort> allPorts = neutronPortsCache.getAllPorts();
-        Iterator<NeutronPort> i = allPorts.iterator();
-        while (i.hasNext()) {
-            NeutronPort port = i.next();
-            fixedIPs = port.getFixedIPs();
-            if (fixedIPs != null && fixedIPs.size() > 0) {
-                fixedIPIterator = fixedIPs.iterator();
-                while (fixedIPIterator.hasNext()) {
-                    ip = fixedIPIterator.next();
+        for (NeutronPort port : allPorts) {
+            List<Neutron_IPs> fixedIPs = port.getFixedIPs();
+            if (fixedIPs != null && !fixedIPs.isEmpty()) {
+                for (Neutron_IPs ip : fixedIPs) {
                     if (ip.getIpAddress().equals(ipAddr) && ip.getSubnetUUID().equals(subnetID)) {
                         return port.getMacAddress();
                     }
@@ -87,9 +78,8 @@ public class NeutronCacheUtils {
         List<NeutronNetwork> allNetworks = neutronNetworkCache.getAllNetworks();
         for (NeutronNetwork network: allNetworks) {
             if (network.getID().equals(networkID)) {
-                Map.Entry<String,String> entry = new AbstractMap.SimpleEntry<String, String>(
+                return new AbstractMap.SimpleEntry<>(
                         network.getProviderNetworkType(), network.getProviderSegmentationID());
-                return entry;
             }
         }
         return null;
index 209e292b0aa49dd2ca75fa9ad06d3f82db0415fc..88a9ebc073f14198d13633c1ee3d096644c1bca8 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter_Interface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSubnet;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 
@@ -30,6 +31,7 @@ public class NorthboundEvent extends AbstractEvent {
     private NeutronLoadBalancer loadBalancer;
     private NeutronLoadBalancerPool loadBalancerPool;
     private NeutronLoadBalancerPoolMember loadBalancerPoolMember;
+    private NeutronSecurityRule neutronSecurityRule;
 
     NorthboundEvent(NeutronPort port, Action action) {
         super(HandlerType.NEUTRON_PORT, action);
@@ -77,6 +79,11 @@ public class NorthboundEvent extends AbstractEvent {
         this.loadBalancerPoolMember = loadBalancerPoolMember;
     }
 
+    NorthboundEvent(NeutronSecurityRule neutronSecurityRule, Action action) {
+        super(HandlerType.NEUTRON_PORT_SECURITY, action);
+        this.neutronSecurityRule = neutronSecurityRule;
+    }
+
     public NeutronPort getPort() {
         return port;
     }
@@ -104,6 +111,9 @@ public class NorthboundEvent extends AbstractEvent {
     public NeutronLoadBalancerPoolMember getLoadBalancerPoolMember() {
         return loadBalancerPoolMember;
     }
+    public NeutronSecurityRule getNeutronSecurityRule() {
+        return neutronSecurityRule;
+    }
 
     @Override
     public String toString() {
@@ -118,6 +128,7 @@ public class NorthboundEvent extends AbstractEvent {
                + ", loadBalancer=" + loadBalancer
                + ", loadBalancerPool=" + loadBalancerPool
                + ", loadBalancerPoolMember=" + loadBalancerPoolMember
+               + ", neutronsecurityRule=" + neutronSecurityRule
                + "]";
     }
 
@@ -131,6 +142,7 @@ public class NorthboundEvent extends AbstractEvent {
         result = prime * result + ((routerInterface == null) ? 0 : routerInterface.hashCode());
         result = prime * result + ((neutronFloatingIP == null) ? 0 : neutronFloatingIP.hashCode());
         result = prime * result + ((neutronNetwork == null) ? 0 : neutronNetwork.hashCode());
+        result = prime * result + ((neutronSecurityRule == null) ? 0 : neutronSecurityRule.hashCode());
         return result;
     }
 
@@ -212,6 +224,13 @@ public class NorthboundEvent extends AbstractEvent {
         } else if (!loadBalancerPoolMember.equals(other.loadBalancerPoolMember)) {
             return false;
         }
+        if (neutronSecurityRule == null) {
+            if (other.neutronSecurityRule != null) {
+                return false;
+            }
+        } else if (!neutronSecurityRule.equals(other.neutronSecurityRule)) {
+            return false;
+        }
         return true;
     }
 }
index e6568000a947c14e8433c990d6355035a76c0bf5..646693cd263950310ad51f608b252d49f9366816 100644 (file)
@@ -9,12 +9,19 @@
 package org.opendaylight.ovsdb.openstack.netvirt;
 
 import java.net.HttpURLConnection;
+import java.util.ArrayList;
+import java.util.List;
 
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSecurityGroupAware;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSecurityRuleAware;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
@@ -27,6 +34,8 @@ public class PortSecurityHandler extends AbstractHandler
         implements INeutronSecurityGroupAware, INeutronSecurityRuleAware, ConfigInterface {
 
     private static final Logger LOG = LoggerFactory.getLogger(PortSecurityHandler.class);
+    private volatile INeutronPortCRUD neutronPortCache;
+    private volatile SecurityServicesManager securityServicesManager;
 
     @Override
     public int canCreateNeutronSecurityGroup(NeutronSecurityGroup neutronSecurityGroup) {
@@ -80,10 +89,7 @@ public class PortSecurityHandler extends AbstractHandler
 
     @Override
     public void neutronSecurityRuleCreated(NeutronSecurityRule neutronSecurityRule) {
-        int result = canCreateNeutronSecurityRule(neutronSecurityRule);
-        if (result != HttpURLConnection.HTTP_CREATED) {
-            LOG.debug("Neutron Security Group creation failed {} ", result);
-        }
+        enqueueEvent(new NorthboundEvent(neutronSecurityRule, Action.ADD));
     }
 
     @Override
@@ -103,10 +109,7 @@ public class PortSecurityHandler extends AbstractHandler
 
     @Override
     public void neutronSecurityRuleDeleted(NeutronSecurityRule neutronSecurityRule) {
-        int result = canDeleteNeutronSecurityRule(neutronSecurityRule);
-        if  (result != HttpURLConnection.HTTP_OK) {
-            LOG.error(" delete Neutron Security Rule validation failed for result - {} ", result);
-        }
+        enqueueEvent(new NorthboundEvent(neutronSecurityRule, Action.DELETE));
     }
 
     /**
@@ -123,19 +126,71 @@ public class PortSecurityHandler extends AbstractHandler
         }
         NorthboundEvent ev = (NorthboundEvent) abstractEvent;
         switch (ev.getAction()) {
-            // TODO: add handling of events here, once callbacks do something
-            //       other than logging.
+            case ADD:
+                processNeutronSecurityRuleAdded(ev.getNeutronSecurityRule());
+                break;
+            case DELETE:
+                processNeutronSecurityRuleDeleted(ev.getNeutronSecurityRule());
+                break;
             default:
                 LOG.warn("Unable to process event action {}", ev.getAction());
                 break;
         }
     }
 
+    private void processNeutronSecurityRuleAdded(NeutronSecurityRule neutronSecurityRule) {
+        List<NeutronPort> portList = getPortWithSecurityGroup(neutronSecurityRule.getSecurityRuleGroupID());
+        for (NeutronPort port:portList) {
+            syncSecurityGroup(neutronSecurityRule,port,neutronSecurityRule.getSecurityRuleGroupID(),true);
+        }
+    }
+
+    private void processNeutronSecurityRuleDeleted(NeutronSecurityRule neutronSecurityRule) {
+        List<NeutronPort> portList = getPortWithSecurityGroup(neutronSecurityRule.getSecurityRuleGroupID());
+        for (NeutronPort port:portList) {
+            syncSecurityGroup(neutronSecurityRule,port,neutronSecurityRule.getSecurityRuleGroupID(),false);
+        }
+    }
+
+    private void syncSecurityGroup(NeutronSecurityRule  securityRule,NeutronPort port,
+                                   String neutronSecurityGroupId,boolean write) {
+
+        if (null != securityRule.getSecurityRemoteGroupID()) {
+            List<Neutron_IPs> vmIpList  = securityServicesManager
+                    .getVmListForSecurityGroup(port.getID(), neutronSecurityGroupId);
+            for (Neutron_IPs vmIp :vmIpList ) {
+                securityServicesManager.syncSecurityRule(port, securityRule, vmIp, write);
+            }
+        } else {
+            securityServicesManager.syncSecurityRule(port, securityRule, null, write);
+        }
+    }
+
+    private List<NeutronPort> getPortWithSecurityGroup(String securityGroupUuid) {
+
+        List<NeutronPort> neutronPortList = neutronPortCache.getAllPorts();
+        List<NeutronPort> neutronPortInSG = new ArrayList<NeutronPort>();
+        for (NeutronPort neutronPort:neutronPortList) {
+            List<NeutronSecurityGroup> securityGroupList = neutronPort.getSecurityGroups();
+            for (NeutronSecurityGroup neutronSecurityGroup:securityGroupList) {
+                if (neutronSecurityGroup.getID().equals(securityGroupUuid)) {
+                    neutronPortInSG.add(neutronPort);
+                    break;
+                }
+            }
+        }
+        return neutronPortInSG;
+    }
+
     @Override
     public void setDependencies(ServiceReference serviceReference) {
         eventDispatcher =
                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
         eventDispatcher.eventHandlerAdded(serviceReference, this);
+        neutronPortCache =
+                (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, this);
+        securityServicesManager =
+                (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
     }
 
     @Override
index 7438ce28c981656a096bf02bad1bf41ea659f266..069fd6c24dcc967a41a259bfed8efbd15b8b4c05 100644 (file)
@@ -8,32 +8,47 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.api;
 
-import java.util.List;
-
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
 
+import java.util.List;
+
 /**
  *  This interface allows egress Port Security flows to be written to devices.
  */
 public interface EgressAclProvider {
 
     /**
-     * Program port security ACL.
+     * Program port security Group.
      *
      * @param dpid the dpid
      * @param segmentationId the segmentation id
      * @param attachedMac the attached mac
      * @param localPort the local port
      * @param securityGroup the security group
-     * @param srcAddressList the src address associated with the vm port
+     * @param portUuid the uuid of the port.
      * @param write  is this flow write or delete
      */
-    void programPortSecurityAcl(Long dpid, String segmentationId, String attachedMac,
+    void programPortSecurityGroup(Long dpid, String segmentationId, String attachedMac,
                                        long localPort, NeutronSecurityGroup securityGroup,
-                                       List<Neutron_IPs> srcAddressList, boolean write);
+                                       String portUuid, boolean write);
+    /**
+     * Program port security rule.
+     *
+     * @param dpid the dpid
+     * @param segmentationId the segmentation id
+     * @param attachedMac the attached mac
+     * @param localPort the local port
+     * @param portSecurityRule the security rule
+     * @param vmIp the ip of the remote vm if it has a remote security group.
+     * @param write  is this flow write or delete
+     */
+    public void programPortSecurityRule(Long dpid, String segmentationId, String attachedMac,
+                                        long localPort, NeutronSecurityRule portSecurityRule,
+                                        Neutron_IPs vmIp, boolean write) ;
     /**
-     *  Program fixed egress ACL rules that will be associated with the VM port when a vm is spawned.
+     *  Program fixed egress security group rules that will be associated with the VM port when a vm is spawned.
      *
      * @param dpid the dpid
      * @param segmentationId the segmentation id
@@ -44,7 +59,7 @@ public interface EgressAclProvider {
      * @param isComputePort indicates whether this port is a compute port or not
      * @param write is this flow writing or deleting
      */
-    void programFixedSecurityAcl(Long dpid, String segmentationId,String attachedMac, long localPort,
+    void programFixedSecurityGroup(Long dpid, String segmentationId,String attachedMac, long localPort,
                                   List<Neutron_IPs> srcAddressList, boolean isLastPortinBridge,
                                   boolean isComputePort, boolean write);
 }
\ No newline at end of file
index 5810f95d3860c7e2ff77adb2320dd4d33ca308cb..6121adaf1b7e48d9608996f902e1572b8c9ee6a3 100644 (file)
@@ -8,9 +8,8 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.api;
 
-import java.util.List;
-
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
 
 /**
@@ -19,19 +18,33 @@ import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
 public interface IngressAclProvider {
 
     /**
-     * Program port security ACL.
+     * Program port security Group.
      *
      * @param dpid the dpid
      * @param segmentationId the segmentation id
      * @param attachedMac the attached mac
      * @param localPort the local port
      * @param securityGroup the security group
-     * @param srcAddressList the src address associated with the vm port
+     * @param portUuid the uuid of the port.
      * @param write  is this flow write or delete
      */
-    void programPortSecurityAcl(Long dpid, String segmentationId, String attachedMac,
+    void programPortSecurityGroup(Long dpid, String segmentationId, String attachedMac,
                                        long localPort, NeutronSecurityGroup securityGroup,
-                                       List<Neutron_IPs> srcAddressList, boolean write);
+                                       String portUuid, boolean write);
+    /**
+     * Program port security rule.
+     *
+     * @param dpid the dpid
+     * @param segmentationId the segmentation id
+     * @param attachedMac the attached mac
+     * @param localPort the local port
+     * @param portSecurityRule the security rule
+     * @param vmIp the ip of the remote vm if it has a remote security group.
+     * @param write  is this flow write or delete
+     */
+    void programPortSecurityRule(Long dpid, String segmentationId, String attachedMac,
+                                 long localPort, NeutronSecurityRule portSecurityRule,
+                                 Neutron_IPs vmIp, boolean write);
     /**
      * Program fixed ingress ACL rules that will be associated with the VM port when a vm is spawned.
      * *
@@ -43,6 +56,6 @@ public interface IngressAclProvider {
      * @param isComputePort indicates whether this port is a compute port or not
      * @param write is this flow writing or deleting
      */
-    void programFixedSecurityAcl(Long dpid, String segmentationId, String attachedMac, long localPort,
+    void programFixedSecurityGroup(Long dpid, String segmentationId, String attachedMac, long localPort,
                                   boolean isLastPortinSubnet, boolean isComputePort, boolean write);
 }
\ No newline at end of file
index f11e2451271f17f6f049485eac78f17f664ec9a2..274450b98a1b719cb19f6c047579339f2e0b7d6a 100755 (executable)
@@ -182,7 +182,7 @@ public class LoadBalancerConfiguration {
          */
         int index = 0;
         for(Map.Entry<String, LoadBalancerPoolMember> entry : this.getMembers().entrySet()) {
-            ((LoadBalancerPoolMember) entry.getValue()).setIndex(index++);
+            entry.getValue().setIndex(index++);
         }
         return this.members;
     }
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/SecurityGroupCacheManger.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/SecurityGroupCacheManger.java
new file mode 100644 (file)
index 0000000..ccf598e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, 2015 HP, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.api;
+
+/**
+ *  This interface maintain a mapping between the security group and the ports
+ *  have this security group as a remote security group. Whenever a new port is
+ *  added with a security group associated with it, a rule will be added to allow
+ *  traffic from/to the vm from  the vms which has the former as a remote sg in its rule.
+ *
+ *  @author Aswin Suryanarayanan.
+ */
+
+public interface SecurityGroupCacheManger {
+
+    /**
+     * Notifies that a new port in the security group with securityGroupUuid.
+     * @param securityGroupUuid the uuid of the security group associated with the port.
+     * @param portUuid the uuid of the port.
+     */
+    void portAdded(String securityGroupUuid, String portUuid);
+    /**
+     * Notifies that a port is removed with the securityGroupUuid.
+     * @param securityGroupUuid the uuid of the security group associated with the port.
+     * @param portUuid the uuid of the port.
+     */
+    void portRemoved(String securityGroupUuid, String portUuid);
+    /**
+     * A port with portUuid has a reference remote security group remoteSgUuid will be added
+     * to the cache maintained.
+     * @param remoteSgUuid the remote security group uuid.
+     * @param portUuid the uuid of the port.
+     */
+    void addToCache(String remoteSgUuid, String portUuid);
+    /**A port with portUUID has a reference remote security group remoteSgUuid will be removed
+     * from the cache maintained.
+     * @param remoteSgUuid the remote security group uuid.
+     * @param portUuid portUUID the uuid of the port.
+     */
+    void removeFromCache(String remoteSgUuid, String portUuid);
+}
index 997b7668256259d73735c8795207cdcc31de6f34..b09e06199bbef2e2022e5be93b41b962091bc735 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.ovsdb.openstack.netvirt.api;
 
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
@@ -83,17 +84,25 @@ public interface SecurityServicesManager {
     List<Neutron_IPs> getIpAddressList(Node node, OvsdbTerminationPointAugmentation intf);
     /**
      * Get the list of vm belonging to a security group.
-     * @param srcAddressList the address list of the connected vm.
+     * @param portUuid the uuid of the port.
      * @param securityGroupUuid the UUID of the remote security group.
      * @return the list of all vm belonging to the security group UUID passed.
      */
-    List<Neutron_IPs> getVmListForSecurityGroup(List<Neutron_IPs> srcAddressList,
+    List<Neutron_IPs> getVmListForSecurityGroup(String portUuid,
                                                 String securityGroupUuid);
     /**
-     * Add or remove the security groups rules from the port.
+     * Add or remove the security groups  from the port.
      * @param port the neutron port.
      * @param securityGroup the security group associated with the port.
      * @param write whether to add/delete flow.
      */
     void syncSecurityGroup(NeutronPort port, List<NeutronSecurityGroup> securityGroup, boolean write);
-}
+    /**
+     * Add or remove individual security  rules from the port.
+     * @param port the neutron port.
+     * @param securityRule the security group associated with the port.
+     * @param vmIp The list of remote vm ips.
+     * @param write whether to add/delete flow.
+     */
+    void syncSecurityRule(NeutronPort port, NeutronSecurityRule securityRule,Neutron_IPs vmIp, boolean write);
+}
\ No newline at end of file
index 5289742d8c250dd50237520703dc4a6058be665b..f0baac9d1cb7672db24c918fc968be4b4b9077a3 100644 (file)
@@ -31,6 +31,7 @@ public interface Southbound {
     OvsdbNodeAugmentation extractOvsdbNode(Node node);
     NodeId extractBridgeOvsdbNodeId(Node bridgeNode);
     List<Node> readOvsdbTopologyNodes();
+    List<Node> readOvsdbTopologyBridgeNodes();
     Node readOvsdbNode(Node bridgeNode);
     boolean isBridgeOnOvsdbNode(Node node, String bridgeName);
     String getOvsdbNodeUUID(Node node);
index b01dc1fc518076a0431e4255aaf2841266f96308..5fb2e967500c8768470e7b6e6e274612c4f163a1 100644 (file)
@@ -44,14 +44,18 @@ public class MdsalUtils {
     public <D extends org.opendaylight.yangtools.yang.binding.DataObject> boolean delete(
             final LogicalDatastoreType store, final InstanceIdentifier<D> path)  {
         boolean result = false;
-        final WriteTransaction transaction = databroker.newWriteOnlyTransaction();
-        transaction.delete(store, path);
-        CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
-        try {
-            future.checkedGet();
+        if(this.read(store,path) != null) {
+            final WriteTransaction transaction = databroker.newWriteOnlyTransaction();
+            transaction.delete(store, path);
+            CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
+            try {
+                future.checkedGet();
+                result = true;
+            } catch (TransactionCommitFailedException e) {
+                LOG.warn("Failed to delete {} ", path, e);
+            }
+        } else {
             result = true;
-        } catch (TransactionCommitFailedException e) {
-            LOG.warn("Failed to delete {} ", path, e);
         }
         return result;
     }
index ad447f22af946c2733a89a602d8b1b2df043f842..8d379f416fb06258daccb1525b36d667ceffc011 100644 (file)
@@ -8,8 +8,35 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.impl;
 
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.ovsdb.openstack.netvirt.ConfigInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
+import org.opendaylight.ovsdb.openstack.netvirt.api.ArpProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolver;
+import org.opendaylight.ovsdb.openstack.netvirt.api.InboundNatProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.L3ForwardingProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
+import org.opendaylight.ovsdb.openstack.netvirt.api.OutboundNatProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.RoutingProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Status;
+import org.opendaylight.ovsdb.openstack.netvirt.api.StatusCode;
+import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFloatingIP;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
@@ -18,39 +45,31 @@ import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter_Interfa
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSubnet;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronFloatingIPCRUD;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronNetworkCRUD;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSubnetCRUD;
-import org.opendaylight.ovsdb.openstack.netvirt.ConfigInterface;
-import org.opendaylight.ovsdb.openstack.netvirt.api.*;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronIAwareUtil;
+import org.opendaylight.ovsdb.utils.mdsal.utils.NeutronModelsDataStoreHelper;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 
-import org.osgi.framework.ServiceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
 /**
  * Neutron L3 Adapter implements a hub-like adapter for the various Neutron events. Based on
  * these events, the abstract router callbacks can be generated to the multi-tenant aware router,
@@ -66,6 +85,7 @@ public class NeutronL3Adapter implements ConfigInterface {
     private volatile INeutronNetworkCRUD neutronNetworkCache;
     private volatile INeutronSubnetCRUD neutronSubnetCache;
     private volatile INeutronPortCRUD neutronPortCache;
+    private volatile INeutronFloatingIPCRUD neutronFloatingIpCache;
     private volatile L3ForwardingProvider l3ForwardingProvider;
     private volatile InboundNatProvider inboundNatProvider;
     private volatile OutboundNatProvider outboundNatProvider;
@@ -100,43 +120,37 @@ public class NeutronL3Adapter implements ConfigInterface {
         }
     }
 
-    private Set<String> inboundIpRewriteCache;
-    private Set<String> outboundIpRewriteCache;
-    private Set<String> outboundIpRewriteExclusionCache;
-    private Set<String> routerInterfacesCache;
-    private Set<String> staticArpEntryCache;
-    private Set<String> l3ForwardingCache;
     private Map<String, String> networkIdToRouterMacCache;
     private Map<String, List<Neutron_IPs>> networkIdToRouterIpListCache;
     private Map<String, NeutronRouter_Interface> subnetIdToRouterInterfaceCache;
+
     private Map<String, Pair<Long, Uuid>> neutronPortToDpIdCache;
     private Map<String, FloatIpData> floatIpDataMapCache;
+
     private String externalRouterMac;
     private Boolean enabled = false;
     private Boolean flgDistributedARPEnabled = true;
-    private Southbound southbound;
+    private Boolean isCachePopulationDone = false;
     private final ExecutorService gatewayMacResolverPool = Executors.newFixedThreadPool(5);
 
+    private Southbound southbound;
+    private NeutronModelsDataStoreHelper neutronModelsDataStoreHelper;
+
     private static final String OWNER_ROUTER_INTERFACE = "network:router_interface";
     private static final String OWNER_ROUTER_INTERFACE_DISTRIBUTED = "network:router_interface_distributed";
     private static final String OWNER_ROUTER_GATEWAY = "network:router_gateway";
     private static final String OWNER_FLOATING_IP = "network:floatingip";
     private static final String DEFAULT_EXT_RTR_MAC = "00:00:5E:00:01:01";
 
-    public NeutronL3Adapter() {
+    public NeutronL3Adapter(NeutronModelsDataStoreHelper neutronHelper) {
         LOG.info(">>>>>> NeutronL3Adapter constructor {}", this.getClass());
+        this.neutronModelsDataStoreHelper = neutronHelper;
     }
 
     private void initL3AdapterMembers() {
         Preconditions.checkNotNull(configurationService);
 
         if (configurationService.isL3ForwardingEnabled()) {
-            this.inboundIpRewriteCache = new HashSet<>();
-            this.outboundIpRewriteCache = new HashSet<>();
-            this.outboundIpRewriteExclusionCache = new HashSet<>();
-            this.routerInterfacesCache = new HashSet<>();
-            this.staticArpEntryCache = new HashSet<>();
-            this.l3ForwardingCache = new HashSet<>();
             this.networkIdToRouterMacCache = new HashMap<>();
             this.networkIdToRouterIpListCache = new HashMap<>();
             this.subnetIdToRouterInterfaceCache = new HashMap<>();
@@ -161,10 +175,158 @@ public class NeutronL3Adapter implements ConfigInterface {
         }
     }
 
-    //
-    // Callbacks from OVSDB's northbound handlers
-    //
 
+    private void populateL3ForwardingCaches() {
+        if (!this.enabled) {
+            return;
+        }
+        if(this.isCachePopulationDone || this.neutronFloatingIpCache == null
+                || this.neutronPortCache == null ||this.neutronNetworkCache == null) {
+            return;
+        }
+        this.isCachePopulationDone = true;
+        LOG.debug("Populating NetVirt L3 caches from data store configuration");
+        Routers routers = this.neutronModelsDataStoreHelper.readAllNeutronRouters();
+        Ports ports = this.neutronModelsDataStoreHelper.readAllNeutronPorts();
+        if(routers != null && routers.getRouter() != null && ports != null) {
+            LOG.debug("L3 Cache Population : {} Neutron router present in data store",routers.getRouter().size());
+            for( Router router : routers.getRouter()) {
+                LOG.debug("L3 Cache Population : Populate caches for router {}",router);
+                if(!ports.getPort().isEmpty()) {
+                    for( Port port : ports.getPort()) {
+                        if (port.getDeviceId().equals(router.getUuid().getValue()) &&
+                                port.getDeviceOwner().equals(OWNER_ROUTER_INTERFACE)) {
+                            LOG.debug("L3 Cache Population : Router interface {} found.",port);
+                            networkIdToRouterMacCache.put(port.getNetworkId().getValue()
+                                    , port.getMacAddress());
+
+                            networkIdToRouterIpListCache.put(port.getNetworkId().getValue(),
+                                    NeutronIAwareUtil.convertMDSalIpToNeutronIp(port.getFixedIps()));
+                            subnetIdToRouterInterfaceCache.put(port.getFixedIps().get(0).getSubnetId().getValue(),
+                                    NeutronIAwareUtil.convertMDSalInterfaceToNeutronRouterInterface(port));
+                        }
+                    }
+                }else {
+                    LOG.warn("L3 Cache Population :Did not find any port information " +
+                            "in config Data Store for router {}",router);
+                }
+            }
+        }
+        LOG.debug("NetVirt L3 caches population is done");
+    }
+
+    private Pair<Long, Uuid> getDpIdOfNeutronPort(String neutronTenantPortUuid) {
+        if(neutronPortToDpIdCache.get(neutronTenantPortUuid) == null) {
+            List<Node> bridges = this.southbound.readOvsdbTopologyBridgeNodes();
+            LOG.debug("getDpIdOfNeutronPort : {} bridges present in ovsdb topology",bridges.size());
+            for(Node bridge : bridges) {
+                List<OvsdbTerminationPointAugmentation> interfaces
+                        = southbound.extractTerminationPointAugmentations(bridge);
+                if(interfaces != null && !interfaces.isEmpty()) {
+                    LOG.debug("getDpIdOfNeutronPort : {} termination point present on bridge {}",
+                            interfaces.size(), bridge.getNodeId());
+                    for (OvsdbTerminationPointAugmentation intf : interfaces) {
+                        NeutronPort neutronPort = tenantNetworkManager.getTenantPort(intf);
+                        if(neutronPort != null && neutronPort.getID().equals(neutronTenantPortUuid)) {
+                            Long dpId = getDpidForIntegrationBridge(bridge);
+                            Uuid interfaceUuid = intf.getInterfaceUuid();
+                            LOG.debug("getDpIdOfNeutronPort : Found bridge {} and interface {} for the tenant neutron" +
+                                    " port {}",dpId,interfaceUuid,neutronTenantPortUuid);
+                            handleInterfaceEventAdd(neutronPort.getPortUUID(), dpId, interfaceUuid);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return neutronPortToDpIdCache.get(neutronTenantPortUuid);
+    }
+
+    private Collection<FloatIpData> getAllFloatingIPsWithMetadata() {
+        LOG.debug("getAllFloatingIPsWithMetadata : Fechting all floating Ips and it's metadata");
+        List<NeutronFloatingIP> neutronFloatingIps = neutronFloatingIpCache.getAllFloatingIPs();
+        if(neutronFloatingIps != null && !neutronFloatingIps.isEmpty()) {
+            for (NeutronFloatingIP neutronFloatingIP : neutronFloatingIps) {
+                if(!floatIpDataMapCache.containsKey(neutronFloatingIP.getID())){
+                    LOG.debug("Metadata for floating ip {} is not present in the cache. " +
+                            "Fetching from data store.",neutronFloatingIP.getID());
+                    this.getFloatingIPWithMetadata(neutronFloatingIP.getID());
+                }
+            }
+        }
+        LOG.debug("getAllFloatingIPsWithMetadata : {} floating points found in data store",floatIpDataMapCache.size());
+        return floatIpDataMapCache.values();
+    }
+    private FloatIpData getFloatingIPWithMetadata(String neutronFloatingId) {
+        LOG.debug("getFloatingIPWithMetadata : Get Floating ip and it's meta data for neutron " +
+                "floating id {} ",neutronFloatingId);
+        if(floatIpDataMapCache.get(neutronFloatingId) == null) {
+            NeutronFloatingIP neutronFloatingIP = neutronFloatingIpCache.getFloatingIP(neutronFloatingId);
+            if (neutronFloatingIP == null) {
+                LOG.error("getFloatingIPWithMetadata : Floating ip {} is missing from data store, that should not happen",neutronFloatingId);
+                return null;
+            }
+            List<NeutronPort> neutronPorts = neutronPortCache.getAllPorts();
+            NeutronPort neutronPortForFloatIp = null;
+            for (NeutronPort neutronPort : neutronPorts) {
+                if (neutronPort.getDeviceOwner().equals(OWNER_FLOATING_IP) &&
+                        neutronPort.getDeviceID().equals(neutronFloatingIP.getID())) {
+                    neutronPortForFloatIp = neutronPort;
+                    break;
+                }
+            }
+
+            String neutronTenantPortUuid = neutronFloatingIP.getPortUUID();
+            if(neutronTenantPortUuid == null) {
+                return null;
+            }
+            Pair<Long, Uuid> nodeIfPair = this.getDpIdOfNeutronPort(neutronTenantPortUuid);
+            String floatingIpMac = neutronPortForFloatIp == null ? null : neutronPortForFloatIp.getMacAddress();
+            String fixedIpAddress = neutronFloatingIP.getFixedIPAddress();
+            String floatingIpAddress = neutronFloatingIP.getFloatingIPAddress();
+
+            NeutronPort tenantNeutronPort = neutronPortCache.getPort(neutronTenantPortUuid);
+            NeutronNetwork tenantNeutronNetwork = tenantNeutronPort != null ?
+                    neutronNetworkCache.getNetwork(tenantNeutronPort.getNetworkUUID()) : null;
+            String providerSegmentationId = tenantNeutronNetwork != null ?
+                    tenantNeutronNetwork.getProviderSegmentationID() : null;
+            String neutronRouterMac = tenantNeutronNetwork != null ?
+                    networkIdToRouterMacCache.get(tenantNeutronNetwork.getID()) : null;
+
+            if (nodeIfPair == null || neutronTenantPortUuid == null ||
+                    providerSegmentationId == null || providerSegmentationId.isEmpty() ||
+                    floatingIpMac == null || floatingIpMac.isEmpty() ||
+                    neutronRouterMac == null || neutronRouterMac.isEmpty()) {
+                LOG.debug("getFloatingIPWithMetadata :Floating IP {}<->{}, incomplete floatPort {} tenantPortUuid {} " +
+                                "seg {} mac {} rtrMac {}",
+                        fixedIpAddress,
+                        floatingIpAddress,
+                        neutronPortForFloatIp,
+                        neutronTenantPortUuid,
+                        providerSegmentationId,
+                        floatingIpMac,
+                        neutronRouterMac);
+
+                return null;
+            }
+
+            // get ofport for patch port in br-int
+            final Long dpId = nodeIfPair.getLeft();
+            final Long ofPort = findOFPortForExtPatch(dpId);
+            if (ofPort == null) {
+                LOG.warn("getFloatingIPWithMetadata : Unable to locate OF port of patch port " +
+                                "to connect floating ip to external bridge. dpid {}",
+                        dpId);
+                return null;
+            }
+
+            final FloatIpData floatIpData = new FloatIpData(dpId, ofPort, providerSegmentationId, floatingIpMac,
+                    floatingIpAddress, fixedIpAddress, neutronRouterMac);
+            floatIpDataMapCache.put(neutronFloatingIP.getID(), floatIpData);
+
+        }
+        return floatIpDataMapCache.get(neutronFloatingId);
+    }
     /**
      * Invoked to configure the mac address for the external gateway in br-ex. ovsdb netvirt needs help in getting
      * mac for given ip in br-ex (bug 3378). For example, since ovsdb has no real arp, it needs a service in can
@@ -379,7 +541,7 @@ public class NeutronL3Adapter implements ConfigInterface {
     private void programFlowsForFloatingIPInbound(final NeutronFloatingIP neutronFloatingIP, final Action action) {
         Preconditions.checkNotNull(neutronFloatingIP);
 
-        final FloatIpData fid = floatIpDataMapCache.get(neutronFloatingIP.getID());
+        final FloatIpData fid = getFloatingIPWithMetadata(neutronFloatingIP.getID());
         if (fid == null) {
             LOG.trace("programFlowsForFloatingIPInboundAdd {} for {} uuid {} not in local cache",
                     action, neutronFloatingIP.getFloatingIPAddress(), neutronFloatingIP.getID());
@@ -396,7 +558,7 @@ public class NeutronL3Adapter implements ConfigInterface {
     private void programFlowsForFloatingIPOutbound(final NeutronFloatingIP neutronFloatingIP, final Action action) {
         Preconditions.checkNotNull(neutronFloatingIP);
 
-        final FloatIpData fid = floatIpDataMapCache.get(neutronFloatingIP.getID());
+        final FloatIpData fid = getFloatingIPWithMetadata(neutronFloatingIP.getID());
         if (fid == null) {
             LOG.trace("programFlowsForFloatingIPOutbound {} for {} uuid {} not in local cache",
                     action, neutronFloatingIP.getFloatingIPAddress(), neutronFloatingIP.getID());
@@ -406,13 +568,13 @@ public class NeutronL3Adapter implements ConfigInterface {
     }
 
     private void flushExistingIpRewrite() {
-        for (FloatIpData fid : floatIpDataMapCache.values()) {
+        for (FloatIpData fid : getAllFloatingIPsWithMetadata()) {
             programOutboundIpRewriteStage1(fid, Action.DELETE);
         }
     }
 
     private void rebuildExistingIpRewrite() {
-        for (FloatIpData fid : floatIpDataMapCache.values()) {
+        for (FloatIpData fid : getAllFloatingIPsWithMetadata()) {
             programOutboundIpRewriteStage1(fid, Action.ADD);
         }
     }
@@ -427,16 +589,10 @@ public class NeutronL3Adapter implements ConfigInterface {
         Preconditions.checkNotNull(neutronFloatingIP.getFixedIPAddress());
         Preconditions.checkNotNull(neutronFloatingIP.getFloatingIPAddress());
 
-        if (floatIpDataMapCache.get(neutronFloatingIP.getID()) != null) {
-            LOG.trace("programFlowsForFloatingIPArpAdd for neutronFloatingIP {} uuid {} is already done",
-                    neutronFloatingIP.getFloatingIPAddress(), neutronFloatingIP.getID());
-            return;
-        }
-
         // find bridge Node where floating ip is configured by looking up cache for its port
         final NeutronPort neutronPortForFloatIp = findNeutronPortForFloatingIp(neutronFloatingIP.getID());
         final String neutronTenantPortUuid = neutronFloatingIP.getPortUUID();
-        final Pair<Long, Uuid> nodeIfPair = neutronPortToDpIdCache.get(neutronTenantPortUuid);
+        final Pair<Long, Uuid> nodeIfPair = this.getDpIdOfNeutronPort(neutronTenantPortUuid);
         final String floatingIpMac = neutronPortForFloatIp == null ? null : neutronPortForFloatIp.getMacAddress();
         final String fixedIpAddress = neutronFloatingIP.getFixedIPAddress();
         final String floatingIpAddress = neutronFloatingIP.getFloatingIPAddress();
@@ -487,7 +643,7 @@ public class NeutronL3Adapter implements ConfigInterface {
     }
 
     private void programFlowsForFloatingIPArpDelete(final String neutronFloatingIPUuid) {
-        final FloatIpData floatIpData = floatIpDataMapCache.get(neutronFloatingIPUuid);
+        final FloatIpData floatIpData = getFloatingIPWithMetadata(neutronFloatingIPUuid);
         if (floatIpData == null) {
             LOG.trace("programFlowsForFloatingIPArpDelete for uuid {} is not needed", neutronFloatingIPUuid);
             return;
@@ -571,8 +727,7 @@ public class NeutronL3Adapter implements ConfigInterface {
         if (neutronPort != null) {
             final String neutronPortUuid = neutronPort.getPortUUID();
 
-            if (action != Action.DELETE && neutronPortToDpIdCache.get(neutronPortUuid) == null &&
-                    dpId != null && interfaceUuid != null) {
+            if (action != Action.DELETE && dpId != null && interfaceUuid != null) {
                 handleInterfaceEventAdd(neutronPortUuid, dpId, interfaceUuid);
             }
 
@@ -693,8 +848,8 @@ public class NeutronL3Adapter implements ConfigInterface {
 
     private List<NeutronSecurityGroup> getsecurityGroupChanged(NeutronPort port1, NeutronPort port2) {
         LOG.trace("getsecurityGroupChanged:" + "Port1:" + port1 + "Port2" + port2);
-        ArrayList<NeutronSecurityGroup> list1 = new ArrayList<NeutronSecurityGroup>(port1.getSecurityGroups());
-        ArrayList<NeutronSecurityGroup> list2 = new ArrayList<NeutronSecurityGroup>(port2.getSecurityGroups());
+        List<NeutronSecurityGroup> list1 = new ArrayList<>(port1.getSecurityGroups());
+        List<NeutronSecurityGroup> list2 = new ArrayList<>(port2.getSecurityGroups());
         for (Iterator<NeutronSecurityGroup> iterator = list1.iterator(); iterator.hasNext();) {
             NeutronSecurityGroup securityGroup1 = iterator.next();
             for (NeutronSecurityGroup securityGroup2 :list2) {
@@ -709,33 +864,17 @@ public class NeutronL3Adapter implements ConfigInterface {
     private void programL3ForwardingStage1(Node node, Long dpid, String providerSegmentationId,
                                            String macAddress, String ipStr,
                                            Action actionForNode) {
-        // Based on the local cache, figure out whether programming needs to occur. To do this, we
-        // will look at desired action for node.
-
-        final String cacheKey = node.getNodeId().getValue() + ":" + providerSegmentationId + ":" + ipStr;
-        final boolean isProgrammed = l3ForwardingCache.contains(cacheKey);
-
-        if (actionForNode == Action.DELETE && !isProgrammed) {
-            LOG.trace("programL3ForwardingStage1 for node {} providerId {} mac {} ip {} action {} is already done",
+        if (actionForNode == Action.DELETE) {
+            LOG.trace("Deleting Flow : programL3ForwardingStage1 for node {} providerId {} mac {} ip {} action {}",
                          node.getNodeId().getValue(), providerSegmentationId, macAddress, ipStr, actionForNode);
-            return;
         }
-        if (actionForNode == Action.ADD && isProgrammed) {
-            LOG.trace("programL3ForwardingStage1 for node {} providerId {} mac {} ip {} action {} is already done",
+        if (actionForNode == Action.ADD) {
+            LOG.trace("Adding Flow : programL3ForwardingStage1 for node {} providerId {} mac {} ip {} action {}",
                     node.getNodeId().getValue(), providerSegmentationId, macAddress, ipStr, actionForNode);
-            return;
         }
 
-        Status status = this.programL3ForwardingStage2(node, dpid, providerSegmentationId,
+        this.programL3ForwardingStage2(node, dpid, providerSegmentationId,
                                                        macAddress, ipStr, actionForNode);
-        if (status.isSuccess()) {
-            // Update cache
-            if (actionForNode == Action.ADD) {
-                l3ForwardingCache.add(cacheKey);
-            } else {
-                l3ForwardingCache.remove(cacheKey);
-            }
-        }
     }
 
     private Status programL3ForwardingStage2(Node node, Long dpid, String providerSegmentationId,
@@ -961,41 +1100,22 @@ public class NeutronL3Adapter implements ConfigInterface {
                                               String destinationSegmentationId,
                                               String macAddress, String ipStr, int mask,
                                               Action actionForNode) {
-        // Based on the local cache, figure out whether programming needs to occur. To do this, we
-        // will look at desired action for node.
-        //
-        final String cacheKey = node.getNodeId().getValue() + ":" +
-                                sourceSegmentationId + ":" + destinationSegmentationId + ":" +
-                                ipStr + "/" + Integer.toString(mask);
-        final boolean isProgrammed = routerInterfacesCache.contains(cacheKey);
-
-        if (actionForNode == Action.DELETE && !isProgrammed) {
-            LOG.trace("programRouterInterfaceStage1 for node {} sourceSegId {} destSegId {} mac {} ip {} mask {}" +
-                         " action {} is already done",
+        if (actionForNode == Action.DELETE) {
+            LOG.trace("Deleting Flow : programRouterInterfaceStage1 for node {} sourceSegId {} destSegId {} mac {} ip {} mask {}" +
+                         " action {}",
                          node.getNodeId().getValue(), sourceSegmentationId, destinationSegmentationId,
                          macAddress, ipStr, mask, actionForNode);
             return;
         }
-        if (actionForNode == Action.ADD && isProgrammed) {
-            LOG.trace("programRouterInterfaceStage1 for node {} sourceSegId {} destSegId {} mac {} ip {} mask {}" +
-                         " action {} is already done",
+        if (actionForNode == Action.ADD) {
+            LOG.trace("Adding Flow : programRouterInterfaceStage1 for node {} sourceSegId {} destSegId {} mac {} ip {} mask {}" +
+                         " action {}",
                          node.getNodeId().getValue(), sourceSegmentationId, destinationSegmentationId,
                          macAddress, ipStr, mask, actionForNode);
-            return;
         }
 
-        Status status = this.programRouterInterfaceStage2(node, dpid, sourceSegmentationId, destinationSegmentationId,
+        this.programRouterInterfaceStage2(node, dpid, sourceSegmentationId, destinationSegmentationId,
                                                           macAddress, ipStr, mask, actionForNode);
-        if (status.isSuccess()) {
-            // Update cache
-            if (actionForNode == Action.ADD) {
-                // TODO: multiTenantAwareRouter.addInterface(UUID.fromString(tenant), ...);
-                routerInterfacesCache.add(cacheKey);
-            } else {
-                // TODO: multiTenantAwareRouter.removeInterface(...);
-                routerInterfacesCache.remove(cacheKey);
-            }
-        }
     }
 
     private Status programRouterInterfaceStage2(Node node, Long dpid, String sourceSegmentationId,
@@ -1030,34 +1150,17 @@ public class NeutronL3Adapter implements ConfigInterface {
     private boolean programStaticArpStage1(Long dpid, String segOrOfPort,
                                            String macAddress, String ipStr,
                                            Action action) {
-        // Based on the local cache, figure out whether programming needs to occur. To do this, we
-        // will look at desired action for node.
-        //
-        final String cacheKey = dpid + ":" + segOrOfPort + ":" + ipStr;
-        final boolean isProgrammed = staticArpEntryCache.contains(cacheKey);
-
-        if (action == Action.DELETE && !isProgrammed) {
-            LOG.trace("programStaticArpStage1 dpid {} segOrOfPort {} mac {} ip {} action {} is already done",
+        if (action == Action.DELETE ) {
+            LOG.trace("Deleting Flow : programStaticArpStage1 dpid {} segOrOfPort {} mac {} ip {} action {}",
                     dpid, segOrOfPort, macAddress, ipStr, action);
-            return true;
         }
-        if (action == Action.ADD && isProgrammed) {
-            LOG.trace("programStaticArpStage1 dpid {} segOrOfPort {} mac {} ip {} action {} is already done",
+        if (action == Action.ADD) {
+            LOG.trace("Adding Flow : programStaticArpStage1 dpid {} segOrOfPort {} mac {} ip {} action {} is already done",
                     dpid, segOrOfPort, macAddress, ipStr, action);
-            return true;
         }
 
         Status status = this.programStaticArpStage2(dpid, segOrOfPort, macAddress, ipStr, action);
-        if (status.isSuccess()) {
-            // Update cache
-            if (action == Action.ADD) {
-                staticArpEntryCache.add(cacheKey);
-            } else {
-                staticArpEntryCache.remove(cacheKey);
-            }
-            return true;
-        }
-        return false;
+        return status.isSuccess();
     }
 
     private Status programStaticArpStage2(Long dpid,
@@ -1090,37 +1193,20 @@ public class NeutronL3Adapter implements ConfigInterface {
     private boolean programInboundIpRewriteStage1(Long dpid, Long inboundOFPort, String providerSegmentationId,
                                                   String matchAddress, String rewriteAddress,
                                                   Action action) {
-        // Based on the local cache, figure out whether programming needs to occur. To do this, we
-        // will look at desired action for node.
-        //
-        final String cacheKey = dpid + ":" + inboundOFPort + ":" + providerSegmentationId + ":" + matchAddress;
-        final boolean isProgrammed = inboundIpRewriteCache.contains(cacheKey);
-
-        if (action == Action.DELETE && !isProgrammed) {
-            LOG.trace("programInboundIpRewriteStage1 dpid {} OFPort {} seg {} matchAddress {} rewriteAddress {}" +
-                    " action {} is already done",
+        if (action == Action.DELETE ) {
+            LOG.trace("Deleting Flow : programInboundIpRewriteStage1 dpid {} OFPort {} seg {} matchAddress {} rewriteAddress {}" +
+                    " action {}",
                     dpid, inboundOFPort, providerSegmentationId, matchAddress, rewriteAddress, action);
-            return true;
         }
-        if (action == Action.ADD && isProgrammed) {
-            LOG.trace("programInboundIpRewriteStage1 dpid {} OFPort {} seg {} matchAddress {} rewriteAddress {}" +
-                    " action is already done",
+        if (action == Action.ADD ) {
+            LOG.trace("Adding Flow : programInboundIpRewriteStage1 dpid {} OFPort {} seg {} matchAddress {} rewriteAddress {}" +
+                    " action {}",
                     dpid, inboundOFPort, providerSegmentationId, matchAddress, rewriteAddress, action);
-            return true;
         }
 
         Status status = programInboundIpRewriteStage2(dpid, inboundOFPort, providerSegmentationId, matchAddress,
                 rewriteAddress, action);
-        if (status.isSuccess()) {
-            // Update cache
-            if (action == Action.ADD) {
-                inboundIpRewriteCache.add(cacheKey);
-            } else {
-                inboundIpRewriteCache.remove(cacheKey);
-            }
-            return true;
-        }
-        return false;
+        return status.isSuccess();
     }
 
     private Status programInboundIpRewriteStage2(Long dpid, Long inboundOFPort, String providerSegmentationId,
@@ -1155,33 +1241,16 @@ public class NeutronL3Adapter implements ConfigInterface {
 
     private void programIpRewriteExclusionStage1(Node node, Long dpid, String providerSegmentationId, String cidr,
                                                  Action actionForRewriteExclusion) {
-        // Based on the local cache, figure out whether programming needs to occur. To do this, we
-        // will look at desired action for node.
-        //
-        final String cacheKey = node.getNodeId().getValue() + ":" + providerSegmentationId + ":" + cidr;
-        final boolean isProgrammed = outboundIpRewriteExclusionCache.contains(cacheKey);
-
-        if (actionForRewriteExclusion == Action.DELETE && !isProgrammed) {
-            LOG.trace("programIpRewriteExclusionStage1 node {} providerId {} cidr {} action {} is already done",
+        if (actionForRewriteExclusion == Action.DELETE ) {
+            LOG.trace("Deleting Flow : programIpRewriteExclusionStage1 node {} providerId {} cidr {} action {}",
                          node.getNodeId().getValue(), providerSegmentationId, cidr, actionForRewriteExclusion);
-            return;
         }
-        if (actionForRewriteExclusion == Action.ADD && isProgrammed) {
-            LOG.trace("programIpRewriteExclusionStage1 node {} providerId {} cidr {} action {} is already done",
+        if (actionForRewriteExclusion == Action.ADD) {
+            LOG.trace("Adding Flow : programIpRewriteExclusionStage1 node {} providerId {} cidr {} action {}",
                          node.getNodeId().getValue(), providerSegmentationId, cidr, actionForRewriteExclusion);
-            return;
         }
 
-        Status status = this.programIpRewriteExclusionStage2(node, dpid, providerSegmentationId, cidr,
-                                                             actionForRewriteExclusion);
-        if (status.isSuccess()) {
-            // Update cache
-            if (actionForRewriteExclusion == Action.ADD) {
-                    outboundIpRewriteExclusionCache.add(cacheKey);
-            } else {
-                    outboundIpRewriteExclusionCache.remove(cacheKey);
-            }
-        }
+        this.programIpRewriteExclusionStage2(node, dpid, providerSegmentationId, cidr,actionForRewriteExclusion);
     }
 
     private Status programIpRewriteExclusionStage2(Node node, Long dpid, String providerSegmentationId, String cidr,
@@ -1202,34 +1271,17 @@ public class NeutronL3Adapter implements ConfigInterface {
     }
 
     private void programOutboundIpRewriteStage1(FloatIpData fid, Action action) {
-        // Based on the local cache, figure out whether programming needs to occur. To do this, we
-        // will look at desired action for node.
-        //
-        final String cacheKey = fid.dpid + ":" + fid.segId + ":" + fid.fixedIpAddress;
-        final boolean isProgrammed = outboundIpRewriteCache.contains(cacheKey);
 
-        if (action == Action.DELETE && !isProgrammed) {
-            LOG.trace("programOutboundIpRewriteStage1 dpid {} seg {} fixedIpAddress {} floatIp {} action {} " +
-                         "is already done",
+        if (action == Action.DELETE) {
+            LOG.trace("Deleting Flow : programOutboundIpRewriteStage1 dpid {} seg {} fixedIpAddress {} floatIp {} action {} ",
                     fid.dpid, fid.segId, fid.fixedIpAddress, fid.floatingIpAddress, action);
-            return;
         }
-        if (action == Action.ADD && isProgrammed) {
-            LOG.trace("programOutboundIpRewriteStage1 dpid {} seg {} fixedIpAddress {} floatIp {} action {} " +
-                         "is already done",
+        if (action == Action.ADD) {
+            LOG.trace("Adding Flow : programOutboundIpRewriteStage1 dpid {} seg {} fixedIpAddress {} floatIp {} action {} " ,
                     fid.dpid, fid.segId, fid.fixedIpAddress, fid.floatingIpAddress, action);
-            return;
         }
 
-        Status status = this.programOutboundIpRewriteStage2(fid, action);
-        if (status.isSuccess()) {
-            // Update cache
-            if (action == Action.ADD) {
-                outboundIpRewriteCache.add(cacheKey);
-            } else {
-                outboundIpRewriteCache.remove(cacheKey);
-            }
-        }
+        this.programOutboundIpRewriteStage2(fid, action);
     }
 
     private Status programOutboundIpRewriteStage2(FloatIpData fid, Action action) {
@@ -1432,6 +1484,8 @@ public class NeutronL3Adapter implements ConfigInterface {
             neutronPortCache = (INeutronPortCRUD)impl;
         } else if (impl instanceof INeutronSubnetCRUD) {
             neutronSubnetCache = (INeutronSubnetCRUD)impl;
+        } else if (impl instanceof INeutronFloatingIPCRUD) {
+            neutronFloatingIpCache = (INeutronFloatingIPCRUD)impl;
         } else if (impl instanceof ArpProvider) {
             arpProvider = (ArpProvider)impl;
         } else if (impl instanceof InboundNatProvider) {
@@ -1445,5 +1499,6 @@ public class NeutronL3Adapter implements ConfigInterface {
         }else if (impl instanceof GatewayMacResolver) {
             gatewayMacResolver = (GatewayMacResolver)impl;
         }
+        populateL3ForwardingCaches();
     }
 }
index 0f7cd698930dac213d07e4f8accb34de445578e4..7e21101e004a9e3cff4cab2f7adeacd8f6240e48 100644 (file)
@@ -164,6 +164,19 @@ public class NodeCacheManagerImpl extends AbstractHandler implements NodeCacheMa
         return nodes;
     }
 
+    private void populateNodeCache() {
+        LOG.debug("populateNodeCache : Populating the node cache");
+        List<Node> nodes = southbound.readOvsdbTopologyNodes();
+        for(Node ovsdbNode : nodes) {
+            this.nodeCache.put(ovsdbNode.getNodeId(), ovsdbNode);
+        }
+        nodes = southbound.readOvsdbTopologyBridgeNodes();
+        for(Node bridgeNode : nodes) {
+            this.nodeCache.put(bridgeNode.getNodeId(), bridgeNode);
+        }
+        LOG.debug("populateNodeCache : Node cache population is done. Total nodes : {}",this.nodeCache.size());
+    }
+
     @Override
     public void setDependencies(ServiceReference serviceReference) {
         southbound =
@@ -171,6 +184,7 @@ public class NodeCacheManagerImpl extends AbstractHandler implements NodeCacheMa
         eventDispatcher =
                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
         eventDispatcher.eventHandlerAdded(serviceReference, this);
+        populateNodeCache();
     }
 
     @Override
index 60388974f223e4af40a731c5a9f140e4b09eca8f..530fee8311bd319ee5330b4774251e32f312e3b6 100644 (file)
@@ -22,6 +22,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronFl
 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronNetworkChangeListener;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronPortChangeListener;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronRouterChangeListener;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronSecurityRuleDataChangeListener;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronSubnetChangeListener;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronLoadBalancerPoolChangeListener;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronLoadBalancerPoolMemberChangeListener;
@@ -104,6 +105,7 @@ public class OvsdbInventoryServiceImpl implements ConfigInterface, OvsdbInventor
         new NeutronFloatingIPChangeListener(db);
         new NeutronLoadBalancerPoolChangeListener(db);
         new NeutronLoadBalancerPoolMemberChangeListener(db);
+        new NeutronSecurityRuleDataChangeListener(db);
     }
 
 }
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/SecurityGroupCacheManagerImpl.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/SecurityGroupCacheManagerImpl.java
new file mode 100644 (file)
index 0000000..53231ec
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2014, 2015 HP, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.impl;
+
+import org.opendaylight.ovsdb.openstack.netvirt.ConfigInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityGroupCacheManger;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
+import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+/**
+ * @author Aswin Suryanarayanan.
+ */
+
+public class SecurityGroupCacheManagerImpl implements ConfigInterface, SecurityGroupCacheManger{
+
+    private final Map<String, Set<String>> securityGroupCache = new ConcurrentHashMap<>();
+    private static final Logger LOG = LoggerFactory.getLogger(SecurityGroupCacheManagerImpl.class);
+    private volatile SecurityServicesManager securityServicesManager;
+    private volatile INeutronPortCRUD neutronPortCache;
+
+    @Override
+    public void portAdded(String securityGroupUuid, String portUuid) {
+        LOG.debug("In portAdded securityGroupUuid:" + securityGroupUuid + " portUuid:" + portUuid);
+        NeutronPort port = neutronPortCache.getPort(portUuid);
+        processPortAdded(securityGroupUuid,port);
+    }
+
+    @Override
+    public void portRemoved(String securityGroupUuid, String portUuid) {
+        LOG.debug("In portRemoved securityGroupUuid:" + securityGroupUuid + " portUuid:" + portUuid);
+        NeutronPort port = neutronPortCache.getPort(portUuid);
+        processPortRemoved(securityGroupUuid,port);
+    }
+
+    @Override
+    public void addToCache(String remoteSgUuid, String portUuid) {
+        LOG.debug("In addToCache remoteSgUuid:" + remoteSgUuid + "portUuid:" + portUuid);
+        Set<String> portList = securityGroupCache.get(remoteSgUuid);
+        if (null == portList) {
+            portList = new HashSet<>();
+            securityGroupCache.put(remoteSgUuid, portList);
+        }
+        portList.add(portUuid);
+    }
+
+    @Override
+    public void removeFromCache(String remoteSgUuid, String portUuid) {
+        LOG.debug("In removeFromCache remoteSgUuid:" + remoteSgUuid + " portUuid:" + portUuid);
+        Set<String> portList = securityGroupCache.get(remoteSgUuid);
+        if (null == portList) {
+            return;
+        }
+        for (Iterator<String> iterator = portList.iterator(); iterator.hasNext();) {
+            String cachedPort = iterator.next();
+            if (cachedPort.equals(portUuid)) {
+                iterator.remove();
+                break;
+            }
+        }
+        if (portList.isEmpty()) {
+            securityGroupCache.remove(remoteSgUuid);
+        }
+    }
+
+    private void processPortAdded(String securityGroupUuid, NeutronPort port) {
+        /*
+         * Itreate through the cache maintained for the security group added. For each port in the cache
+         * add the rule to allow traffic to/from the new port added.
+         */
+        LOG.debug("In processPortAdded securityGroupUuid:" + securityGroupUuid + " NeutronPort:" + port);
+        Set<String> portList = this.securityGroupCache.get(securityGroupUuid);
+        if (null == portList) {
+            return;
+        }
+        for (String cachedportUuid : portList) {
+            if (cachedportUuid.equals(port.getID())) {
+                continue;
+            }
+            NeutronPort cachedport = neutronPortCache.getPort(cachedportUuid);
+            if (null == cachedport) {
+                return;
+            }
+            List<NeutronSecurityRule> remoteSecurityRules = retrieveSecurityRules(securityGroupUuid, cachedportUuid);
+            for (NeutronSecurityRule securityRule : remoteSecurityRules) {
+                for (Neutron_IPs vmIp : port.getFixedIPs()) {
+                    securityServicesManager.syncSecurityRule(cachedport, securityRule, vmIp, true);
+                }
+            }
+        }
+    }
+
+    private void processPortRemoved(String securityGroupUuid, NeutronPort port) {
+        /*
+         * Itreate through the cache maintained for the security group added. For each port in the cache remove
+         * the rule to allow traffic to/from the  port that got deleted.
+         */
+        LOG.debug("In processPortRemoved securityGroupUuid:" + securityGroupUuid + " port:" + port);
+        Set<String> portList = this.securityGroupCache.get(securityGroupUuid);
+        if (null == portList) {
+            return;
+        }
+        for (String cachedportUuid : portList) {
+            if (cachedportUuid.equals(port.getID())) {
+                continue;
+            }
+            NeutronPort cachedport = neutronPortCache.getPort(cachedportUuid);
+            if (null == cachedport) {
+                return;
+            }
+            List<NeutronSecurityRule> remoteSecurityRules = retrieveSecurityRules(securityGroupUuid, cachedportUuid);
+            for (NeutronSecurityRule securityRule : remoteSecurityRules) {
+                for (Neutron_IPs vmIp : port.getFixedIPs()) {
+                    securityServicesManager.syncSecurityRule(cachedport, securityRule, vmIp, false);
+                }
+            }
+        }
+    }
+
+    private List<NeutronSecurityRule> retrieveSecurityRules(String securityGroupUuid, String portUuid) {
+        /*
+         * Get the list of security rules in the port with portUuid that has securityGroupUuid as a remote
+         * security group.
+         */
+        LOG.debug("In retrieveSecurityRules securityGroupUuid:" + securityGroupUuid + " portUuid:" + portUuid);
+        NeutronPort port = neutronPortCache.getPort(portUuid);
+        if (null == port) {
+            return null;
+        }
+        List<NeutronSecurityRule> remoteSecurityRules = new ArrayList<>();
+        List<NeutronSecurityGroup> securityGroups = port.getSecurityGroups();
+        for (NeutronSecurityGroup securityGroup : securityGroups) {
+            List<NeutronSecurityRule> securityRules = securityGroup.getSecurityRules();
+            for (NeutronSecurityRule securityRule : securityRules) {
+                if (securityGroupUuid.equals(securityRule.getSecurityRemoteGroupID())) {
+                    remoteSecurityRules.add(securityRule);
+                }
+            }
+        }
+        return remoteSecurityRules;
+    }
+
+    private void init() {
+        /*
+         * Rebuild the cache in case of a restart.
+         */
+        List<NeutronPort> portList = neutronPortCache.getAllPorts();
+        for (NeutronPort port:portList) {
+            List<NeutronSecurityGroup> securityGroupList = port.getSecurityGroups();
+            if ( null != securityGroupList) {
+                for (NeutronSecurityGroup securityGroup : securityGroupList) {
+                    List<NeutronSecurityRule> securityRuleList = securityGroup.getSecurityRules();
+                    if ( null != securityRuleList) {
+                        for (NeutronSecurityRule securityRule : securityRuleList) {
+                            if (null != securityRule.getSecurityRemoteGroupID()) {
+                                this.addToCache(securityRule.getSecurityRemoteGroupID(), port.getID());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setDependencies(ServiceReference serviceReference) {
+        securityServicesManager =
+                (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
+        neutronPortCache = (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, this);
+        init();
+    }
+
+    @Override
+    public void setDependencies(Object impl) {
+    }
+}
index 277c5a26804135ba1e6ed36b12d2f6ad284f92f7..aa9b946d9004c7e0dc95c22de883589e29fdd2c1 100644 (file)
@@ -18,6 +18,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSubnet;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronNetworkCRUD;
@@ -43,7 +44,6 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
     private volatile ConfigurationService configurationService;
     private volatile IngressAclProvider ingressAclProvider;
     private volatile EgressAclProvider egressAclProvider;
-    private volatile SecurityServicesManager securityServicesManager;
 
     @Override
     public boolean isPortSecurityReady(OvsdbTerminationPointAugmentation terminationPointAugmentation) {
@@ -79,7 +79,7 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
     @Override
     public List<NeutronSecurityGroup> getSecurityGroupInPortList(OvsdbTerminationPointAugmentation
                                                              terminationPointAugmentation) {
-        List<NeutronSecurityGroup> neutronSecurityGroups = new ArrayList<NeutronSecurityGroup>();
+        List<NeutronSecurityGroup> neutronSecurityGroups = new ArrayList<>();
         if (neutronPortCache == null) {
             LOG.error("neutron port is null");
             return neutronSecurityGroups;
@@ -301,8 +301,8 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
     }
 
     @Override
-    public List<Neutron_IPs> getVmListForSecurityGroup(List<Neutron_IPs> srcAddressList, String securityGroupUuid) {
-        List<Neutron_IPs> vmListForSecurityGroup = new ArrayList<Neutron_IPs>();
+    public List<Neutron_IPs> getVmListForSecurityGroup(String portUuid, String securityGroupUuid) {
+        List<Neutron_IPs> vmListForSecurityGroup = new ArrayList<>();
         /*For every port check whether security grouplist contains the current
          * security group.*/
         try {
@@ -312,11 +312,13 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
                             + "compute port belongs to {}", neutronPort.getID(), neutronPort.getDeviceOwner());
                     continue;
                 }
+                if (portUuid.equals(neutronPort.getID())) {
+                    continue;
+                }
                 List<NeutronSecurityGroup> securityGroups = neutronPort.getSecurityGroups();
                 if (null != securityGroups) {
                     for (NeutronSecurityGroup securityGroup:securityGroups) {
-                        if (securityGroup.getSecurityGroupUUID().equals(securityGroupUuid)
-                                && !neutronPort.getFixedIPs().containsAll(srcAddressList)) {
+                        if (securityGroup.getSecurityGroupUUID().equals(securityGroupUuid)) {
                             LOG.debug("getVMListForSecurityGroup : adding ports with ips {} "
                                     + "compute port", neutronPort.getFixedIPs());
                             vmListForSecurityGroup.addAll(neutronPort.getFixedIPs());
@@ -336,7 +338,7 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
 
     @Override
     public void syncSecurityGroup(NeutronPort port, List<NeutronSecurityGroup> securityGroupList, boolean write) {
-        LOG.trace("syncSecurityGroup:" + securityGroupList + " Write:" + Boolean.valueOf(write));
+        LOG.trace("syncSecurityGroup:" + securityGroupList + " Write:" + write);
         if (null != port && null != port.getSecurityGroups()) {
             Node node = getNode(port);
             NeutronNetwork neutronNetwork = neutronNetworkCache.getNetwork(port.getNetworkUUID());
@@ -349,12 +351,41 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
                 return;
             }
             long dpid = getDpidOfIntegrationBridge(node);
-            List<Neutron_IPs> srcAddressList = securityServicesManager.getIpAddressList(node, intf);
+            String neutronPortId = southbound.getInterfaceExternalIdsValue(intf,
+                                                                           Constants.EXTERNAL_ID_INTERFACE_ID);
             for (NeutronSecurityGroup securityGroupInPort:securityGroupList) {
-                ingressAclProvider.programPortSecurityAcl(dpid, segmentationId, attachedMac, localPort,
-                                                          securityGroupInPort, srcAddressList, write);
-                egressAclProvider.programPortSecurityAcl(dpid, segmentationId, attachedMac, localPort,
-                                                         securityGroupInPort, srcAddressList, write);
+                ingressAclProvider.programPortSecurityGroup(dpid, segmentationId, attachedMac, localPort,
+                                                          securityGroupInPort, neutronPortId, write);
+                egressAclProvider.programPortSecurityGroup(dpid, segmentationId, attachedMac, localPort,
+                                                         securityGroupInPort, neutronPortId, write);
+            }
+        }
+    }
+
+    @Override
+    public void syncSecurityRule(NeutronPort port, NeutronSecurityRule securityRule,Neutron_IPs vmIp, boolean write) {
+        LOG.trace("syncSecurityGroup:" + securityRule + " Write:" + write);
+        if (null != port && null != port.getSecurityGroups()) {
+            Node node = getNode(port);
+            NeutronNetwork neutronNetwork = neutronNetworkCache.getNetwork(port.getNetworkUUID());
+            String segmentationId = neutronNetwork.getProviderSegmentationID();
+            OvsdbTerminationPointAugmentation intf = getInterface(node, port);
+            long localPort = southbound.getOFPort(intf);
+            String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC);
+            if (attachedMac == null) {
+                LOG.debug("programVlanRules: No AttachedMac seen in {}", intf);
+                return;
+            }
+            long dpid = getDpidOfIntegrationBridge(node);
+            if ("IPv4".equals(securityRule.getSecurityRuleEthertype())
+                    && "ingress".equals(securityRule.getSecurityRuleDirection())) {
+
+                ingressAclProvider.programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
+                                                           securityRule, vmIp, write);
+            } else if (securityRule.getSecurityRuleEthertype().equals("IPv4")
+                    && securityRule.getSecurityRuleDirection().equals("egress")) {
+                egressAclProvider.programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
+                                                          securityRule, vmIp, write);
             }
         }
     }
@@ -424,8 +455,6 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
                 (INeutronNetworkCRUD) ServiceHelper.getGlobalInstance(INeutronNetworkCRUD.class, this);
         configurationService =
                 (ConfigurationService) ServiceHelper.getGlobalInstance(ConfigurationService.class, this);
-        securityServicesManager =
-                (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
     }
 
     @Override
@@ -440,4 +469,4 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
             egressAclProvider = (EgressAclProvider) impl;
         }
     }
-}
+}
\ No newline at end of file
index 6b84f9f7f68170e86b220c8fe880f862f28e7e5e..38eeaecbdab60b1cf01d9e76dbf35d85703f1943 100644 (file)
@@ -33,6 +33,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.re
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
@@ -128,6 +130,21 @@ public class SouthboundImpl implements Southbound {
         return ovsdbNodes;
     }
 
+    public List<Node> readOvsdbTopologyBridgeNodes() {
+        List<Node> ovsdbNodes = new ArrayList<>();
+        InstanceIdentifier<Topology> topologyInstanceIdentifier = MdsalHelper.createInstanceIdentifier();
+        Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyInstanceIdentifier);
+        if (topology != null && topology.getNode() != null) {
+            for (Node node : topology.getNode()) {
+                OvsdbBridgeAugmentation ovsdbBridgeAugmentation = node.getAugmentation(OvsdbBridgeAugmentation.class);
+                if (ovsdbBridgeAugmentation != null) {
+                    ovsdbNodes.add(node);
+                }
+            }
+        }
+        return ovsdbNodes;
+    }
+
     public Node readOvsdbNode(Node bridgeNode) {
         Node ovsdbNode = null;
         OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
@@ -182,6 +199,13 @@ public class SouthboundImpl implements Southbound {
             ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
             ovsdbBridgeAugmentationBuilder.setFailMode(
                     MdsalHelper.OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
+            BridgeOtherConfigsBuilder bridgeOtherConfigsBuilder = new BridgeOtherConfigsBuilder();
+            bridgeOtherConfigsBuilder.setBridgeOtherConfigKey(MdsalHelper.DISABLE_IN_BAND);
+            bridgeOtherConfigsBuilder.setBridgeOtherConfigValue("true");
+            bridgeOtherConfigsBuilder.setBridgeOtherConfigKey(MdsalHelper.DISABLE_IN_BAND);
+            List<BridgeOtherConfigs> bridgeOtherConfigsList = new ArrayList<>();
+            bridgeOtherConfigsList.add(bridgeOtherConfigsBuilder.build());
+            ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(bridgeOtherConfigsList);
             setManagedByForBridge(ovsdbBridgeAugmentationBuilder, ovsdbNode.getKey());
             if (isOvsdbNodeDpdk(ovsdbNode)) {
                 ovsdbBridgeAugmentationBuilder.setDatapathType(DatapathTypeNetdev.class);
@@ -290,11 +314,11 @@ public class SouthboundImpl implements Southbound {
     }
 
     private List<ProtocolEntry> createMdsalProtocols() {
-        List<ProtocolEntry> protocolList = new ArrayList<ProtocolEntry>();
+        List<ProtocolEntry> protocolList = new ArrayList<>();
         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
                 MdsalHelper.OVSDB_PROTOCOL_MAP.inverse();
         protocolList.add(new ProtocolEntryBuilder().
-                setProtocol((Class<? extends OvsdbBridgeProtocolBase>) mapper.get("OpenFlow13")).build());
+                setProtocol(mapper.get("OpenFlow13")).build());
         return protocolList;
     }
 
@@ -357,7 +381,7 @@ public class SouthboundImpl implements Southbound {
     }
 
     public List<Node> getAllBridgesOnOvsdbNode(Node node) {
-        List<Node> nodes = new ArrayList<Node>();
+        List<Node> nodes = new ArrayList<>();
         List<ManagedNodeEntry> managedNodes = node.getAugmentation(OvsdbNodeAugmentation.class).getManagedNodeEntry();
         for (ManagedNodeEntry managedNode : managedNodes) {
             InstanceIdentifier<?> bridgeIid = managedNode.getBridgeRef().getValue();
@@ -450,7 +474,7 @@ public class SouthboundImpl implements Southbound {
     }
 
     public List<TerminationPoint> extractTerminationPoints(Node node) {
-        List<TerminationPoint> terminationPoints = new ArrayList<TerminationPoint>();
+        List<TerminationPoint> terminationPoints = new ArrayList<>();
         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = node.getAugmentation(OvsdbBridgeAugmentation.class);
         if (ovsdbBridgeAugmentation != null) {
             terminationPoints.addAll(node.getTerminationPoint());
@@ -459,7 +483,7 @@ public class SouthboundImpl implements Southbound {
     }
 
     public List<OvsdbTerminationPointAugmentation> extractTerminationPointAugmentations( Node node ) {
-        List<OvsdbTerminationPointAugmentation> tpAugmentations = new ArrayList<OvsdbTerminationPointAugmentation>();
+        List<OvsdbTerminationPointAugmentation> tpAugmentations = new ArrayList<>();
         List<TerminationPoint> terminationPoints = node.getTerminationPoint();
         if(terminationPoints != null && !terminationPoints.isEmpty()){
             for(TerminationPoint tp : terminationPoints){
@@ -479,7 +503,7 @@ public class SouthboundImpl implements Southbound {
         if(operNode != null){
             return extractTerminationPointAugmentations(operNode);
         }
-        return new ArrayList<OvsdbTerminationPointAugmentation>();
+        return new ArrayList<>();
     }
 
     public String getInterfaceExternalIdsValue(
@@ -530,7 +554,7 @@ public class SouthboundImpl implements Southbound {
             tpAugmentationBuilder.setInterfaceType(MdsalHelper.OVSDB_INTERFACE_TYPE_MAP.get(type));
         }
 
-        List<Options> optionsList = new ArrayList<Options>();
+        List<Options> optionsList = new ArrayList<>();
         for (Map.Entry<String, String> entry : options.entrySet()) {
             OptionsBuilder optionsBuilder = new OptionsBuilder();
             optionsBuilder.setKey(new OptionsKey(entry.getKey()));
@@ -563,7 +587,7 @@ public class SouthboundImpl implements Southbound {
     }
 
     public Boolean addPatchTerminationPoint(Node node, String bridgeName, String portName, String peerPortName) {
-        Map<String, String> option = new HashMap<String, String>();
+        Map<String, String> option = new HashMap<>();
         option.put("peer", peerPortName);
         return addTerminationPoint(node, bridgeName, portName, PATCH_PORT_TYPE, option);
     }
@@ -697,8 +721,7 @@ public class SouthboundImpl implements Southbound {
                 .create(NetworkTopology.class)
                 .child(Topology.class, new TopologyKey(MdsalHelper.OVSDB_TOPOLOGY_ID));
 
-        Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
-        return topology;
+        return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
     }
 
     public Long getOFPort(OvsdbTerminationPointAugmentation port) {
index 935fadb28bb223856a3e8c524b9b381e134cadc5..e72187f40771acac23757c26b7090f696ae02562 100644 (file)
@@ -13,7 +13,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import java.io.Serializable;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -140,32 +139,32 @@ public class NeutronFirewall implements Serializable, INeutronObject {
 
     public NeutronFirewall extractFields(List<String> fields) {
         NeutronFirewall ans = new NeutronFirewall();
-        Iterator<String> i = fields.iterator();
-        while (i.hasNext()) {
-            String s = i.next();
-            if (s.equals("id")) {
-                ans.setID(this.getID());
-            }
-            if (s.equals("tenant_id")) {
-                ans.setFirewallTenantID(this.getFirewallTenantID());
-            }
-            if (s.equals("name")) {
-                ans.setFirewallName(this.getFirewallName());
-            }
-            if(s.equals("description")) {
-                ans.setFirewallDescription(this.getFirewallDescription());
-            }
-            if (s.equals("admin_state_up")) {
-                ans.setFirewallAdminStateIsUp(firewallAdminStateIsUp);
-            }
-            if (s.equals("status")) {
-                ans.setFirewallStatus(this.getFirewallStatus());
-            }
-            if (s.equals("shared")) {
-                ans.setFirewallIsShared(firewallIsShared);
-            }
-            if (s.equals("firewall_policy_id")) {
-                ans.setNeutronFirewallPolicyID(this.getFirewallPolicyID());
+        for (String s : fields) {
+            switch (s) {
+                case "id":
+                    ans.setID(this.getID());
+                    break;
+                case "tenant_id":
+                    ans.setFirewallTenantID(this.getFirewallTenantID());
+                    break;
+                case "name":
+                    ans.setFirewallName(this.getFirewallName());
+                    break;
+                case "description":
+                    ans.setFirewallDescription(this.getFirewallDescription());
+                    break;
+                case "admin_state_up":
+                    ans.setFirewallAdminStateIsUp(firewallAdminStateIsUp);
+                    break;
+                case "status":
+                    ans.setFirewallStatus(this.getFirewallStatus());
+                    break;
+                case "shared":
+                    ans.setFirewallIsShared(firewallIsShared);
+                    break;
+                case "firewall_policy_id":
+                    ans.setNeutronFirewallPolicyID(this.getFirewallPolicyID());
+                    break;
             }
         }
         return ans;
index ad9da39bb8db2ea5256bf6cfd6b6413a0da33a79..5a6efb8067bb9a57a10c43d73e2225061198ac88 100644 (file)
@@ -14,7 +14,6 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -129,31 +128,31 @@ public class NeutronFirewallPolicy implements Serializable, INeutronObject {
 
     public NeutronFirewallPolicy extractFields(List<String> fields) {
         NeutronFirewallPolicy ans = new NeutronFirewallPolicy();
-        Iterator<String> i = fields.iterator();
-        while (i.hasNext()) {
-            String s = i.next();
-            if (s.equals("id")) {
-                ans.setID(this.getID());
-            }
-            if (s.equals("tenant_id")) {
-                ans.setFirewallPolicyTenantID(this.getFirewallPolicyTenantID());
-            }
-            if (s.equals("name")) {
-                ans.setFirewallPolicyName(this.getFirewallPolicyName());
-            }
-            if(s.equals("description")) {
-                ans.setFirewallPolicyDescription(this.getFirewallPolicyDescription());
-            }
-            if (s.equals("shared")) {
-                ans.setFirewallPolicyIsShared(firewallPolicyIsShared);
-            }
-            if (s.equals("firewall_rules")) {
-                List<String> firewallRuleList = new ArrayList<String>();
-                firewallRuleList.addAll(this.getFirewallPolicyRules());
-                ans.setFirewallPolicyRules(firewallRuleList);
-            }
-            if (s.equals("audited")) {
-                ans.setFirewallPolicyIsAudited(firewallPolicyIsAudited);
+        for (String s : fields) {
+            switch (s) {
+                case "id":
+                    ans.setID(this.getID());
+                    break;
+                case "tenant_id":
+                    ans.setFirewallPolicyTenantID(this.getFirewallPolicyTenantID());
+                    break;
+                case "name":
+                    ans.setFirewallPolicyName(this.getFirewallPolicyName());
+                    break;
+                case "description":
+                    ans.setFirewallPolicyDescription(this.getFirewallPolicyDescription());
+                    break;
+                case "shared":
+                    ans.setFirewallPolicyIsShared(firewallPolicyIsShared);
+                    break;
+                case "firewall_rules":
+                    List<String> firewallRuleList = new ArrayList<>();
+                    firewallRuleList.addAll(this.getFirewallPolicyRules());
+                    ans.setFirewallPolicyRules(firewallRuleList);
+                    break;
+                case "audited":
+                    ans.setFirewallPolicyIsAudited(firewallPolicyIsAudited);
+                    break;
             }
         }
         return ans;
index 9bc4c52b9f80e978b0b71fd2d2d85ac34d72e145..e198cb1d7ac7368916b3621638f31a0622a70dca 100644 (file)
@@ -13,7 +13,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import java.io.Serializable;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -237,53 +236,53 @@ public class NeutronFirewallRule implements Serializable, INeutronObject {
 
     public NeutronFirewallRule extractFields(List<String> fields) {
         NeutronFirewallRule ans = new NeutronFirewallRule();
-        Iterator<String> i = fields.iterator();
-        while (i.hasNext()) {
-            String s = i.next();
-            if (s.equals("id")) {
-                ans.setID(this.getID());
-            }
-            if (s.equals("tenant_id")) {
-                ans.setFirewallRuleTenantID(this.getFirewallRuleTenantID());
-            }
-            if (s.equals("name")) {
-                ans.setFirewallRuleName(this.getFirewallRuleName());
-            }
-            if (s.equals("description")) {
-                ans.setFirewallRuleDescription(this.getFirewallRuleDescription());
-            }
-            if (s.equals("status")) {
-                ans.setFirewallRuleStatus(this.getFirewallRuleStatus());
-            }
-            if (s.equals("shared")) {
-                ans.setFirewallRuleIsShared(firewallRuleIsShared);
-            }
-            if (s.equals("firewall_policy_id")) {
-                ans.setFirewallRulesPolicyID(this.getFirewallRulePolicyID());
-            }
-            if (s.equals("protocol")) {
-                ans.setFirewallRuleProtocol(this.getFirewallRuleProtocol());
-            }
-            if (s.equals("source_ip_address")) {
-                ans.setFirewallRuleSrcIpAddr(this.getFirewallRuleSrcIpAddr());
-            }
-            if (s.equals("destination_ip_address")) {
-                ans.setFirewallRuleDstIpAddr(this.getFirewallRuleDstIpAddr());
-            }
-            if (s.equals("source_port")) {
-                ans.setFirewallRuleSrcPort(this.getFirewallRuleSrcPort());
-            }
-            if (s.equals("destination_port")) {
-                ans.setFirewallRuleDstPort(this.getFirewallRuleDstPort());
-            }
-            if (s.equals("position")) {
-                ans.setFirewallRulePosition(this.getFirewallRulePosition());
-            }
-            if (s.equals("action")) {
-                ans.setFirewallRuleAction(this.getFirewallRuleAction());
-            }
-            if (s.equals("enabled")) {
-                ans.setFirewallRuleIsEnabled(firewallRuleIsEnabled);
+        for (String s : fields) {
+            switch (s) {
+                case "id":
+                    ans.setID(this.getID());
+                    break;
+                case "tenant_id":
+                    ans.setFirewallRuleTenantID(this.getFirewallRuleTenantID());
+                    break;
+                case "name":
+                    ans.setFirewallRuleName(this.getFirewallRuleName());
+                    break;
+                case "description":
+                    ans.setFirewallRuleDescription(this.getFirewallRuleDescription());
+                    break;
+                case "status":
+                    ans.setFirewallRuleStatus(this.getFirewallRuleStatus());
+                    break;
+                case "shared":
+                    ans.setFirewallRuleIsShared(firewallRuleIsShared);
+                    break;
+                case "firewall_policy_id":
+                    ans.setFirewallRulesPolicyID(this.getFirewallRulePolicyID());
+                    break;
+                case "protocol":
+                    ans.setFirewallRuleProtocol(this.getFirewallRuleProtocol());
+                    break;
+                case "source_ip_address":
+                    ans.setFirewallRuleSrcIpAddr(this.getFirewallRuleSrcIpAddr());
+                    break;
+                case "destination_ip_address":
+                    ans.setFirewallRuleDstIpAddr(this.getFirewallRuleDstIpAddr());
+                    break;
+                case "source_port":
+                    ans.setFirewallRuleSrcPort(this.getFirewallRuleSrcPort());
+                    break;
+                case "destination_port":
+                    ans.setFirewallRuleDstPort(this.getFirewallRuleDstPort());
+                    break;
+                case "position":
+                    ans.setFirewallRulePosition(this.getFirewallRulePosition());
+                    break;
+                case "action":
+                    ans.setFirewallRuleAction(this.getFirewallRuleAction());
+                    break;
+                case "enabled":
+                    ans.setFirewallRuleIsEnabled(firewallRuleIsEnabled);
+                    break;
             }
 
         }
index 89bde7004faa0623fa8ff8739d50edc4a1c1acc6..3b1e4ffc589ecae6d8c045e9d2da330472a733c4 100644 (file)
@@ -9,7 +9,6 @@
 package org.opendaylight.ovsdb.openstack.netvirt.translator;
 
 import java.io.Serializable;
-import java.util.Iterator;
 import java.util.List;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -139,32 +138,32 @@ public class NeutronFloatingIP implements Serializable, INeutronObject {
 
     public NeutronFloatingIP extractFields(List<String> fields) {
         NeutronFloatingIP ans = new NeutronFloatingIP();
-        Iterator<String> i = fields.iterator();
-        while (i.hasNext()) {
-            String s = i.next();
-            if (s.equals("id")) {
-                ans.setID(this.getID());
-            }
-            if (s.equals("floating_network_id")) {
-                ans.setFloatingNetworkUUID(this.getFloatingNetworkUUID());
-            }
-            if (s.equals("port_id")) {
-                ans.setPortUUID(this.getPortUUID());
-            }
-            if (s.equals("fixed_ip_address")) {
-                ans.setFixedIPAddress(this.getFixedIPAddress());
-            }
-            if (s.equals("floating_ip_address")) {
-                ans.setFloatingIPAddress(this.getFloatingIPAddress());
-            }
-            if (s.equals("tenant_id")) {
-                ans.setTenantUUID(this.getTenantUUID());
-            }
-            if (s.equals("router_id")) {
-                ans.setRouterUUID(this.getRouterUUID());
-            }
-            if (s.equals("status")) {
-                ans.setStatus(this.getStatus());
+        for (String s : fields) {
+            switch (s) {
+                case "id":
+                    ans.setID(this.getID());
+                    break;
+                case "floating_network_id":
+                    ans.setFloatingNetworkUUID(this.getFloatingNetworkUUID());
+                    break;
+                case "port_id":
+                    ans.setPortUUID(this.getPortUUID());
+                    break;
+                case "fixed_ip_address":
+                    ans.setFixedIPAddress(this.getFixedIPAddress());
+                    break;
+                case "floating_ip_address":
+                    ans.setFloatingIPAddress(this.getFloatingIPAddress());
+                    break;
+                case "tenant_id":
+                    ans.setTenantUUID(this.getTenantUUID());
+                    break;
+                case "router_id":
+                    ans.setRouterUUID(this.getRouterUUID());
+                    break;
+                case "status":
+                    ans.setStatus(this.getStatus());
+                    break;
             }
         }
         return ans;
index cf9572291e114525570c0ff92877e804ca266db1..03160067c50982512831dc15cf68c1b590e3d83c 100644 (file)
@@ -13,7 +13,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import java.io.Serializable;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -138,32 +137,32 @@ public class NeutronLoadBalancer implements Serializable, INeutronObject {
 
     public NeutronLoadBalancer extractFields(List<String> fields) {
         NeutronLoadBalancer ans = new NeutronLoadBalancer();
-        Iterator<String> i = fields.iterator();
-        while (i.hasNext()) {
-            String s = i.next();
-            if (s.equals("id")) {
-                ans.setID(this.getID());
-            }
-            if (s.equals("tenant_id")) {
-                ans.setLoadBalancerTenantID(this.getLoadBalancerTenantID());
-            }
-            if (s.equals("name")) {
-                ans.setLoadBalancerName(this.getLoadBalancerName());
-            }
-            if(s.equals("description")) {
-                ans.setLoadBalancerDescription(this.getLoadBalancerDescription());
-            }
-            if (s.equals("vip_address")) {
-                ans.setLoadBalancerVipAddress(this.getLoadBalancerVipAddress());
-            }
-            if (s.equals("vip_subnet_id")) {
-                ans.setLoadBalancerVipSubnetID(this.getLoadBalancerVipSubnetID());
-            }
-            if (s.equals("status")) {
-                ans.setLoadBalancerStatus(this.getLoadBalancerStatus());
-            }
-            if (s.equals("admin_state_up")) {
-                ans.setLoadBalancerAdminStateUp(this.getLoadBalancerAdminStateUp());
+        for (String s : fields) {
+            switch (s) {
+                case "id":
+                    ans.setID(this.getID());
+                    break;
+                case "tenant_id":
+                    ans.setLoadBalancerTenantID(this.getLoadBalancerTenantID());
+                    break;
+                case "name":
+                    ans.setLoadBalancerName(this.getLoadBalancerName());
+                    break;
+                case "description":
+                    ans.setLoadBalancerDescription(this.getLoadBalancerDescription());
+                    break;
+                case "vip_address":
+                    ans.setLoadBalancerVipAddress(this.getLoadBalancerVipAddress());
+                    break;
+                case "vip_subnet_id":
+                    ans.setLoadBalancerVipSubnetID(this.getLoadBalancerVipSubnetID());
+                    break;
+                case "status":
+                    ans.setLoadBalancerStatus(this.getLoadBalancerStatus());
+                    break;
+                case "admin_state_up":
+                    ans.setLoadBalancerAdminStateUp(this.getLoadBalancerAdminStateUp());
+                    break;
             }
         }
         return ans;
index 430cef8385eee4ad021dd3e526ac82307e90b464..af55dbe9c5b740975b112fb79a540dae76af15a9 100644 (file)
@@ -13,7 +13,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import java.io.Serializable;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -177,38 +176,38 @@ public class NeutronLoadBalancerHealthMonitor
 
     public NeutronLoadBalancerHealthMonitor extractFields(List<String> fields) {
         NeutronLoadBalancerHealthMonitor ans = new NeutronLoadBalancerHealthMonitor();
-        Iterator<String> i = fields.iterator();
-        while (i.hasNext()) {
-            String s = i.next();
-            if (s.equals("id")) {
-                ans.setID(this.getID());
-            }
-            if (s.equals("tenant_id")) {
-                ans.setLoadBalancerHealthMonitorTenantID(this.getLoadBalancerHealthMonitorTenantID());
-            }
-            if (s.equals("type")) {
-                ans.setLoadBalancerHealthMonitorType(this.getLoadBalancerHealthMonitorType());
-            }
-            if (s.equals("delay")) {
-                ans.setLoadBalancerHealthMonitorDelay(this.getLoadBalancerHealthMonitorDelay());
-            }
-            if (s.equals("timeout")) {
-                ans.setLoadBalancerHealthMonitorTimeout(this.getLoadBalancerHealthMonitorTimeout());
-            }
-            if (s.equals("max_retries")) {
-                ans.setLoadBalancerHealthMonitorMaxRetries(this.getLoadBalancerHealthMonitorMaxRetries());
-            }
-            if (s.equals("http_method")) {
-                ans.setLoadBalancerHealthMonitorHttpMethod(this.getLoadBalancerHealthMonitorHttpMethod());
-            }
-            if(s.equals("url_path")) {
-                ans.setLoadBalancerHealthMonitorUrlPath(this.getLoadBalancerHealthMonitorUrlPath());
-            }
-            if (s.equals("expected_codes")) {
-                ans.setLoadBalancerHealthMonitorExpectedCodes(this.getLoadBalancerHealthMonitorExpectedCodes());
-            }
-            if (s.equals("admin_state_up")) {
-                ans.setLoadBalancerHealthMonitorAdminStateIsUp(loadBalancerHealthMonitorAdminStateIsUp);
+        for (String s : fields) {
+            switch (s) {
+                case "id":
+                    ans.setID(this.getID());
+                    break;
+                case "tenant_id":
+                    ans.setLoadBalancerHealthMonitorTenantID(this.getLoadBalancerHealthMonitorTenantID());
+                    break;
+                case "type":
+                    ans.setLoadBalancerHealthMonitorType(this.getLoadBalancerHealthMonitorType());
+                    break;
+                case "delay":
+                    ans.setLoadBalancerHealthMonitorDelay(this.getLoadBalancerHealthMonitorDelay());
+                    break;
+                case "timeout":
+                    ans.setLoadBalancerHealthMonitorTimeout(this.getLoadBalancerHealthMonitorTimeout());
+                    break;
+                case "max_retries":
+                    ans.setLoadBalancerHealthMonitorMaxRetries(this.getLoadBalancerHealthMonitorMaxRetries());
+                    break;
+                case "http_method":
+                    ans.setLoadBalancerHealthMonitorHttpMethod(this.getLoadBalancerHealthMonitorHttpMethod());
+                    break;
+                case "url_path":
+                    ans.setLoadBalancerHealthMonitorUrlPath(this.getLoadBalancerHealthMonitorUrlPath());
+                    break;
+                case "expected_codes":
+                    ans.setLoadBalancerHealthMonitorExpectedCodes(this.getLoadBalancerHealthMonitorExpectedCodes());
+                    break;
+                case "admin_state_up":
+                    ans.setLoadBalancerHealthMonitorAdminStateIsUp(loadBalancerHealthMonitorAdminStateIsUp);
+                    break;
             }
         }
         return ans;
index 48d19b5e2e02c880cfc6cfdd64e0192bab11e027..38101addfb6794bf82168e6d88e2746417eeadb1 100644 (file)
@@ -13,7 +13,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import java.io.Serializable;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -166,32 +165,32 @@ public class NeutronLoadBalancerListener
 
     public NeutronLoadBalancerListener extractFields(List<String> fields) {
         NeutronLoadBalancerListener ans = new NeutronLoadBalancerListener();
-        Iterator<String> i = fields.iterator();
-        while (i.hasNext()) {
-            String s = i.next();
-            if (s.equals("id")) {
-                ans.setID(this.getID());
-            }
-            if(s.equals("default_pool_id")) {
-                ans.setNeutronLoadBalancerListenerDefaultPoolID(this.getNeutronLoadBalancerListenerDefaultPoolID());
-            }
-            if (s.equals("tenant_id")) {
-                ans.setLoadBalancerListenerTenantID(this.getLoadBalancerListenerTenantID());
-            }
-            if (s.equals("name")) {
-                ans.setLoadBalancerListenerName(this.getLoadBalancerListenerName());
-            }
-            if(s.equals("description")) {
-                ans.setLoadBalancerListenerDescription(this.getLoadBalancerListenerDescription());
-            }
-            if (s.equals("protocol")) {
-                ans.setNeutronLoadBalancerListenerProtocol(this.getNeutronLoadBalancerListenerProtocol());
-            }
-            if (s.equals("protocol_port")) {
-                ans.setNeutronLoadBalancerListenerProtocolPort(this.getNeutronLoadBalancerListenerProtocolPort());
-            }
-            if (s.equals("admin_state_up")) {
-                ans.setLoadBalancerListenerAdminStateIsUp(loadBalancerListenerAdminStateIsUp);
+        for (String s : fields) {
+            switch (s) {
+                case "id":
+                    ans.setID(this.getID());
+                    break;
+                case "default_pool_id":
+                    ans.setNeutronLoadBalancerListenerDefaultPoolID(this.getNeutronLoadBalancerListenerDefaultPoolID());
+                    break;
+                case "tenant_id":
+                    ans.setLoadBalancerListenerTenantID(this.getLoadBalancerListenerTenantID());
+                    break;
+                case "name":
+                    ans.setLoadBalancerListenerName(this.getLoadBalancerListenerName());
+                    break;
+                case "description":
+                    ans.setLoadBalancerListenerDescription(this.getLoadBalancerListenerDescription());
+                    break;
+                case "protocol":
+                    ans.setNeutronLoadBalancerListenerProtocol(this.getNeutronLoadBalancerListenerProtocol());
+                    break;
+                case "protocol_port":
+                    ans.setNeutronLoadBalancerListenerProtocolPort(this.getNeutronLoadBalancerListenerProtocolPort());
+                    break;
+                case "admin_state_up":
+                    ans.setLoadBalancerListenerAdminStateIsUp(loadBalancerListenerAdminStateIsUp);
+                    break;
             }
         }
         return ans;
index 890dd3879f7ae80e3ebb9051133f8f4f9f418fc1..195b82ae9e81f4d60593c885ca6535f2fe69413f 100644 (file)
@@ -13,7 +13,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import java.io.Serializable;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -194,35 +193,35 @@ public class NeutronLoadBalancerPool implements Serializable, INeutronObject {
 
     public NeutronLoadBalancerPool extractFields(List<String> fields) {
         NeutronLoadBalancerPool ans = new NeutronLoadBalancerPool();
-        Iterator<String> i = fields.iterator();
-        while (i.hasNext()) {
-            String s = i.next();
-            if (s.equals("id")) {
-                ans.setID(this.getID());
-            }
-            if (s.equals("tenant_id")) {
-                ans.setLoadBalancerPoolTenantID(this.getLoadBalancerPoolTenantID());
-            }
-            if (s.equals("name")) {
-                ans.setLoadBalancerPoolName(this.getLoadBalancerPoolName());
-            }
-            if(s.equals("description")) {
-                ans.setLoadBalancerPoolDescription(this.getLoadBalancerPoolDescription());
-            }
-            if(s.equals("protocol")) {
-                ans.setLoadBalancerPoolProtocol(this.getLoadBalancerPoolProtocol());
-            }
-            if (s.equals("lb_algorithm")) {
-                ans.setLoadBalancerPoolLbAlgorithm(this.getLoadBalancerPoolLbAlgorithm());
-            }
-            if (s.equals("healthmonitor_id")) {
-                ans.setNeutronLoadBalancerPoolHealthMonitorID(this.getNeutronLoadBalancerPoolHealthMonitorID());
-            }
-            if (s.equals("admin_state_up")) {
-                ans.setLoadBalancerPoolAdminStateIsUp(loadBalancerPoolAdminStateIsUp);
-            }
-            if (s.equals("members")) {
-                ans.setLoadBalancerPoolMembers(getLoadBalancerPoolMembers());
+        for (String s : fields) {
+            switch (s) {
+                case "id":
+                    ans.setID(this.getID());
+                    break;
+                case "tenant_id":
+                    ans.setLoadBalancerPoolTenantID(this.getLoadBalancerPoolTenantID());
+                    break;
+                case "name":
+                    ans.setLoadBalancerPoolName(this.getLoadBalancerPoolName());
+                    break;
+                case "description":
+                    ans.setLoadBalancerPoolDescription(this.getLoadBalancerPoolDescription());
+                    break;
+                case "protocol":
+                    ans.setLoadBalancerPoolProtocol(this.getLoadBalancerPoolProtocol());
+                    break;
+                case "lb_algorithm":
+                    ans.setLoadBalancerPoolLbAlgorithm(this.getLoadBalancerPoolLbAlgorithm());
+                    break;
+                case "healthmonitor_id":
+                    ans.setNeutronLoadBalancerPoolHealthMonitorID(this.getNeutronLoadBalancerPoolHealthMonitorID());
+                    break;
+                case "admin_state_up":
+                    ans.setLoadBalancerPoolAdminStateIsUp(loadBalancerPoolAdminStateIsUp);
+                    break;
+                case "members":
+                    ans.setLoadBalancerPoolMembers(getLoadBalancerPoolMembers());
+                    break;
             }
         }
         return ans;
index 274aa6c36c7ee4fb115550ad542480e7fb4cc424..d36487f01bf56e12ef860307cdbc66fcdc0c188d 100644 (file)
@@ -14,7 +14,6 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 import java.io.Serializable;
-import java.util.Iterator;
 import java.util.List;
 
 @XmlRootElement
@@ -131,32 +130,32 @@ public class NeutronLoadBalancerPoolMember
 
     public NeutronLoadBalancerPoolMember extractFields(List<String> fields) {
         NeutronLoadBalancerPoolMember ans = new NeutronLoadBalancerPoolMember();
-        Iterator<String> i = fields.iterator();
-        while (i.hasNext()) {
-            String s = i.next();
-            if (s.equals("id")) {
-                ans.setID(this.getID());
-            }
-            if (s.equals("pool_id")) {
-                ans.setPoolID(this.getPoolID());
-            }
-            if (s.equals("tenant_id")) {
-                ans.setPoolMemberTenantID(this.getPoolMemberTenantID());
-            }
-            if (s.equals("address")) {
-                ans.setPoolMemberAddress(this.getPoolMemberAddress());
-            }
-            if(s.equals("protocol_port")) {
-                ans.setPoolMemberProtoPort(this.getPoolMemberProtoPort());
-            }
-            if (s.equals("admin_state_up")) {
-                ans.setPoolMemberAdminStateIsUp(poolMemberAdminStateIsUp);
-            }
-            if(s.equals("weight")) {
-                ans.setPoolMemberWeight(this.getPoolMemberWeight());
-            }
-            if(s.equals("subnet_id")) {
-                ans.setPoolMemberSubnetID(this.getPoolMemberSubnetID());
+        for (String s : fields) {
+            switch (s) {
+                case "id":
+                    ans.setID(this.getID());
+                    break;
+                case "pool_id":
+                    ans.setPoolID(this.getPoolID());
+                    break;
+                case "tenant_id":
+                    ans.setPoolMemberTenantID(this.getPoolMemberTenantID());
+                    break;
+                case "address":
+                    ans.setPoolMemberAddress(this.getPoolMemberAddress());
+                    break;
+                case "protocol_port":
+                    ans.setPoolMemberProtoPort(this.getPoolMemberProtoPort());
+                    break;
+                case "admin_state_up":
+                    ans.setPoolMemberAdminStateIsUp(poolMemberAdminStateIsUp);
+                    break;
+                case "weight":
+                    ans.setPoolMemberWeight(this.getPoolMemberWeight());
+                    break;
+                case "subnet_id":
+                    ans.setPoolMemberSubnetID(this.getPoolMemberSubnetID());
+                    break;
             }
         }
         return ans;
index b6396dc6e42c782c948201bd0199e572aabca9c6..4d5b3118a6adaba8665a43b41eebec71ad927e35 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.ovsdb.openstack.netvirt.translator;
 
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -81,7 +80,7 @@ public class NeutronNetwork implements Serializable, INeutronObject {
     }
 
     public void initDefaults() {
-        subnets = new ArrayList<String>();
+        subnets = new ArrayList<>();
         if (status == null) {
             status = "ACTIVE";
         }
@@ -237,43 +236,43 @@ public class NeutronNetwork implements Serializable, INeutronObject {
 
     public NeutronNetwork extractFields(List<String> fields) {
         NeutronNetwork ans = new NeutronNetwork();
-        Iterator<String> i = fields.iterator();
-        while (i.hasNext()) {
-            String s = i.next();
-            if (s.equals("id")) {
-                ans.setNetworkUUID(this.getNetworkUUID());
-            }
-            if (s.equals("name")) {
-                ans.setNetworkName(this.getNetworkName());
-            }
-            if (s.equals("admin_state_up")) {
-                ans.setAdminStateUp(adminStateUp);
-            }
-            if (s.equals("status")) {
-                ans.setStatus(this.getStatus());
-            }
-            if (s.equals("subnets")) {
-                List<String> subnetList = new ArrayList<String>();
-                subnetList.addAll(this.getSubnets());
-                ans.setSubnets(subnetList);
-            }
-            if (s.equals("shared")) {
-                ans.setShared(shared);
-            }
-            if (s.equals("tenant_id")) {
-                ans.setTenantID(this.getTenantID());
-            }
-            if (s.equals("external")) {
-                ans.setRouterExternal(this.getRouterExternal());
-            }
-            if (s.equals("segmentation_id")) {
-                ans.setProviderSegmentationID(this.getProviderSegmentationID());
-            }
-            if (s.equals("physical_network")) {
-                ans.setProviderPhysicalNetwork(this.getProviderPhysicalNetwork());
-            }
-            if (s.equals("network_type")) {
-                ans.setProviderNetworkType(this.getProviderNetworkType());
+        for (String s : fields) {
+            switch (s) {
+                case "id":
+                    ans.setNetworkUUID(this.getNetworkUUID());
+                    break;
+                case "name":
+                    ans.setNetworkName(this.getNetworkName());
+                    break;
+                case "admin_state_up":
+                    ans.setAdminStateUp(adminStateUp);
+                    break;
+                case "status":
+                    ans.setStatus(this.getStatus());
+                    break;
+                case "subnets":
+                    List<String> subnetList = new ArrayList<>();
+                    subnetList.addAll(this.getSubnets());
+                    ans.setSubnets(subnetList);
+                    break;
+                case "shared":
+                    ans.setShared(shared);
+                    break;
+                case "tenant_id":
+                    ans.setTenantID(this.getTenantID());
+                    break;
+                case "external":
+                    ans.setRouterExternal(this.getRouterExternal());
+                    break;
+                case "segmentation_id":
+                    ans.setProviderSegmentationID(this.getProviderSegmentationID());
+                    break;
+                case "physical_network":
+                    ans.setProviderPhysicalNetwork(this.getProviderPhysicalNetwork());
+                    break;
+                case "network_type":
+                    ans.setProviderNetworkType(this.getProviderNetworkType());
+                    break;
             }
         }
         return ans;
index 2608cd47dbf1c53f17e8d3002fda3a3a05a7e32c..b77e4113e1a2929bae9289e2903778b27f93451f 100644 (file)
@@ -274,7 +274,7 @@ public class NeutronPort implements Serializable, INeutronObject {
                 ans.setMacAddress(this.getMacAddress());
             }
             if ("fixed_ips".equals(field)) {
-                ans.setFixedIPs(new ArrayList<Neutron_IPs>(this.getFixedIPs()));
+                ans.setFixedIPs(new ArrayList<>(this.getFixedIPs()));
             }
             if ("device_id".equals(field)) {
                 ans.setDeviceID(this.getDeviceID());
@@ -286,7 +286,7 @@ public class NeutronPort implements Serializable, INeutronObject {
                 ans.setTenantID(this.getTenantID());
             }
             if ("security_groups".equals(field)) {
-                ans.setSecurityGroups(new ArrayList<NeutronSecurityGroup>(this.getSecurityGroups()));
+                ans.setSecurityGroups(new ArrayList<>(this.getSecurityGroups()));
             }
         }
         return ans;
@@ -298,7 +298,7 @@ public class NeutronPort implements Serializable, INeutronObject {
             status = "ACTIVE";
         }
         if (fixedIPs == null) {
-            fixedIPs = new ArrayList<Neutron_IPs>();
+            fixedIPs = new ArrayList<>();
         }
     }
 
index cc64cd055695ab5e1ca53f792ede44272a91edb5..a37a188d555d845d8db7d651c253b7ef7626cecf 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.ovsdb.openstack.netvirt.translator;
 
 import java.io.Serializable;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -60,7 +59,7 @@ public class NeutronRouter implements Serializable, INeutronObject {
     Map<String, NeutronRouter_Interface> interfaces;
 
     public NeutronRouter() {
-        interfaces = new HashMap<String, NeutronRouter_Interface>();
+        interfaces = new HashMap<>();
     }
 
     public String getID() { return routerUUID; }
@@ -155,35 +154,35 @@ public class NeutronRouter implements Serializable, INeutronObject {
      */
     public NeutronRouter extractFields(List<String> fields) {
         NeutronRouter ans = new NeutronRouter();
-        Iterator<String> i = fields.iterator();
-        while (i.hasNext()) {
-            String s = i.next();
-            if (s.equals("id")) {
-                ans.setRouterUUID(this.getRouterUUID());
-            }
-            if (s.equals("name")) {
-                ans.setName(this.getName());
-            }
-            if (s.equals("admin_state_up")) {
-                ans.setAdminStateUp(this.getAdminStateUp());
-            }
-            if (s.equals("status")) {
-                ans.setStatus(this.getStatus());
-            }
-            if (s.equals("tenant_id")) {
-                ans.setTenantID(this.getTenantID());
-            }
-            if (s.equals("external_gateway_info")) {
-                ans.setExternalGatewayInfo(this.getExternalGatewayInfo());
-            }
-            if (s.equals("distributed")) {
-                ans.setDistributed(this.getDistributed());
-            }
-            if (s.equals("gw_port_id")) {
-                ans.setGatewayPortId(this.getGatewayPortId());
-            }
-            if (s.equals("routes")){
-                ans.setRoutes(this.getRoutes());
+        for (String s : fields) {
+            switch (s) {
+                case "id":
+                    ans.setRouterUUID(this.getRouterUUID());
+                    break;
+                case "name":
+                    ans.setName(this.getName());
+                    break;
+                case "admin_state_up":
+                    ans.setAdminStateUp(this.getAdminStateUp());
+                    break;
+                case "status":
+                    ans.setStatus(this.getStatus());
+                    break;
+                case "tenant_id":
+                    ans.setTenantID(this.getTenantID());
+                    break;
+                case "external_gateway_info":
+                    ans.setExternalGatewayInfo(this.getExternalGatewayInfo());
+                    break;
+                case "distributed":
+                    ans.setDistributed(this.getDistributed());
+                    break;
+                case "gw_port_id":
+                    ans.setGatewayPortId(this.getGatewayPortId());
+                    break;
+                case "routes":
+                    ans.setRoutes(this.getRoutes());
+                    break;
             }
         }
         return ans;
index 9a5daedf68c7f80a923378126200ed7bc40e4cc9..9f898b8c7cd60d038e441515320256480930c53b 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.ovsdb.openstack.netvirt.translator;
 
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -52,7 +51,7 @@ public class NeutronSecurityGroup implements Serializable, INeutronObject {
     List<NeutronSecurityRule> neutronSecurityRule;
 
     public NeutronSecurityGroup() {
-        neutronSecurityRule = new ArrayList<NeutronSecurityRule>();
+        neutronSecurityRule = new ArrayList<>();
 
     }
 
@@ -109,23 +108,23 @@ public class NeutronSecurityGroup implements Serializable, INeutronObject {
 
     public NeutronSecurityGroup extractFields(List<String> fields) {
         NeutronSecurityGroup ans = new NeutronSecurityGroup ();
-        Iterator<String> i = fields.iterator ();
-        while (i.hasNext ()) {
-            String s = i.next ();
-            if (s.equals ("id")) {
-                ans.setID (this.getID ());
-            }
-            if (s.equals ("name")) {
-                ans.setSecurityGroupName (this.getSecurityGroupName ());
-            }
-            if (s.equals ("description")) {
-                ans.setSecurityGroupDescription (this.getSecurityGroupDescription ());
-            }
-            if (s.equals ("tenant_id")) {
-                ans.setSecurityGroupTenantID (this.getSecurityGroupTenantID ());
-            }
-            if (s.equals ("security_group_rules")) {
-                ans.setSecurityRules (this.getSecurityRules ());
+        for (String s : fields) {
+            switch (s) {
+                case "id":
+                    ans.setID(this.getID());
+                    break;
+                case "name":
+                    ans.setSecurityGroupName(this.getSecurityGroupName());
+                    break;
+                case "description":
+                    ans.setSecurityGroupDescription(this.getSecurityGroupDescription());
+                    break;
+                case "tenant_id":
+                    ans.setSecurityGroupTenantID(this.getSecurityGroupTenantID());
+                    break;
+                case "security_group_rules":
+                    ans.setSecurityRules(this.getSecurityRules());
+                    break;
             }
         }
         return ans;
index bd6ddd566f405d4fc7267aa334432203c09edabe..b8b9228a3e914e8bcfdd9721feecec026741128d 100644 (file)
@@ -13,7 +13,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import java.io.Serializable;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -164,38 +163,38 @@ public class NeutronSecurityRule implements Serializable, INeutronObject {
 
     public NeutronSecurityRule extractFields(List<String> fields) {
         NeutronSecurityRule ans = new NeutronSecurityRule();
-        Iterator<String> i = fields.iterator();
-        while (i.hasNext()) {
-            String s = i.next();
-            if (s.equals("id")) {
-                ans.setID(this.getID());
-            }
-            if (s.equals("direction")) {
-                ans.setSecurityRuleDirection(this.getSecurityRuleDirection());
-            }
-            if (s.equals("protocol")) {
-                ans.setSecurityRuleProtocol(this.getSecurityRuleProtocol());
-            }
-            if (s.equals("port_range_min")) {
-                ans.setSecurityRulePortMin(this.getSecurityRulePortMin());
-            }
-            if (s.equals("port_range_max")) {
-                ans.setSecurityRulePortMax(this.getSecurityRulePortMax());
-            }
-            if (s.equals("ethertype")) {
-                ans.setSecurityRuleEthertype(this.getSecurityRuleEthertype());
-            }
-            if (s.equals("remote_ip_prefix")) {
-                ans.setSecurityRuleRemoteIpPrefix(this.getSecurityRuleRemoteIpPrefix());
-            }
-            if (s.equals("remote_group_id")) {
-                ans.setSecurityRemoteGroupID(this.getSecurityRemoteGroupID());
-            }
-            if (s.equals("security_group_id")) {
-                ans.setSecurityRuleGroupID(this.getSecurityRuleGroupID());
-            }
-            if (s.equals("tenant_id")) {
-                ans.setSecurityRuleTenantID(this.getSecurityRuleTenantID());
+        for (String s : fields) {
+            switch (s) {
+                case "id":
+                    ans.setID(this.getID());
+                    break;
+                case "direction":
+                    ans.setSecurityRuleDirection(this.getSecurityRuleDirection());
+                    break;
+                case "protocol":
+                    ans.setSecurityRuleProtocol(this.getSecurityRuleProtocol());
+                    break;
+                case "port_range_min":
+                    ans.setSecurityRulePortMin(this.getSecurityRulePortMin());
+                    break;
+                case "port_range_max":
+                    ans.setSecurityRulePortMax(this.getSecurityRulePortMax());
+                    break;
+                case "ethertype":
+                    ans.setSecurityRuleEthertype(this.getSecurityRuleEthertype());
+                    break;
+                case "remote_ip_prefix":
+                    ans.setSecurityRuleRemoteIpPrefix(this.getSecurityRuleRemoteIpPrefix());
+                    break;
+                case "remote_group_id":
+                    ans.setSecurityRemoteGroupID(this.getSecurityRemoteGroupID());
+                    break;
+                case "security_group_id":
+                    ans.setSecurityRuleGroupID(this.getSecurityRuleGroupID());
+                    break;
+                case "tenant_id":
+                    ans.setSecurityRuleTenantID(this.getSecurityRuleTenantID());
+                    break;
             }
         }
         return ans;
index 9d32fc3e78f1fa4c0e9100aad955eb1a164b04cf..1b7e8c979c423d92aa25eb27273b919ab352f504 100644 (file)
@@ -94,7 +94,7 @@ public class NeutronSubnet implements Serializable, INeutronObject {
     List<NeutronPort> myPorts;
 
     public NeutronSubnet() {
-        myPorts = new ArrayList<NeutronPort>();
+        myPorts = new ArrayList<>();
     }
 
     // @deprecated - will be removed in Boron
@@ -219,53 +219,53 @@ public class NeutronSubnet implements Serializable, INeutronObject {
 
     public NeutronSubnet extractFields(List<String> fields) {
         NeutronSubnet ans = new NeutronSubnet();
-        Iterator<String> i = fields.iterator();
-        while (i.hasNext()) {
-            String s = i.next();
-            if (s.equals("id")) {
-                ans.setSubnetUUID(this.getSubnetUUID());
-            }
-            if (s.equals("network_id")) {
-                ans.setNetworkUUID(this.getNetworkUUID());
-            }
-            if (s.equals("name")) {
-                ans.setName(this.getName());
-            }
-            if (s.equals("ip_version")) {
-                ans.setIpVersion(this.getIpVersion());
-            }
-            if (s.equals("cidr")) {
-                ans.setCidr(this.getCidr());
-            }
-            if (s.equals("gateway_ip")) {
-                ans.setGatewayIP(this.getGatewayIP());
-            }
-            if (s.equals("dns_nameservers")) {
-                List<String> nsList = new ArrayList<String>();
-                nsList.addAll(this.getDnsNameservers());
-                ans.setDnsNameservers(nsList);
-            }
-            if (s.equals("allocation_pools")) {
-                List<NeutronSubnetIPAllocationPool> aPools = new ArrayList<NeutronSubnetIPAllocationPool>();
-                aPools.addAll(this.getAllocationPools());
-                ans.setAllocationPools(aPools);
-            }
-            if (s.equals("host_routes")) {
-                List<NeutronSubnet_HostRoute> hRoutes = new ArrayList<NeutronSubnet_HostRoute>();
-                hRoutes.addAll(this.getHostRoutes());
-                ans.setHostRoutes(hRoutes);
-            }
-            if (s.equals("enable_dhcp")) {
-                ans.setEnableDHCP(this.getEnableDHCP());
-            }
-            if (s.equals("tenant_id")) {
-                ans.setTenantID(this.getTenantID());
-            }
-            if (s.equals("ipv6_address_mode")) {
-                ans.setIpV6AddressMode(this.getIpV6AddressMode());
-            }
-            if (s.equals("ipv6_ra_mode")) {
-                ans.setIpV6RaMode(this.getIpV6RaMode());
+        for (String s : fields) {
+            switch (s) {
+                case "id":
+                    ans.setSubnetUUID(this.getSubnetUUID());
+                    break;
+                case "network_id":
+                    ans.setNetworkUUID(this.getNetworkUUID());
+                    break;
+                case "name":
+                    ans.setName(this.getName());
+                    break;
+                case "ip_version":
+                    ans.setIpVersion(this.getIpVersion());
+                    break;
+                case "cidr":
+                    ans.setCidr(this.getCidr());
+                    break;
+                case "gateway_ip":
+                    ans.setGatewayIP(this.getGatewayIP());
+                    break;
+                case "dns_nameservers":
+                    List<String> nsList = new ArrayList<>();
+                    nsList.addAll(this.getDnsNameservers());
+                    ans.setDnsNameservers(nsList);
+                    break;
+                case "allocation_pools":
+                    List<NeutronSubnetIPAllocationPool> aPools = new ArrayList<>();
+                    aPools.addAll(this.getAllocationPools());
+                    ans.setAllocationPools(aPools);
+                    break;
+                case "host_routes":
+                    List<NeutronSubnet_HostRoute> hRoutes = new ArrayList<>();
+                    hRoutes.addAll(this.getHostRoutes());
+                    ans.setHostRoutes(hRoutes);
+                    break;
+                case "enable_dhcp":
+                    ans.setEnableDHCP(this.getEnableDHCP());
+                    break;
+                case "tenant_id":
+                    ans.setTenantID(this.getTenantID());
+                    break;
+                case "ipv6_address_mode":
+                    ans.setIpV6AddressMode(this.getIpV6AddressMode());
+                    break;
+                case "ipv6_ra_mode":
+                    ans.setIpV6RaMode(this.getIpV6RaMode());
+                    break;
             }
         }
         return ans;
@@ -278,7 +278,7 @@ public class NeutronSubnet implements Serializable, INeutronObject {
 
     // @deprecated - will be removed in Boron
     public List<NeutronPort> getPortsInSubnet(String ignore) {
-       List<NeutronPort> answer = new ArrayList<NeutronPort>();
+       List<NeutronPort> answer = new ArrayList<>();
        for (NeutronPort port : myPorts) {
            if (!port.getDeviceOwner().equalsIgnoreCase(ignore)) {
                 answer.add(port);
@@ -319,7 +319,7 @@ public class NeutronSubnet implements Serializable, INeutronObject {
                 int length = Integer.parseInt(parts[1]);
                 //TODO?: limit check on length
                 // convert to byte array
-                byte[] addrBytes = ((Inet6Address) InetAddress.getByName(parts[0])).getAddress();
+                byte[] addrBytes = InetAddress.getByName(parts[0]).getAddress();
                 int i;
                 for (i = length; i < IPV6_LENGTH; i++) {
                     if (((((int) addrBytes[i/IPV6_LENGTH_BYTES]) & IPV6_LSB_MASK) & (1 << (IPV6_BYTE_OFFSET-(i%IPV6_LENGTH_BYTES)))) != 0) {
@@ -340,9 +340,7 @@ public class NeutronSubnet implements Serializable, INeutronObject {
      * or assigning a gateway IP)
      */
     public boolean gatewayIP_Pool_overlap() {
-        Iterator<NeutronSubnetIPAllocationPool> i = allocationPools.iterator();
-        while (i.hasNext()) {
-            NeutronSubnetIPAllocationPool pool = i.next();
+        for (NeutronSubnetIPAllocationPool pool : allocationPools) {
             if (ipVersion == IPV4_VERSION && pool.contains(gatewayIP)) {
                 return true;
             }
@@ -360,12 +358,12 @@ public class NeutronSubnet implements Serializable, INeutronObject {
         if (ipVersion == null) {
             ipVersion = IPV4_VERSION;
         }
-        dnsNameservers = new ArrayList<String>();
+        dnsNameservers = new ArrayList<>();
         if (hostRoutes == null) {
-            hostRoutes = new ArrayList<NeutronSubnet_HostRoute>();
+            hostRoutes = new ArrayList<>();
         }
         if (allocationPools == null) {
-            allocationPools = new ArrayList<NeutronSubnetIPAllocationPool>();
+            allocationPools = new ArrayList<>();
             if (ipVersion == IPV4_VERSION) {
                 try {
                     SubnetUtils util = new SubnetUtils(cidr);
@@ -432,8 +430,8 @@ public class NeutronSubnet implements Serializable, INeutronObject {
             String[] parts = cidr.split("/");
             try {
                 int length = Integer.parseInt(parts[1]);
-                byte[] cidrBytes = ((Inet6Address) InetAddress.getByName(parts[0])).getAddress();
-                byte[] ipBytes =  ((Inet6Address) InetAddress.getByName(ipAddress)).getAddress();
+                byte[] cidrBytes = InetAddress.getByName(parts[0]).getAddress();
+                byte[] ipBytes =  InetAddress.getByName(ipAddress).getAddress();
                 int i;
                 for (i = 0; i < length; i++) {
                     if (((((int) cidrBytes[i/IPV6_LENGTH_BYTES]) & IPV6_LSB_MASK) & (1 << (IPV6_BYTE_OFFSET-(i%IPV6_LENGTH_BYTES)))) !=
@@ -456,23 +454,21 @@ public class NeutronSubnet implements Serializable, INeutronObject {
      */
     public String getLowAddr() {
         String ans = null;
-        Iterator<NeutronSubnetIPAllocationPool> i = allocationPools.iterator();
-        while (i.hasNext()) {
-            NeutronSubnetIPAllocationPool pool = i.next();
+        for (NeutronSubnetIPAllocationPool pool : allocationPools) {
             if (ans == null) {
                 ans = pool.getPoolStart();
-            }
-            else {
+            } else {
                 if (ipVersion == IPV4_VERSION &&
-                    NeutronSubnetIPAllocationPool.convert(pool.getPoolStart()) <
-                            NeutronSubnetIPAllocationPool.convert(ans)) {
+                        NeutronSubnetIPAllocationPool.convert(pool.getPoolStart()) <
+                                NeutronSubnetIPAllocationPool.convert(ans)) {
                     ans = pool.getPoolStart();
                 }
                 if (ipVersion == IPV6_VERSION &&
-                    NeutronSubnetIPAllocationPool.convertV6(pool.getPoolStart()).compareTo(NeutronSubnetIPAllocationPool.convertV6(ans)) < 0) {
+                        NeutronSubnetIPAllocationPool.convertV6(pool.getPoolStart()).compareTo(
+                                NeutronSubnetIPAllocationPool.convertV6(ans)) < 0) {
                     ans = pool.getPoolStart();
                 }
-           }
+            }
         }
         return ans;
     }
index 38f31c74b51653dbab9633452ab24187f97d432d..c3cc0518585d6ad0e02dc54613dc79ed8b8614af 100644 (file)
@@ -138,7 +138,7 @@ public class NeutronSubnetIPAllocationPool implements Serializable {
             return BigInteger.ZERO;
         }
         try {
-            return new BigInteger(((Inet6Address) InetAddress.getByName(inputString)).getAddress());
+            return new BigInteger(InetAddress.getByName(inputString).getAddress());
         } catch (Exception e) {
             LOGGER.error("convertV6 error", e);
             return BigInteger.ZERO;
@@ -211,7 +211,7 @@ public class NeutronSubnetIPAllocationPool implements Serializable {
      * the other ranging from parameter+1 to high
      */
     public List<NeutronSubnetIPAllocationPool> splitPool(String ipAddress) {
-        List<NeutronSubnetIPAllocationPool> ans = new ArrayList<NeutronSubnetIPAllocationPool>();
+        List<NeutronSubnetIPAllocationPool> ans = new ArrayList<>();
         long gIP = NeutronSubnetIPAllocationPool.convert(ipAddress);
         long sIP = NeutronSubnetIPAllocationPool.convert(poolStart);
         long eIP = NeutronSubnetIPAllocationPool.convert(poolEnd);
@@ -277,7 +277,7 @@ public class NeutronSubnetIPAllocationPool implements Serializable {
      * If the pool is a single address, return null
      */
     public List<NeutronSubnetIPAllocationPool> splitPoolV6(String ipAddress) {
-        List<NeutronSubnetIPAllocationPool> ans = new ArrayList<NeutronSubnetIPAllocationPool>();
+        List<NeutronSubnetIPAllocationPool> ans = new ArrayList<>();
         BigInteger gIP = NeutronSubnetIPAllocationPool.convertV6(ipAddress);
         BigInteger sIP = NeutronSubnetIPAllocationPool.convertV6(poolStart);
         BigInteger eIP = NeutronSubnetIPAllocationPool.convertV6(poolEnd);
index 20dc3c37fc9cc266f3392ed1fce8b47fa7c6b87e..c417e6e4220b60a69cab9bec05310f832f4296f7 100644 (file)
@@ -53,7 +53,7 @@ public class NeutronFloatingIPInterface extends AbstractNeutronInterface<Floatin
 
     @Override
     public List<NeutronFloatingIP> getAllFloatingIPs() {
-        Set<NeutronFloatingIP> allIPs = new HashSet<NeutronFloatingIP>();
+        Set<NeutronFloatingIP> allIPs = new HashSet<>();
         Floatingips fips = readMd(createInstanceIdentifier());
         if (fips != null) {
             for (Floatingip fip: fips.getFloatingip()) {
@@ -61,7 +61,7 @@ public class NeutronFloatingIPInterface extends AbstractNeutronInterface<Floatin
             }
         }
         LOGGER.debug("Exiting getAllFloatingIPs, Found {} FloatingIPs", allIPs.size());
-        List<NeutronFloatingIP> ans = new ArrayList<NeutronFloatingIP>();
+        List<NeutronFloatingIP> ans = new ArrayList<>();
         ans.addAll(allIPs);
         return ans;
     }
index 770516e234d4a152b0c9ba67c49584d39d4b1cba..058607de8cc6736f304c803ee095426a35eb87b1 100644 (file)
@@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory;
  */
 public class NeutronLoadBalancerInterface extends AbstractNeutronInterface<Loadbalancer, NeutronLoadBalancer> implements INeutronLoadBalancerCRUD {
     private static final Logger LOGGER = LoggerFactory.getLogger(NeutronLoadBalancerInterface.class);
-    private ConcurrentMap<String, NeutronLoadBalancer> loadBalancerDB  = new ConcurrentHashMap<String, NeutronLoadBalancer>();
+    private ConcurrentMap<String, NeutronLoadBalancer> loadBalancerDB  = new ConcurrentHashMap<>();
 
 
     NeutronLoadBalancerInterface(ProviderContext providerContext) {
@@ -60,13 +60,13 @@ public class NeutronLoadBalancerInterface extends AbstractNeutronInterface<Loadb
 
     @Override
     public List<NeutronLoadBalancer> getAllNeutronLoadBalancers() {
-        Set<NeutronLoadBalancer> allLoadBalancers = new HashSet<NeutronLoadBalancer>();
+        Set<NeutronLoadBalancer> allLoadBalancers = new HashSet<>();
         for (Entry<String, NeutronLoadBalancer> entry : loadBalancerDB.entrySet()) {
             NeutronLoadBalancer loadBalancer = entry.getValue();
             allLoadBalancers.add(loadBalancer);
         }
         LOGGER.debug("Exiting getLoadBalancers, Found {} OpenStackLoadBalancer", allLoadBalancers.size());
-        List<NeutronLoadBalancer> ans = new ArrayList<NeutronLoadBalancer>();
+        List<NeutronLoadBalancer> ans = new ArrayList<>();
         ans.addAll(allLoadBalancers);
         return ans;
     }
index adc1c3832133fbb3bc86eb57ba22c126265cacb7..6b0c3827718fc791a428dbb9f4f06ffb13624d8a 100644 (file)
@@ -47,7 +47,7 @@ import com.google.common.collect.ImmutableBiMap;
 
 public class NeutronLoadBalancerPoolInterface extends AbstractNeutronInterface<Pool, NeutronLoadBalancerPool> implements INeutronLoadBalancerPoolCRUD {
     private static final Logger LOGGER = LoggerFactory.getLogger(NeutronLoadBalancerPoolInterface.class);
-    private ConcurrentMap<String, NeutronLoadBalancerPool> loadBalancerPoolDB = new ConcurrentHashMap<String, NeutronLoadBalancerPool>();
+    private ConcurrentMap<String, NeutronLoadBalancerPool> loadBalancerPoolDB = new ConcurrentHashMap<>();
 
     private static final ImmutableBiMap<Class<? extends ProtocolBase>,String> PROTOCOL_MAP
             = new ImmutableBiMap.Builder<Class<? extends ProtocolBase>,String>()
@@ -76,13 +76,13 @@ public class NeutronLoadBalancerPoolInterface extends AbstractNeutronInterface<P
 
     @Override
     public List<NeutronLoadBalancerPool> getAllNeutronLoadBalancerPools() {
-        Set<NeutronLoadBalancerPool> allLoadBalancerPools = new HashSet<NeutronLoadBalancerPool>();
+        Set<NeutronLoadBalancerPool> allLoadBalancerPools = new HashSet<>();
         for (Entry<String, NeutronLoadBalancerPool> entry : loadBalancerPoolDB.entrySet()) {
             NeutronLoadBalancerPool loadBalancerPool = entry.getValue();
             allLoadBalancerPools.add(loadBalancerPool);
         }
         LOGGER.debug("Exiting getLoadBalancerPools, Found {} OpenStackLoadBalancerPool", allLoadBalancerPools.size());
-        List<NeutronLoadBalancerPool> ans = new ArrayList<NeutronLoadBalancerPool>();
+        List<NeutronLoadBalancerPool> ans = new ArrayList<>();
         ans.addAll(allLoadBalancerPools);
         return ans;
     }
@@ -149,7 +149,7 @@ public class NeutronLoadBalancerPoolInterface extends AbstractNeutronInterface<P
             poolBuilder.setLbAlgorithm(pool.getLoadBalancerPoolLbAlgorithm());
         }
         if (pool.getLoadBalancerPoolListeners() != null) {
-            List<Uuid> listListener = new ArrayList<Uuid>();
+            List<Uuid> listListener = new ArrayList<>();
             for (Neutron_ID neutron_id : pool.getLoadBalancerPoolListeners()) {
                 listListener.add(toUuid(neutron_id.getID()));
             }
@@ -163,7 +163,7 @@ public class NeutronLoadBalancerPoolInterface extends AbstractNeutronInterface<P
         if (pool.getLoadBalancerPoolProtocol() != null) {
             ImmutableBiMap<String, Class<? extends ProtocolBase>> mapper =
                 PROTOCOL_MAP.inverse();
-            poolBuilder.setProtocol((Class<? extends ProtocolBase>) mapper.get(pool.getLoadBalancerPoolProtocol()));
+            poolBuilder.setProtocol(mapper.get(pool.getLoadBalancerPoolProtocol()));
         }
         if (pool.getLoadBalancerPoolSessionPersistence() != null) {
             NeutronLoadBalancer_SessionPersistence sessionPersistence = pool.getLoadBalancerPoolSessionPersistence();
index 03e38ebe07cb7d04fe184e2de49aa4511d5437ec..c94dd2f2701dadebbe4bf5222a8ef55c2171f354 100644 (file)
@@ -78,7 +78,7 @@ public class NeutronNetworkInterface extends AbstractNeutronInterface<Network,Ne
 
     @Override
     public List<NeutronNetwork> getAllNetworks() {
-        Set<NeutronNetwork> allNetworks = new HashSet<NeutronNetwork>();
+        Set<NeutronNetwork> allNetworks = new HashSet<>();
         Networks networks = readMd(createInstanceIdentifier());
         if (networks != null) {
             for (Network network: networks.getNetwork()) {
@@ -86,7 +86,7 @@ public class NeutronNetworkInterface extends AbstractNeutronInterface<Network,Ne
             }
         }
         LOGGER.debug("Exiting getAllNetworks, Found {} OpenStackNetworks", allNetworks.size());
-        List<NeutronNetwork> ans = new ArrayList<NeutronNetwork>();
+        List<NeutronNetwork> ans = new ArrayList<>();
         ans.addAll(allNetworks);
         return ans;
     }
@@ -135,7 +135,7 @@ public class NeutronNetworkInterface extends AbstractNeutronInterface<Network,Ne
         result.setShared(network.isShared());
         result.setStatus(network.getStatus());
         if (network.getSubnets() != null) {
-            List<String> neutronSubnets = new ArrayList<String>();
+            List<String> neutronSubnets = new ArrayList<>();
             for( Uuid subnet : network.getSubnets()) {
                neutronSubnets.add(subnet.getValue());
             }
@@ -152,7 +152,7 @@ public class NeutronNetworkInterface extends AbstractNeutronInterface<Network,Ne
         result.setProviderPhysicalNetwork(providerExtension.getPhysicalNetwork());
         result.setProviderSegmentationID(providerExtension.getSegmentationId());
         result.setProviderNetworkType(NETWORK_MAP.get(providerExtension.getNetworkType()));
-        List<NeutronNetwork_Segment> segments = new ArrayList<NeutronNetwork_Segment>();
+        List<NeutronNetwork_Segment> segments = new ArrayList<>();
         if (providerExtension.getSegments() != null) {
             for (Segments segment: providerExtension.getSegments()) {
                 NeutronNetwork_Segment neutronSegment = new NeutronNetwork_Segment();
@@ -183,10 +183,10 @@ public class NeutronNetworkInterface extends AbstractNeutronInterface<Network,Ne
         if (network.getProviderNetworkType() != null) {
             ImmutableBiMap<String, Class<? extends NetworkTypeBase>> mapper =
                 NETWORK_MAP.inverse();
-            providerExtensionBuilder.setNetworkType((Class<? extends NetworkTypeBase>) mapper.get(network.getProviderNetworkType()));
+            providerExtensionBuilder.setNetworkType(mapper.get(network.getProviderNetworkType()));
         }
         if (network.getSegments() != null) {
-            List<Segments> segments = new ArrayList<Segments>();
+            List<Segments> segments = new ArrayList<>();
             long count = 0;
             for( NeutronNetwork_Segment segment : network.getSegments()) {
                 count++;
@@ -200,9 +200,9 @@ public class NeutronNetworkInterface extends AbstractNeutronInterface<Network,Ne
                 if (segment.getProviderNetworkType() != null) {
                     ImmutableBiMap<String, Class<? extends NetworkTypeBase>> mapper =
                         NETWORK_MAP.inverse();
-                    segmentsBuilder.setNetworkType((Class<? extends NetworkTypeBase>) mapper.get(segment.getProviderNetworkType()));
+                    segmentsBuilder.setNetworkType(mapper.get(segment.getProviderNetworkType()));
                 }
-                segmentsBuilder.setSegmentationIndex(Long.valueOf(count));
+                segmentsBuilder.setSegmentationIndex(count);
                 segments.add(segmentsBuilder.build());
             }
             providerExtensionBuilder.setSegments(segments);
@@ -232,7 +232,7 @@ public class NeutronNetworkInterface extends AbstractNeutronInterface<Network,Ne
             networkBuilder.setStatus(network.getStatus());
         }
         if (network.getSubnets() != null) {
-            List<Uuid> subnets = new ArrayList<Uuid>();
+            List<Uuid> subnets = new ArrayList<>();
             for( String subnet : network.getSubnets()) {
                 subnets.add(toUuid(subnet));
             }
index c1ab927846ce9d336697622db7b2719610aaf0b5..08f0c415b97f15f594215c64fbbbfa680bf48081 100644 (file)
@@ -71,7 +71,7 @@ public class NeutronPortInterface extends AbstractNeutronInterface<Port, Neutron
 
     @Override
     public List<NeutronPort> getAllPorts() {
-        Set<NeutronPort> allPorts = new HashSet<NeutronPort>();
+        Set<NeutronPort> allPorts = new HashSet<>();
         Ports ports = readMd(createInstanceIdentifier());
         if (ports != null) {
             for (Port port : ports.getPort()) {
@@ -79,7 +79,7 @@ public class NeutronPortInterface extends AbstractNeutronInterface<Port, Neutron
             }
         }
         LOGGER.debug("Exiting getAllPorts, Found {} OpenStackPorts", allPorts.size());
-        List<NeutronPort> ans = new ArrayList<NeutronPort>();
+        List<NeutronPort> ans = new ArrayList<>();
         ans.addAll(allPorts);
         return ans;
     }
@@ -138,7 +138,7 @@ public class NeutronPortInterface extends AbstractNeutronInterface<Port, Neutron
         PortBindingExtension binding = port.getAugmentation(PortBindingExtension.class);
         result.setBindinghostID(binding.getHostId());
         if (binding.getVifDetails() != null) {
-            List<NeutronPort_VIFDetail> details = new ArrayList<NeutronPort_VIFDetail>();
+            List<NeutronPort_VIFDetail> details = new ArrayList<>();
             for (VifDetails vifDetail : binding.getVifDetails()) {
                 NeutronPort_VIFDetail detail = new NeutronPort_VIFDetail();
                 detail.setPortFilter(vifDetail.isPortFilter());
@@ -155,7 +155,7 @@ public class NeutronPortInterface extends AbstractNeutronInterface<Port, Neutron
         NeutronPort result = new NeutronPort();
         result.setAdminStateUp(port.isAdminStateUp());
         if (port.getAllowedAddressPairs() != null) {
-            List<NeutronPort_AllowedAddressPairs> pairs = new ArrayList<NeutronPort_AllowedAddressPairs>();
+            List<NeutronPort_AllowedAddressPairs> pairs = new ArrayList<>();
             for (AllowedAddressPairs mdPair : port.getAllowedAddressPairs()) {
                 NeutronPort_AllowedAddressPairs pair = new NeutronPort_AllowedAddressPairs();
                 pair.setIpAddress(mdPair.getIpAddress());
@@ -168,7 +168,7 @@ public class NeutronPortInterface extends AbstractNeutronInterface<Port, Neutron
         result.setDeviceID(port.getDeviceId());
         result.setDeviceOwner(port.getDeviceOwner());
         if (port.getExtraDhcpOpts() != null) {
-            List<NeutronPort_ExtraDHCPOption> options = new ArrayList<NeutronPort_ExtraDHCPOption>();
+            List<NeutronPort_ExtraDHCPOption> options = new ArrayList<>();
             for (ExtraDhcpOpts opt : port.getExtraDhcpOpts()) {
                 NeutronPort_ExtraDHCPOption arg = new NeutronPort_ExtraDHCPOption();
                 arg.setName(opt.getOptName());
@@ -178,7 +178,7 @@ public class NeutronPortInterface extends AbstractNeutronInterface<Port, Neutron
             result.setExtraDHCPOptions(options);
         }
         if (port.getFixedIps() != null) {
-            List<Neutron_IPs> ips = new ArrayList<Neutron_IPs>();
+            List<Neutron_IPs> ips = new ArrayList<>();
             for (FixedIps mdIP : port.getFixedIps()) {
                 Neutron_IPs ip = new Neutron_IPs();
                 ip.setIpAddress(String.valueOf(mdIP.getIpAddress().getValue()));
@@ -191,13 +191,16 @@ public class NeutronPortInterface extends AbstractNeutronInterface<Port, Neutron
         result.setName(port.getName());
         result.setNetworkUUID(String.valueOf(port.getNetworkId().getValue()));
         if (port.getSecurityGroups() != null) {
-            Set<NeutronSecurityGroup> allGroups = new HashSet<NeutronSecurityGroup>();
+            Set<NeutronSecurityGroup> allGroups = new HashSet<>();
             NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces().fetchINeutronSecurityGroupCRUD(this);
             INeutronSecurityGroupCRUD sgIf = interfaces.getSecurityGroupInterface();
             for (Uuid sgUuid : port.getSecurityGroups()) {
-                allGroups.add(sgIf.getNeutronSecurityGroup(sgUuid.getValue()));
+                NeutronSecurityGroup secGroup = sgIf.getNeutronSecurityGroup(sgUuid.getValue());
+                if (secGroup != null) {
+                    allGroups.add(sgIf.getNeutronSecurityGroup(sgUuid.getValue()));
+                }
             }
-            List<NeutronSecurityGroup> groups = new ArrayList<NeutronSecurityGroup>();
+            List<NeutronSecurityGroup> groups = new ArrayList<>();
             groups.addAll(allGroups);
             result.setSecurityGroups(groups);
         }
@@ -217,7 +220,7 @@ public class NeutronPortInterface extends AbstractNeutronInterface<Port, Neutron
             bindingBuilder.setHostId(neutronPort.getBindinghostID());
         }
         if (neutronPort.getVIFDetail() != null) {
-            List<VifDetails> listVifDetail = new ArrayList<VifDetails>();
+            List<VifDetails> listVifDetail = new ArrayList<>();
             for (NeutronPort_VIFDetail detail: neutronPort.getVIFDetail()) {
                 VifDetailsBuilder vifDetailsBuilder = new VifDetailsBuilder();
                 if (detail.getPortFilter() != null) {
@@ -242,7 +245,7 @@ public class NeutronPortInterface extends AbstractNeutronInterface<Port, Neutron
                                     bindingBuilder.build());
         portBuilder.setAdminStateUp(neutronPort.isAdminStateUp());
         if(neutronPort.getAllowedAddressPairs() != null) {
-            List<AllowedAddressPairs> listAllowedAddressPairs = new ArrayList<AllowedAddressPairs>();
+            List<AllowedAddressPairs> listAllowedAddressPairs = new ArrayList<>();
             for (NeutronPort_AllowedAddressPairs allowedAddressPairs : neutronPort.getAllowedAddressPairs()) {
                     AllowedAddressPairsBuilder allowedAddressPairsBuilder = new AllowedAddressPairsBuilder();
                     allowedAddressPairsBuilder.setIpAddress(allowedAddressPairs.getIpAddress());
@@ -259,7 +262,7 @@ public class NeutronPortInterface extends AbstractNeutronInterface<Port, Neutron
         portBuilder.setDeviceOwner(neutronPort.getDeviceOwner());
         }
         if (neutronPort.getExtraDHCPOptions() != null) {
-            List<ExtraDhcpOpts> listExtraDHCPOptions = new ArrayList<ExtraDhcpOpts>();
+            List<ExtraDhcpOpts> listExtraDHCPOptions = new ArrayList<>();
             for (NeutronPort_ExtraDHCPOption extraDHCPOption : neutronPort.getExtraDHCPOptions()) {
                 ExtraDhcpOptsBuilder extraDHCPOptsBuilder = new ExtraDhcpOptsBuilder();
                 extraDHCPOptsBuilder.setOptName(extraDHCPOption.getName());
@@ -269,7 +272,7 @@ public class NeutronPortInterface extends AbstractNeutronInterface<Port, Neutron
             portBuilder.setExtraDhcpOpts(listExtraDHCPOptions);
         }
         if (neutronPort.getFixedIPs() != null) {
-            List<FixedIps> listNeutronIPs = new ArrayList<FixedIps>();
+            List<FixedIps> listNeutronIPs = new ArrayList<>();
             for (Neutron_IPs neutron_IPs : neutronPort.getFixedIPs()) {
                 FixedIpsBuilder fixedIpsBuilder = new FixedIpsBuilder();
                 fixedIpsBuilder.setIpAddress(new IpAddress(neutron_IPs.getIpAddress().toCharArray()));
@@ -288,7 +291,7 @@ public class NeutronPortInterface extends AbstractNeutronInterface<Port, Neutron
         portBuilder.setNetworkId(toUuid(neutronPort.getNetworkUUID()));
         }
         if (neutronPort.getSecurityGroups() != null) {
-            List<Uuid> listSecurityGroups = new ArrayList<Uuid>();
+            List<Uuid> listSecurityGroups = new ArrayList<>();
             for (NeutronSecurityGroup neutronSecurityGroup : neutronPort.getSecurityGroups()) {
                 listSecurityGroups.add(toUuid(neutronSecurityGroup.getID()));
             }
index a1ab29329bc1e4144ded1ae1a5e7b17a5f6cfd43..fbaafe20f7e815c83d53592cd22152747378a0ba 100644 (file)
@@ -67,7 +67,7 @@ public class NeutronRouterInterface extends  AbstractNeutronInterface<Router, Ne
 
     @Override
     public List<NeutronRouter> getAllRouters() {
-        Set<NeutronRouter> allRouters = new HashSet<NeutronRouter>();
+        Set<NeutronRouter> allRouters = new HashSet<>();
         Routers routers = readMd(createInstanceIdentifier());
         if (routers != null) {
             for (Router router: routers.getRouter()) {
@@ -75,7 +75,7 @@ public class NeutronRouterInterface extends  AbstractNeutronInterface<Router, Ne
             }
         }
         LOGGER.debug("Exiting getAllRouters, Found {} Routers", allRouters.size());
-        List<NeutronRouter> ans = new ArrayList<NeutronRouter>();
+        List<NeutronRouter> ans = new ArrayList<>();
         ans.addAll(allRouters);
         return ans;
     }
@@ -138,7 +138,7 @@ public class NeutronRouterInterface extends  AbstractNeutronInterface<Router, Ne
         routerBuilder.setAdminStateUp(router.getAdminStateUp());
         routerBuilder.setDistributed(router.getDistributed());
         if (router.getRoutes() != null) {
-            List<String> routes = new ArrayList<String>();
+            List<String> routes = new ArrayList<>();
             for (String route : router.getRoutes()) {
                 routes.add(route);
             }
@@ -146,14 +146,14 @@ public class NeutronRouterInterface extends  AbstractNeutronInterface<Router, Ne
         }
         if (router.getExternalGatewayInfo() != null) {
             ExternalGatewayInfo externalGatewayInfo = null;
-            List<NeutronRouter_NetworkReference> neutronRouter_NetworkReferences = new ArrayList<NeutronRouter_NetworkReference>();
+            List<NeutronRouter_NetworkReference> neutronRouter_NetworkReferences = new ArrayList<>();
             neutronRouter_NetworkReferences.add(router.getExternalGatewayInfo());
             for (NeutronRouter_NetworkReference externalGatewayInfos : neutronRouter_NetworkReferences) {
                 ExternalGatewayInfoBuilder builder = new ExternalGatewayInfoBuilder();
                 builder.setEnableSnat(externalGatewayInfos.getEnableSNAT());
                 builder.setExternalNetworkId(toUuid(externalGatewayInfos.getNetworkID()));
                 if (externalGatewayInfos.getExternalFixedIPs() != null) {
-                    List<ExternalFixedIps> externalFixedIps = new ArrayList<ExternalFixedIps>();
+                    List<ExternalFixedIps> externalFixedIps = new ArrayList<>();
                     for (Neutron_IPs eIP : externalGatewayInfos.getExternalFixedIPs()) {
                         ExternalFixedIpsBuilder eFixedIpBuilder = new ExternalFixedIpsBuilder();
                         eFixedIpBuilder.setIpAddress(new IpAddress(eIP.getIpAddress().toCharArray()));
@@ -167,8 +167,8 @@ public class NeutronRouterInterface extends  AbstractNeutronInterface<Router, Ne
             routerBuilder.setExternalGatewayInfo(externalGatewayInfo);
         }
         if (router.getInterfaces() != null) {
-            Map<String, NeutronRouter_Interface> mapInterfaces = new HashMap<String, NeutronRouter_Interface>();
-            List<Interfaces> interfaces = new ArrayList<Interfaces>();
+            Map<String, NeutronRouter_Interface> mapInterfaces = new HashMap<>();
+            List<Interfaces> interfaces = new ArrayList<>();
             for (Entry<String, NeutronRouter_Interface> entry : mapInterfaces.entrySet()) {
                 interfaces.add((Interfaces) entry.getValue());
             }
@@ -212,7 +212,7 @@ public class NeutronRouterInterface extends  AbstractNeutronInterface<Router, Ne
             result.setGatewayPortId(String.valueOf(router.getGatewayPortId().getValue()));
         }
         if (router.getRoutes() != null) {
-            List<String> routes = new ArrayList<String>();
+            List<String> routes = new ArrayList<>();
             for (String route : router.getRoutes()) {
                 routes.add(route);
             }
@@ -224,7 +224,7 @@ public class NeutronRouterInterface extends  AbstractNeutronInterface<Router, Ne
             extGwInfo.setNetworkID(String.valueOf(router.getExternalGatewayInfo().getExternalNetworkId().getValue()));
             extGwInfo.setEnableSNAT(router.getExternalGatewayInfo().isEnableSnat());
             if (router.getExternalGatewayInfo().getExternalFixedIps() != null) {
-                List<Neutron_IPs> fixedIPs = new ArrayList<Neutron_IPs>();
+                List<Neutron_IPs> fixedIPs = new ArrayList<>();
                 for (ExternalFixedIps mdFixedIP : router.getExternalGatewayInfo().getExternalFixedIps()) {
                      Neutron_IPs fixedIP = new Neutron_IPs();
                      fixedIP.setSubnetUUID(String.valueOf(mdFixedIP.getSubnetId().getValue()));
@@ -237,7 +237,7 @@ public class NeutronRouterInterface extends  AbstractNeutronInterface<Router, Ne
         }
 
         if (router.getInterfaces() != null) {
-            Map<String, NeutronRouter_Interface> interfaces = new HashMap<String, NeutronRouter_Interface>();
+            Map<String, NeutronRouter_Interface> interfaces = new HashMap<>();
             for (Interfaces mdInterface : router.getInterfaces()) {
                 NeutronRouter_Interface pojoInterface = new NeutronRouter_Interface();
                 String id = String.valueOf(mdInterface.getUuid().getValue());
index c30dd5c49e44038d0cfc4e6b28a8932c3aaf5594..9c72959492e3c0ae0c39e0c37f764fb06598fe3b 100644 (file)
@@ -59,7 +59,7 @@ public class NeutronSecurityGroupInterface extends AbstractNeutronInterface<Secu
 
     @Override
     public List<NeutronSecurityGroup> getAllNeutronSecurityGroups() {
-        Set<NeutronSecurityGroup> allSecurityGroups = new HashSet<NeutronSecurityGroup>();
+        Set<NeutronSecurityGroup> allSecurityGroups = new HashSet<>();
         SecurityGroups groups = readMd(createInstanceIdentifier());
         if (groups != null) {
             for (SecurityGroup group: groups.getSecurityGroup()) {
@@ -67,7 +67,7 @@ public class NeutronSecurityGroupInterface extends AbstractNeutronInterface<Secu
             }
         }
         LOGGER.debug("Exiting getSecurityGroups, Found {} OpenStackSecurityGroup", allSecurityGroups.size());
-        List<NeutronSecurityGroup> ans = new ArrayList<NeutronSecurityGroup>();
+        List<NeutronSecurityGroup> ans = new ArrayList<>();
         ans.addAll(allSecurityGroups);
         return ans;
     }
@@ -120,7 +120,7 @@ public class NeutronSecurityGroupInterface extends AbstractNeutronInterface<Secu
                 .fetchINeutronSecurityRuleCRUD(this);
             INeutronSecurityRuleCRUD srCrud = interfaces.getSecurityRuleInterface();
 
-            List<NeutronSecurityRule> rules = new ArrayList<NeutronSecurityRule>();
+            List<NeutronSecurityRule> rules = new ArrayList<>();
             for (Uuid uuid: group.getSecurityRules()) {
                  rules.add(srCrud.getNeutronSecurityRule(uuid.getValue()));
             }
@@ -145,7 +145,7 @@ public class NeutronSecurityGroupInterface extends AbstractNeutronInterface<Secu
             securityGroupBuilder.setTenantId(toUuid(securityGroup.getSecurityGroupTenantID()));
         }
         if (securityGroup.getSecurityRules() != null) {
-            List<Uuid> neutronSecurityRule = new ArrayList<Uuid>();
+            List<Uuid> neutronSecurityRule = new ArrayList<>();
             for (NeutronSecurityRule securityRule : securityGroup.getSecurityRules()) {
                 if (securityRule.getID() != null) {
                     neutronSecurityRule.add(toUuid(securityRule.getID()));
index cfcc9cd8a4103b2db68020ddd6379cdea2bbdd2e..8218c84f43a7923dd77f4202e8911c0a0f660918 100644 (file)
@@ -94,7 +94,7 @@ public class NeutronSecurityRuleInterface extends AbstractNeutronInterface<Secur
         INeutronSecurityGroupCRUD sgCrud = interfaces.getSecurityGroupInterface();
         NeutronSecurityGroup sg = sgCrud.getNeutronSecurityGroup(input.getSecurityRuleGroupID());
         if(sg != null && sg.getSecurityRules() != null) {
-            List<NeutronSecurityRule> toRemove = new ArrayList<NeutronSecurityRule>();
+            List<NeutronSecurityRule> toRemove = new ArrayList<>();
             for(NeutronSecurityRule sgr :sg.getSecurityRules()) {
                 if(sgr.getID() != null && sgr.getID().equals(input.getID())) {
                     toRemove.add(sgr);
@@ -124,7 +124,7 @@ public class NeutronSecurityRuleInterface extends AbstractNeutronInterface<Secur
 
     @Override
     public List<NeutronSecurityRule> getAllNeutronSecurityRules() {
-        Set<NeutronSecurityRule> allSecurityRules = new HashSet<NeutronSecurityRule>();
+        Set<NeutronSecurityRule> allSecurityRules = new HashSet<>();
         SecurityRules rules = readMd(createInstanceIdentifier());
         if (rules != null) {
             for (SecurityRule rule: rules.getSecurityRule()) {
@@ -132,7 +132,7 @@ public class NeutronSecurityRuleInterface extends AbstractNeutronInterface<Secur
             }
         }
         LOGGER.debug("Exiting getSecurityRule, Found {} OpenStackSecurityRule", allSecurityRules.size());
-        List<NeutronSecurityRule> ans = new ArrayList<NeutronSecurityRule>();
+        List<NeutronSecurityRule> ans = new ArrayList<>();
         ans.addAll(allSecurityRules);
         return ans;
     }
@@ -218,7 +218,7 @@ public class NeutronSecurityRuleInterface extends AbstractNeutronInterface<Secur
         if (securityRule.getSecurityRuleDirection() != null) {
             ImmutableBiMap<String, Class<? extends DirectionBase>> mapper =
                     DIRECTION_MAP.inverse();
-            securityRuleBuilder.setDirection((Class<? extends DirectionBase>) mapper.get(securityRule.getSecurityRuleDirection()));
+            securityRuleBuilder.setDirection(mapper.get(securityRule.getSecurityRuleDirection()));
         }
         if (securityRule.getSecurityRuleGroupID() != null) {
             securityRuleBuilder.setSecurityGroupId(toUuid(securityRule.getSecurityRuleGroupID()));
@@ -232,12 +232,12 @@ public class NeutronSecurityRuleInterface extends AbstractNeutronInterface<Secur
         if (securityRule.getSecurityRuleProtocol() != null) {
             ImmutableBiMap<String, Class<? extends ProtocolBase>> mapper =
                     PROTOCOL_MAP.inverse();
-            securityRuleBuilder.setProtocol((Class<? extends ProtocolBase>) mapper.get(securityRule.getSecurityRuleProtocol()));
+            securityRuleBuilder.setProtocol(mapper.get(securityRule.getSecurityRuleProtocol()));
         }
         if (securityRule.getSecurityRuleEthertype() != null) {
             ImmutableBiMap<String, Class<? extends EthertypeBase>> mapper =
                     ETHERTYPE_MAP.inverse();
-            securityRuleBuilder.setEthertype((Class<? extends EthertypeBase>) mapper.get(securityRule.getSecurityRuleEthertype()));
+            securityRuleBuilder.setEthertype(mapper.get(securityRule.getSecurityRuleEthertype()));
         }
         if (securityRule.getSecurityRulePortMin() != null) {
             securityRuleBuilder.setPortRangeMin(Integer.valueOf(securityRule.getSecurityRulePortMin()));
index fd228087f7c60f06b04ef843d53c2794ea09da37..60844b72305ed8396dd96b31f896670d393306eb 100644 (file)
@@ -51,8 +51,8 @@ public class NeutronSubnetInterface extends AbstractNeutronInterface<Subnet, Neu
 
     private static final ImmutableBiMap<Class<? extends IpVersionBase>,Integer> IPV_MAP
             = new ImmutableBiMap.Builder<Class<? extends IpVersionBase>,Integer>()
-            .put(IpVersionV4.class,Integer.valueOf(4))
-            .put(IpVersionV6.class,Integer.valueOf(6))
+            .put(IpVersionV4.class, 4)
+            .put(IpVersionV6.class, 6)
             .build();
 
     private static final ImmutableBiMap<Class<? extends Dhcpv6Base>,String> DHCPV6_MAP
@@ -89,7 +89,7 @@ public class NeutronSubnetInterface extends AbstractNeutronInterface<Subnet, Neu
 
     @Override
     public List<NeutronSubnet> getAllSubnets() {
-        Set<NeutronSubnet> allSubnets = new HashSet<NeutronSubnet>();
+        Set<NeutronSubnet> allSubnets = new HashSet<>();
         Subnets subnets = readMd(createInstanceIdentifier());
         if (subnets != null) {
             for (Subnet subnet: subnets.getSubnet()) {
@@ -97,7 +97,7 @@ public class NeutronSubnetInterface extends AbstractNeutronInterface<Subnet, Neu
             }
         }
         LOGGER.debug("Exiting getAllSubnets, Found {} OpenStackSubnets", allSubnets.size());
-        List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();
+        List<NeutronSubnet> ans = new ArrayList<>();
         ans.addAll(allSubnets);
         return ans;
     }
@@ -164,7 +164,7 @@ public class NeutronSubnetInterface extends AbstractNeutronInterface<Subnet, Neu
         result.setIpV6AddressMode(DHCPV6_MAP.get(subnet.getIpv6AddressMode()));
         result.setEnableDHCP(subnet.isEnableDhcp());
         if (subnet.getAllocationPools() != null) {
-            List<NeutronSubnetIPAllocationPool> allocationPools = new ArrayList<NeutronSubnetIPAllocationPool>();
+            List<NeutronSubnetIPAllocationPool> allocationPools = new ArrayList<>();
             for (AllocationPools allocationPool : subnet.getAllocationPools()) {
                 NeutronSubnetIPAllocationPool pool = new NeutronSubnetIPAllocationPool();
                 pool.setPoolStart(allocationPool.getStart());
@@ -174,7 +174,7 @@ public class NeutronSubnetInterface extends AbstractNeutronInterface<Subnet, Neu
             result.setAllocationPools(allocationPools);
         }
         if (subnet.getDnsNameservers() != null) {
-            List<String> dnsNameServers = new ArrayList<String>();
+            List<String> dnsNameServers = new ArrayList<>();
             for (IpAddress dnsNameServer : subnet.getDnsNameservers()) {
                 dnsNameServers.add(String.valueOf(dnsNameServer.getValue()));
             }
@@ -184,7 +184,7 @@ public class NeutronSubnetInterface extends AbstractNeutronInterface<Subnet, Neu
 // read through the ports and put the ones in this subnet into the internal
 // myPorts object.
 // @deprecated and will be removed in Boron
-        Set<NeutronPort> allPorts = new HashSet<NeutronPort>();
+        Set<NeutronPort> allPorts = new HashSet<>();
         NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces()
             .fetchINeutronPortCRUD(this);
         INeutronPortCRUD portIf = interfaces.getPortInterface();
@@ -197,7 +197,7 @@ public class NeutronSubnetInterface extends AbstractNeutronInterface<Subnet, Neu
                 }
             }
         }
-        List<NeutronPort> ports = new ArrayList<NeutronPort>();
+        List<NeutronPort> ports = new ArrayList<>();
         ports.addAll(allPorts);
         result.setPorts(ports);
         return result;
@@ -217,7 +217,7 @@ public class NeutronSubnetInterface extends AbstractNeutronInterface<Subnet, Neu
         if (subnet.getIpVersion() != null) {
             ImmutableBiMap<Integer, Class<? extends IpVersionBase>> mapper =
                     IPV_MAP.inverse();
-            subnetBuilder.setIpVersion((Class<? extends IpVersionBase>) mapper.get(subnet
+            subnetBuilder.setIpVersion(mapper.get(subnet
                     .getIpVersion()));
         }
         if (subnet.getCidr() != null) {
@@ -231,16 +231,16 @@ public class NeutronSubnetInterface extends AbstractNeutronInterface<Subnet, Neu
         if (subnet.getIpV6RaMode() != null) {
             ImmutableBiMap<String, Class<? extends Dhcpv6Base>> mapper =
                     DHCPV6_MAP.inverse();
-            subnetBuilder.setIpv6RaMode((Class<? extends Dhcpv6Base>) mapper.get(subnet.getIpV6RaMode()));
+            subnetBuilder.setIpv6RaMode(mapper.get(subnet.getIpV6RaMode()));
         }
         if (subnet.getIpV6AddressMode() != null) {
             ImmutableBiMap<String, Class<? extends Dhcpv6Base>> mapper =
                     DHCPV6_MAP.inverse();
-            subnetBuilder.setIpv6AddressMode((Class<? extends Dhcpv6Base>) mapper.get(subnet.getIpV6AddressMode()));
+            subnetBuilder.setIpv6AddressMode(mapper.get(subnet.getIpV6AddressMode()));
         }
         subnetBuilder.setEnableDhcp(subnet.getEnableDHCP());
         if (subnet.getAllocationPools() != null) {
-            List<AllocationPools> allocationPools = new ArrayList<AllocationPools>();
+            List<AllocationPools> allocationPools = new ArrayList<>();
             for (NeutronSubnetIPAllocationPool allocationPool : subnet
                     .getAllocationPools()) {
                 AllocationPoolsBuilder builder = new AllocationPoolsBuilder();
@@ -252,7 +252,7 @@ public class NeutronSubnetInterface extends AbstractNeutronInterface<Subnet, Neu
             subnetBuilder.setAllocationPools(allocationPools);
         }
         if (subnet.getDnsNameservers() != null) {
-            List<IpAddress> dnsNameServers = new ArrayList<IpAddress>();
+            List<IpAddress> dnsNameServers = new ArrayList<>();
             for (String dnsNameServer : subnet.getDnsNameservers()) {
                 IpAddress ipAddress = new IpAddress(dnsNameServer.toCharArray());
                 dnsNameServers.add(ipAddress);
index c8466fec8141d8d70f3ed0a7acfb2c1f1731d3c5..fdb1e81953ce8c695e70991d86c75eef14d2cc7c 100644 (file)
@@ -8,6 +8,15 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter_Interface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.ServiceReference;
@@ -42,4 +51,31 @@ public class NeutronIAwareUtil {
         return instances;
     }
 
+    public static List<Neutron_IPs> convertMDSalIpToNeutronIp(List<FixedIps> fixedIps) {
+        List<Neutron_IPs> ips = null;
+        if (fixedIps != null) {
+            ips = new ArrayList<Neutron_IPs>();
+            for (FixedIps mdIP : fixedIps) {
+                Neutron_IPs ip = new Neutron_IPs();
+                ip.setIpAddress(String.valueOf(mdIP.getIpAddress().getValue()));
+                ip.setSubnetUUID(mdIP.getSubnetId().getValue());
+                ips.add(ip);
+            }
+        }
+        return ips;
+    }
+
+    public static NeutronRouter_Interface convertMDSalInterfaceToNeutronRouterInterface(
+            Port routerInterface) {
+        NeutronRouter_Interface neutronInterface = new NeutronRouter_Interface();
+        String id = String.valueOf(routerInterface.getUuid().getValue());
+        neutronInterface.setID(id);
+        neutronInterface.setTenantID(routerInterface.getTenantId().getValue());
+        neutronInterface.setSubnetUUID(routerInterface.getFixedIps().get(0).getSubnetId().getValue());
+        neutronInterface.setPortUUID(routerInterface.getUuid().getValue());
+        return neutronInterface;
+    }
+
+
+
 }
index bb045b4a8eebd9e20b4d422bbecc31b58821e2ad..ae035a04ff8ad1c65f75a9db9bfd1465b9060de4 100644 (file)
@@ -129,7 +129,7 @@ public class NeutronNetworkChangeListener implements DataChangeListener, AutoClo
         result.setShared(network.isShared());
         result.setStatus(network.getStatus());
         if (network.getSubnets() != null) {
-            List<String> neutronSubnets = new ArrayList<String>();
+            List<String> neutronSubnets = new ArrayList<>();
             for( Uuid subnet : network.getSubnets()) {
                neutronSubnets.add(subnet.getValue());
             }
@@ -147,7 +147,7 @@ public class NeutronNetworkChangeListener implements DataChangeListener, AutoClo
         result.setProviderPhysicalNetwork(providerExtension.getPhysicalNetwork());
         result.setProviderSegmentationID(providerExtension.getSegmentationId());
         result.setProviderNetworkType(NETWORK_MAP.get(providerExtension.getNetworkType()));
-        List<NeutronNetwork_Segment> segments = new ArrayList<NeutronNetwork_Segment>();
+        List<NeutronNetwork_Segment> segments = new ArrayList<>();
         if (providerExtension.getSegments() != null) {
             for (Segments segment: providerExtension.getSegments()) {
                 NeutronNetwork_Segment neutronSegment = new NeutronNetwork_Segment();
index 35bf7ff30cbae64b3c23de5dc6409fdaa1af619f..6f7bab994ce3256e36538665d2fc6f3efb7b3c53 100644 (file)
@@ -131,7 +131,7 @@ public class NeutronPortChangeListener implements DataChangeListener, AutoClosea
         NeutronPort result = new NeutronPort();
         result.setAdminStateUp(port.isAdminStateUp());
         if (port.getAllowedAddressPairs() != null) {
-            List<NeutronPort_AllowedAddressPairs> pairs = new ArrayList<NeutronPort_AllowedAddressPairs>();
+            List<NeutronPort_AllowedAddressPairs> pairs = new ArrayList<>();
             for (AllowedAddressPairs mdPair : port.getAllowedAddressPairs()) {
                 NeutronPort_AllowedAddressPairs pair = new NeutronPort_AllowedAddressPairs();
                 pair.setIpAddress(mdPair.getIpAddress());
@@ -144,7 +144,7 @@ public class NeutronPortChangeListener implements DataChangeListener, AutoClosea
         result.setDeviceID(port.getDeviceId());
         result.setDeviceOwner(port.getDeviceOwner());
         if (port.getExtraDhcpOpts() != null) {
-            List<NeutronPort_ExtraDHCPOption> options = new ArrayList<NeutronPort_ExtraDHCPOption>();
+            List<NeutronPort_ExtraDHCPOption> options = new ArrayList<>();
             for (ExtraDhcpOpts opt : port.getExtraDhcpOpts()) {
                 NeutronPort_ExtraDHCPOption arg = new NeutronPort_ExtraDHCPOption();
                 arg.setName(opt.getOptName());
@@ -154,7 +154,7 @@ public class NeutronPortChangeListener implements DataChangeListener, AutoClosea
             result.setExtraDHCPOptions(options);
         }
         if (port.getFixedIps() != null) {
-            List<Neutron_IPs> ips = new ArrayList<Neutron_IPs>();
+            List<Neutron_IPs> ips = new ArrayList<>();
             for (FixedIps mdIP : port.getFixedIps()) {
                 Neutron_IPs ip = new Neutron_IPs();
                 ip.setIpAddress(String.valueOf(mdIP.getIpAddress().getValue()));
@@ -167,13 +167,16 @@ public class NeutronPortChangeListener implements DataChangeListener, AutoClosea
         result.setName(port.getName());
         result.setNetworkUUID(String.valueOf(port.getNetworkId().getValue()));
         if (port.getSecurityGroups() != null) {
-            Set<NeutronSecurityGroup> allGroups = new HashSet<NeutronSecurityGroup>();
+            Set<NeutronSecurityGroup> allGroups = new HashSet<>();
             NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces().fetchINeutronSecurityGroupCRUD(this);
             INeutronSecurityGroupCRUD sgIf = interfaces.getSecurityGroupInterface();
             for (Uuid sgUuid : port.getSecurityGroups()) {
-                allGroups.add(sgIf.getNeutronSecurityGroup(sgUuid.getValue()));
+                NeutronSecurityGroup secGroup = sgIf.getNeutronSecurityGroup(sgUuid.getValue());
+                if (secGroup != null) {
+                    allGroups.add(sgIf.getNeutronSecurityGroup(sgUuid.getValue()));
+                }
             }
-            List<NeutronSecurityGroup> groups = new ArrayList<NeutronSecurityGroup>();
+            List<NeutronSecurityGroup> groups = new ArrayList<>();
             groups.addAll(allGroups);
             result.setSecurityGroups(groups);
         }
@@ -190,7 +193,7 @@ public class NeutronPortChangeListener implements DataChangeListener, AutoClosea
         PortBindingExtension binding = port.getAugmentation(PortBindingExtension.class);
         result.setBindinghostID(binding.getHostId());
         if (binding.getVifDetails() != null) {
-            List<NeutronPort_VIFDetail> details = new ArrayList<NeutronPort_VIFDetail>();
+            List<NeutronPort_VIFDetail> details = new ArrayList<>();
             for (VifDetails vifDetail : binding.getVifDetails()) {
                 NeutronPort_VIFDetail detail = new NeutronPort_VIFDetail();
                 detail.setPortFilter(vifDetail.isPortFilter());
@@ -205,7 +208,7 @@ public class NeutronPortChangeListener implements DataChangeListener, AutoClosea
 
     private  Map<String,NeutronPort> getChangedPorts(Map<InstanceIdentifier<?>, DataObject> changedData) {
         LOG.trace("getChangedPorts:" + changedData);
-        Map<String,NeutronPort> portMap = new HashMap<String,NeutronPort>();
+        Map<String,NeutronPort> portMap = new HashMap<>();
         for (Map.Entry<InstanceIdentifier<?>, DataObject> changed : changedData.entrySet()) {
             if (changed.getValue() instanceof Port) {
                 NeutronPort port = fromMd((Port)changed.getValue());
index 5ad885d395540a633d2584bf5057249c4827db8c..a45c0a48b169bbf7deb23e4cf8b00653acd8d2d5 100644 (file)
@@ -122,7 +122,7 @@ public class NeutronRouterChangeListener implements DataChangeListener, AutoClos
             result.setGatewayPortId(String.valueOf(router.getGatewayPortId().getValue()));
         }
         if (router.getRoutes() != null) {
-            List<String> routes = new ArrayList<String>();
+            List<String> routes = new ArrayList<>();
             for (String route : router.getRoutes()) {
                 routes.add(route);
             }
@@ -134,7 +134,7 @@ public class NeutronRouterChangeListener implements DataChangeListener, AutoClos
             extGwInfo.setNetworkID(String.valueOf(router.getExternalGatewayInfo().getExternalNetworkId().getValue()));
             extGwInfo.setEnableSNAT(router.getExternalGatewayInfo().isEnableSnat());
             if (router.getExternalGatewayInfo().getExternalFixedIps() != null) {
-                List<Neutron_IPs> fixedIPs = new ArrayList<Neutron_IPs>();
+                List<Neutron_IPs> fixedIPs = new ArrayList<>();
                 for (ExternalFixedIps mdFixedIP : router.getExternalGatewayInfo().getExternalFixedIps()) {
                      Neutron_IPs fixedIP = new Neutron_IPs();
                      fixedIP.setSubnetUUID(String.valueOf(mdFixedIP.getSubnetId().getValue()));
@@ -147,7 +147,7 @@ public class NeutronRouterChangeListener implements DataChangeListener, AutoClos
         }
 
         if (router.getInterfaces() != null) {
-            Map<String, NeutronRouter_Interface> interfaces = new HashMap<String, NeutronRouter_Interface>();
+            Map<String, NeutronRouter_Interface> interfaces = new HashMap<>();
             for (Interfaces mdInterface : router.getInterfaces()) {
                 NeutronRouter_Interface pojoInterface = new NeutronRouter_Interface();
                 String id = String.valueOf(mdInterface.getUuid().getValue());
index 796d1b1c2f86778b3c86bf05080aec37155d330e..335de4f04f8836349236aa2b38852c39cb8d9db2 100644 (file)
@@ -131,7 +131,7 @@ public class NeutronSecurityGroupDataChangeListener implements
             INeutronSecurityRuleCRUD srCrud = interfaces
                     .getSecurityRuleInterface();
 
-            List<NeutronSecurityRule> rules = new ArrayList<NeutronSecurityRule>();
+            List<NeutronSecurityRule> rules = new ArrayList<>();
             for (Uuid uuid : group.getSecurityRules()) {
                 rules.add(srCrud.getNeutronSecurityRule(uuid.getValue()));
             }
index 488b32d885f46d7dcdb5b5f9d4f644db0f579be1..6f09a7fa5ca840755923dbbb51e7581d0500b27d 100644 (file)
@@ -23,10 +23,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV4;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV6;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolBase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolHttp;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolHttps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmpV6;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolTcp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolUdp;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.SecurityRules;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRule;
@@ -43,20 +43,20 @@ public class NeutronSecurityRuleDataChangeListener implements DataChangeListener
     private static final Logger LOG = LoggerFactory.getLogger(NeutronSecurityRuleDataChangeListener.class);
 
     private static final ImmutableBiMap<Class<? extends DirectionBase>, String> DIRECTION_MAP
-            = new ImmutableBiMap.Builder<Class<? extends DirectionBase>, String>()
-            .put(DirectionEgress.class, "egress")
-            .put(DirectionIngress.class, "ingress").build();
-    private static final ImmutableBiMap<Class<? extends ProtocolBase>, String> PROTOCOL_MAP
-            = new ImmutableBiMap.Builder<Class<? extends ProtocolBase>, String>()
-            .put(ProtocolHttp.class, "HTTP")
-            .put(ProtocolHttps.class, "HTTPS")
-            .put(ProtocolIcmp.class, "ICMP")
-            .put(ProtocolTcp.class, "TCP")
+        = new ImmutableBiMap.Builder<Class<? extends DirectionBase>, String>()
+        .put(DirectionEgress.class, "egress")
+        .put(DirectionIngress.class, "ingress").build();
+    private static final ImmutableBiMap<Class<? extends ProtocolBase>,String> PROTOCOL_MAP
+            = new ImmutableBiMap.Builder<Class<? extends ProtocolBase>,String>()
+            .put(ProtocolIcmp.class,"icmp")
+            .put(ProtocolTcp.class,"tcp")
+            .put(ProtocolUdp.class,"udp")
+            .put(ProtocolIcmpV6.class,"icmpv6")
             .build();
-    private static final ImmutableBiMap<Class<? extends EthertypeBase>, String> ETHERTYPE_MAP
-            = new ImmutableBiMap.Builder<Class<? extends EthertypeBase>, String>()
-            .put(EthertypeV4.class, "v4")
-            .put(EthertypeV6.class, "v6")
+    private static final ImmutableBiMap<Class<? extends EthertypeBase>,String> ETHERTYPE_MAP
+            = new ImmutableBiMap.Builder<Class<? extends EthertypeBase>,String>()
+            .put(EthertypeV4.class,"IPv4")
+            .put(EthertypeV6.class,"IPv6")
             .build();
 
     private ListenerRegistration<DataChangeListener> registration;
index 7f3073aec1f06ee6cc91d6b51689fccc9ab1de35..3d9be3cb45a294b2d3914ef0f9f0dac2e6b0c1ed 100644 (file)
@@ -51,8 +51,8 @@ public class NeutronSubnetChangeListener implements DataChangeListener, AutoClos
 
     private static final ImmutableBiMap<Class<? extends IpVersionBase>,Integer> IPV_MAP
     = new ImmutableBiMap.Builder<Class<? extends IpVersionBase>,Integer>()
-    .put(IpVersionV4.class,Integer.valueOf(4))
-    .put(IpVersionV6.class,Integer.valueOf(6))
+    .put(IpVersionV4.class, 4)
+    .put(IpVersionV6.class, 6)
     .build();
 
     private static final ImmutableBiMap<Class<? extends Dhcpv6Base>,String> DHCPV6_MAP
@@ -147,7 +147,7 @@ public class NeutronSubnetChangeListener implements DataChangeListener, AutoClos
         result.setIpV6AddressMode(DHCPV6_MAP.get(subnet.getIpv6AddressMode()));
         result.setEnableDHCP(subnet.isEnableDhcp());
         if (subnet.getAllocationPools() != null) {
-            List<NeutronSubnetIPAllocationPool> allocationPools = new ArrayList<NeutronSubnetIPAllocationPool>();
+            List<NeutronSubnetIPAllocationPool> allocationPools = new ArrayList<>();
             for (AllocationPools allocationPool : subnet.getAllocationPools()) {
                 NeutronSubnetIPAllocationPool pool = new NeutronSubnetIPAllocationPool();
                 pool.setPoolStart(allocationPool.getStart());
@@ -157,7 +157,7 @@ public class NeutronSubnetChangeListener implements DataChangeListener, AutoClos
             result.setAllocationPools(allocationPools);
         }
         if (subnet.getDnsNameservers() != null) {
-            List<String> dnsNameServers = new ArrayList<String>();
+            List<String> dnsNameServers = new ArrayList<>();
             for (IpAddress dnsNameServer : subnet.getDnsNameservers()) {
                 dnsNameServers.add(String.valueOf(dnsNameServer.getValue()));
             }
@@ -167,7 +167,7 @@ public class NeutronSubnetChangeListener implements DataChangeListener, AutoClos
 
         // read through the ports and put the ones in this subnet into the internal
         // myPorts object.
-       Set<NeutronPort> allPorts = new HashSet<NeutronPort>();
+       Set<NeutronPort> allPorts = new HashSet<>();
         NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces()
             .fetchINeutronPortCRUD(this);
         INeutronPortCRUD portIf = interfaces.getPortInterface();
@@ -180,7 +180,7 @@ public class NeutronSubnetChangeListener implements DataChangeListener, AutoClos
                 }
             }
         }
-        List<NeutronPort> ports = new ArrayList<NeutronPort>();
+        List<NeutronPort> ports = new ArrayList<>();
         ports.addAll(allPorts);
         result.setPorts(ports);
         return result;
index a3976def3c368eb6bf697f90f7921e5d5d6ee892..cbfeed386e6c5f625baa50ee3f79ea3e4ac73473 100644 (file)
@@ -63,16 +63,16 @@ public class FloatingIPHandlerTest {
         when(ev.getNeutronFloatingIP()).thenReturn(mock(NeutronFloatingIP.class));
 
         when(ev.getAction()).thenReturn(Action.UPDATE);
-        floatingHandler.processEvent((AbstractEvent) ev);
-        verify(neutronL3Adapter, times(1)).handleNeutronFloatingIPEvent(ev.getNeutronFloatingIP(), ev.getAction());;
+        floatingHandler.processEvent(ev);
+        verify(neutronL3Adapter, times(1)).handleNeutronFloatingIPEvent(ev.getNeutronFloatingIP(), ev.getAction());
 
         when(ev.getAction()).thenReturn(Action.ADD);
-        floatingHandler.processEvent((AbstractEvent) ev);
-        verify(neutronL3Adapter, times(1)).handleNeutronFloatingIPEvent(ev.getNeutronFloatingIP(), ev.getAction());;
+        floatingHandler.processEvent(ev);
+        verify(neutronL3Adapter, times(1)).handleNeutronFloatingIPEvent(ev.getNeutronFloatingIP(), ev.getAction());
 
         when(ev.getAction()).thenReturn(Action.DELETE);
-        floatingHandler.processEvent((AbstractEvent) ev);
-        verify(neutronL3Adapter, times(1)).handleNeutronFloatingIPEvent(ev.getNeutronFloatingIP(), ev.getAction());;
+        floatingHandler.processEvent(ev);
+        verify(neutronL3Adapter, times(1)).handleNeutronFloatingIPEvent(ev.getNeutronFloatingIP(), ev.getAction());
     }
 
     @Test
index 52458c6e9b6161015e647111db1e458cd2181ea4..35317e0d443317a7318c50b3c7240308f2239794 100644 (file)
@@ -72,7 +72,7 @@ public class LBaaSPoolHandlerTest {
     public void setUp() {
         when(neutronLBPool.getLoadBalancerPoolProtocol()).thenReturn(LoadBalancerConfiguration.PROTOCOL_HTTP);
 
-        List<NeutronLoadBalancerPoolMember> members = new ArrayList<NeutronLoadBalancerPoolMember>();
+        List<NeutronLoadBalancerPoolMember> members = new ArrayList<>();
         NeutronLoadBalancerPoolMember neutronLBPoolMember = mock(NeutronLoadBalancerPoolMember.class);
         when(neutronLBPoolMember.getPoolMemberAdminStateIsUp()).thenReturn(true);
         when(neutronLBPoolMember.getPoolMemberSubnetID()).thenReturn("subnetID");
@@ -82,7 +82,7 @@ public class LBaaSPoolHandlerTest {
         members.add(neutronLBPoolMember);
         when(neutronLBPool.getLoadBalancerPoolMembers()).thenReturn(members);
 
-        List<NeutronLoadBalancer> list_neutronLB = new ArrayList<NeutronLoadBalancer>();
+        List<NeutronLoadBalancer> list_neutronLB = new ArrayList<>();
         NeutronLoadBalancer neutronLB = mock(NeutronLoadBalancer.class);
         when(neutronLB.getLoadBalancerName()).thenReturn("load_balancer_name");
         when(neutronLB.getLoadBalancerVipAddress()).thenReturn("vip_address");
@@ -146,7 +146,7 @@ public class LBaaSPoolHandlerTest {
         NorthboundEvent ev = mock(NorthboundEvent.class);
         when(ev.getLoadBalancerPool()).thenReturn(neutronLBPool);
 
-        List<Node> list_node = new ArrayList<Node>();
+        List<Node> list_node = new ArrayList<>();
         list_node .add(mock(Node.class));
         when(nodeCacheManager.getBridgeNodes()).thenReturn(list_node);
 
index d9c99df1157fa55764f30be120f52c55da8ee4fd..ee02019085076b70016da10c46722e8f2cbfa397 100644 (file)
@@ -85,7 +85,7 @@ public class LBaaSPoolMemberHandlerTest {
         when(NeutronCacheUtils.getMacAddress(any(INeutronPortCRUD.class), anyString(), anyString())).thenReturn("mac_address");
         when(NeutronCacheUtils.getProviderInformation(any(INeutronNetworkCRUD.class), any(INeutronSubnetCRUD.class), anyString())).thenReturn(providerInfo);
 
-        List<NeutronLoadBalancerPoolMember> members = new ArrayList<NeutronLoadBalancerPoolMember>();
+        List<NeutronLoadBalancerPoolMember> members = new ArrayList<>();
         NeutronLoadBalancerPoolMember neutronLBPoolMember = mock(NeutronLoadBalancerPoolMember.class);
         when(neutronLBPoolMember.getPoolMemberAdminStateIsUp()).thenReturn(true);
         when(neutronLBPoolMember.getPoolMemberSubnetID()).thenReturn("subnetID");
@@ -98,7 +98,7 @@ public class LBaaSPoolMemberHandlerTest {
         when(neutronLBPool.getLoadBalancerPoolMembers()).thenReturn(members);
         when(neutronLBPoolCache.getNeutronLoadBalancerPool(anyString())).thenReturn(neutronLBPool);
 
-        List<NeutronLoadBalancer> list_neutronLB = new ArrayList<NeutronLoadBalancer>();
+        List<NeutronLoadBalancer> list_neutronLB = new ArrayList<>();
         NeutronLoadBalancer neutronLB = mock(NeutronLoadBalancer.class);
         when(neutronLB.getLoadBalancerName()).thenReturn("load_balancer_name");
         when(neutronLB.getLoadBalancerVipAddress()).thenReturn("vip_address");
@@ -169,7 +169,7 @@ public class LBaaSPoolMemberHandlerTest {
         NorthboundEvent ev = mock(NorthboundEvent.class);
         when(ev.getLoadBalancerPoolMember()).thenReturn(neutronLBMember);
 
-        List<Node> list_node = new ArrayList<Node>();
+        List<Node> list_node = new ArrayList<>();
         list_node .add(mock(Node.class));
         when(nodeCacheManager.getBridgeNodes()).thenReturn(list_node);
 
index 61b9e10d906665e1dba0b9795b1d03e9d4f2123c..fce0462938234e4239008633ecf6560b6a00504f 100644 (file)
@@ -44,11 +44,11 @@ public class NeutronCacheUtilsTest {
         Neutron_IPs ip = mock(Neutron_IPs.class);
         when(ip.getIpAddress()).thenReturn("ip_address");
         when(ip.getSubnetUUID()).thenReturn("subnetUUID");
-        List<Neutron_IPs> list_fixedIP = new ArrayList<Neutron_IPs>();
+        List<Neutron_IPs> list_fixedIP = new ArrayList<>();
         list_fixedIP.add(ip);
         when(port.getFixedIPs()).thenReturn(list_fixedIP);
         when(port.getMacAddress()).thenReturn("mac_address");
-        List<NeutronPort> list_port = new ArrayList<NeutronPort>();
+        List<NeutronPort> list_port = new ArrayList<>();
         list_port.add(port);
 
         when(neutronPortsCache.getAllPorts()).thenReturn(list_port);
@@ -65,7 +65,7 @@ public class NeutronCacheUtilsTest {
         NeutronSubnet subnet = mock(NeutronSubnet.class);
         when(subnet.getID()).thenReturn("subnetUUID");
         when(subnet.getNetworkUUID()).thenReturn("networkUUID");
-        List<NeutronSubnet> list_subnet = new ArrayList<NeutronSubnet>();
+        List<NeutronSubnet> list_subnet = new ArrayList<>();
         list_subnet.add(subnet);
 
         when(neutronSubnetCache.getAllSubnets()).thenReturn(list_subnet );
@@ -75,12 +75,12 @@ public class NeutronCacheUtilsTest {
         when(network.getID()).thenReturn("networkUUID");
         when(network.getProviderNetworkType()).thenReturn("network_type_1");
         when(network.getProviderSegmentationID()).thenReturn("network_segID");
-        List<NeutronNetwork> list_network = new ArrayList<NeutronNetwork>();
+        List<NeutronNetwork> list_network = new ArrayList<>();
         list_network.add(network);
 
         when(neutronNetworkCache.getAllNetworks()).thenReturn(list_network);
 
-        Map.Entry<String,String> entry = new AbstractMap.SimpleEntry<String, String>(
+        Map.Entry<String,String> entry = new AbstractMap.SimpleEntry<>(
                 network.getProviderNetworkType(), network.getProviderSegmentationID());
 
         assertEquals("Error, getProviderInformation() did not return the correct values", entry, NeutronCacheUtils.getProviderInformation(neutronNetworkCache, neutronSubnetCache, "subnetUUID"));
index 9e1e4859d5083dd310e9e6f8eb2a49c96f4f64eb..6d72ee26a441fe3b32943eb137ef0d2fb5a03ef8 100644 (file)
@@ -90,11 +90,11 @@ public class PortHandlerTest {
         portHandlerSpy.processEvent(ev);
         verify(neutronL3Adapter, times(1)).handleNeutronPortEvent(neutronPort, Action.UPDATE);
 
-        List<Node> nodes = new ArrayList<Node>();
+        List<Node> nodes = new ArrayList<>();
         nodes.add(mock(Node.class));
         when(nodeCacheManager.getNodes()).thenReturn(nodes);
 
-        List<OvsdbTerminationPointAugmentation> ports = new ArrayList<OvsdbTerminationPointAugmentation>();
+        List<OvsdbTerminationPointAugmentation> ports = new ArrayList<>();
         OvsdbTerminationPointAugmentation port = mock(OvsdbTerminationPointAugmentation.class);
         ports.add(port);
         when(southbound.getTerminationPointsOfBridge(any(Node.class))).thenReturn(ports);
index b00c7a50291e5b185b63524f53d311eb84514b21..660aad36146458a2498a363ee203e5e33890c34f 100644 (file)
@@ -21,6 +21,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
+import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
@@ -40,6 +41,7 @@ public class PortSecurityHandlerTest {
 
     @InjectMocks private PortSecurityHandler portSecurityHandler;
     private PortSecurityHandler posrtSecurityHandlerSpy;
+    @Mock EventDispatcher eventDispatcher;
 
     @Before
     public void setUp() {
@@ -72,7 +74,7 @@ public class PortSecurityHandlerTest {
         assertEquals("Error, did not return the correct HTTP flag", HttpURLConnection.HTTP_CREATED, portSecurityHandler.canCreateNeutronSecurityRule(mock(NeutronSecurityRule.class)));
 
         posrtSecurityHandlerSpy.neutronSecurityRuleCreated(any(NeutronSecurityRule.class));
-        verify(posrtSecurityHandlerSpy, times(1)).canCreateNeutronSecurityRule(any(NeutronSecurityRule.class));
+        verify(posrtSecurityHandlerSpy, times(1)).enqueueEvent(any(AbstractEvent.class));
     }
 
     @Test
@@ -85,7 +87,7 @@ public class PortSecurityHandlerTest {
         assertEquals("Error, did not return the correct HTTP flag", HttpURLConnection.HTTP_OK, portSecurityHandler.canDeleteNeutronSecurityRule(mock(NeutronSecurityRule.class)));
 
         posrtSecurityHandlerSpy.neutronSecurityRuleDeleted(any(NeutronSecurityRule.class));
-        verify(posrtSecurityHandlerSpy, times(1)).canDeleteNeutronSecurityRule(any(NeutronSecurityRule.class));
+        verify(posrtSecurityHandlerSpy, times(1)).enqueueEvent(any(AbstractEvent.class));
    }
 
     @Test
index 707929416132628cacfeefb9b8d3d77285a36a10..bc754725ca67b605dd23c25e020dea75a805a6e0 100644 (file)
@@ -81,12 +81,13 @@ public class SouthboundHandlerTest {
         Node node = mock(Node.class);
         when(node.getAugmentation(OvsdbNodeAugmentation.class)).thenReturn(mock(OvsdbNodeAugmentation.class));
 
-        List<Node> nodes = new ArrayList<Node>();
+        List<Node> nodes = new ArrayList<>();
         nodes.add(mock(Node.class));
         when(southbound.readOvsdbTopologyNodes()).thenReturn(nodes);
 
         southboundHandlerSpy.triggerUpdates();
-        verify(southboundHandlerSpy, times(1)).ovsdbUpdate(any(Node.class), any(DataObject.class), any(OvsdbType.class), any(Action.class));;
+        verify(southboundHandlerSpy, times(1)).ovsdbUpdate(any(Node.class), any(DataObject.class), any(OvsdbType.class), any(Action.class));
+
     }
 
     @Test
@@ -218,7 +219,7 @@ public class SouthboundHandlerTest {
         when(ev.getType()).thenReturn(Type.OPENVSWITCH);
 
         when(ovsdbTerminationPointAugmentation.getName()).thenReturn("network");
-        List<TerminationPoint> terminationPoints = new ArrayList<TerminationPoint>();
+        List<TerminationPoint> terminationPoints = new ArrayList<>();
         terminationPoints.add(mock(TerminationPoint.class));
         when(southbound.extractTerminationPoints(any(Node.class))).thenReturn(terminationPoints);
 
index 1ca405c209c213f50c0ede992502f902ab2393c3..10d3c281013d5b129ff43a59beea1cc569f64afe 100644 (file)
@@ -64,15 +64,15 @@ public class SubnetHandlerTest {
 
         when(ev.getAction()).thenReturn(Action.ADD);
         subnetHandler.processEvent(ev);
-        verify(neutronl3Adapter, times(1)).handleNeutronSubnetEvent(ev.getSubnet(), ev.getAction());;
+        verify(neutronl3Adapter, times(1)).handleNeutronSubnetEvent(ev.getSubnet(), ev.getAction());
 
         when(ev.getAction()).thenReturn(Action.DELETE);
         subnetHandler.processEvent(ev);
-        verify(neutronl3Adapter, times(1)).handleNeutronSubnetEvent(ev.getSubnet(), ev.getAction());;
+        verify(neutronl3Adapter, times(1)).handleNeutronSubnetEvent(ev.getSubnet(), ev.getAction());
 
         when(ev.getAction()).thenReturn(Action.UPDATE);
         subnetHandler.processEvent(ev);
-        verify(neutronl3Adapter, times(1)).handleNeutronSubnetEvent(ev.getSubnet(), ev.getAction());;
+        verify(neutronl3Adapter, times(1)).handleNeutronSubnetEvent(ev.getSubnet(), ev.getAction());
     }
 
     @Test
index 3a803c75959a0dc533059054fcbbf7150ad97a0d..c4909341c541c84646260c1dc5660768adfb7900 100644 (file)
@@ -25,7 +25,7 @@ public class LoadBalancerConfigurationTest {
             {"10.10.1.343", "10.10.1.391", "10.10.1.31"},
             {"D5:6B:59:E8:F4:84", "D5:4B:60:E8:F5:84", "D5:4B:60:E8:F6:84"},
             {"tcp", "tcp", "http"},
-            {Integer.valueOf(125304), Integer.valueOf(125304), Integer.valueOf(1204)}};
+            {125304, 125304, 1204}};
 
     @Before
     public void setUp() throws Exception {
index dec0f7358e6e5f2a0ada969bf58375130711da19..5246a42b02cb09a81cf975a590cb5d9aa0d32a61 100644 (file)
@@ -263,12 +263,16 @@ public class BridgeConfigurationManagerImplTest {
 
             assertTrue("Error, isCreated is not true for " + networkType,
                     bridgeConfigurationManagerImplSpy.createLocalNetwork(node, neutronNetworkMock));
-            if (networkType.equals("vlan")) {
-                verify(neutronNetworkMock, times(1)).getProviderNetworkType();
-            } else if (networkType.equals("vxlan")) {
-                verify(neutronNetworkMock, times(2)).getProviderNetworkType();
-            } else if (networkType.equals("gre")) {
-                verify(neutronNetworkMock, times(3)).getProviderNetworkType();
+            switch (networkType) {
+                case "vlan":
+                    verify(neutronNetworkMock, times(1)).getProviderNetworkType();
+                    break;
+                case "vxlan":
+                    verify(neutronNetworkMock, times(2)).getProviderNetworkType();
+                    break;
+                case "gre":
+                    verify(neutronNetworkMock, times(3)).getProviderNetworkType();
+                    break;
             }
             reset(neutronNetworkMock);
             reset(node);
index f07d2271157f468dd43b046c689586500edcb9b1..98f6a646943ab439eabc6bdd91b6ebc0ac37c085 100644 (file)
@@ -21,7 +21,9 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.stubbing.OngoingStubbing;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
@@ -33,6 +35,8 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
+import org.powermock.api.mockito.PowerMockito;
+
 /**
  * Unit test for class {@link MdsalUtils}
  *
@@ -46,13 +50,24 @@ public class MdsalUtilsTest {
     @Mock private DataBroker databroker;
 
     @Test
-    public void testDelete() {
+    public void testDelete() throws ReadFailedException{
         WriteTransaction writeTransaction = mock(WriteTransaction.class);
         when(databroker.newWriteOnlyTransaction()).thenReturn(writeTransaction);
         CheckedFuture<Void, TransactionCommitFailedException> future = mock(CheckedFuture.class);
         when(writeTransaction.submit()).thenReturn(future );
+        InstanceIdentifier<?> iid = mock(InstanceIdentifier.class);
+
+        ReadOnlyTransaction readOnlyTransaction = mock(ReadOnlyTransaction.class);
+        when(databroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction);
+        CheckedFuture<Optional, ReadFailedException> futureRead = mock(CheckedFuture.class);
+        Optional opt = mock(Optional.class);
+        when(opt.isPresent()).thenReturn(true);
+        DataObject obj = mock(DataObject.class);
+        when(opt.get()).thenReturn(obj );
+        when(futureRead.checkedGet()).thenReturn(opt);
+        when(readOnlyTransaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(futureRead);
 
-        boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, mock(InstanceIdentifier.class));
+        boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid);
 
         verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(1)).submit();
index 521c7c6a23d40a95fe7e81660326af9d259bfdb6..c0d6a019f396f60d42fe443132dbb5bc70b32eac 100644 (file)
@@ -135,11 +135,11 @@ public class NeutronL3AdapterTest {
 
     @Test
     public void testHandleNeutronPortEvent() throws Exception {
-        Map<String, NeutronRouter_Interface> subnetIdToRouterInterfaceCache = new HashMap<String, NeutronRouter_Interface>();
+        Map<String, NeutronRouter_Interface> subnetIdToRouterInterfaceCache = new HashMap<>();
         // Mock variables
         Neutron_IPs neutronIP = mock(Neutron_IPs.class);
         when(neutronIP.getSubnetUUID()).thenReturn(UUID);
-        List<Neutron_IPs> list_neutronIP = new ArrayList<Neutron_IPs>();
+        List<Neutron_IPs> list_neutronIP = new ArrayList<>();
         list_neutronIP.add(neutronIP);
         NeutronPort neutronPort = mock(NeutronPort.class);
         when(neutronPort.getDeviceOwner()).thenReturn(OWNER_ROUTER_INTERFACE);
@@ -182,7 +182,7 @@ public class NeutronL3AdapterTest {
         Neutron_IPs neutronIP = mock(Neutron_IPs.class);
         when(neutronIP.getSubnetUUID()).thenReturn(UUID);
         NeutronPort neutronPort = mock(NeutronPort.class);
-        List<Neutron_IPs> list_neutronIP = new ArrayList<Neutron_IPs>();
+        List<Neutron_IPs> list_neutronIP = new ArrayList<>();
         list_neutronIP.add(neutronIP);
         when(neutronPort.getFixedIPs()).thenReturn(list_neutronIP);
         List<NeutronPort> list_neutronPort = new ArrayList<>();
@@ -280,7 +280,7 @@ public class NeutronL3AdapterTest {
 
         // Suppress the called to these functions
         MemberModifier.suppress(MemberMatcher.method(NeutronL3Adapter.class, "programOutboundIpRewriteStage1", floatingIpClass, Action.class));
-
+        PowerMockito.doReturn(floatIpDataMapCache.values()).when(neutronL3Adapter, "getAllFloatingIPsWithMetadata");
         Whitebox.invokeMethod(neutronL3Adapter, "flushExistingIpRewrite");
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programOutboundIpRewriteStage1", any(floatingIpClass), eq(Action.DELETE));
     }
@@ -297,6 +297,7 @@ public class NeutronL3AdapterTest {
         // Suppress the called to these functions
         MemberModifier.suppress(MemberMatcher.method(NeutronL3Adapter.class, "programOutboundIpRewriteStage1", floatingIpClass, Action.class));
 
+        PowerMockito.doReturn(floatIpDataMapCache.values()).when(neutronL3Adapter, "getAllFloatingIPsWithMetadata");
         Whitebox.invokeMethod(neutronL3Adapter, "rebuildExistingIpRewrite");
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programOutboundIpRewriteStage1", any(floatingIpClass), eq(Action.ADD));
     }
@@ -304,8 +305,8 @@ public class NeutronL3AdapterTest {
     @SuppressWarnings({ "unchecked", "rawtypes" })
     @Test
     public void testProgramFlowsForFloatingIPArpAdd() throws Exception {
-        Map<String, Pair> neutronPortToDpIdCache = new HashMap<String, Pair>();
-        Map<String, String> networkIdToRouterMacCache = new HashMap<String, String>();
+        Map<String, Pair> neutronPortToDpIdCache = new HashMap<>();
+        Map<String, String> networkIdToRouterMacCache = new HashMap<>();
         Map floatIpDataMapCache = new HashMap();
 
         NeutronFloatingIP neutronFloatingIP = mock(NeutronFloatingIP.class);
@@ -327,7 +328,7 @@ public class NeutronL3AdapterTest {
         INeutronPortCRUD neutronPortCache = mock(INeutronPortCRUD.class);
         when(neutronPortCache.getPort(anyString())).thenReturn(neutronPort);
         PowerMockito.doReturn(neutronPort).when(neutronL3Adapter, "findNeutronPortForFloatingIp", anyString());
-        PowerMockito.doReturn(Long.valueOf(15)).when(neutronL3Adapter, "findOFPortForExtPatch", anyLong());
+        PowerMockito.doReturn(15L).when(neutronL3Adapter, "findOFPortForExtPatch", anyLong());
         MemberModifier.field(NeutronL3Adapter.class, "floatIpDataMapCache").set(neutronL3Adapter , floatIpDataMapCache);
         MemberModifier.field(NeutronL3Adapter.class, "neutronPortToDpIdCache").set(neutronL3Adapter , neutronPortToDpIdCache);
         MemberModifier.field(NeutronL3Adapter.class, "neutronPortCache").set(neutronL3Adapter , neutronPortCache);
@@ -380,7 +381,7 @@ public class NeutronL3AdapterTest {
         ConfigurationService configurationService = mock(ConfigurationService.class);
         when(configurationService.getPatchPortName(any(Pair.class))).thenReturn(PORT_INT);
         MemberModifier.field(NeutronL3Adapter.class, "configurationService").set(neutronL3Adapter , configurationService);
-        List<Node> nodes = new ArrayList<Node>();
+        List<Node> nodes = new ArrayList<>();
         nodes.add(mock(Node.class));
         NodeCacheManager nodeCacheManager = mock(NodeCacheManager.class);
         when(nodeCacheManager.getBridgeNodes()).thenReturn(nodes);
@@ -403,7 +404,7 @@ public class NeutronL3AdapterTest {
 
     @Test
     public void testHandleInterfaceEvent() throws Exception {
-        Map<String, Pair<Long, Uuid>> neutronPortToDpIdCache = new HashMap<String, Pair<Long,Uuid>>();
+        Map<String, Pair<Long, Uuid>> neutronPortToDpIdCache = new HashMap<>();
         // init instance variables
         TenantNetworkManager tenantNetworkManager = mock(TenantNetworkManager.class);
         MemberModifier.field(NeutronL3Adapter.class, "tenantNetworkManager").set(neutronL3Adapter , tenantNetworkManager);
@@ -429,7 +430,7 @@ public class NeutronL3AdapterTest {
         MemberModifier.suppress(MemberMatcher.method(NeutronL3Adapter.class, "handleInterfaceEventAdd", String.class, Long.class, Uuid.class));
         MemberModifier.suppress(MemberMatcher.method(NeutronL3Adapter.class, "handleInterfaceEventDelete", OvsdbTerminationPointAugmentation.class, Long.class));
 
-        PowerMockito.when(neutronL3Adapter, "getDpidForIntegrationBridge", any(Node.class)).thenReturn(Long.valueOf(45));
+        PowerMockito.when(neutronL3Adapter, "getDpidForIntegrationBridge", any(Node.class)).thenReturn(45L);
         Mockito.doNothing().when(neutronL3Adapter).handleNeutronPortEvent(any(NeutronPort.class), any(Action.class));
 
         neutronL3Adapter.handleInterfaceEvent(node, intf, mock(NeutronNetwork.class), Action.ADD);
@@ -444,7 +445,7 @@ public class NeutronL3AdapterTest {
 
     @Test
     public void testHandleInterfaceEventAdd() throws Exception {
-        Map<String, Pair<Long, Uuid>> neutronPortToDpIdCache = new HashMap<String, Pair<Long,Uuid>>();
+        Map<String, Pair<Long, Uuid>> neutronPortToDpIdCache = new HashMap<>();
         // init instance variables
         MemberModifier.field(NeutronL3Adapter.class, "neutronPortToDpIdCache").set(neutronL3Adapter , neutronPortToDpIdCache);
         int temp = neutronPortToDpIdCache.size();
@@ -457,7 +458,7 @@ public class NeutronL3AdapterTest {
     @SuppressWarnings("unchecked")
     @Test
     public void testHandleInterfaceEventDelete() throws Exception {
-        Map<String, Pair<Long, Uuid>> neutronPortToDpIdCache = new HashMap<String, Pair<Long,Uuid>>();
+        Map<String, Pair<Long, Uuid>> neutronPortToDpIdCache = new HashMap<>();
         OvsdbTerminationPointAugmentation intf = mock(OvsdbTerminationPointAugmentation.class);
         Uuid uuid = mock(Uuid.class);
         when(intf.getInterfaceUuid()).thenReturn(uuid );
@@ -476,11 +477,11 @@ public class NeutronL3AdapterTest {
 
     @Test
     public void testUpdateL3ForNeutronPort() throws Exception {
-        Map<String, String> networkIdToRouterMacCache = new HashMap<String, String>();
+        Map<String, String> networkIdToRouterMacCache = new HashMap<>();
 
         Neutron_IPs neutronIp = mock(Neutron_IPs.class);
         when(neutronIp.getIpAddress()).thenReturn(FIXED_IP_ADDRESS);
-        List<Neutron_IPs> neutronIps = new ArrayList<Neutron_IPs>();
+        List<Neutron_IPs> neutronIps = new ArrayList<>();
         neutronIps.add(neutronIp);
         NeutronPort neutronPort = mock(NeutronPort.class);
         when(neutronPort.getNetworkUUID()).thenReturn(UUID);
@@ -488,9 +489,9 @@ public class NeutronL3AdapterTest {
         when(neutronPort.getFixedIPs()).thenReturn(neutronIps);
         NeutronNetwork neutronNetwork = mock(NeutronNetwork.class);
         when(neutronNetwork.getProviderSegmentationID()).thenReturn(ID);
-        List<Node> nodes = new ArrayList<Node>();
+        List<Node> nodes = new ArrayList<>();
         nodes.add(mock(Node.class));
-        PowerMockito.doReturn(Long.valueOf(15)).when(neutronL3Adapter, "getDpidForIntegrationBridge", any(Node.class));
+        PowerMockito.doReturn(15L).when(neutronL3Adapter, "getDpidForIntegrationBridge", any(Node.class));
 
         // init instance variables
         networkIdToRouterMacCache .put(UUID, MAC_ADDRESS);
@@ -519,10 +520,8 @@ public class NeutronL3AdapterTest {
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programStaticArpStage1", anyLong(), anyString(), anyString(), anyString(), eq(Action.DELETE));
     }
 
-    // either add or remove item in l3ForwardingCache
     @Test
     public void testProgramL3ForwardingStage1() throws Exception {
-        Set<String> l3ForwardingCache = new HashSet<String>();
 
         NodeId nodeId = mock(NodeId.class);
         when(nodeId.getValue()).thenReturn(ID);
@@ -533,22 +532,16 @@ public class NeutronL3AdapterTest {
         MemberModifier.suppress(MemberMatcher.method(NeutronL3Adapter.class, "programL3ForwardingStage2", Node.class, Long.class, String.class, String.class, String.class, Action.class));
 
         // init instance variables
-        MemberModifier.field(NeutronL3Adapter.class, "l3ForwardingCache").set(neutronL3Adapter , l3ForwardingCache );
         PowerMockito.when(neutronL3Adapter, "programL3ForwardingStage2", any(Node.class), anyLong(), anyString(), anyString(), anyString(), eq(Action.ADD)).thenReturn(new Status(StatusCode.SUCCESS));
         PowerMockito.when(neutronL3Adapter, "programL3ForwardingStage2", any(Node.class), anyLong(), anyString(), anyString(), anyString(), eq(Action.DELETE)).thenReturn(new Status(StatusCode.SUCCESS));
 
-        int temp = l3ForwardingCache.size();
 
         Whitebox.invokeMethod(neutronL3Adapter, "programL3ForwardingStage1", node, Long.valueOf(45), SEG_ID, MAC_ADDRESS, IP, Action.ADD);
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programL3ForwardingStage2", any(Node.class), anyLong(), anyString(), anyString(), anyString(), eq(Action.ADD));
-        assertEquals("Error, did not add the value", temp, l3ForwardingCache.size()-1);
 
-        l3ForwardingCache.add(node.getNodeId().getValue() + ":" + SEG_ID + ":" + IP);
-        temp = l3ForwardingCache.size();
 
         Whitebox.invokeMethod(neutronL3Adapter, "programL3ForwardingStage1", node, Long.valueOf(45), SEG_ID, MAC_ADDRESS, IP, Action.DELETE);
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programL3ForwardingStage2", any(Node.class), anyLong(), anyString(), anyString(), anyString(), eq(Action.DELETE));
-        assertEquals("Error, did not delete the value", temp, l3ForwardingCache.size()+1);
     }
 
     @Test
@@ -569,16 +562,16 @@ public class NeutronL3AdapterTest {
 
     @Test
     public void testProgramFlowsForNeutronRouterInterface() throws Exception {
-        Map<String, String> networkIdToRouterMacCache = new HashMap<String, String>();
-        Map<String, List<Neutron_IPs>> networkIdToRouterIpListCache = new HashMap<String, List<Neutron_IPs>>();
-        Map<String, NeutronRouter_Interface> subnetIdToRouterInterfaceCache = new HashMap<String, NeutronRouter_Interface>();
+        Map<String, String> networkIdToRouterMacCache = new HashMap<>();
+        Map<String, List<Neutron_IPs>> networkIdToRouterIpListCache = new HashMap<>();
+        Map<String, NeutronRouter_Interface> subnetIdToRouterInterfaceCache = new HashMap<>();
 
         NeutronRouter_Interface intf = mock(NeutronRouter_Interface.class);
         when(intf.getPortUUID()).thenReturn(UUID);
         when(intf.getSubnetUUID()).thenReturn(UUID);
         Neutron_IPs neutronIp = mock(Neutron_IPs.class);
         when(neutronIp.getIpAddress()).thenReturn(FIXED_IP_ADDRESS);
-        List<Neutron_IPs> ips = new ArrayList<Neutron_IPs>();
+        List<Neutron_IPs> ips = new ArrayList<>();
         ips.add(neutronIp);
         NeutronPort neutronPort = mock(NeutronPort.class);
         when(neutronPort.getMacAddress()).thenReturn(MAC_ADDRESS);
@@ -595,7 +588,7 @@ public class NeutronL3AdapterTest {
         NeutronRouter neutronRouter = mock(NeutronRouter.class);
 
         Node node = mock(Node.class);
-        List<Node> nodes = new ArrayList<Node>();
+        List<Node> nodes = new ArrayList<>();
         nodes.add(node);
 
         MemberModifier.suppress(MemberMatcher.method(NeutronL3Adapter.class, "getDpidForIntegrationBridge", Node.class));
@@ -621,7 +614,7 @@ public class NeutronL3AdapterTest {
         MemberModifier.field(NeutronL3Adapter.class, "neutronSubnetCache").set(neutronL3Adapter , neutronSubnetCache);
         MemberModifier.field(NeutronL3Adapter.class, "neutronNetworkCache").set(neutronL3Adapter , neutronNetworkCache);
         MemberModifier.field(NeutronL3Adapter.class, "nodeCacheManager").set(neutronL3Adapter , nodeCacheManager);
-        PowerMockito.when(neutronL3Adapter, "getDpidForIntegrationBridge", any(Node.class)).thenReturn(Long.valueOf(45));
+        PowerMockito.when(neutronL3Adapter, "getDpidForIntegrationBridge", any(Node.class)).thenReturn(45L);
 
         int networkIdToRouterMacCacheSize, networkIdToRouterIpListCacheSize, subnetIdToRouterInterfaceCacheSize;
         networkIdToRouterMacCacheSize = networkIdToRouterMacCache.size();
@@ -680,7 +673,7 @@ public class NeutronL3AdapterTest {
         when(neutronNetwork.getProviderSegmentationID()).thenReturn(ID);
         Neutron_IPs ip = mock(Neutron_IPs.class);
         when(ip.getIpAddress()).thenReturn(IP);
-        List<Neutron_IPs> ips = new ArrayList<Neutron_IPs>();
+        List<Neutron_IPs> ips = new ArrayList<>();
         ips.add(ip);
         ips.add(ip);
         ips.add(ip);
@@ -715,7 +708,6 @@ public class NeutronL3AdapterTest {
 
     @Test
     public void testProgramRouterInterfaceStage1() throws Exception {
-        Set<String> routerInterfacesCache = new HashSet<String>();
 
         NodeId nodeId = mock(NodeId.class);
         when(nodeId.getValue()).thenReturn(ID);
@@ -724,24 +716,18 @@ public class NeutronL3AdapterTest {
 
         MemberModifier.suppress(MemberMatcher.method(NeutronL3Adapter.class, "programRouterInterfaceStage2", Node.class, Long.class, String.class, String.class, String.class, String.class, int.class, Action.class));
 
-        MemberModifier.field(NeutronL3Adapter.class, "routerInterfacesCache").set(neutronL3Adapter , routerInterfacesCache);
         PowerMockito.when(neutronL3Adapter, "programRouterInterfaceStage2", any(Node.class), anyLong(), anyString(), anyString(), anyString(), anyString(), anyInt(), any(Action.class)).thenReturn(new Status(StatusCode.SUCCESS));
 
-        int t = routerInterfacesCache.size();
 
         Whitebox.invokeMethod(neutronL3Adapter, "programRouterInterfaceStage1", node, Long.valueOf(12), SEG_ID, SEG_ID, MAC_ADDRESS, IP, 4, Action.ADD);
 
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programRouterInterfaceStage1", any(Node.class), anyLong(), anyString(), anyString(), anyString(), anyString(), anyInt(), eq(Action.ADD));
-        assertEquals("Error, did not add the interface", t, routerInterfacesCache.size() - 1);
 
-        t = routerInterfacesCache.size();
         Whitebox.invokeMethod(neutronL3Adapter, "programRouterInterfaceStage1", node, Long.valueOf(12), SEG_ID, SEG_ID, MAC_ADDRESS, IP, 4, Action.DELETE);
 
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programRouterInterfaceStage1", any(Node.class), anyLong(), anyString(), anyString(), anyString(), anyString(), anyInt(), eq(Action.DELETE));
-        assertEquals("Error, did not delete the interface", t, routerInterfacesCache.size() + 1);
     }
 
-    // either add or remove routerInterfacesCache
     @Test
     public void testProgramRouterInterfaceStage2() throws Exception {
         NodeId nodeId = mock(NodeId.class);
@@ -759,28 +745,21 @@ public class NeutronL3AdapterTest {
 
     }
 
-    //either add or remove staticArpEntryCache
     @Test
     public void testProgramStaticArpStage1() throws Exception {
-        Set<String> staticArpEntryCache = new HashSet<String>();
 
         MemberModifier.suppress(MemberMatcher.method(NeutronL3Adapter.class, "programStaticArpStage2", Long.class, String.class, String.class, String.class, Action.class));
 
-        MemberModifier.field(NeutronL3Adapter.class, "staticArpEntryCache").set(neutronL3Adapter , staticArpEntryCache);
         PowerMockito.when(neutronL3Adapter, "programStaticArpStage2", anyLong(), anyString(), anyString(), anyString(), any(Action.class)).thenReturn(new Status(StatusCode.SUCCESS));
 
-        int t = staticArpEntryCache.size();
 
         Whitebox.invokeMethod(neutronL3Adapter, "programStaticArpStage1", Long.valueOf(12), PORT_INT, MAC_ADDRESS, IP, Action.ADD);
 
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programStaticArpStage2", anyLong(), anyString(), anyString(), anyString(), eq(Action.ADD));
-        assertEquals("Error, did not add the static arp", t, staticArpEntryCache.size() - 1);
 
-        t = staticArpEntryCache.size();
         Whitebox.invokeMethod(neutronL3Adapter, "programStaticArpStage1", Long.valueOf(12), PORT_INT, MAC_ADDRESS, IP, Action.DELETE);
 
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programStaticArpStage2", anyLong(), anyString(), anyString(), anyString(), eq(Action.DELETE));
-        assertEquals("Error, did not delete the static arp", t, staticArpEntryCache.size() + 1);
     }
 
     @Test
@@ -794,28 +773,21 @@ public class NeutronL3AdapterTest {
         assertEquals("Error, this not return the correct status code", new Status(StatusCode.SUCCESS), Whitebox.invokeMethod(neutronL3Adapter, "programStaticArpStage2", Long.valueOf(45), PORT_INT, MAC_ADDRESS, IP, Action.ADD));
     }
 
-    // either add or remove inboundIpRewriteCache
     @Test
     public void testProgramInboundIpRewriteStage1() throws Exception {
-        Set<String> inboundIpRewriteCache = new HashSet<String>();
 
         MemberModifier.suppress(MemberMatcher.method(NeutronL3Adapter.class, "programInboundIpRewriteStage2", Long.class, Long.class, String.class, String.class, String.class, Action.class));
 
-        MemberModifier.field(NeutronL3Adapter.class, "inboundIpRewriteCache").set(neutronL3Adapter , inboundIpRewriteCache);
         PowerMockito.when(neutronL3Adapter, "programInboundIpRewriteStage2", anyLong(), anyLong(), anyString(), anyString(), anyString(), any(Action.class)).thenReturn(new Status(StatusCode.SUCCESS));
 
-        int t = inboundIpRewriteCache.size();
 
         Whitebox.invokeMethod(neutronL3Adapter, "programInboundIpRewriteStage1", Long.valueOf(12), Long.valueOf(12), PORT_INT, MAC_ADDRESS, IP, Action.ADD);
 
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programInboundIpRewriteStage2", anyLong(), anyLong(), anyString(), anyString(), anyString(), eq(Action.ADD));
-        assertEquals("Error, did not add the inboundIpRewrite", t, inboundIpRewriteCache.size() - 1);
 
-        t = inboundIpRewriteCache.size();
         Whitebox.invokeMethod(neutronL3Adapter, "programInboundIpRewriteStage1", Long.valueOf(12), Long.valueOf(12),PORT_INT, MAC_ADDRESS, IP, Action.DELETE);
 
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programInboundIpRewriteStage2", anyLong(), anyLong(), anyString(), anyString(), anyString(), eq(Action.DELETE));
-        assertEquals("Error, did not delete the inboundIpRewrite", t, inboundIpRewriteCache.size() + 1);
     }
 
     @Test
@@ -829,10 +801,8 @@ public class NeutronL3AdapterTest {
         assertEquals("Error, this not return the correct status code", new Status(StatusCode.SUCCESS), Whitebox.invokeMethod(neutronL3Adapter, "programInboundIpRewriteStage2", Long.valueOf(45), Long.valueOf(45), SEG_ID, MAC_ADDRESS, IP, Action.ADD));
     }
 
-    // either add or remove outboundIpRewriteExclusionCache
     @Test
     public void testProgramIpRewriteExclusionStage1() throws Exception {
-        Set<String> outboundIpRewriteExclusionCache = new HashSet<String>();
 
         NodeId nodeId = mock(NodeId.class);
         when(nodeId.getValue()).thenReturn(ID);
@@ -841,21 +811,16 @@ public class NeutronL3AdapterTest {
 
         MemberModifier.suppress(MemberMatcher.method(NeutronL3Adapter.class, "programIpRewriteExclusionStage2", Node.class, Long.class, String.class, String.class, Action.class));
 
-        MemberModifier.field(NeutronL3Adapter.class, "outboundIpRewriteExclusionCache").set(neutronL3Adapter , outboundIpRewriteExclusionCache);
         PowerMockito.when(neutronL3Adapter, "programIpRewriteExclusionStage2", any(Node.class), anyLong(), anyString(), anyString(), any(Action.class)).thenReturn(new Status(StatusCode.SUCCESS));
 
-        int t = outboundIpRewriteExclusionCache.size();
 
         Whitebox.invokeMethod(neutronL3Adapter, "programIpRewriteExclusionStage1", node, Long.valueOf(12), SEG_ID, CIDR, Action.ADD);
 
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programIpRewriteExclusionStage2", any(Node.class), anyLong(), anyString(), anyString(), eq(Action.ADD));
-        assertEquals("Error, did not add the outboundIpRewriteExclusion", t, outboundIpRewriteExclusionCache.size() - 1);
 
-        t = outboundIpRewriteExclusionCache.size();
         Whitebox.invokeMethod(neutronL3Adapter, "programIpRewriteExclusionStage1", node, Long.valueOf(12), SEG_ID, CIDR, Action.DELETE);
 
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programIpRewriteExclusionStage2", any(Node.class), anyLong(), anyString(), anyString(), eq(Action.DELETE));
-        assertEquals("Error, did not delete the outboundIpRewriteExclusion", t, outboundIpRewriteExclusionCache.size() + 1);
     }
 
     @Test
@@ -868,29 +833,22 @@ public class NeutronL3AdapterTest {
         assertEquals("Error, this not return the correct status code", new Status(StatusCode.SUCCESS), Whitebox.invokeMethod(neutronL3Adapter, "programIpRewriteExclusionStage2", node, Long.valueOf(45), SEG_ID, CIDR, Action.ADD));
     }
 
-    // either add or remove outboundIpRewriteCache
     @SuppressWarnings("unchecked")
     @Test
     public void testProgramOutboundIpRewriteStage1() throws Exception{
-        Set<String> outboundIpRewriteCache = new HashSet<String>();
 
         MemberModifier.suppress(MemberMatcher.method(NeutronL3Adapter.class, "programOutboundIpRewriteStage2", floatingIpClass, Action.class));
 
-        MemberModifier.field(NeutronL3Adapter.class, "outboundIpRewriteCache").set(neutronL3Adapter , outboundIpRewriteCache);
         PowerMockito.when(neutronL3Adapter, "programOutboundIpRewriteStage2", any(floatingIpClass), any(Action.class)).thenReturn(new Status(StatusCode.SUCCESS));
 
-        int t = outboundIpRewriteCache.size();
 
         Whitebox.invokeMethod(neutronL3Adapter, "programOutboundIpRewriteStage1", floatingIpObject, Action.ADD);
 
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programOutboundIpRewriteStage2", any(floatingIpClass), eq(Action.ADD));
-        assertEquals("Error, did not add the outbound ip", t, outboundIpRewriteCache.size() - 1);
 
-        t = outboundIpRewriteCache.size();
         Whitebox.invokeMethod(neutronL3Adapter, "programOutboundIpRewriteStage1", floatingIpObject, Action.DELETE);
 
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programOutboundIpRewriteStage2", any(floatingIpClass), eq(Action.DELETE));
-        assertEquals("Error, did not delete the outbound ip", t, outboundIpRewriteCache.size() + 1);
     }
 
     /*@Test
@@ -919,14 +877,14 @@ public class NeutronL3AdapterTest {
 
         PowerMockito.when(southbound.getBridge(any(Node.class), anyString())).thenReturn(mock(OvsdbBridgeAugmentation.class));
         PowerMockito.when(configurationService.getIntegrationBridgeName()).thenReturn("");
-        PowerMockito.when(southbound.getDataPathId(any(Node.class))).thenReturn(Long.valueOf(45));
+        PowerMockito.when(southbound.getDataPathId(any(Node.class))).thenReturn(45L);
 
-        assertEquals("Error, did not return the correct Dpid", Long.valueOf(45), Whitebox.invokeMethod(neutronL3Adapter, "getDpidForIntegrationBridge", mock(Node.class)));
+        assertEquals("Error, did not return the correct Dpid", 45L, Whitebox.invokeMethod(neutronL3Adapter, "getDpidForIntegrationBridge", mock(Node.class)));
     }
 
     @Test
     public void testencodeExcplicitOFPort() throws Exception {
-        assertEquals("Error, did not correctly encode the port", OFPort, NeutronL3Adapter.encodeExcplicitOFPort(Long.valueOf(45)));
+        assertEquals("Error, did not correctly encode the port", OFPort, NeutronL3Adapter.encodeExcplicitOFPort(45L));
     }
 
     @Test
@@ -967,6 +925,8 @@ public class NeutronL3AdapterTest {
 
     @Test
     public void testSetDependenciesObject() throws Exception{
+        MemberModifier.field(NeutronL3Adapter.class, "enabled").set(neutronL3Adapter , false);
+
         INeutronNetworkCRUD iNeutronNetworkCRUD = mock(INeutronNetworkCRUD.class);
         neutronL3Adapter.setDependencies(iNeutronNetworkCRUD);
         assertEquals("Error, did not return the correct object", getField("neutronNetworkCache"), iNeutronNetworkCRUD);
@@ -998,6 +958,8 @@ public class NeutronL3AdapterTest {
         L3ForwardingProvider l3ForwardingProvider = mock(L3ForwardingProvider.class);
         neutronL3Adapter.setDependencies(l3ForwardingProvider);
         assertEquals("Error, did not return the correct object", getField("l3ForwardingProvider"), l3ForwardingProvider);
+
+        MemberModifier.field(NeutronL3Adapter.class, "enabled").set(neutronL3Adapter , true);
     }
 
     private Object getField(String fieldName) throws Exception {
@@ -1011,6 +973,6 @@ public class NeutronL3AdapterTest {
         Class clazz = Whitebox.getInnerClassType(NeutronL3Adapter.class, "FloatIpData");
         Constructor [] constructors = clazz.getConstructors();
         Constructor c  = constructors[0];
-        return c.newInstance(new NeutronL3Adapter(), Long.valueOf(415), Long.valueOf(415), "a", "b", "c", "d", "e");
+        return c.newInstance(neutronL3Adapter, 415L, 415L, "a", "b", "c", "d", "e");
     }
 }
index 95a5ef5b6f20455067d6a7490e0fc268f90e51ab..45d48bb849a3854addb794002448dadb98d72824 100644 (file)
@@ -69,7 +69,7 @@ public class NodeCacheManagerImplTest {
     @Test
     public void testCacheListenerAddedAndRemoved() {
         ServiceReference ref = mock(ServiceReference.class);
-        when(ref.getProperty(org.osgi.framework.Constants.SERVICE_ID)).thenReturn(Long.valueOf(1));
+        when(ref.getProperty(org.osgi.framework.Constants.SERVICE_ID)).thenReturn(1L);
 
         // add
         nodeCacheManagerImpl.cacheListenerAdded(ref, mock(NodeCacheListener.class));
index 5e345a4e385865b12f053d9d4d62575dbbd097bf..54e44a45911a93bddc6488a5bb5d65e9fb88ea3c 100644 (file)
@@ -67,7 +67,7 @@ public class ProviderNetworkManagerImplTest {
         Map<?, ?> map = (HashMap<?, ?>) getField("providers");
 
         ServiceReference<?> ref = mock(ServiceReference.class);
-        when(ref.getProperty(org.osgi.framework.Constants.SERVICE_ID)).thenReturn(Long.valueOf(1));
+        when(ref.getProperty(org.osgi.framework.Constants.SERVICE_ID)).thenReturn(1L);
 
         providerNetworkManagerImpl.providerAdded(ref, mock(NetworkingProvider.class));
 
index 1888003e88a149e10be92e7358eb31c319d052bf..b0628218a19699c640911323eaa86836de67ee4e 100644 (file)
@@ -56,7 +56,7 @@ public class SecurityServicesImplTest {
     public void setUp(){
         NeutronPort neutronPort = mock(NeutronPort.class);
 
-        List<NeutronSecurityGroup> securityGroups = new ArrayList<NeutronSecurityGroup>();
+        List<NeutronSecurityGroup> securityGroups = new ArrayList<>();
         securityGroups.add(neutronSecurityGroup);
 
         when(neutronPort.getSecurityGroups()).thenReturn(securityGroups);
index 5a738a6a8d476bffe987171df31c35ab89573177..92e92ea7d45c99c66625c02819e6acf0aede2cd2 100644 (file)
@@ -106,7 +106,7 @@ public class TenantNetworkManagerImplTest {
         NeutronNetwork neutronNetwork = mock(NeutronNetwork.class);
         when(neutronNetwork.getProviderSegmentationID()).thenReturn(SEG_ID);
         when(neutronNetwork.getNetworkUUID()).thenReturn(NETWORK_ID);
-        List<NeutronNetwork> listNeutronNetwork = new ArrayList<NeutronNetwork>();
+        List<NeutronNetwork> listNeutronNetwork = new ArrayList<>();
         listNeutronNetwork.add(neutronNetwork);
         when(neutronNetworkCache.getAllNetworks()).thenReturn(listNeutronNetwork);
 
@@ -115,7 +115,7 @@ public class TenantNetworkManagerImplTest {
         when(neutronPort.getNetworkUUID()).thenReturn(NETWORK_ID);
         when(neutronPortCache.getPort(anyString())).thenReturn(neutronPort);
 
-        List<OvsdbTerminationPointAugmentation> ports = new ArrayList<OvsdbTerminationPointAugmentation>();
+        List<OvsdbTerminationPointAugmentation> ports = new ArrayList<>();
         ports.add(mock(OvsdbTerminationPointAugmentation.class));
         when(southbound.getTerminationPointsOfBridge(any(Node.class))).thenReturn(ports);
 
@@ -128,7 +128,7 @@ public class TenantNetworkManagerImplTest {
     @Test
     public void testGetNetworkId() {
         NeutronNetwork neutronNetwork = mock(NeutronNetwork.class);
-        List<NeutronNetwork> listNeutronNetwork = new ArrayList<NeutronNetwork>();
+        List<NeutronNetwork> listNeutronNetwork = new ArrayList<>();
         listNeutronNetwork.add(neutronNetwork);
 
         when(neutronNetwork.getProviderSegmentationID()).thenReturn("segId");
index 7ab12eff4d64a7d62d6f5930b6811f460b2534aa..6f4695fb80fbbc78106d78380919dd2f061d9fcb 100644 (file)
@@ -55,7 +55,7 @@ public class VlanConfigurationCacheImplTest {
     @Before
     public void setUp(){
         when(southbound.getOvsdbNodeUUID(any(Node.class))).thenReturn(NODE_UUID);
-        List<OvsdbTerminationPointAugmentation> ports = new ArrayList<OvsdbTerminationPointAugmentation>();
+        List<OvsdbTerminationPointAugmentation> ports = new ArrayList<>();
         OvsdbTerminationPointAugmentation port = mock(OvsdbTerminationPointAugmentation.class);
         VlanId vlanId = mock(VlanId.class);
         when(vlanId.getValue()).thenReturn(VLAN_ID);
index 01dddbdf30f09e6f8319aef63528f2febb318b2e..735fc6e10ade09432295889f69a9418dc55128aa 100644 (file)
@@ -1,18 +1,32 @@
-define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3, OvsCore, _) {
+define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function (d3, OvsCore, _) {
   'use strict';
 
   var root = null,
     canvasWidth = -1,
     canvasHeight = -1,
-    bbox = { x:0, y:15, width: 0, height: 0},
+    bbox = {
+      x: 0,
+      y: 15,
+      width: 0,
+      height: 0
+    },
     // config
     nodeWidth = 15,
     nodeHeight = -1,
-    defaultRouterWidth = 66,
-    defaultRouterHeight = 66,
-    networkMargin = { width: 120, height: 15},
-    routerMargin = { width: 120, height: 40},
-    vmMargin = { width: 90, height: 30},
+    defaultRouterWidth = 52,
+    defaultRouterHeight = 52,
+    networkMargin = {
+      width: 120,
+      height: 15
+    },
+    routerMargin = {
+      width: 120,
+      height: 40
+    },
+    vmMargin = {
+      width: 90,
+      height: 30
+    },
     defaultVmsWidth = 48,
     defaultVmsHeight = 48,
     ipNetworkTextMaxLength = 60,
@@ -31,25 +45,25 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
     d3Router = null,
     randomize = OvsCore.Util.Math.Random(42);
 
-  function LogicalGraph(id, width , height) {
+  function LogicalGraph(id, width, height) {
     canvasWidth = width;
     canvasHeight = height;
 
     nodeHeight = height - 15;
 
     var tmp = d3.select(id).append("svg")
-    .attr('width', width)
-    .attr('height', height)
-    .append("svg:g")
-    .attr('class', 'layer_0');
+      .attr('width', width)
+      .attr('height', height)
+      .append("svg:g")
+      .attr('class', 'layer_0');
 
     tmp.append('svg:rect')
-    .attr('width', width)
-    .attr('height', height)
-    .attr('fill', 'white');
+      .attr('width', width)
+      .attr('height', height)
+      .attr('fill', 'white');
 
     root = tmp.call(d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom))
-    .append("g");
+      .append("g");
     tmp.on("dblclick.zoom", null);
     addDefs();
   }
@@ -60,7 +74,7 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
     var defs = d3.select('svg').insert('svg:defs', ':first-child');
     var filter = defs.append('svg:filter').attr('id', 'boxShadow').attr('x', '0').attr('y', '0').attr('width', '200%').attr('height', '200%');
     filter.append('feOffset').attr('in', 'SourceAlpha').attr('result', 'offOut').attr('dx', 0).attr('dy', 0);
-    filter.append('feGaussianBlur').attr('stdDeviation', '5').attr('in','offOut').attr('result', 'blurOut');
+    filter.append('feGaussianBlur').attr('stdDeviation', '5').attr('in', 'offOut').attr('result', 'blurOut');
     filter.append('feOffset').attr('in', 'SourceGraphic').attr('in2', 'blurOut').attr('mode', 'normal');
   }
 
@@ -70,26 +84,26 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
 
   Object.defineProperties(LogicalGraph.prototype, {
     networks: {
-      set: function(value) {
+      set: function (value) {
         networkData = value;
-        value.forEach(function(net) {
+        value.forEach(function (net) {
           routerData = routerData.concat(net.routers);
         });
-        value.forEach(function(net) {
+        value.forEach(function (net) {
           vmData = vmData.concat(net.instances);
         });
       }
     }
   });
 
-  LogicalGraph.prototype.start = function() {
+  LogicalGraph.prototype.start = function () {
     setTopologyPosition.call(this, networkData);
     addLinksToDom.call(this, linkData);
     addNetWorkRouterVmsToDom.call(this, networkData, routerData, vmData);
     update.call(this);
   };
 
-  LogicalGraph.prototype.freeDOM = function() {
+  LogicalGraph.prototype.freeDOM = function () {
     d3Node.remove();
     d3Link.remove();
     d3Vm.remove();
@@ -99,48 +113,39 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
     routerData = [];
     vmData = [];
     linkData = [];
-    bbox = { x:0, y:15, width: 0, height: 0};
+    bbox = {
+      x: 0,
+      y: 15,
+      width: 0,
+      height: 0
+    };
   };
 
   function addLinksToDom(linksData) {
-      d3Link = root.selectAll('.llink')
+    d3Link = root.selectAll('.llink')
       .data(linksData).enter().append('svg:g');
 
-      d3Link.append('rect')
-      .attr('width', function(d) {
+    d3Link.append('rect')
+      .attr('width', function (d) {
         return d.target.x - d.source.x;
       })
       .attr('height', linkHeight)
-      .style('fill', function(d) {
+      .style('fill', function (d) {
         return d.color;
       });
 
-      d3Link.append('text')
+    d3Link.append('text')
       .attr('x', 40)
       .attr('y', -3)
-      .text(function(d) {return d.text;});
+      .text(function (d) {
+        return d.text;
+      });
   }
 
   function addNetWorkRouterVmsToDom(networks, routers, vms) {
     var ctx = this,
       timer = null;
 
-    function getAbsPos() {
-      var elem = d3.select(this)[0][0],
-        elemAbsBBox = elem.getBoundingClientRect(),
-        parentAbsBox = d3.select('#l_graph').node().getBoundingClientRect(),
-        left = elemAbsBBox.left - parentAbsBox.left + (elemAbsBBox.right - elemAbsBBox.left),
-        top = elemAbsBBox.top  - parentAbsBox.top;
-
-      if (top < 0 ) {
-        top = 10;
-      }
-      var event = {
-         left : left,
-         top : top
-       };
-       return event;
-    }
     d3Node = root.selectAll('.network')
       .data(networks).enter()
       .append('svg:g');
@@ -157,28 +162,29 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
       .attr('height', nodeHeight)
       .attr('rx', 10)
       .attr('ry', 10)
-      .style('fill', function(d) {
+      .style('fill', function (d) {
         return d.color;
-      }).on('click', function(d) {
+      }).on('click', function (d) {
         if (d3.event.defaultPrevented) return;
-        timer = setTimeout(function() {
-          var e = getAbsPos.call(this);
-          ctx.onClick(e, d);
+        timer = setTimeout(function () {
+          ctx.onClick(d);
         }.bind(this), 150);
-      }).on('dblclick', function(d) {
+      }).on('dblclick', function (d) {
         clearTimeout(timer);
         ctx.dblClick(d);
       });
 
     // append the network name text
     d3Node.append('text')
-      .attr('x', nodeWidth / 2 )
-      .attr('y', nodeHeight /)
+      .attr('x', nodeWidth / 2)
+      .attr('y', nodeHeight / 2)
       .style('text-anchor', 'middle')
       .style('writing-mode', 'tb')
       .style('font-size', '12px')
       .style('glyph-orientation-vertical', '0')
-      .text(function(d) { return d.name; });
+      .text(function (d) {
+        return d.name;
+      });
 
     // text info for the network ip
     d3Node.append('text')
@@ -187,24 +193,25 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
       .attr('transform',
         OvsCore.Util.String.Format('translate({0} {1}) rotate(-90) translate(-{0} -{1})', nodeWidth + 10, nodeHeight - 15))
       .attr('class', 'linfolabel')
-      .text(function(d) {return d.ip;});
+      .text(function (d) {
+        return d.ip;
+      });
 
     // vm
     d3Vm.append('svg:image')
       .attr('width', defaultVmsWidth)
       .attr('height', defaultVmsHeight)
       .attr('filter', 'url(#boxShadow)')
-      .attr('xlink:href', function(d) {
+      .attr('xlink:href', function (d) {
         return d.type === 'network:dhcp' ?
           'src/app/ovsdb/assets/dhcp.png' : 'src/app/ovsdb/assets/vm.png';
       })
-      .on('click', function(d) {
+      .on('click', function (d) {
         if (d3.event.defaultPrevented) return;
-        timer = setTimeout(function() {
-          var e = getAbsPos.call(this);
-          ctx.onClick(e, d);
+        timer = setTimeout(function () {
+          ctx.onClick(d);
         }.bind(this), 150);
-      }).on('dblclick', function(d) {
+      }).on('dblclick', function (d) {
         clearTimeout(timer);
         ctx.dblClick(d);
       });
@@ -214,13 +221,12 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
       .attr('width', defaultRouterWidth)
       .attr('height', defaultRouterHeight)
       .attr('xlink:href', 'src/app/ovsdb/assets/router.png')
-      .on('click', function(d) {
+      .on('click', function (d) {
         if (d3.event.defaultPrevented) return;
-        timer = setTimeout(function() {
-          var e = getAbsPos.call(this);
-          ctx.onClick(e, d);
+        timer = setTimeout(function () {
+          ctx.onClick(d);
         }.bind(this), 150);
-      }).on('dblclick', function(d) {
+      }).on('dblclick', function (d) {
         clearTimeout(timer);
         ctx.dblClick(d);
       });
@@ -231,7 +237,9 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
       .attr('y', defaultRouterHeight + 15)
       .attr('text-anchor', 'middle')
       .attr('class', 'linfolabel')
-      .text(function(d) { return d.name; });
+      .text(function (d) {
+        return d.name;
+      });
 
     // vm name label
     d3Vm.append('text')
@@ -239,14 +247,16 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
       .attr('y', defaultVmsHeight + 15)
       .attr('text-anchor', 'middle')
       .attr('class', 'linfolabel')
-      .text(function(d) { return d.name; });
+      .text(function (d) {
+        return d.name;
+      });
 
     // vm floating ip label
     d3Vm.append('text')
       .attr('x', -35)
       .attr('y', 40)
       .attr('text-anchor', 'middle')
-      .text(function(d) {
+      .text(function (d) {
         return (d.floatingIp) ? d.floatingIp.ip : '';
       });
 
@@ -254,12 +264,15 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
 
   function findNetworkWithRouter(router) {
     var result = [];
-    _.each(router.interfaces, function(inter) {
+    _.each(router.interfaces, function (inter) {
       if (inter.type === 'router_interface') {
-        var net  = tmpNetHolder[inter.networkId] || null;
+        var net = tmpNetHolder[inter.networkId] || null;
 
         if (net) {
-          result.push({network: net, interface: inter});
+          result.push({
+            network: net,
+            interface: inter
+          });
         }
       }
     });
@@ -274,7 +287,7 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
     network.color = d3.hsl(randomize.next() * 360, 1, 0.6).toString();
 
     // look is the network is the highest
-    bbox.height = network.y > bbox.height ? network.y : bbox.height ;
+    bbox.height = network.y > bbox.height ? network.y : bbox.height;
     bbox.width = network.x > bbox.width ? network.x : bbox.width;
 
     // get the number of "childs" (router, vm)
@@ -282,10 +295,10 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
     var nbVm = network.instances.length;
 
     if (!network.external) {
-      _.each(network.subnets, function(subnet, i) {
+      _.each(network.subnets, function (subnet, i) {
         network.ip += subnet.cidr;
-        if (i < network.subnets.length -1) {
-            network.ip += ', ';
+        if (i < network.subnets.length - 1) {
+          network.ip += ', ';
         }
       });
     }
@@ -302,11 +315,11 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
 
   function positionateRouter(network, x, y) {
     var px = x,
-      py = y ;
+      py = y;
 
     // loop over all routers
-    _.each(network.routers, function(router, i) {
-      router.x = getRouterCentroid(x, py).x ;
+    _.each(network.routers, function (router, i) {
+      router.x = getRouterCentroid(x, py).x;
       router.y = py;
       py += getRouterMarginHeight();
 
@@ -318,13 +331,19 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
       }
 
       // look is the router is the highest
-      bbox.height = router.y > bbox.height ? router.y : bbox.height ;
+      bbox.height = router.y > bbox.height ? router.y : bbox.height;
       bbox.width = router.x > bbox.width ? router.x : bbox.width;
 
       linkData.push({
-        source: {x: network.x + (nodeWidth * 0.5), y: router.y + (defaultRouterHeight * 0.5)},
-        target: {x: router.x + (defaultRouterWidth * 0.5), y: router.y + (nodeWidth * 0.5)},
-        color:  network.color,
+        source: {
+          x: network.x + (nodeWidth * 0.5),
+          y: router.y + (defaultRouterHeight * 0.5)
+        },
+        target: {
+          x: router.x + (defaultRouterWidth * 0.5),
+          y: router.y + (nodeWidth * 0.5)
+        },
+        color: network.color,
         text: router.externalGateway.external_fixed_ips[0].ip_address
       });
 
@@ -332,13 +351,19 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
       var nets = findNetworkWithRouter(router),
         step = defaultRouterHeight / (nets.length + 1);
 
-      _.forEach(nets, function(net, i) {
+      _.forEach(nets, function (net, i) {
         var netPos = getNetworkLayerPosition(bbox.width + defaultRouterWidth);
 
         positionateNetwork(net.network, netPos.x, netPos.y);
         linkData.push({
-          source: {x: router.x + (2 * nodeWidth), y: router.y + step * (i + 1) },
-          target: {x: net.network.x + (nodeWidth * 0.5), y: router.y + (nodeWidth * 0.5 )},
+          source: {
+            x: router.x + (2 * nodeWidth),
+            y: router.y + step * (i + 1)
+          },
+          target: {
+            x: net.network.x + (nodeWidth * 0.5),
+            y: router.y + (nodeWidth * 0.5)
+          },
           color: net.network.color,
           text: net.interface.ip.ip_address
         });
@@ -351,56 +376,62 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
 
     // I do vm before router because router
     // will step to another BUS
-    _.each(network.instances, function(vm) {
+    _.each(network.instances, function (vm) {
       vm.x = x;
       vm.y = y;
 
       // look is the network is the highest
-      bbox.height = vm.y > bbox.height ? vm.y : bbox.height ;
+      bbox.height = vm.y > bbox.height ? vm.y : bbox.height;
       bbox.width = vm.x > bbox.width ? vm.x : bbox.width;
 
       y += getVmMarginHeight();
       linkData.push({
-        source: {x: network.x + (nodeWidth * 0.5), y: vm.y + (defaultVmsHeight * 0.5 )},
-        target: {x: vm.x + (defaultVmsWidth * 0.5), y: vm.y + (nodeWidth * 0.5)},
-        color:  network.color,
+        source: {
+          x: network.x + (nodeWidth * 0.5),
+          y: vm.y + (defaultVmsHeight * 0.5)
+        },
+        target: {
+          x: vm.x + (defaultVmsWidth * 0.5),
+          y: vm.y + (nodeWidth * 0.5)
+        },
+        color: network.color,
         text: vm.ip
       });
     });
   }
 
   /*
-  *  Scan the whole "BUS" to display it properly
-  * ------------------------------------------------
-  *  I build it in a virtual space, if it need to be
-  *  resize it at the end when the overal bounding
-  *  box is known
-  */
+   *  Scan the whole "BUS" to display it properly
+   * ------------------------------------------------
+   *  I build it in a virtual space, if it need to be
+   *  resize it at the end when the overal bounding
+   *  box is known
+   */
   function setTopologyPosition(networks) {
-    _.each(networks, function(net) {
+    _.each(networks, function (net) {
       tmpNetHolder[net.id] = net;
     });
 
     var i = 0;
-    for(var key in tmpNetHolder) {
-        var margin = (i === 0) ? 5 : networkMargin.width,
-          net = tmpNetHolder[key];
-        if (net.routers.length > 0) {
-          positionateNetwork(net, bbox.x + bbox.width + margin, bbox.y);
-          ++i;
-        }
+    for (var key in tmpNetHolder) {
+      var margin = (i === 0) ? 5 : networkMargin.width,
+        net = tmpNetHolder[key];
+      if (net.routers.length > 0) {
+        positionateNetwork(net, bbox.x + bbox.width + margin, bbox.y);
+        ++i;
+      }
     }
 
-    for(var key in tmpNetHolder) {
-        var margin = networkMargin.width,
-          net = tmpNetHolder[key];
-          positionateNetwork(net, bbox.x + bbox.width + margin, bbox.y);
+    for (var key in tmpNetHolder) {
+      var margin = networkMargin.width,
+        net = tmpNetHolder[key];
+      positionateNetwork(net, bbox.x + bbox.width + margin, bbox.y);
     }
   }
 
   /*
-  * Check and ajust the height for a network.
-  */
+   * Check and ajust the height for a network.
+   */
   function ajustHeighBaseOnChilds(nbRouter, nbVm) {
     // calculate the height for the number of childs
     var childHeight = nbRouter * (getRouterMarginHeight()) +
@@ -413,29 +444,29 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
   }
 
   /*
-  * Set the view to the modal position
-  */
+   * Set the view to the modal position
+   */
   function update() {
 
-    d3Node.attr('transform', function(d) {
+    d3Node.attr('transform', function (d) {
       return OvsCore.Util.String.Format("translate({0}, {1})",
         d.x, d.y
       );
     });
 
-    d3Router.attr('transform', function(d, i) {
+    d3Router.attr('transform', function (d, i) {
       return OvsCore.Util.String.Format("translate({0}, {1})",
         d.x, d.y
       );
     });
 
-    d3Vm.attr('transform', function(d) {
+    d3Vm.attr('transform', function (d) {
       return OvsCore.Util.String.Format("translate({0}, {1})",
         d.x, d.y
       );
     });
 
-    d3Link.attr('transform', function(d) {
+    d3Link.attr('transform', function (d) {
       return OvsCore.Util.String.Format("translate({0}, {1})",
         d.source.x, d.source.y
       );
@@ -454,8 +485,8 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
 
   function getRouterCentroid(x, y) {
     return {
-      x : x + defaultRouterWidth * 0.5,
-      y : y + defaultRouterHeight * 0.5
+      x: x + defaultRouterWidth * 0.5,
+      y: y + defaultRouterHeight * 0.5
     };
   }
 
@@ -469,15 +500,15 @@ define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3,
 
   function getNetworkLayerPosition(x) {
     return {
-      x : x + networkMargin.width,
-      y : networkMargin.height
+      x: x + networkMargin.width,
+      y: networkMargin.height
     };
   }
 
   function getVmLayerPosition(nbRouter, x) {
-    var t =  {
-      x : x + vmMargin.width * 2,
-      y : getRoutersDim(nbRouter).height + getVmMarginHeight()
+    var t = {
+      x: x + vmMargin.width * 2,
+      y: getRoutersDim(nbRouter).height + getVmMarginHeight()
     };
     return t;
   }
index 5d3d402f6b54e2dc344f1669e72fe73bac6f9fbf..70733ef7318a642f730dbd5f92bdcec0e224da17 100644 (file)
@@ -24,7 +24,7 @@ define(['underscore'], function (_) {
         }
       },
       nodes: {
-        get: function() {
+        get: function () {
           return _.extend({}, this._bridgeNodes, this._ovsdbNodes);
         }
       },
@@ -58,10 +58,10 @@ define(['underscore'], function (_) {
     Topology.prototype.updateLink = function () {
       _.each(this._links, (function (link, key) {
         if (link instanceof Link) {
-          srcNode = _.filter(this._bridgeNodes, function(node) {
+          srcNode = _.filter(this._bridgeNodes, function (node) {
             return node.getFLowName() === link.srcNodeId;
           });
-          destNode = _.filter(this._bridgeNodes, function(node) {
+          destNode = _.filter(this._bridgeNodes, function (node) {
             return node.getFLowName() === link.destNodeId;
           });
           link.srcNodeId = srcNode[0].nodeId;
@@ -85,22 +85,37 @@ define(['underscore'], function (_) {
       this.ovsVersion = ovsVersion;
     }
 
-    OvsNode.prototype.showIpAdress = function() {
+    OvsNode.prototype.showIpAdress = function () {
       return this.otherLocalIp;
     };
 
-    OvsNode.prototype.pretty = function() {
+    OvsNode.prototype.pretty = function () {
       return {
-        'tabs' : ['Info'],
-        'containts' : [ {
-          'hasHeader' : false,
-          'headers' : [],
-          'datas' : [
-            { key: 'ID', value: this.nodeId},
-            { key: 'InetMgr', value: this.inetMgr},
-            { key: 'InetNode', value: this.inetNode},
-            { key: 'Local IP', value: this.otherLocalIp},
-            { key: 'OVS Version', value: this.ovsVersion}
+        'tabs': ['Info'],
+        'containts': [{
+          'hasHeader': false,
+          'headers': [],
+          'datas': [
+            {
+              key: 'ID',
+              value: this.nodeId
+            },
+            {
+              key: 'InetMgr',
+              value: this.inetMgr
+            },
+            {
+              key: 'InetNode',
+              value: this.inetNode
+            },
+            {
+              key: 'Local IP',
+              value: this.otherLocalIp
+            },
+            {
+              key: 'OVS Version',
+              value: this.ovsVersion
+            }
           ]
         }]
       };
@@ -140,60 +155,90 @@ define(['underscore'], function (_) {
 
     BridgeNode.prototype.addTerminationPoint = function (tp) {
       this._tpList.push(tp);
-      this._tpList.sort(function(tp1, tp2) {
+      this._tpList.sort(function (tp1, tp2) {
         return tp1.ofPort - tp2.ofPort;
       });
     };
 
-    BridgeNode.prototype.addFlowTableInfo = function(flowTable) {
+    BridgeNode.prototype.addFlowTableInfo = function (flowTable) {
       this.flowTable.push(flowTable);
-      this.flowTable.sort(function(ft1, ft2) {
+      this.flowTable.sort(function (ft1, ft2) {
         return ft1.key - ft2.key;
       });
     };
 
-    BridgeNode.prototype.pretty = function() {
+    BridgeNode.prototype.pretty = function () {
       return {
-        'tabs' : [
+        'tabs': [
           'Basic Info',
           'Ports',
           'Flow Info',
           'Flow Tables'
         ],
-        'containts' : [
+        'containts': [
           {
-            'hasHeader' : false,
-            'headers' : [],
-            'datas' : [
-              { key: 'ID', value: this.nodeId},
-              { key: 'Name', value: this.name},
-              { key: 'OpenFlow Name', value: this.getFLowName()},
-              { key: 'Controller Target', value: this.controllerTarget},
-              { key: 'Controller Connected', value: this.controllerConnected}
+            'hasHeader': false,
+            'headers': [],
+            'datas': [
+              {
+                key: 'ID',
+                value: this.nodeId
+              },
+              {
+                key: 'Name',
+                value: this.name
+              },
+              {
+                key: 'OpenFlow Name',
+                value: this.getFLowName()
+              },
+              {
+                key: 'Controller Target',
+                value: this.controllerTarget
+              },
+              {
+                key: 'Controller Connected',
+                value: this.controllerConnected
+              }
             ]
           },
           {
-            'hasHeader' : true,
-            'header' : ['Of Port', 'Name', 'Mac', 'IFace Id',],
-            'datas' : this._tpList.map(function(s) {
+            'hasHeader': true,
+            'header': ['Of Port', 'Name', 'Mac', 'IFace Id', ],
+            'datas': this._tpList.map(function (s) {
               return [s.ofPort, s.name, s.mac, s.ifaceId];
             })
           },
           {
-              'hasHeader' : false,
-              'headers' : [],
-              'datas': [
-                {key : 'Manufacturer', value: this.flowInfo.manufacturer},
-                {key : 'Hardware', value: this.flowInfo.hardware},
-                {key : 'Software', value: this.flowInfo.software},
-                {key : 'Feature', value: this.flowInfo.features},
-                {key : 'Ip', value: this.flowInfo.ip}
+            'hasHeader': false,
+            'headers': [],
+            'datas': [
+              {
+                key: 'Manufacturer',
+                value: this.flowInfo.manufacturer
+              },
+              {
+                key: 'Hardware',
+                value: this.flowInfo.hardware
+              },
+              {
+                key: 'Software',
+                value: this.flowInfo.software
+              },
+              {
+                key: 'Feature',
+                value: this.flowInfo.features
+              },
+              {
+                key: 'Ip',
+                value: this.flowInfo.ip
+              }
               ]
           },
           {
-            'hasHeader' : true,
-            'headers' : ['Table Id', 'Value'],
-            'datas' :this.flowTable.map(function(t) {
+            'hasHeader': true,
+            'headers': ['Table Id', 'Value'],
+            'datas': this.flowTable.map(function (t) {
               return [t.key, t.value];
             })
           }
@@ -215,12 +260,24 @@ define(['underscore'], function (_) {
     return TerminationPoint;
   })();
 
-  var BaseLink = (function() {
+  var Tunnel = (function () {
+    function Tunnel(name, ofPort, tpType, mac, ifaceId, localIp, remoteIp) {
+      TerminationPoint.call(this, name, ofPort, tpType, mac, ifaceId);
+      this.localIp = localIp;
+      this.remoteIp = remoteIp;
+    }
+    Tunnel.prototype = Object.create(TerminationPoint.prototype);
+    Tunnel.prototype.constructor = Tunnel;
+
+    return Tunnel;
+  })();
+
+  var BaseLink = (function () {
     function BaseLink(linkId, srcNodeId, destNodeId, linkType, styles) {
       this.linkId = linkId;
       this.srcNodeId = srcNodeId;
       this.destNodeId = destNodeId;
-      this.linkType  = linkType;
+      this.linkType = linkType;
 
       // styling
       styles = _.extend({}, styles);
@@ -250,7 +307,7 @@ define(['underscore'], function (_) {
     return Link;
   })();
 
-  var TunnelLink = (function() {
+  var TunnelLink = (function () {
     function TunnelLink(linkId, srcNodeId, destNodeId, linkType, color) {
       var opt = {
         color: 'green',
@@ -266,7 +323,7 @@ define(['underscore'], function (_) {
     return TunnelLink;
   })();
 
-  var BridgeOvsLink = (function() {
+  var BridgeOvsLink = (function () {
     function BridgeOvsLink(linkId, srcNodeId, destNodeId, linkType, color) {
       var opt = {
         color: 'gray',
@@ -281,43 +338,43 @@ define(['underscore'], function (_) {
     return BridgeOvsLink;
   })();
 
-  var Util = (function() {
-    var Maths = (function() {
+  var Util = (function () {
+    var Maths = (function () {
       function Maths() {
 
       }
       // random function in javascript use timespan only
-      Maths.Random = function(nseed) {
-        var constant = Math.pow(2, 13)+1,
+      Maths.Random = function (nseed) {
+        var constant = Math.pow(2, 13) + 1,
           prime = 1987,
           maximum = 1000;
 
-          if (nseed) {
-            seed = nseed;
-          }
+        if (nseed) {
+          seed = nseed;
+        }
 
-          return {
-            next : function(min, max) {
-              seed *= constant;
-              seed += prime;
+        return {
+          next: function (min, max) {
+            seed *= constant;
+            seed += prime;
 
-              return min && max ? min+seed%maximum/maximum*(max-min) : seed%maximum/maximum;
-            }
-          };
+            return min && max ? min + seed % maximum / maximum * (max - min) : seed % maximum / maximum;
+          }
+        };
       };
       return Maths;
     })();
 
-    var String = (function() {
+    var String = (function () {
 
       function String() {
 
       }
-      String.Format = function() {
+      String.Format = function () {
         var s = arguments[0];
         for (var i = 0; i < arguments.length - 1; i++) {
-            var reg = new RegExp("\\{" + i + "\\}", "gm");
-            s = s.replace(reg, arguments[i + 1]);
+          var reg = new RegExp("\\{" + i + "\\}", "gm");
+          s = s.replace(reg, arguments[i + 1]);
         }
         return s;
       };
@@ -331,9 +388,9 @@ define(['underscore'], function (_) {
     };
   })();
 
-  var Neutron = (function() {
+  var Neutron = (function () {
 
-    var SubNet = (function() {
+    var SubNet = (function () {
       function SubNet(id, networkId, name, ipVersion, cidr, gatewayIp, tenantId) {
         this.id = id;
         this.networkId = networkId;
@@ -346,7 +403,7 @@ define(['underscore'], function (_) {
       return SubNet;
     })();
 
-    var Network = (function() {
+    var Network = (function () {
       function Network(id, name, shared, status, external, tenantId) {
         this.id = id;
         this.ip = '';
@@ -360,52 +417,72 @@ define(['underscore'], function (_) {
         this.routers = [];
       }
 
-      Network.prototype.addSubNets = function(subnets) {
-        if(subnets) {
+      Network.prototype.addSubNets = function (subnets) {
+        if (subnets) {
           if (_.isArray(subnets)) {
             var i = 0;
             for (; i < subnets.length; ++i) {
               this.subnets.push(subnets[i]);
             }
-          }
-          else {
+          } else {
             this.subnets.push(subnet);
           }
         }
       };
 
-      Network.prototype.asSubnet = function(subnet) {
-        return _.every(subnet, function(sub) {
-          return _.some(this.subnets, function(s) {
+      Network.prototype.asSubnet = function (subnet) {
+        return _.every(subnet, function (sub) {
+          return _.some(this.subnets, function (s) {
             return s.id === sub;
           });
         }.bind(this));
       };
 
-      Network.prototype.pretty = function() {
+      Network.prototype.pretty = function () {
         return {
-          'tabs' : [
+          'tabs': [
             'Info',
             'Subnets'
           ],
-          'containts' : [
+          'containts': [
             {
-              'hasHeader' : false,
+              'hasHeader': false,
               'headers': [],
-              'datas' : [
-                {key : 'ID', value: this.id},
-                {key : 'Ip', value: this.ip},
-                {key : 'Name', value: this.name},
-                {key : 'Shared', value: this.shared},
-                {key : 'Status', value: this.status},
-                {key : 'External', value: this.external},
-                {key : 'Tenant Id', value: this.tenantId}
+              'datas': [
+                {
+                  key: 'ID',
+                  value: this.id
+                },
+                {
+                  key: 'Ip',
+                  value: this.ip
+                },
+                {
+                  key: 'Name',
+                  value: this.name
+                },
+                {
+                  key: 'Shared',
+                  value: this.shared
+                },
+                {
+                  key: 'Status',
+                  value: this.status
+                },
+                {
+                  key: 'External',
+                  value: this.external
+                },
+                {
+                  key: 'Tenant Id',
+                  value: this.tenantId
+                }
               ]
             },
             {
-              'hasHeader' : true,
-              'header' : ['ID', 'Name', 'Ip Version', 'Ip', 'Gateway Ip'],
-              'datas' : this.subnets.map(function(s) {
+              'hasHeader': true,
+              'header': ['ID', 'Name', 'Ip Version', 'Ip', 'Gateway Ip'],
+              'datas': this.subnets.map(function (s) {
                 return [s.id, s.name, s.ipVersion, s.cidr, s.gatewayIp];
               })
             }
@@ -416,7 +493,7 @@ define(['underscore'], function (_) {
       return Network;
     })();
 
-    var Port = (function() {
+    var Port = (function () {
       function Port(id, networkId, name, tenantId, deviceId, deviceOwner, fixed_ips, mac) {
         this.id = id;
         this.networkId = networkId;
@@ -428,21 +505,39 @@ define(['underscore'], function (_) {
         this.mac = mac;
       }
 
-      Port.prototype.pretty = function() {
+      Port.prototype.pretty = function () {
         return [
-          { key: 'ID', value : this.id },
-          { key: 'Name', value: name },
-          { key: 'Tenant Id', value : this.tenantId },
-          { key: 'Device Id', value : this.deviceId },
-          { key: 'Device Owner', value : this.deviceOwner },
-          { key: 'MAC', value : this.mac }
+          {
+            key: 'ID',
+            value: this.id
+          },
+          {
+            key: 'Name',
+            value: name
+          },
+          {
+            key: 'Tenant Id',
+            value: this.tenantId
+          },
+          {
+            key: 'Device Id',
+            value: this.deviceId
+          },
+          {
+            key: 'Device Owner',
+            value: this.deviceOwner
+          },
+          {
+            key: 'MAC',
+            value: this.mac
+          }
         ];
       };
 
       return Port;
     })();
 
-    var Router = (function() {
+    var Router = (function () {
       function Router(id, name, status, tenantId, externalGateway) {
         this.id = id;
         this.name = name;
@@ -452,27 +547,39 @@ define(['underscore'], function (_) {
         this.externalGateway = externalGateway;
       }
 
-      Router.prototype.pretty = function() {
+      Router.prototype.pretty = function () {
         return {
-          'tabs' : [
+          'tabs': [
             'Info',
             'Interfaces'
           ],
-          'containts' : [
+          'containts': [
             {
-              'hasHeader' : false,
+              'hasHeader': false,
               'headers': [],
-              'datas' : [
-                { key: 'ID', value: this.id},
-                { key: 'Name', value: this.name},
-                { key: 'status', value: this.status},
-                { key: 'Tenant ID', value: this.tenantId}
+              'datas': [
+                {
+                  key: 'ID',
+                  value: this.id
+                },
+                {
+                  key: 'Name',
+                  value: this.name
+                },
+                {
+                  key: 'status',
+                  value: this.status
+                },
+                {
+                  key: 'Tenant ID',
+                  value: this.tenantId
+                }
               ]
             },
             {
-              'hasHeader' : true,
-              'header' : ['ID', 'Type', 'Mac Address', 'Ip', 'Tenant Id'],
-              'datas' : this.interfaces.map(function(s) {
+              'hasHeader': true,
+              'header': ['ID', 'Type', 'Mac Address', 'Ip', 'Tenant Id'],
+              'datas': this.interfaces.map(function (s) {
                 return [s.id, s.type, s.mac, s.ip.ip_address, s.tenantId];
               })
             }
@@ -483,7 +590,7 @@ define(['underscore'], function (_) {
       return Router;
     })();
 
-    var Instance = (function() {
+    var Instance = (function () {
       function Instance(id, networkId, name, ip, mac, deviceOwner, tenantId, topoInfo) {
         this.id = id;
         this.networkId = networkId;
@@ -496,39 +603,63 @@ define(['underscore'], function (_) {
         this.floatingIp = {};
       }
 
-      Instance.prototype.extractFloatingIps = function(floatingIps) {
+      Instance.prototype.extractFloatingIps = function (floatingIps) {
         var ctx = this;
-        this.floatingIp = _.find(floatingIps, function(fIp) {
+        this.floatingIp = _.find(floatingIps, function (fIp) {
           return fIp.tenantId === ctx.tenantId &&
             fIp.fixedIp === ctx.ip;
         });
       };
 
-      Instance.prototype.pretty = function() {
+      Instance.prototype.pretty = function () {
         return {
-          'tabs' : [
+          'tabs': [
             'Info',
             'Ports'
           ],
-          'containts' : [
+          'containts': [
             {
-              'hasHeader' : false,
+              'hasHeader': false,
               'headers': [],
-              'datas' : [
-                { key: 'ID', value: this.id},
-                { key: "Network Id", value : this.networkId},
-                { key: 'Name', value: this.name},
-                { key: 'Ip', value: this.ip},
-                { key: 'Floating Ip', value: (this.floatingIp) ? this.floatingIp.ip : 'Not found' },
-                { key: 'MAC', value: this.mac},
-                { key: 'Type', value: this.type},
-                { key: 'Tenant ID', value: this.tenantId}
+              'datas': [
+                {
+                  key: 'ID',
+                  value: this.id
+                },
+                {
+                  key: "Network Id",
+                  value: this.networkId
+                },
+                {
+                  key: 'Name',
+                  value: this.name
+                },
+                {
+                  key: 'Ip',
+                  value: this.ip
+                },
+                {
+                  key: 'Floating Ip',
+                  value: (this.floatingIp) ? this.floatingIp.ip : 'Not found'
+                },
+                {
+                  key: 'MAC',
+                  value: this.mac
+                },
+                {
+                  key: 'Type',
+                  value: this.type
+                },
+                {
+                  key: 'Tenant ID',
+                  value: this.tenantId
+                }
               ]
             },
             {
-              'hasHeader' : true,
-              'header' : ['Name', 'Of Port', 'Mac', 'Flow', 'Ovsdb Node', 'Ovsdb Node IP'],
-              'datas' : this.topoInfo.map(function(s) {
+              'hasHeader': true,
+              'header': ['Name', 'Of Port', 'Mac', 'Flow', 'Ovsdb Node', 'Ovsdb Node IP'],
+              'datas': this.topoInfo.map(function (s) {
                 return [s.name, s.ofPort, s.mac, s.bridge.getFLowName(), s.ovsNode.nodeId, s.ovsNode.showIpAdress()];
               })
             }
@@ -539,7 +670,7 @@ define(['underscore'], function (_) {
       return Instance;
     })();
 
-    var FloatingIp =(function() {
+    var FloatingIp = (function () {
       function FloatingIp(id, networkId, portId, fixedIp, floatingIp, tentantId, status) {
         this.id = id;
         this.networkId = networkId;
@@ -568,11 +699,12 @@ define(['underscore'], function (_) {
     BridgeNode: BridgeNode,
     TerminationPoint: TerminationPoint,
     Topology: Topology,
+    Tunnel: Tunnel,
     BaseLink: BaseLink,
     Link: Link,
     TunnelLink: TunnelLink,
-    BridgeOvsLink:BridgeOvsLink,
-    Util:Util,
+    BridgeOvsLink: BridgeOvsLink,
+    Util: Util,
     Neutron: Neutron
   };
 });
index 82e7daea2367bbc8229b9f29eefacbb7a214989c..d52cbd45065f7c8e6ad622a0d28bc76389121a38 100644 (file)
Binary files a/ovsdb-ui/module/src/main/resources/ovsdb/assets/dhcp.png and b/ovsdb-ui/module/src/main/resources/ovsdb/assets/dhcp.png differ
index d4a82f445504785b7d7400be7627c3adb44fdf11..fde4ce564aa2ca5b4d1b294a597e13e460351b43 100644 (file)
Binary files a/ovsdb-ui/module/src/main/resources/ovsdb/assets/router.png and b/ovsdb-ui/module/src/main/resources/ovsdb/assets/router.png differ
index e75572a1040968ef516eda6c8ee6e1924a227d78..50cbcf65043294165b7001deb8775cfcc1a445fb 100644 (file)
Binary files a/ovsdb-ui/module/src/main/resources/ovsdb/assets/vm.png and b/ovsdb-ui/module/src/main/resources/ovsdb/assets/vm.png differ
index cc1441dec6c88038d1ff8621f6bef6f14ecd3e1c..cc07e73ddec639f02a6c7259c45da5e51bd8cbbf 100644 (file)
@@ -1,4 +1,4 @@
-define(['app/ovsdb/ovsdb.module'], function(ovsdb) {
+define(['app/ovsdb/ovsdb.module'], function (ovsdb) {
 
   ovsdb.register.constant('nodeIdentifier', {
     IP: 'ip',
@@ -61,4 +61,12 @@ define(['app/ovsdb/ovsdb.module'], function(ovsdb) {
     ID: 'link-id',
     DEST: 'destination'
   });
+
+  ovsdb.register.constant('OVSConstant', {
+    TP_TYPE: {
+      INTERNAL: 'ovsdb:interface-type-internal',
+      VXLAN: 'ovsdb:interface-type-vxlan'
+    }
+  })
+
 });
index 57299d0ee65eebd38e1fd477bf8b18d046d04036..b929eb975c4b1727da7dc8b56111d2bbc3681f7b 100644 (file)
@@ -5,22 +5,22 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-define(['app/ovsdb/ovsdb.module', 'app/ovsdb/lib/d3.min', 'app/ovsdb/Graph', 'app/ovsdb/LogicalGraph','app/ovsdb/OvsCore', 'underscore', 'jquery', 'jquery-ui'], function (ovsdb, d3, Graph, LogicalGraph, OvsCore, _, $) {
+define(['app/ovsdb/ovsdb.module', 'app/ovsdb/lib/d3.min', 'app/ovsdb/Graph', 'app/ovsdb/LogicalGraph', 'app/ovsdb/OvsCore', 'underscore', 'jquery', 'jquery-ui'], function (ovsdb, d3, Graph, LogicalGraph, OvsCore, _, $) {
   'use strict';
 
-  ovsdb.register.directive('logicalGraph', function() {
+  ovsdb.register.directive('logicalGraph', function () {
     return {
       restrict: 'EA',
       scope: false,
-      link : function (scope, elem, attr) {
+      link: function (scope, elem, attr) {
         var lgraph = null,
-        tabCreated = false,
-        width = scope.canvasWidth, //ele[0].clientWidth,
-        height = scope.canvasHeight;
+          tabCreated = false,
+          width = scope.canvasWidth, //ele[0].clientWidth,
+          height = scope.canvasHeight;
 
         scope.lDialogData = {};
 
-        scope.lgraphIsReadyPromise.then(function(ltopo) {
+        scope.lgraphIsReadyPromise.then(function (ltopo) {
           if (!lgraph) {
             lgraph = new LogicalGraph(elem[0], width, height);
           }
@@ -29,7 +29,7 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/lib/d3.min', 'app/ovsdb/Graph', 'ap
 
           lgraph.start();
 
-          lgraph.onClick = function(e, d) {
+          lgraph.onClick = function (d) {
             var dialogId = '#lDialog';
             scope.lDialogData = d.pretty();
             scope.$apply();
@@ -38,26 +38,28 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/lib/d3.min', 'app/ovsdb/Graph', 'ap
               $(dialogId).tabs();
               $(dialogId).draggable({
                 containment: 'parent',
-                cancel:'.window_content'
+                cancel: '.window_content'
               });
               tabCreated = true;
             } else {
               $(dialogId).tabs('refresh');
             }
 
-            var $dia = $(dialogId);
-            $dia.css('left', e.left + 30);
-            $dia.css('top', e.top + 35);
+            var $dia = $(dialogId),
+              left = $dia.css('left'),
+              top = $dia.css('top') || e.top + 35;
+            $dia.css('left', left !== 'auto' ? left : 10);
+            $dia.css('top', top !== 'auto' ? top : 10);
             $dia.show();
 
           };
 
-          lgraph.dblClick = function(d) {
+          lgraph.dblClick = function (d) {
             scope.goToPhysicalView(d);
           };
         });
-        scope.hideLogicalDialog = function() {
-            $('#lDialog').tabs("option", "active", 0)
+        scope.hideLogicalDialog = function () {
+          $('#lDialog').tabs("option", "active", 0)
             .hide();
         };
         elem.on('$destroy', function () {
@@ -136,13 +138,15 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/lib/d3.min', 'app/ovsdb/Graph', 'ap
             });
 
             links.style("stroke", function (o) {
-                return ((o.source.index == d.index || o.target.index == d.index) && o.linkType != 'tunnel')  ? "blue" : o.color;
+              return ((o.source.index == d.index || o.target.index == d.index) && o.linkType != 'tunnel') ? "blue" : o.color;
             });
           };
 
           graph.onNodeOut = function (d, nodes, links) {
             nodes.selectAll('.switch > rect').style("stroke", "black");
-            links.style("stroke", function(o) { return o.color; });
+            links.style("stroke", function (o) {
+              return o.color;
+            });
           };
 
           graph.onNodeClick = function (d, nodes, links, ctx) {
@@ -157,27 +161,27 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/lib/d3.min', 'app/ovsdb/Graph', 'ap
               $(dialogId).tabs();
               $(dialogId).draggable({
                 containment: 'parent',
-                cancel:'.window_content'
+                cancel: '.window_content'
               });
               tabCreated = true;
             } else {
               $(dialogId).tabs('refresh');
             }
 
-            $dia.css('left', /*e.left + */30);
-            $dia.css('top', /*e.top + */35);
+            $dia.css('left', /*e.left + */ 30);
+            $dia.css('top', /*e.top + */ 35);
             $dia.show();
           };
 
         });
 
-        ele.on('$destroy', function() {
+        ele.on('$destroy', function () {
           graph.freeDOM();
         });
 
-        scope.hidePhysicalDialog = function() {
+        scope.hidePhysicalDialog = function () {
           $('#pDialog').tabs("option", "active", 0)
-          .hide();
+            .hide();
         };
 
         scope.rotateGraph = function (value) {
@@ -187,30 +191,30 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/lib/d3.min', 'app/ovsdb/Graph', 'ap
           $('path.tunnel').toggle();
         };
 
-        scope.filterNode = function(nodeIds, tags, exclude) {
+        scope.filterNode = function (nodeIds, tags, exclude) {
           exclude = (exclude === null) ? true : exclude;
           var nodes = d3.selectAll(tags);
-          nodes.each(function(d) {
-              if (nodeIds.indexOf(d.node.nodeId) < 0) {
-                d.hidden = exclude;
-              } else {
-                d.hidden = !exclude;
-              }
-            });
-          nodes.transition().duration(200).style('opacity', function(d) {
-              return d.hidden ? '0.3' : '1';
+          nodes.each(function (d) {
+            if (nodeIds.indexOf(d.node.nodeId) < 0) {
+              d.hidden = exclude;
+            } else {
+              d.hidden = !exclude;
+            }
+          });
+          nodes.transition().duration(200).style('opacity', function (d) {
+            return d.hidden ? '0.3' : '1';
           });
 
         };
 
-        scope.filterLink = function() {
+        scope.filterLink = function () {
           var links = d3.selectAll(".tunnel, .link, .bridgeOvsLink");
 
-          links.each(function(d, i) {
+          links.each(function (d, i) {
             d.hidden = d.source.hidden || d.target.hidden;
           });
-          links.transition().duration(200).style('opacity', function(d) {
-              return d.hidden ? '0.3' : '1';
+          links.transition().duration(200).style('opacity', function (d) {
+            return d.hidden ? '0.3' : '1';
           });
         };
       }
index 29fc85755d3566e26adb0949257d31d11325f2f8..4ef135c3f7a083e4807247d6fa7671c8756ef917 100644 (file)
@@ -5,23 +5,23 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/ovsdb.constant'], function(ovsdb, OvsCore, _) {
+define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/ovsdb.constant'], function (ovsdb, OvsCore, _) {
   'use strict';
 
-  ovsdb.register.factory('OvsdbRestangular', ['Restangular', 'ENV', function(Restangular, ENV) {
-    return Restangular.withConfig(function(RestangularConfig) {
+  ovsdb.register.factory('OvsdbRestangular', ['Restangular', 'ENV', function (Restangular, ENV) {
+    return Restangular.withConfig(function (RestangularConfig) {
       RestangularConfig.setBaseUrl(ENV.getBaseURL("MD_SAL"));
     });
   }]);
 
   // nbv2 support depricated in dlux
-  ovsdb.register.factory('NeutronRestangular', ['Restangular', function(Restangular) {
-    return Restangular.withConfig(function(RestangularConfig) {
+  ovsdb.register.factory('NeutronRestangular', ['Restangular', function (Restangular) {
+    return Restangular.withConfig(function (RestangularConfig) {
       RestangularConfig.setBaseUrl('http://localhost:8080/controller/nb/v2/neutron');
     });
   }]);
 
-  ovsdb.register.factory('CacheFactory', function($q) {
+  ovsdb.register.factory('CacheFactory', function ($q) {
     var svc = {},
       ovsCache = {};
     /*BUG : Using the persistant cache make the physical
@@ -29,26 +29,26 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
      * algorithm. The current behavior is to use the cache
      * only the pile up the datas.
      */
-    svc.obtainDataFromCache = function(key, fn, ctx) {
+    svc.obtainDataFromCache = function (key, fn, ctx) {
       var cacheDefer = $q.defer();
 
       if (angular.isUndefined(ovsCache[key])) {
-        fn.call(ctx, function(data) {
-            ovsCache[key] = {
-              obj : data,
-              timestamp : Date.now() + 2000//300000 // 5 mintues
-            };
-            cacheDefer.resolve(data);
+        fn.call(ctx, function (data) {
+          ovsCache[key] = {
+            obj: data,
+            timestamp: Date.now() + 2000 //300000 // 5 mintues
+          };
+          cacheDefer.resolve(data);
         });
       } else {
         var cacheObj = ovsCache[key];
-        if (cacheObj.timestamp < Date.now() ||  _.isEmpty(cacheObj.obj)) {
-          fn.call(ctx, function(data) {
-              ovsCache[key] = {
-                obj : data,
-                timestamp : Date.now() + 2000//300000 // 5 mintues
-              };
-              cacheDefer.resolve(data);
+        if (cacheObj.timestamp < Date.now() || _.isEmpty(cacheObj.obj)) {
+          fn.call(ctx, function (data) {
+            ovsCache[key] = {
+              obj: data,
+              timestamp: Date.now() + 2000 //300000 // 5 mintues
+            };
+            cacheDefer.resolve(data);
           });
         } else {
           cacheDefer.resolve(cacheObj.obj);
@@ -58,7 +58,7 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
       return cacheDefer.promise;
     };
 
-    svc.getCacheObj = function(key) {
+    svc.getCacheObj = function (key) {
       if (angular.isUndefined(ovsCache[key])) {
         ovsCache[key] = {};
       }
@@ -68,9 +68,9 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
     return svc;
   });
 
-  var TopologySvc = function(OvsdbRestangular, nodeIdentifier, ovsNodeKeys, bridgeNodeKeys, tpKeys, flowInfoKeys, linkIdentifier, $q, $http, CacheFactory) {
+  var TopologySvc = function (OvsdbRestangular, nodeIdentifier, ovsNodeKeys, bridgeNodeKeys, tpKeys, flowInfoKeys, linkIdentifier, OVSConstant, $q, $http, CacheFactory) {
     var svc = {
-      base: function(type) {
+      base: function (type) {
         return OvsdbRestangular.one('restconf').one(type);
       }
     };
@@ -91,7 +91,7 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
       }
 
       if (_.isArray(otherInfo)) {
-        _.each(otherInfo, function(value) {
+        _.each(otherInfo, function (value) {
           if (value[ovsNodeKeys.OTHER_CONFIG_KEY] === 'local_ip') {
             otherLocalIp = value[ovsNodeKeys.OTHER_CONFIG_VALUE];
           }
@@ -108,7 +108,7 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
         tp = node[bridgeNodeKeys.TP],
         controllerEntries = node[bridgeNodeKeys.CONTROLLER_ENTRY];
 
-      _.each(controllerEntries, function(value) {
+      _.each(controllerEntries, function (value) {
         controllerTarget = value[bridgeNodeKeys.TARGET];
         controllerEntries = value[bridgeNodeKeys.IS_CONNECTED];
         return false; // break the anonymus function
@@ -116,7 +116,7 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
 
       bridgeNode = new OvsCore.BridgeNode(node[bridgeNodeKeys.NODE_ID], node[bridgeNodeKeys.DATA_PATH], node[bridgeNodeKeys.BRIDGE_NAME], controllerTarget, controllerConnected);
 
-      _.each(tp, function(value) {
+      _.each(tp, function (value) {
         var tp = parseBridgeTP(value);
 
         if (tp.ofPort == '65534' && (tp.name === 'br-ex' || tp.name === 'br-int')) {
@@ -133,9 +133,10 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
     function parseBridgeTP(tp) {
       var mac = '',
         ifaceId = '',
-        extInfo = tp['ovsdb:port-external-ids'] || tp['ovsdb:interface-external-ids'];
+        extInfo = tp['ovsdb:port-external-ids'] || tp['ovsdb:interface-external-ids'],
+        type = tp[tpKeys.INTERFACE_TYPE];
 
-      _.each(extInfo, function(ext) {
+      _.each(extInfo, function (ext) {
         if (ext[tpKeys.EXTERNAL_KEY_ID] === tpKeys.ATTACHED_MAC) {
           mac = ext[tpKeys.EXTERNAL_KEY_VALUE];
         }
@@ -143,8 +144,23 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
           ifaceId = ext[tpKeys.EXTERNAL_KEY_VALUE] || '';
         }
       });
+      if (type === OVSConstant.TP_TYPE.VXLAN) {
+        var localIp = null,
+          remoteIp = null;
+        _.each(tp['ovsdb:options'], function (option) {
+          switch (option.option) {
+            case 'local_ip':
+              localIp = option.value;
+              break;
+            case 'remote_ip':
+              remoteIp = option.value;
+              break;
+          }
+        });
+        return new OvsCore.Tunnel(tp[tpKeys.NAME], tp[tpKeys.OF_PORT], type, mac, ifaceId, localIp, remoteIp);
+      }
+      return new OvsCore.TerminationPoint(tp[tpKeys.NAME], tp[tpKeys.OF_PORT], type, mac, ifaceId);
 
-      return new OvsCore.TerminationPoint(tp[tpKeys.NAME], tp[tpKeys.OF_PORT], tp[tpKeys.INTERFACE_TYPE], mac, ifaceId);
     }
 
     function fetchTopology(cb) {
@@ -152,7 +168,7 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
       var netTopoDefer = this.base('operational').one('network-topology:network-topology').getList();
 
       // be sure all data are loaded
-      $q.all([invNodeDefer, netTopoDefer]).then(function(values) {
+      $q.all([invNodeDefer, netTopoDefer]).then(function (values) {
           var invNode = values[0],
             netTopo = values[1],
             index_hash = [],
@@ -173,13 +189,13 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
             nodes = invNode.nodes.node,
             topo = new OvsCore.Topology();
 
-          _.each(topologies, function(topology, topo_index) {
+          _.each(topologies, function (topology, topo_index) {
             if (!topology.hasOwnProperty('topology-id')) {
               throw new Error('Invalide JSON format, no topology-id for the topology [' + topo_index + ']');
             }
 
             // if there no node it will be an empty array so noop
-            (topology.node || []).forEach(function(node) {
+            (topology.node || []).forEach(function (node) {
               if (!node[nodeIdentifier.ID]) {
                 throw new Error('Unexpected node : undefined ' + nodeIdentifier.ID + ' key');
               }
@@ -195,7 +211,7 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
             });
 
             // if there no link it will be an empty array so noop
-            (topology.link || []).forEach(function(link) {
+            (topology.link || []).forEach(function (link) {
 
               var source = link[linkIdentifier.SRC]['source-node'],
                 dest = link[linkIdentifier.DEST]['dest-node'];
@@ -205,14 +221,14 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
 
           });
 
-          _.each(nodes, function(node, index) {
+          _.each(nodes, function (node, index) {
             if (!node.id) {
               return;
             }
 
             var bridgeId = node.id;
 
-            var bridgeNode = _.filter(topo.bridgeNodes, function(bridgeNode) {
+            var bridgeNode = _.filter(topo.bridgeNodes, function (bridgeNode) {
               return bridgeNode.getFLowName() === bridgeId;
             })[0];
 
@@ -224,10 +240,13 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
               bridgeNode.flowInfo.manufacturer = node[flowInfoKeys.MANUFACTURER];
               bridgeNode.flowInfo.ip = node[flowInfoKeys.IP];
 
-              _.each(node[flowInfoKeys.TABLE], function(entry) {
+              _.each(node[flowInfoKeys.TABLE], function (entry) {
                 if (!_.isUndefined(entry.id)) {
-                    _.each(entry.flow, function(flow) {
-                    bridgeNode.addFlowTableInfo({ key: flow.table_id, value: flow.id});
+                  _.each(entry.flow, function (flow) {
+                    bridgeNode.addFlowTableInfo({
+                      key: flow.table_id,
+                      value: flow.id
+                    });
                   });
                 }
               });
@@ -235,11 +254,11 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
           });
 
           // show relation between ovsNode and switch with a link
-          _.each(topo.ovsdbNodes, function(node, index) {
-            var bridges = _.filter(topo.bridgeNodes, function(bnode) {
+          _.each(topo.ovsdbNodes, function (node, index) {
+            var bridges = _.filter(topo.bridgeNodes, function (bnode) {
               return bnode.nodeId.indexOf(node.nodeId) > -1;
             });
-            _.each(bridges, function(bridge) {
+            _.each(bridges, function (bridge) {
               var size = _.size(topo.links),
                 link = new OvsCore.BridgeOvsLink(++size, node.nodeId, bridge.nodeId);
               topo.registerLink(link);
@@ -249,19 +268,18 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
           function findVxlan(bridgeNode) {
             var tunnels = [];
 
-            _.each(bridgeNode, function(node) {
-              var ovsdbNode = _.find(topo.ovsdbNodes, function(oNode) {
+            _.each(bridgeNode, function (node) {
+              var ovsdbNode = _.find(topo.ovsdbNodes, function (oNode) {
                 return node.nodeId.indexOf(oNode.nodeId) > -1;
               });
               if (!ovsdbNode) {
                 return false;
               }
-              _.each(node.tPs, function(tp, index) {
-                if (tp.name.indexOf('vxlan-') > -1) {
+              _.each(node.tPs, function (tp, index) {
+                if (tp instanceof OvsCore.Tunnel) {
                   tunnels.push({
-                    port : tp,
-                    bridge : node,
-                    ovsIp : ovsdbNode.otherLocalIp || ovsdbNode.inetMgr
+                    port: tp,
+                    bridge: node
                   });
                 }
               });
@@ -273,47 +291,50 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
           // extract all tunnel paired with their bridge
           var tunnels = findVxlan(topo.bridgeNodes);
           // loop over all pairs
-          _.each(tunnels, function(tunnel, index) {
-            var currIp = tunnel.ovsIp,
-              destIp = tunnel.port.name.replace('vxlan-', ''),
-              linkedBridge = _.find(tunnels.slice(index), function(t) {
-                var vxlanIp =  t.port.name.replace('vxlan-', '');
-                return vxlanIp === currIp;
+          for (var index = 0; index < tunnels.length; ++index) {
+            var tunnel = tunnels[index],
+              currIp = tunnel.port.localIp,
+              destIp = tunnel.port.remoteIp,
+              pairIndex = 0,
+              linkedBridge = _.find(tunnels, function (t, i) {
+                pairIndex = i;
+                return t.port.remoteIp === currIp && t.port.localIp == destIp;
               });
 
-              if (linkedBridge) {
-                  topo.registerLink(new OvsCore.TunnelLink(tunnel.port.name + linkedBridge.port.name, tunnel.bridge.nodeId, linkedBridge.bridge.nodeId));
-              }
-          });
+            if (linkedBridge) {
+              tunnels.splice(pairIndex, 1);
+              topo.registerLink(new OvsCore.TunnelLink(tunnel.port.name + linkedBridge.port.name, tunnel.bridge.nodeId, linkedBridge.bridge.nodeId));
+            }
+          }
 
           topo.updateLink();
           cb(topo);
         },
-        function(err) {
+        function (err) {
           throw err;
         }
       );
     }
 
-    svc.getTopologies = function() {
+    svc.getTopologies = function () {
       return CacheFactory.obtainDataFromCache('topologies', fetchTopology, this);
     };
 
     return svc;
   };
-  TopologySvc.$inject = ['OvsdbRestangular', 'nodeIdentifier', 'ovsNodeKeys', 'bridgeNodeKeys', 'tpKeys', 'flowInfoKeys', 'linkIdentifier', '$q', '$http', 'CacheFactory'];
+  TopologySvc.$inject = ['OvsdbRestangular', 'nodeIdentifier', 'ovsNodeKeys', 'bridgeNodeKeys', 'tpKeys', 'flowInfoKeys', 'linkIdentifier', 'OVSConstant', '$q', '$http', 'CacheFactory'];
 
-  var NeutronSvc = function(NeutronRestangular, CacheFactory, $q, $http) {
+  var NeutronSvc = function (NeutronRestangular, CacheFactory, $q, $http) {
     var svc = {
-      base: function(type) {
-        return NeutronRestangular.one(type);
-      }
-    },
-    tenant_hash = {};
+        base: function (type) {
+          return NeutronRestangular.one(type);
+        }
+      },
+      tenant_hash = {};
 
     function fetchSubNetworks(cb) {
       var subnetskDefer = svc.base('subnets').getList();
-      subnetskDefer.then(function(data) {
+      subnetskDefer.then(function (data) {
         var subnets = data,
           subnetHash = {};
 
@@ -321,20 +342,20 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
           throw new Error('Invalid format from neutron subnets');
         }
 
-        _.each(subnets.subnets, function(subnet) {
-            if (!subnetHash[subnet.network_id]) {
-              subnetHash[subnet.network_id] = [];
-            }
-            tenant_hash[subnet.tenant_id] = {};
-            subnetHash[subnet.network_id].push(new OvsCore.Neutron.SubNet(
-              subnet.id,
-              subnet.network_id,
-              subnet.name,
-              subnet.ip_version,
-              subnet.cidr,
-              subnet.gateway_ip,
-              subnet.tenant_id
-            ));
+        _.each(subnets.subnets, function (subnet) {
+          if (!subnetHash[subnet.network_id]) {
+            subnetHash[subnet.network_id] = [];
+          }
+          tenant_hash[subnet.tenant_id] = {};
+          subnetHash[subnet.network_id].push(new OvsCore.Neutron.SubNet(
+            subnet.id,
+            subnet.network_id,
+            subnet.name,
+            subnet.ip_version,
+            subnet.cidr,
+            subnet.gateway_ip,
+            subnet.tenant_id
+          ));
         });
         cb(subnetHash);
       });
@@ -344,7 +365,7 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
       var networkDefer = svc.base('networks').getList();
       var subnetskDefer = svc.getSubNets();
 
-      $q.all([subnetskDefer, networkDefer]).then(function(datas) {
+      $q.all([subnetskDefer, networkDefer]).then(function (datas) {
         var subnetsHash = datas[0],
           networks = datas[1],
           networkArray = [];
@@ -353,7 +374,7 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
           throw new Error('Invalid format from neutron networks');
         }
 
-        _.each(networks.networks, function(network) {
+        _.each(networks.networks, function (network) {
           var net = new OvsCore.Neutron.Network(
             network.id,
             network.name,
@@ -366,29 +387,29 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
           net.addSubNets(subnetsHash[net.id]);
           networkArray.push(net);
         });
-          cb(networkArray);
+        cb(networkArray);
       });
     }
 
     function fetchRouters(cb) {
       var routerDefer = svc.base('routers').getList();
-      routerDefer.then(function(data) {
+      routerDefer.then(function (data) {
         var routers = data.routers,
           routerArray = [];
 
         if (!routers) {
           throw new Error('Invalid format from neutron routers');
         }
-        _.each(routers, function(router) {
-            var id = router.id,
+        _.each(routers, function (router) {
+          var id = router.id,
             name = router.name,
             status = router.status,
             tenantId = router.tenant_id,
             extGateWayInfo = router.external_gateway_info;
-            tenant_hash[tenantId] = {};
-            routerArray.push(new OvsCore.Neutron.Router(
-              id, name, status, tenantId, extGateWayInfo
-            ));
+          tenant_hash[tenantId] = {};
+          routerArray.push(new OvsCore.Neutron.Router(
+            id, name, status, tenantId, extGateWayInfo
+          ));
         });
         cb(routerArray);
       });
@@ -396,14 +417,14 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
 
     function fetchPorts(cb) {
       var portDefer = svc.base('ports').getList();
-      portDefer.then(function(data){
+      portDefer.then(function (data) {
         var ports = data.ports,
           portArray = [];
 
         if (!ports) {
           throw new Error('Invalid format from neutron ports');
         }
-        _.each(ports, function(port) {
+        _.each(ports, function (port) {
           tenant_hash[port.tenant_id] = {};
           portArray.push(new OvsCore.Neutron.Port(
             port.id,
@@ -422,7 +443,7 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
 
     function fetchFloatingIps(cb) {
       var floatingIpDefer = svc.base('floatingips').getList();
-      floatingIpDefer.then(function(data) {
+      floatingIpDefer.then(function (data) {
         var floatingIps = data.floatingips,
           floatingIpArray = [];
 
@@ -430,7 +451,7 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
           throw new Error('Invalid format from neutron floatingIps');
         }
 
-        _.each(floatingIps, function(fIp) {
+        _.each(floatingIps, function (fIp) {
           tenant_hash[fIp.tenant_id] = {};
           floatingIpArray.push(new OvsCore.Neutron.FloatingIp(
             fIp.id,
@@ -447,27 +468,27 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
       });
     }
 
-    svc.getNetworks = function() {
-        return CacheFactory.obtainDataFromCache('networks', fetchNetworks, this);
+    svc.getNetworks = function () {
+      return CacheFactory.obtainDataFromCache('networks', fetchNetworks, this);
     };
 
-    svc.getSubNets = function() {
+    svc.getSubNets = function () {
       return CacheFactory.obtainDataFromCache('subnet', fetchSubNetworks, this);
     };
 
-    svc.getPorts = function() {
+    svc.getPorts = function () {
       return CacheFactory.obtainDataFromCache('ports', fetchPorts, this);
     };
 
-    svc.getRouters = function() {
+    svc.getRouters = function () {
       return CacheFactory.obtainDataFromCache('routers', fetchRouters, this);
     };
 
-    svc.getFloatingIps = function() {
+    svc.getFloatingIps = function () {
       return CacheFactory.obtainDataFromCache('floatingips', fetchFloatingIps, this);
     };
 
-    svc.getAllTenants = function() {
+    svc.getAllTenants = function () {
       return Object.keys(tenant_hash);
     };
 
@@ -475,11 +496,11 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
   };
   NeutronSvc.$inject = ['NeutronRestangular', 'CacheFactory', '$q', '$http'];
 
-  var OvsUtil = function(NeutronSvc, TopologySvc, CacheFactory, $q) {
+  var OvsUtil = function (NeutronSvc, TopologySvc, CacheFactory, $q) {
     var svc = {};
 
     function findOvsdbNodeForBridge(ovsdbNodes, bridge) {
-      return _.find(ovsdbNodes, function(node) {
+      return _.find(ovsdbNodes, function (node) {
         return bridge.nodeId.indexOf(node.nodeId) > -1;
       });
     }
@@ -493,41 +514,43 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
 
       $q.all([networksDefer, routersDefer, portsDefer, floatingDefer, netTopoDefer]).then(function (datas) {
         var networks = datas[0],
-         routers = datas[1],
-         ports = datas[2],
-         floatingIps = datas[3],
-         topo = datas[4];
+          routers = datas[1],
+          ports = datas[2],
+          floatingIps = datas[3],
+          topo = datas[4];
 
         // match ports with elements
-         _.each(ports, function(port) {
-           port.topoInfo = [];
-           // corelate port.topoInfo data with network topology termination point
-           _.each(topo.bridgeNodes, function(bridge) {
-             _.each(bridge.tPs, function(tp) {
-               if (tp.ifaceId === port.id) {
-                 port.topoInfo.push({
-                   name : tp.name,
-                   ofPort : tp.ofPort,
-                   mac : bridge.dpIp,
-                   bridge : bridge,
-                   ovsNode : findOvsdbNodeForBridge(topo.ovsdbNodes, bridge)
-                 });
-               }
-             });
-           });
-
-           switch(port.deviceOwner) {
-             case 'network:router_gateway':
-             case 'network:router_interface':
-              var router = _.find(routers, function(r) { return r.id === port.deviceId; });
+        _.each(ports, function (port) {
+          port.topoInfo = [];
+          // corelate port.topoInfo data with network topology termination point
+          _.each(topo.bridgeNodes, function (bridge) {
+            _.each(bridge.tPs, function (tp) {
+              if (tp.ifaceId === port.id) {
+                port.topoInfo.push({
+                  name: tp.name,
+                  ofPort: tp.ofPort,
+                  mac: bridge.dpIp,
+                  bridge: bridge,
+                  ovsNode: findOvsdbNodeForBridge(topo.ovsdbNodes, bridge)
+                });
+              }
+            });
+          });
+
+          switch (port.deviceOwner) {
+            case 'network:router_gateway':
+            case 'network:router_interface':
+              var router = _.find(routers, function (r) {
+                return r.id === port.deviceId;
+              });
               if (router) {
                 router.interfaces.push({
                   id: port.id,
-                  networkId : port.networkId,
-                  ip : port.fixed_ips[0],
-                  mac : port.mac,
+                  networkId: port.networkId,
+                  ip: port.fixed_ips[0],
+                  mac: port.mac,
                   type: port.deviceOwner.replace('network:', ''),
-                  tenantId : port.tenantId,
+                  tenantId: port.tenantId,
                   topoInfo: port.topoInfo
                 });
               }
@@ -535,62 +558,64 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
             case 'compute:None':
             case 'compute:nova':
             case 'network:dhcp':
-              var network = _.find(networks, function(n) { return n.id === port.networkId;}),
+              var network = _.find(networks, function (n) {
+                  return n.id === port.networkId;
+                }),
                 inst = null;
 
               if (network) {
-                inst = new OvsCore.Neutron.Instance(port.id,  port.networkId,
+                inst = new OvsCore.Neutron.Instance(port.id, port.networkId,
                   port.name, port.fixed_ips[0].ip_address, port.mac,
-                  port.deviceOwner, port.tenantId, port.topoInfo );
+                  port.deviceOwner, port.tenantId, port.topoInfo);
 
                 inst.extractFloatingIps(floatingIps);
                 network.instances.push(inst);
               }
               break;
-           }
+          }
 
-         });
+        });
 
-         // find all routers for a specific network
-         _.each(networks, function(network) {
-           network.routers = _.filter(routers, function(router) {
-             return network.id === router.externalGateway.network_id;
-           });
+        // find all routers for a specific network
+        _.each(networks, function (network) {
+          network.routers = _.filter(routers, function (router) {
+            return network.id === router.externalGateway.network_id;
+          });
 
-           // order instance by ip
-           network.instances.sort(function(a, b) {
-             var ipA = a.ip.slice(a.ip.lastIndexOf('.') + 1),
-               ipB = b.ip.slice(b.ip.lastIndexOf('.') + 1);
-               return ipA - ipB;
-           });
-         });
+          // order instance by ip
+          network.instances.sort(function (a, b) {
+            var ipA = a.ip.slice(a.ip.lastIndexOf('.') + 1),
+              ipB = b.ip.slice(b.ip.lastIndexOf('.') + 1);
+            return ipA - ipB;
+          });
+        });
 
-         cb(networks);
+        cb(networks);
       });
     }
 
-    svc.getLogicalTopology = function() {
+    svc.getLogicalTopology = function () {
       return CacheFactory.obtainDataFromCache('logicalTopology', pileUpTopologyData, this);
     };
 
-    svc.extractLogicalByTenant = function(tenantId, subSet) {
+    svc.extractLogicalByTenant = function (tenantId, subSet) {
       var lTopoDefer = svc.getLogicalTopology(),
         resultDefer = $q.defer();
-      lTopoDefer.then(function() {
+      lTopoDefer.then(function () {
         var ports = CacheFactory.getCacheObj('ports').obj,
-          filteredPorts = _.filter(ports, function(p) {
+          filteredPorts = _.filter(ports, function (p) {
             return p.tenantId === tenantId;
           });
 
         if (!_.isEmpty(filteredPorts)) {
           var bridgeHash = {};
-          _.each(filteredPorts, function(p) {
+          _.each(filteredPorts, function (p) {
             if (!_.isEmpty(p.topoInfo) && !bridgeHash[p.topoInfo[0].bridge.nodeId]) {
               bridgeHash[p.topoInfo[0].bridge.nodeId] = {};
             }
           });
           var ovsdbHash = {};
-          _.each(filteredPorts, function(p) {
+          _.each(filteredPorts, function (p) {
             if (!_.isEmpty(p.topoInfo) && !ovsdbHash[p.topoInfo[0].ovsNode.nodeId]) {
               ovsdbHash[p.topoInfo[0].ovsNode.nodeId] = {};
             }
@@ -604,15 +629,15 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
       return resultDefer.promise;
     };
 
-    svc.extractLogicalBySubnet = function(subnets, subSet) {
+    svc.extractLogicalBySubnet = function (subnets, subSet) {
       var lTopoDefer = svc.getLogicalTopology(),
         resultDefer = $q.defer();
-      lTopoDefer.then(function() {
+      lTopoDefer.then(function () {
         var ports = CacheFactory.getCacheObj('ports').obj,
           networks = CacheFactory.getCacheObj('networks').obj;
 
-        var filteredPorts = _.filter(ports, function(p) {
-          var net = _.find(networks, function(d) {
+        var filteredPorts = _.filter(ports, function (p) {
+          var net = _.find(networks, function (d) {
             return d.id === p.networkId;
           });
 
@@ -620,13 +645,13 @@ define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/
         });
         if (!_.isEmpty(filteredPorts)) {
           var bridgeHash = {};
-          _.each(filteredPorts, function(p) {
+          _.each(filteredPorts, function (p) {
             if (!_.isEmpty(p.topoInfo) && !bridgeHash[p.topoInfo[0].bridge.nodeId]) {
               bridgeHash[p.topoInfo[0].bridge.nodeId] = {};
             }
           });
           var ovsdbHash = {};
-          _.each(filteredPorts, function(p) {
+          _.each(filteredPorts, function (p) {
             if (!_.isEmpty(p.topoInfo) && !ovsdbHash[p.topoInfo[0].ovsNode.nodeId]) {
               ovsdbHash[p.topoInfo[0].ovsNode.nodeId] = {};
             }
index ff0c104bd5745f586de90466f0606be70e8a89d9..8cb2a5fe567ca7335923a89554793ad09eb1a9fd 100644 (file)
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
 -->\r
 <div id="ovsdb_contain">\r
-<!--\r
+  <!--\r
 <div class="row">\r
   <div class="col-md-2 form-inline">\r
     <label class="switch-light well">\r
   </div>\r
 </div>\r
 -->\r
-<div class="row">\r
-  <div class="col-md-12">\r
-    <div id="tabs" >\r
-      <ul class="nav nav-tabs tabsHeader" style="margin-bottom:15px;">\r
-        <li><a href="#logical_view">Logical View</a></li>\r
-        <li><a href="#2d_view">2D View</a></li>\r
-        <li><a href="#3d_view">3D View</a></li>\r
-      </ul>\r
-      <div id="logical_view" style="background-color:white; position:relative;">\r
-        <div id="l_graph" style="position:relative; height:580px;" logical-graph ></div>\r
+  <div class="row">\r
+    <div class="col-md-12">\r
+      <div id="tabs">\r
+        <ul class="nav nav-tabs tabsHeader" style="margin-bottom:15px;">\r
+          <li><a href="#logical_view">Logical View</a></li>\r
+          <li><a href="#2d_view">2D View</a></li>\r
+        </ul>\r
+        <div id="logical_view" style="background-color:white; position:relative;">\r
+          <div id="l_graph" style="position:relative; height:580px;" logical-graph></div>\r
 \r
-        <div id="lDialog" class="ovsDialog arrow-left">\r
-          <div style="height:10px;">\r
-            <i data-ng-click="hideLogicalDialog()" class="window-icon icon-remove"></i>\r
-          </div>\r
-          <div class="window_content">\r
-            <ul class="nav nav-tabs tabsHeader">\r
-              <li ng-repeat="tab in lDialogData.tabs track by $index" >\r
-                <a href="#lDialogTab_{{$index}}" class="active">{{tab}}</a>\r
-              </li>\r
-            </ul>\r
-            <div ng-repeat="tabContaint in lDialogData.containts track by $index" id="lDialogTab_{{$index}}">\r
-              <table ng-if="!tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
-                <tr ng-repeat="info in tabContaint.datas track by $index">\r
-                  <td > {{info.key}} </td> <td> {{ info.value }} </td>\r
-                </tr>\r
-              </table>\r
-              <table ng-if="tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
-                <tr>\r
-                  <th ng-repeat=" h in tabContaint.header track by $index">{{h}}</th>\r
-                </tr>\r
-                <tr ng-repeat="item in tabContaint.datas track by $index">\r
-                  <td ng-repeat="value in item track by $index"> {{ value }} </td>\r
-                </tr>\r
-              </table>\r
+          <div id="lDialog" class="ovsDialog arrow-left">\r
+            <div style="height:10px;">\r
+              <i data-ng-click="hideLogicalDialog()" class="window-icon icon-remove"></i>\r
+            </div>\r
+            <div class="window_content">\r
+              <ul class="nav nav-tabs tabsHeader">\r
+                <li ng-repeat="tab in lDialogData.tabs track by $index">\r
+                  <a href="#lDialogTab_{{$index}}" class="active">{{tab}}</a>\r
+                </li>\r
+              </ul>\r
+              <div ng-repeat="tabContaint in lDialogData.containts track by $index" id="lDialogTab_{{$index}}">\r
+                <table ng-if="!tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
+                  <tr ng-repeat="info in tabContaint.datas track by $index">\r
+                    <td> {{info.key}} </td>\r
+                    <td> {{ info.value }} </td>\r
+                  </tr>\r
+                </table>\r
+                <table ng-if="tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
+                  <tr>\r
+                    <th ng-repeat=" h in tabContaint.header track by $index">{{h}}</th>\r
+                  </tr>\r
+                  <tr ng-repeat="item in tabContaint.datas track by $index">\r
+                    <td ng-repeat="value in item track by $index"> {{ value }} </td>\r
+                  </tr>\r
+                </table>\r
+              </div>\r
             </div>\r
           </div>\r
-        </div>\r
 \r
-      </div>\r
-      <div id="2d_view">\r
-        <div class="row">\r
-          <div class="col-md-4 col-md-offset-1 form-inline">\r
-            <span>Tenant</span>\r
-            <select id="tenantSelect" ng-model="selectedTenant" ng-change="fiterByTenant()"  ng-options="tenant.name for tenant in tenants track by tenant.id">\r
-              <option value="">---All---</option>\r
-            </select>\r
-          </div>\r
-          <div class="col-md-4 form-inline">\r
-            <span>Subnet</span>\r
-            <select id="tagPicker" multiple="multiple" ng-model="selectedSubnet" ng-change="filterBySubnet()" ng-options="subnet.name for subnet in subnets track by subnet.id">\r
-            </select>\r
-          </div>\r
         </div>\r
-        <div id="nv_graph" style="position:relative; height:580px;" physical-graph></div>\r
-        <div id="pDialog" class="ovsDialog arrow-left">\r
+        <div id="2d_view">\r
+          <div class="row">\r
+            <div class="col-md-4 col-md-offset-1 form-inline">\r
+              <span>Tenant</span>\r
+              <select id="tenantSelect" ng-model="selectedTenant" ng-change="fiterByTenant()" ng-options="tenant.name for tenant in tenants track by tenant.id">\r
+                <option value="">---All---</option>\r
+              </select>\r
+            </div>\r
+            <div class="col-md-4 form-inline">\r
+              <span>Subnet</span>\r
+              <select id="tagPicker" multiple="multiple" ng-model="selectedSubnet" ng-change="filterBySubnet()" ng-options="subnet.name for subnet in subnets track by subnet.id">\r
+              </select>\r
+            </div>\r
+          </div>\r
+          <div id="nv_graph" style="position:relative; height:580px;" physical-graph></div>\r
+          <div id="pDialog" class="ovsDialog arrow-left">\r
             <div style="height:10px">\r
               <i data-ng-click="hidePhysicalDialog()" class="window-icon icon-remove"></i>\r
             </div>\r
-          <div class="window_content">\r
-            <ul class="nav nav-tabs tabsHeader">\r
-              <li ng-repeat="tab in pDialogData.tabs track by $index" >\r
-                <a href="#pDialogTab_{{$index}}" class="active">{{tab}}</a>\r
-              </li>\r
-            </ul>\r
-            <div ng-repeat="tabContaint in pDialogData.containts track by $index" id="pDialogTab_{{$index}}">\r
-              <table ng-if="!tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
-                <tr ng-repeat="info in tabContaint.datas track by $index">\r
-                  <td > {{info.key}} </td> <td> {{ info.value }} </td>\r
-                </tr>\r
-              </table>\r
-              <table ng-if="tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
-                <tr>\r
-                  <th ng-repeat=" h in tabContaint.header track by $index">{{h}}</th>\r
-                </tr>\r
-                <tr ng-repeat="item in tabContaint.datas track by $index">\r
-                  <td ng-repeat="value in item track by $index"> {{ value }} </td>\r
-                </tr>\r
-              </table>\r
+            <div class="window_content">\r
+              <ul class="nav nav-tabs tabsHeader">\r
+                <li ng-repeat="tab in pDialogData.tabs track by $index">\r
+                  <a href="#pDialogTab_{{$index}}" class="active">{{tab}}</a>\r
+                </li>\r
+              </ul>\r
+              <div ng-repeat="tabContaint in pDialogData.containts track by $index" id="pDialogTab_{{$index}}">\r
+                <table ng-if="!tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
+                  <tr ng-repeat="info in tabContaint.datas track by $index">\r
+                    <td> {{info.key}} </td>\r
+                    <td> {{ info.value }} </td>\r
+                  </tr>\r
+                </table>\r
+                <table ng-if="tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
+                  <tr>\r
+                    <th ng-repeat=" h in tabContaint.header track by $index">{{h}}</th>\r
+                  </tr>\r
+                  <tr ng-repeat="item in tabContaint.datas track by $index">\r
+                    <td ng-repeat="value in item track by $index"> {{ value }} </td>\r
+                  </tr>\r
+                </table>\r
+              </div>\r
             </div>\r
           </div>\r
         </div>\r
-\r
       </div>\r
-    <!--  <div id="3d_view">\r
-    </div> -->\r
-  </div><!-- tab -->\r
-</div>\r
+      <!-- tab -->\r
+    </div>\r
index 1978b83e073d8d076203666e18b921489e2bb39e..f73f0cb8f0ed56f66d6156414f140843bcf398a7 100644 (file)
@@ -4,16 +4,44 @@
     "requests": [
         {
             "collectionId": "bc172f70-35df-2cdf-50a4-8ad09b8f17a2",
-            "data": "{\n    \"access-lists\": {\n        \"access-list\": [\n            {\n                \"acl-name\": \"http-acl\",\n                \"access-list-entries\": {\n                    \"access-list-entry\": [\n                        {\n                            \"rule-name\": \"http-rule\",\n                            \"matches\": {\n                                \"destination-port-range\": {\n                                    \"lower-port\": \"80\",\n                                    \"upper-port\": \"80\"\n                                }\n                            },\n                            \"actions\": {\n                                \"permit\": {}\n                            }\n                        }\n                    ]\n                }\n            }\n        ]\n    }\n}",
+            "data": "{\n    \"access-lists\": {\n        \"acl\": [\n            {\n                \"acl-name\": \"http-acl\",\n                \"access-list-entries\": {\n                    \"ace\": [\n                        {\n                            \"rule-name\": \"http-rule\",\n                            \"matches\": {\n                                \"destination-port-range\": {\n                                    \"lower-port\": \"80\",\n                                    \"upper-port\": \"80\"\n                                }\n                            },\n                            \"actions\": {\n                                \"netvirt-sfc-acl:redirect-sfc\": \"acl\"\n                            }\n                        }\n                    ]\n                }\n            }\n        ]\n    }\n}",
             "dataMode": "raw",
             "description": "",
-            "headers": "Content-Type: application/json\nAuthorization: Basic YWRtaW46YWRtaW4=\n",
-            "id": "37a68007-fc51-b406-43fe-dcaba62e3879",
-            "method": "GET",
-            "name": "Acl",
-            "responses": [],
+            "headers": "Content-Type: application/json\n",
+            "id": "19b44f74-e2ea-9267-50af-ad79b6309859",
+            "method": "PUT",
+            "name": "ietf-acl redirect-sfc",
+            "time": 1445298337983,
+            "timestamp": 0,
+            "url": "http://localhost:8181/restconf/config/ietf-access-control-list:access-lists",
+            "version": 2
+        },
+        {
+            "collectionId": "bc172f70-35df-2cdf-50a4-8ad09b8f17a2",
+            "data": "{\n    \"service-function-forwarders\": {\n        \"service-function-forwarder\": [\n            {\n                \"name\": \"SFF1\",\n                \"service-node\": \"OVSDB2\",\n                \"service-function-forwarder-ovs:ovs-bridge\": {\n                    \"bridge-name\": \"sw2\"\n                },\n                \"service-function-dictionary\": [\n                    {\n                        \"name\": \"firewall-72\",\n                        \"type\": \"service-function-type:firewall\",\n                        \"sff-sf-data-plane-locator\": {\n                            \"port\": 6633,\n                            \"ip\": \"192.168.50.71\",\n                             \"transport\": \"service-locator:vxlan-gpe\"\n                        }\n                    }\n                ],\n                \"sff-data-plane-locator\": [\n                    {\n                        \"name\": \"sfc-tun2\",\n                        \"data-plane-locator\": {\n                            \"transport\": \"service-locator:vxlan-gpe\",\n                            \"port\": 6633,\n                            \"ip\": \"192.168.50.71\"\n                        },\n                        \"service-function-forwarder-ovs:ovs-options\": {\n                            \"remote-ip\": \"flow\",\n                            \"dst-port\": \"6633\",\n                            \"key\": \"flow\",\n                            \"nsp\": \"flow\",\n                            \"nsi\": \"flow\",\n                            \"nshc1\": \"flow\",\n                            \"nshc2\": \"flow\",\n                            \"nshc3\": \"flow\",\n                            \"nshc4\": \"flow\"\n                        }\n                    }\n                ]\n            },\n            {\n                \"name\": \"SFF2\",\n                \"service-node\": \"OVSDB2\",\n                \"service-function-forwarder-ovs:ovs-bridge\": {\n                    \"bridge-name\": \"sw4\"\n                },\n                \"service-function-dictionary\": [\n                    {\n                        \"name\": \"dpi-74\",\n                        \"type\": \"service-function-type:dpi\",\n                        \"sff-sf-data-plane-locator\": {\n                            \"port\": 6633,\n                            \"ip\": \"192.168.50.73\",\n                             \"transport\": \"service-locator:vxlan-gpe\"\n                        }\n                    }\n                ],\n                \"sff-data-plane-locator\": [\n                    {\n                        \"name\": \"sfc-tun4\",\n                        \"data-plane-locator\": {\n                            \"transport\": \"service-locator:vxlan-gpe\",\n                            \"port\": 6633,\n                            \"ip\": \"192.168.50.73\"\n                        },\n                        \"service-function-forwarder-ovs:ovs-options\": {\n                            \"remote-ip\": \"flow\",\n                            \"dst-port\": \"6633\",\n                            \"key\": \"flow\",\n                            \"nsp\": \"flow\",\n                            \"nsi\": \"flow\",\n                            \"nshc1\": \"flow\",\n                            \"nshc2\": \"flow\",\n                            \"nshc3\": \"flow\",\n                            \"nshc4\": \"flow\"\n                        }\n                    }\n                ]\n            }\n        ]\n    }\n}",
+            "dataMode": "raw",
+            "description": "",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "id": "1b067065-f0d5-d871-28cf-5e7e195eb463",
+            "method": "PUT",
+            "name": "service-function-forwarders",
+            "time": 1445302610648,
+            "timestamp": 0,
+            "url": "http://localhost:8181/restconf/config/service-function-forwarder:service-function-forwarders",
+            "version": 2
+        },
+        {
+            "collectionId": "bc172f70-35df-2cdf-50a4-8ad09b8f17a2",
+            "data": "{\n    \"access-lists\": {\n        \"acl\": [\n            {\n                \"acl-name\": \"http-acl\",\n                \"access-list-entries\": {\n                    \"ace\": [\n                        {\n                            \"rule-name\": \"http-rule\",\n                            \"matches\": {\n                                \"destination-port-range\": {\n                                    \"lower-port\": \"80\",\n                                    \"upper-port\": \"80\"\n                                }\n                            },\n                            \"actions\": {\n                                \"permit\": \"true\"\n\n                            }\n                        }\n                    ]\n                }\n            }\n        ]\n    }\n}",
+            "dataMode": "raw",
+            "description": "",
+            "headers": "Content-Type: application/json\n",
+            "id": "62e3b4d9-2672-e2bd-25c9-70bfb6771026",
+            "method": "PUT",
+            "name": "ietf-acl",
+            "time": 1445298397905,
             "timestamp": 0,
-            "url": "http://localhost:8181/restconf/config/ietf-acl:access-lists",
+            "url": "http://localhost:8181/restconf/config/ietf-access-control-list:access-lists",
             "version": 2
         },
         {
         },
         {
             "collectionId": "bc172f70-35df-2cdf-50a4-8ad09b8f17a2",
-            "data": "{\n\t\"sfc\": {\n        \"name\": \"sfc1\"\n    }\n}",
+            "data": "{\n    \"access-lists\": {\n        \"acl\": [\n            {\n                \"acl-name\": \"http-acl\",\n                \"access-list-entries\": {\n                    \"ace\": [\n                        {\n                            \"rule-name\": \"http-rule\",\n                            \"matches\": {\n                                \"destination-port-range\": {\n                                    \"lower-port\": \"80\",\n                                    \"upper-port\": \"80\"\n                                }\n                            },\n                            \"actions\": {\n                                \"permit\": {}\n                            }\n                        }\n                    ]\n                }\n            }\n        ]\n    }\n}",
             "dataMode": "raw",
             "description": "",
-            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
-            "id": "9d418a4b-197d-47c2-e85f-e68f6b5f5c40",
+            "headers": "Content-Type: application/json\n",
+            "id": "7412ee0c-b116-5cf1-0646-efa65f0da784",
             "method": "GET",
-            "name": "Sfc",
+            "name": "ietf-acl",
             "responses": [],
             "timestamp": 0,
-            "url": "http://localhost:8181/restconf/config/netvirt-sfc:sfc/",
+            "url": "http://localhost:8181/restconf/config/ietf-access-control-list:access-lists",
             "version": 2
         },
         {
             "collectionId": "bc172f70-35df-2cdf-50a4-8ad09b8f17a2",
-            "data": "{\n    \"access-lists\": {\n        \"access-list\": [\n            {\n                \"acl-name\": \"http-acl\",\n                \"access-list-entries\": {\n                    \"access-list-entry\": [\n                        {\n                            \"rule-name\": \"http-rule\",\n                            \"matches\": {\n                                \"destination-port-range\": {\n                                    \"lower-port\": \"80\",\n                                    \"upper-port\": \"80\"\n                                }\n                            },\n                            \"actions\": {\n                                \"permit\": {}\n                            }\n                        }\n                    ]\n                }\n            }\n        ]\n    }\n}",
+            "data": "{\n    \"classifiers\": {\n        \"classifier\": [\n            {\n                \"name\": \"http-classifier\",\n                \"acl\": \"http-acl\",\n                \"sffs\": {\n                    \"sff\": [\n                        {\n                            \"name\": \"sff1\"\n                        }\n                    ]\n                }\n            }\n        ]\n    }\n}",
+            "dataMode": "raw",
+            "description": "",
+            "headers": "Content-Type: application/json\nAuthorization: Basic YWRtaW46YWRtaW4=\n",
+            "id": "76b32432-5a24-9d6d-8ba2-76eb816411af",
+            "method": "DELETE",
+            "name": "Classifier",
+            "responses": [],
+            "timestamp": 0,
+            "url": "http://localhost:8181/restconf/config/netvirt-sfc-classifier:classifiers",
+            "version": 2
+        },
+        {
+            "collectionId": "bc172f70-35df-2cdf-50a4-8ad09b8f17a2",
+            "data": "{\n    \"access-lists\": {\n        \"acl\": [\n            {\n                \"acl-name\": \"http-acl\",\n                \"access-list-entries\": {\n                    \"ace\": [\n                        {\n                            \"rule-name\": \"http-rule\",\n                            \"matches\": {\n                                \"destination-port-range\": {\n                                    \"lower-port\": \"80\",\n                                    \"upper-port\": \"80\"\n                                }\n                            },\n                            \"actions\": {\n                                \"netvirt-sfc-acl:redirect-sfc\": \"acl\"\n                            }\n                        }\n                    ]\n                }\n            }\n        ]\n    }\n}",
             "dataMode": "raw",
             "description": "",
             "headers": "Content-Type: application/json\n",
-            "id": "9e688730-6234-8f89-3de2-8a9974c4ea59",
-            "method": "PUT",
-            "name": "Acl",
-            "time": 1444923678505,
+            "id": "99dc6bb5-f01a-64cd-a024-c333fdf82643",
+            "method": "DELETE",
+            "name": "ietf-acl redirect-sfc",
+            "responses": [],
             "timestamp": 0,
-            "url": "http://localhost:8181/restconf/config/ietf-acl:access-lists",
+            "url": "http://localhost:8181/restconf/config/ietf-access-control-list:access-lists",
+            "version": 2
+        },
+        {
+            "collectionId": "bc172f70-35df-2cdf-50a4-8ad09b8f17a2",
+            "data": "{\n\t\"sfc\": {\n        \"name\": \"sfc1\"\n    }\n}",
+            "dataMode": "raw",
+            "description": "",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "id": "9d418a4b-197d-47c2-e85f-e68f6b5f5c40",
+            "method": "GET",
+            "name": "Sfc",
+            "responses": [],
+            "timestamp": 0,
+            "url": "http://localhost:8181/restconf/config/netvirt-sfc:sfc/",
             "version": 2
         },
         {
             "id": "bf4f1148-5192-fd7d-3026-5a11668db75d",
             "method": "PUT",
             "name": "service-functions",
-            "time": 1445035552080,
+            "time": 1445302596335,
             "timestamp": 0,
-            "url": "http://localhost:8181//restconf/config/service-function:service-functions",
+            "url": "http://localhost:8181/restconf/config/service-function:service-functions",
             "version": 2
         },
         {
             "collectionId": "bc172f70-35df-2cdf-50a4-8ad09b8f17a2",
-            "data": "{\n    \"access-lists\": {\n        \"access-list\": [\n            {\n                \"acl-name\": \"http-acl\",\n                \"access-list-entries\": {\n                    \"access-list-entry\": [\n                        {\n                            \"rule-name\": \"http-rule\",\n                            \"matches\": {\n                                \"destination-port-range\": {\n                                    \"lower-port\": \"80\",\n                                    \"upper-port\": \"80\"\n                                }\n                            },\n                            \"actions\": {\n                                \"netvirt-sfc-acl:redirect-sfc\": \"acl\"\n                            }\n                        }\n                    ]\n                }\n            }\n        ]\n    }\n}",
+            "data": "{\n    \"service-function-forwarders\": {\n        \"service-function-forwarder\": [\n            {\n                \"name\": \"SFF1\",\n                \"service-node\": \"OVSDB2\",\n                \"service-function-forwarder-ovs:ovs-bridge\": {\n                    \"bridge-name\": \"sw2\"\n                },\n                \"service-function-dictionary\": [\n                    {\n                        \"name\": \"firewall-72\",\n                        \"type\": \"service-function-type:firewall\",\n                        \"sff-sf-data-plane-locator\": {\n                            \"port\": 6633,\n                            \"ip\": \"192.168.50.71\",\n                             \"transport\": \"service-locator:vxlan-gpe\"\n                        }\n                    }\n                ],\n                \"sff-data-plane-locator\": [\n                    {\n                        \"name\": \"sfc-tun2\",\n                        \"data-plane-locator\": {\n                            \"transport\": \"service-locator:vxlan-gpe\",\n                            \"port\": 6633,\n                            \"ip\": \"192.168.50.71\"\n                        },\n                        \"service-function-forwarder-ovs:ovs-options\": {\n                            \"remote-ip\": \"flow\",\n                            \"dst-port\": \"6633\",\n                            \"key\": \"flow\",\n                            \"nsp\": \"flow\",\n                            \"nsi\": \"flow\",\n                            \"nshc1\": \"flow\",\n                            \"nshc2\": \"flow\",\n                            \"nshc3\": \"flow\",\n                            \"nshc4\": \"flow\"\n                        }\n                    }\n                ]\n            },\n            {\n                \"name\": \"SFF2\",\n                \"service-node\": \"OVSDB2\",\n                \"service-function-forwarder-ovs:ovs-bridge\": {\n                    \"bridge-name\": \"sw4\"\n                },\n                \"service-function-dictionary\": [\n                    {\n                        \"name\": \"dpi-74\",\n                        \"type\": \"service-function-type:dpi\",\n                        \"sff-sf-data-plane-locator\": {\n                            \"port\": 6633,\n                            \"ip\": \"192.168.50.73\",\n                             \"transport\": \"service-locator:vxlan-gpe\"\n                        }\n                    }\n                ],\n                \"sff-data-plane-locator\": [\n                    {\n                        \"name\": \"sfc-tun4\",\n                        \"data-plane-locator\": {\n                            \"transport\": \"service-locator:vxlan-gpe\",\n                            \"port\": 6633,\n                            \"ip\": \"192.168.50.73\"\n                        },\n                        \"service-function-forwarder-ovs:ovs-options\": {\n                            \"remote-ip\": \"flow\",\n                            \"dst-port\": \"6633\",\n                            \"key\": \"flow\",\n                            \"nsp\": \"flow\",\n                            \"nsi\": \"flow\",\n                            \"nshc1\": \"flow\",\n                            \"nshc2\": \"flow\",\n                            \"nshc3\": \"flow\",\n                            \"nshc4\": \"flow\"\n                        }\n                    }\n                ]\n            }\n        ]\n    }\n}",
             "dataMode": "raw",
             "description": "",
-            "headers": "Content-Type: application/json\n",
-            "id": "c3d5a025-23c6-af23-dce1-9edca74cd65c",
-            "method": "PUT",
-            "name": "Acl - redirect-sfc",
-            "time": 1445027841460,
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "id": "e6542ed1-832c-71c9-fe74-2d25c9e7f7ad",
+            "method": "GET",
+            "name": "service-function-forwarders",
+            "responses": [],
             "timestamp": 0,
-            "url": "http://localhost:8181/restconf/config/ietf-acl:access-lists",
+            "url": "http://localhost:8181/restconf/config/service-function-forwarder:service-function-forwarders",
             "version": 2
         },
         {
diff --git a/resources/commons/Ovsdb-HwvtepSouthbound-Collection.json.postman_collection b/resources/commons/Ovsdb-HwvtepSouthbound-Collection.json.postman_collection
new file mode 100755 (executable)
index 0000000..7c98745
--- /dev/null
@@ -0,0 +1,222 @@
+{
+    "id":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+    "name":"Ovsdb HwvtepSouthbound",
+    "timestamp":1424977469540,
+    "order":[
+        "e9ff6957-4dc2-9257-c0c6-21560bfd5de2",
+        "ee151670-85a0-30ec-b22b-5defe7b66e0b",
+        "6de1ede7-817c-ccbb-3df9-ef510bdaf583",
+        "6e7c88e4-485d-ab9f-4c3a-cc235e022905",
+        "92ee7422-5b08-6d63-2b95-961ec0e18ffa",
+        "e92ac963-daaf-0899-c3e8-a00d897be0e2",
+        "9bc22ca7-049c-af51-7c12-6bf71044b2ec",
+        "f6d300f7-380a-d090-0d4a-2b2ddefe5104",
+        "f9f71d74-a49d-b190-d929-b6772ce0ba73",
+        "18032e93-3bc5-9976-4525-fe1e77e98207",
+        "22354294-1d01-cebf-180c-d609747be9bc",
+        "c8e8f3fd-3bfb-aafa-e3ec-a671a942f426",
+        "d362ddc4-1c5f-67d5-e354-c2a8d2ba9d79",
+        "538c71b3-e3e6-f01b-cc4c-d2b686686aa8"
+    ],
+    "owner":0,
+    "sharedWithTeam":false,
+    "synced":false,
+    "subscribed":false,
+    "hasRequests":true,
+    "requests":[
+        {
+            "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id":"18032e93-3bc5-9976-4525-fe1e77e98207",
+            "name":"Delete Specific Config Logical Switch",
+            "description":"This restconf request delete specific logical switch from the config data store.",
+            "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%2Flogicalswitch%2Fls0",
+            "method":"DELETE",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "data":[],
+            "dataMode":"params",
+            "timestamp":0,
+            "version":2,
+            "time":1447335528744
+        },
+        {
+            "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id":"22354294-1d01-cebf-180c-d609747be9bc",
+            "name":"Get All Operational Topology",
+            "description":"This restconf request will fetch the operational topology. Operational topology details are fetch by hwvtepsouthbound plugin from all the connected hwvtep node.",
+            "url":"http://{{controllerHost}}:8181/restconf/operational/network-topology:network-topology/",
+            "method":"GET",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "data":[],
+            "dataMode":"params",
+            "timestamp":0,
+            "version":2
+        },
+        {
+            "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id":"538c71b3-e3e6-f01b-cc4c-d2b686686aa8",
+            "name":"Get Specific Operational Logical Switch",
+            "description":"This restconf request fetch the operational for specific Logical Switch",
+            "url":"http://{{controllerHost}}:8181/restconf/operational/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%2logicalswitch%2ls0",
+            "method":"GET",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "data":"{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640/logicalswitch/ls0\",\n            \"hwvtep-node-description\": \"\",\n            \"hwvtep-node-name\": \"ls0\",\n            \"tunnel-key\": \"10000\"\n        }\n    ]\n}",
+            "dataMode":"raw",
+            "timestamp":0,
+            "version":2,
+            "time":1447335701900
+        },
+        {
+            "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id":"6de1ede7-817c-ccbb-3df9-ef510bdaf583",
+            "name":"Create Specific Config HwvtepNode",
+            "description":"Fire this Restconf request if you want to initiate the connection to hwvtep node from controller. It assumes that hwvtep node is listening for tcp connection in passive mode.",
+            "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/",
+            "method":"POST",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "data":"{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640\",\n            \"connection-info\": {\n              \"hwvtep:remote-port\": 6640,\n              \"hwvtep:remote-ip\": \"{{hwvtepNodeIp}}\"\n            }\n        }\n    ]\n}",
+            "dataMode":"raw",
+            "timestamp":0,
+            "version":2,
+            "time":1447334840814
+        },
+        {
+            "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id":"6e7c88e4-485d-ab9f-4c3a-cc235e022905",
+            "name":"Update Specific Config HwvtepNode",
+            "description":"Fire this Restconf request if you want to update the connection to Hwvtep node from controller.",
+            "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+            "method":"PUT",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "data":"{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640\",\n            \"connection-info\": {\n              \"hwvtep:remote-port\": 6640,\n              \"hwvtep:remote-ip\": \"{{hwvtepNodeIp}}\"\n            }\n        }\n    ]\n}",
+            "dataMode":"raw",
+            "timestamp":0,
+            "version":2,
+            "time":1447334483164
+        },
+        {
+            "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id":"92ee7422-5b08-6d63-2b95-961ec0e18ffa",
+            "name":"Get Specific Config HwvtepNode",
+            "description":"This restconf request fetch the configration for specific hwvtep node.",
+            "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+            "method":"GET",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "data":"{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640\",\n            \"connection-info\": {\n              \"hwvtep:remote-port\": 6640,\n              \"hwvtep:remote-ip\": \"{{hwvtepNodeIp}}\"\n            }\n        }\n    ]\n}",
+            "dataMode":"raw",
+            "timestamp":0,
+            "version":2,
+            "time":1447334914971
+        },
+        {
+            "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id":"9bc22ca7-049c-af51-7c12-6bf71044b2ec",
+            "name":"Create Specific Config Logical Switch",
+            "description":"Fire this Restconf request if you want to create a logical switch.",
+            "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/",
+            "method":"POST",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "data":"{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640/logicalswitch/ls0\",\n            \"hwvtep-node-description\": \"\",\n            \"hwvtep-node-name\": \"ls0\",\n            \"tunnel-key\": \"10000\",\n            \"managed-by\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']\"             \n        }\n    ]\n}",
+            "dataMode":"raw",
+            "timestamp":0,
+            "version":2,
+            "time":1447340822378
+        },
+        {
+            "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id":"c8e8f3fd-3bfb-aafa-e3ec-a671a942f426",
+            "name":"Get Operational Hwvtep Topology",
+            "description":"",
+            "url":"http://{{controllerHost}}:8181/restconf/operational/network-topology:network-topology/topology/hwvtep:1/",
+            "method":"GET",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "data":"{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640\",\n            \"connection-info\": {\n              \"hwvtep:remote-port\": 6640,\n              \"hwvtep:remote-ip\": \"{{hwvtepNodeIp}}\"\n            }\n        }\n    ]\n}",
+            "dataMode":"raw",
+            "timestamp":0,
+            "version":2,
+            "time":1447335830695
+        },
+        {
+            "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id":"d362ddc4-1c5f-67d5-e354-c2a8d2ba9d79",
+            "name":"Get Specific Operational HwvtepNode",
+            "description":"This restconf request fetch the operational for specific HwvtepNode",
+            "url":"http://{{controllerHost}}:8181/restconf/operational/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+            "method":"GET",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "data":"{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640/logicalswitch/ls0\",\n            \"hwvtep-node-description\": \"\",\n            \"hwvtep-node-name\": \"ls0\",\n            \"tunnel-key\": \"10000\"\n        }\n    ]\n}",
+            "dataMode":"raw",
+            "timestamp":0,
+            "version":2,
+            "time":1447335686540
+        },
+        {
+            "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id":"e92ac963-daaf-0899-c3e8-a00d897be0e2",
+            "name":"Delete Specific Config HwvtepNode",
+            "description":"This restconf request delete any node (ovsdb node or bridge node) from the config data store. You can use the same request to delete the ovsdb node by using the following URI: http://localhost:8080/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F10.10.10.10:22222",
+            "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+            "method":"DELETE",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "data":[],
+            "dataMode":"params",
+            "timestamp":0,
+            "version":2
+        },
+        {
+            "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id":"e9ff6957-4dc2-9257-c0c6-21560bfd5de2",
+            "name":"Get All Config Topology",
+            "description":"Fetch all the config topology from configuration data store.",
+            "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/",
+            "method":"GET",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "data":"{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640\",\n            \"connection-info\": {\n              \"hwvtep:remote-port\": 6640,\n              \"hwvtep:remote-ip\": \"{{hwvtepNodeIp}}\"\n            }\n        }\n    ]\n}",
+            "dataMode":"raw",
+            "timestamp":0,
+            "version":2,
+            "time":1447311894927
+        },
+        {
+            "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id":"ee151670-85a0-30ec-b22b-5defe7b66e0b",
+            "name":"Get Config  Hwvtep Topology",
+            "description":"Fetch the config hwvtep topology from configuration data store.",
+            "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/hwvtep:1/",
+            "method":"GET",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "data":"{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640\",\n            \"connection-info\": {\n              \"hwvtep:remote-port\": 6640,\n              \"hwvtep:remote-ip\": \"{{hwvtepNodeIp}}\"\n            }\n        }\n    ]\n}",
+            "dataMode":"raw",
+            "timestamp":0,
+            "version":2,
+            "time":1447335823182
+        },
+        {
+            "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id":"f6d300f7-380a-d090-0d4a-2b2ddefe5104",
+            "name":"Create Specific Config Logical Switch",
+            "description":"Fire this request if you want to update specific logical switch.",
+            "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%2Flogicalswitch%2Fls0",
+            "method":"PUT",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "data":"{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640/logicalswitch/ls0\",\n            \"hwvtep-node-description\": \"\",\n            \"hwvtep-node-name\": \"ls0\",\n            \"tunnel-key\": \"10000\",\n            \"managed-by\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']\"             \n        }\n    ]\n}",
+            "dataMode":"raw",
+            "timestamp":0,
+            "version":2,
+            "time":1447340847211
+        },
+        {
+            "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id":"f9f71d74-a49d-b190-d929-b6772ce0ba73",
+            "name":"Get Specific Config Logical Switch",
+            "description":"This restconf request fetch configuration for specific logical switch.",
+            "url":"http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%2Flogicalswitch%2Fls0",
+            "method":"GET",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "data":"{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640/logicalswitch/ls0\",\n            \"hwvtep-node-description\": \"\",\n            \"hwvtep-node-name\": \"ls0\",\n            \"tunnel-key\": \"10000\"\n        }\n    ]\n}",
+            "dataMode":"raw",
+            "timestamp":0,
+            "version":2,
+            "time":1447335408595
+        }
+    ]
+}
index 25cf72cccfcd29a3282a6e2e0d7d567127c018c9..0cad7271a01ba6b95242b5232038e55125f7d4bb 100644 (file)
@@ -14,13 +14,13 @@ Contents
 - showOvsdbMdsal.py : Dumps mdsal related info from running ODL that is related to ovsdb and netvirt. Use 'showOvsdbMdsal.py -h' for usage
 
 - ODL-Clustering.json.postman_collection : Collection contains Restconf request to fetch clustering service related data to check the state of 3 node cluster and inventory/topology shards.
-       - Please import and load 3-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
+    - Please import and load 3-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
 
 - Ovsdb-Southbound-Collection-for-Single-Node-Cluster.json.postman_collection : Collection contains Restconf request for doing CRUD operations (connection, bridge, termination point) on southbound plugin running in standalone controller.
-       - Please import and load Single-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
+    - Please import and load Single-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
 
-- Ovsdb-Southbound-Collection-for-3-Node-Cluster.json.postman_collection : 
-       - Please import and load 3-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
+- Ovsdb-Southbound-Collection-for-3-Node-Cluster.json.postman_collection :
+    - Please import and load 3-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
 
 
 - Single-Node-Cluster-Setup-Environment-Variables.postman_environment : Postman environment file that defines variables for Restconf request for southbound plugin running in Single controller instance
@@ -28,3 +28,5 @@ Contents
 - 3-Node-Cluster-Setup-Environment-Variables.postman_environment : Postman environment file that defines variables for Restconf request for southbound plugin running in 3 node cluster environment
 
 - NetvirtSfc.json.postman_collection : Collection of REST-APIs to interact with Netvirt-Sfc.
+
+- Ovsdb-HwvtepSouthbound-Collection.json.postman_collection : Collection contains Restconf request for doing CRUD operations (hwvtep global node, physical switch, logical switch, physical locator, and physical port) on hwvtepsouthbound plugin running in standalone controller.
index fa167a8da8253935800cb0a81c651a9c13cb376a..dea8de96dd7d26281f475e7846e1de4fabe36ca9 100644 (file)
@@ -103,6 +103,21 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
           <failsOnError>true</failsOnError>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Export-Package>
+              org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105,
+              org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.*,
+              org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105,
+              org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*
+            </Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
 
index eb3a9506cf4a2b34cea1869fef780563a49a0e5c..bd899a50236ac17a9fc10e8eb77fef2f253d179b 100644 (file)
@@ -10,7 +10,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>features-parent</artifactId>
     <version>1.6.0-SNAPSHOT</version>
-    <relativePath></relativePath>
+    <relativePath/>
   </parent>
   <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>southbound-features</artifactId>
@@ -119,5 +119,12 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <artifactId>southbound-api</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>library-features</artifactId>
+      <type>xml</type>
+      <classifier>features</classifier>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
 </project>
index b66393266559ec1f479b6041a4d4346439933b22..7e2b90b81b2e6e89d3e652aaa9d5c7f09b816abb 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- vi: set et smarttab sw=4 tabstop=4: -->
 <!--
-Necessary TODO: Put your copyright statement here
+Copyright (C) 2015 Red Hat, Inc. and others. All rights reserved.
 
 This program and the accompanying materials are made available under the
 terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -10,31 +10,34 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
 <features name="odl-ovsdb-southbound-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
-  <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.netconf/features-restconf/${restconf.version}/xml/features</repository>
-  <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/${mdsal.model.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.yangtools/features-yangtools/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.controller/features-mdsal/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.netconf/features-restconf/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.ovsdb/library-features/{{VERSION}}/xml/features</repository>
   <feature name='odl-ovsdb-southbound-api' version='${project.version}' description='OpenDaylight :: southbound :: api '>
     <feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
-    <bundle>mvn:org.opendaylight.ovsdb/southbound-api/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/southbound-api/{{VERSION}}</bundle>
   </feature>
   <feature name='odl-ovsdb-southbound-impl' version='${project.version}' description='OpenDaylight :: southbound :: impl '>
     <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
     <feature version='${project.version}'>odl-ovsdb-southbound-api</feature>
-    <bundle>mvn:org.opendaylight.ovsdb/southbound-impl/${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>wrap:mvn:org.json/json/${org.json.version}</bundle>
-    <bundle>mvn:com.google.code.gson/gson/${gson.version}</bundle>
-    <bundle>mvn:io.netty/netty-buffer/${netty.version}</bundle>
-    <bundle>mvn:io.netty/netty-codec/${netty.version}</bundle>
-    <bundle>mvn:io.netty/netty-codec-http/${netty.version}</bundle>
-    <bundle>mvn:io.netty/netty-common/${netty.version}</bundle>
-    <bundle>mvn:io.netty/netty-handler/${netty.version}</bundle>
-    <bundle>mvn:io.netty/netty-transport/${netty.version}</bundle>
-    <configfile finalname="etc/opendaylight/karaf/southbound-impl-default-config.xml">mvn:org.opendaylight.ovsdb/southbound-impl/${project.version}/xml/config</configfile>
+    <bundle>mvn:org.opendaylight.ovsdb/southbound-impl/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/library/{{VERSION}}</bundle>
+    <bundle>mvn:com.fasterxml.jackson.core/jackson-annotations/{{VERSION}}</bundle>
+    <bundle>mvn:com.fasterxml.jackson.core/jackson-core/{{VERSION}}</bundle>
+    <bundle>mvn:com.fasterxml.jackson.core/jackson-databind/{{VERSION}}</bundle>
+    <bundle>mvn:com.fasterxml.jackson.datatype/jackson-datatype-json-org/{{VERSION}}</bundle>
+    <bundle>wrap:mvn:org.json/json/{{VERSION}}</bundle>
+    <bundle>mvn:com.google.code.gson/gson/{{VERSION}}</bundle>
+    <bundle>mvn:io.netty/netty-buffer/{{VERSION}}</bundle>
+    <bundle>mvn:io.netty/netty-codec/{{VERSION}}</bundle>
+    <bundle>mvn:io.netty/netty-codec-http/{{VERSION}}</bundle>
+    <bundle>mvn:io.netty/netty-common/{{VERSION}}</bundle>
+    <bundle>mvn:io.netty/netty-handler/{{VERSION}}</bundle>
+    <bundle>mvn:io.netty/netty-transport/{{VERSION}}</bundle>
+    <feature version="${project.version}">odl-ovsdb-library</feature>
+    <configfile finalname="etc/opendaylight/karaf/southbound-impl-default-config.xml">mvn:org.opendaylight.ovsdb/southbound-impl/{{VERSION}}/xml/config</configfile>
   </feature>
   <feature name='odl-ovsdb-southbound-impl-rest' version='${project.version}' description='OpenDaylight :: southbound :: impl :: REST '>
     <feature version="${project.version}">odl-ovsdb-southbound-impl</feature>
index f5e09078a0307523e4866dfe6b8938ff2397e931..88f72412370d848dced908e007415556efb184d7 100644 (file)
@@ -76,6 +76,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>org.powermock</groupId>
       <artifactId>powermock-api-mockito</artifactId>
@@ -102,8 +107,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
         <artifactId>maven-bundle-plugin</artifactId>
         <configuration>
           <instructions>
-            <Private-Package>!org.opendaylight.ovsdb.lib.osgi,org.opendaylight.ovsdb.lib.*,org.opendaylight.ovsdb.schema.openvswitch</Private-Package>
-            <Export-Package>org.opendaylight.ovsdb.southbound.*,org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.southbound.impl.rev141210</Export-Package>
+            <Export-Package>
+              org.opendaylight.ovsdb.southbound,
+              org.opendaylight.ovsdb.southbound.*,
+              org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.southbound.impl.rev141210.*</Export-Package>
           </instructions>
         </configuration>
       </plugin>
index 547f31ca685dacb094f8a938adea851ac62d6cef..92e91c2803d8f472b297e1f25c57afff833368a3 100644 (file)
@@ -9,7 +9,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
 -->
 <snapshot>
   <required-capabilities>
-    <!--<capability>urn:opendaylight:params:xml:ns:yang:southbound:impl?module=southbound-impl&amp;revision=2015-01-05</capability>-->
+    <capability>urn:opendaylight:params:xml:ns:yang:southbound:impl?module=southbound-impl&amp;revision=2014-12-10</capability>
+    <capability>urn:opendaylight:params:xml:ns:yang:library:impl?module=library&amp;revision=2014-12-10</capability>
   </required-capabilities>
   <configuration>
 
@@ -34,6 +35,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
              <type xmlns:ns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:entity-ownership-service">ns:entity-ownership-service</type>
              <name>entity-ownership-service</name>
           </clustering-entity-ownership-service>
+          <connection-service>
+            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:library:impl">prefix:connection-service</type>
+            <name>connection-service</name>
+          </connection-service>
         </module>
       </modules>
     </data>
index 6b4774d0b977e89997e178eb0edcc4ad7f06aea3..ce91d1dfbe44676c1f5993503983d1a48260a36a 100644 (file)
@@ -67,12 +67,10 @@ public class InstanceIdentifierCodec extends AbstractModuleStringInstanceIdentif
 
     public  InstanceIdentifier<?> bindingDeserializer(String iidString) throws DeserializationException {
         YangInstanceIdentifier normalizedYangIid = deserialize(iidString);
-        InstanceIdentifier<?> iid = bindingNormalizedNodeSerializer.fromYangInstanceIdentifier(normalizedYangIid);
-        return iid;
+        return bindingNormalizedNodeSerializer.fromYangInstanceIdentifier(normalizedYangIid);
     }
 
     public InstanceIdentifier<?> bindingDeserializer(YangInstanceIdentifier yangIID) {
-        InstanceIdentifier<?> iid = bindingNormalizedNodeSerializer.fromYangInstanceIdentifier(yangIID);
-        return iid;
+        return bindingNormalizedNodeSerializer.fromYangInstanceIdentifier(yangIID);
     }
 }
index c477cb0ee6f0fc6a6c35c7b6a045a4ce0376ac6d..605f15f8f6b236337d2f161ca15aef06cb0ed0d3 100644 (file)
@@ -70,7 +70,6 @@ public class OvsdbConnectionInstance implements OvsdbClient {
     private TransactionInvoker txInvoker;
     private Map<DatabaseSchema,TransactInvoker> transactInvokers;
     private MonitorCallBack callback;
-    // private ConnectionInfo key;
     private InstanceIdentifier<Node> instanceIdentifier;
     private volatile boolean hasDeviceOwnership = false;
     private Entity connectedEntity;
@@ -118,7 +117,7 @@ public class OvsdbConnectionInstance implements OvsdbClient {
     public void createTransactInvokers() {
         if (transactInvokers == null) {
             try {
-                transactInvokers = new HashMap<DatabaseSchema,TransactInvoker>();
+                transactInvokers = new HashMap<>();
                 List<String> databases = getDatabases().get();
                 for (String database : databases) {
                     DatabaseSchema dbSchema = getSchema(database).get();
@@ -135,7 +134,7 @@ public class OvsdbConnectionInstance implements OvsdbClient {
     private void monitorAllTables(String database, DatabaseSchema dbSchema) {
         Set<String> tables = dbSchema.getTables();
         if (tables != null) {
-            List<MonitorRequest<GenericTableSchema>> monitorRequests = Lists.newArrayList();
+            List<MonitorRequest> monitorRequests = Lists.newArrayList();
             for (String tableName : tables) {
                 GenericTableSchema tableSchema = dbSchema.table(tableName, GenericTableSchema.class);
                 Set<String> columns = tableSchema.getColumns();
@@ -161,7 +160,7 @@ public class OvsdbConnectionInstance implements OvsdbClient {
 
             // OpenVSwitchPart
             OpenVSwitch ovs = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), OpenVSwitch.class);
-            Map<String, String> externalIdsMap = new HashMap<String, String>();
+            Map<String, String> externalIdsMap = new HashMap<>();
 
             List<OpenvswitchExternalIds> externalIds = this.initialCreateData.getOpenvswitchExternalIds();
 
@@ -188,7 +187,7 @@ public class OvsdbConnectionInstance implements OvsdbClient {
 
             List<OpenvswitchOtherConfigs> otherConfigs = this.initialCreateData.getOpenvswitchOtherConfigs();
             if (otherConfigs != null) {
-                Map<String, String> otherConfigsMap = new HashMap<String, String>();
+                Map<String, String> otherConfigsMap = new HashMap<>();
                 for (OpenvswitchOtherConfigs otherConfig : otherConfigs) {
                     otherConfigsMap.put(otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
                 }
@@ -248,7 +247,7 @@ public class OvsdbConnectionInstance implements OvsdbClient {
     }
 
     public <E extends TableSchema<E>> TableUpdates monitor(
-            DatabaseSchema schema, List<MonitorRequest<E>> monitorRequests,
+            DatabaseSchema schema, List<MonitorRequest> monitorRequests,
             MonitorCallBack callback) {
         return client.monitor(schema, monitorRequests, callback);
     }
@@ -334,7 +333,7 @@ public class OvsdbConnectionInstance implements OvsdbClient {
 
     @Override
     public <E extends TableSchema<E>> TableUpdates monitor(
-            DatabaseSchema schema, List<MonitorRequest<E>> monitorRequests,
+            DatabaseSchema schema, List<MonitorRequest> monitorRequests,
             MonitorHandle monitorHandle, MonitorCallBack callback) {
         return null;
     }
@@ -352,12 +351,12 @@ public class OvsdbConnectionInstance implements OvsdbClient {
     }
 
     public Boolean getHasDeviceOwnership() {
-        return Boolean.valueOf(hasDeviceOwnership);
+        return hasDeviceOwnership;
     }
 
     public void setHasDeviceOwnership(Boolean hasDeviceOwnership) {
         if (hasDeviceOwnership != null) {
-            this.hasDeviceOwnership = hasDeviceOwnership.booleanValue();
+            this.hasDeviceOwnership = hasDeviceOwnership;
         }
     }
 
index 3599644c31b5b4ab7c8b7d50e01a974ec2434658..ecfedfe48f1b787f71331f454c1dc944ad72898e 100644 (file)
@@ -33,8 +33,8 @@ import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipS
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.ovsdb.lib.OvsdbClient;
+import org.opendaylight.ovsdb.lib.OvsdbConnection;
 import org.opendaylight.ovsdb.lib.OvsdbConnectionListener;
-import org.opendaylight.ovsdb.lib.impl.OvsdbConnectionService;
 import org.opendaylight.ovsdb.lib.operations.Operation;
 import org.opendaylight.ovsdb.lib.operations.OperationResult;
 import org.opendaylight.ovsdb.lib.operations.Select;
@@ -60,25 +60,28 @@ import com.google.common.util.concurrent.CheckedFuture;
 
 public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoCloseable {
     private Map<ConnectionInfo, OvsdbConnectionInstance> clients =
-            new ConcurrentHashMap<ConnectionInfo,OvsdbConnectionInstance>();
+            new ConcurrentHashMap<>();
     private static final Logger LOG = LoggerFactory.getLogger(OvsdbConnectionManager.class);
     private static final String ENTITY_TYPE = "ovsdb";
 
     private DataBroker db;
     private TransactionInvoker txInvoker;
     private Map<ConnectionInfo,InstanceIdentifier<Node>> instanceIdentifiers =
-            new ConcurrentHashMap<ConnectionInfo,InstanceIdentifier<Node>>();
+            new ConcurrentHashMap<>();
     private Map<Entity, OvsdbConnectionInstance> entityConnectionMap =
             new ConcurrentHashMap<>();
     private EntityOwnershipService entityOwnershipService;
     private OvsdbDeviceEntityOwnershipListener ovsdbDeviceEntityOwnershipListener;
+    private OvsdbConnection ovsdbConnection;
 
     public OvsdbConnectionManager(DataBroker db,TransactionInvoker txInvoker,
-                                  EntityOwnershipService entityOwnershipService) {
+                                  EntityOwnershipService entityOwnershipService,
+                                  OvsdbConnection ovsdbConnection) {
         this.db = db;
         this.txInvoker = txInvoker;
         this.entityOwnershipService = entityOwnershipService;
         this.ovsdbDeviceEntityOwnershipListener = new OvsdbDeviceEntityOwnershipListener(this, entityOwnershipService);
+        this.ovsdbConnection = ovsdbConnection;
     }
 
     @Override
@@ -104,12 +107,13 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
                 return ovsdbConnectionInstance;
             }
             LOG.warn("OVSDB Connection Instance {} being replaced with client {}", key, externalClient);
-            ovsdbConnectionInstance.disconnect();
 
             // Unregister Cluster Ownership for ConnectionInfo
             // Because the ovsdbConnectionInstance is about to be completely replaced!
             unregisterEntityForOwnership(ovsdbConnectionInstance);
 
+            ovsdbConnectionInstance.disconnect();
+
             removeConnectionInstance(key);
         }
 
@@ -127,13 +131,17 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
         ConnectionInfo key = SouthboundMapper.createConnectionInfo(client);
         OvsdbConnectionInstance ovsdbConnectionInstance = getConnectionInstance(key);
         if (ovsdbConnectionInstance != null) {
+            // Unregister Entity ownership as soon as possible ,so this instance should
+            // not be used as a candidate in Entity election (given that this instance is
+            // about to disconnect as well), if current owner get disconnected from
+            // OVSDB device.
+            unregisterEntityForOwnership(ovsdbConnectionInstance);
+
             txInvoker.invoke(new OvsdbNodeRemoveCommand(ovsdbConnectionInstance, null, null));
-            removeConnectionInstance(key);
 
-            // Unregister Cluster Onwership for ConnectionInfo
-            unregisterEntityForOwnership(ovsdbConnectionInstance);
+            removeConnectionInstance(key);
         } else {
-            LOG.warn("OVSDB disconnected event did not find connection instance for {}", key);
+            LOG.warn("disconnected : Connection instance not found for OVSDB Node {} ", key);
         }
         LOG.trace("OvsdbConnectionManager: disconnected exit");
     }
@@ -144,7 +152,7 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
         // TODO use transaction chains to handle ordering issues between disconnected
         // TODO and connected when writing to the operational store
         InetAddress ip = SouthboundMapper.createInetAddress(ovsdbNode.getConnectionInfo().getRemoteIp());
-        OvsdbClient client = OvsdbConnectionService.getService().connect(ip,
+        OvsdbClient client = ovsdbConnection.connect(ip,
                 ovsdbNode.getConnectionInfo().getRemotePort().getValue());
         // For connections from the controller to the ovs instance, the library doesn't call
         // this method for us
@@ -156,7 +164,7 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
             // Register Cluster Ownership for ConnectionInfo
             registerEntityForOwnership(ovsdbConnectionInstance);
         } else {
-            LOG.warn("Failed to connect to Ovsdb Node {}", ovsdbNode.getConnectionInfo());
+            LOG.warn("Failed to connect to OVSDB Node {}", ovsdbNode.getConnectionInfo());
         }
         return client;
     }
@@ -164,12 +172,14 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
     public void disconnect(OvsdbNodeAugmentation ovsdbNode) throws UnknownHostException {
         OvsdbConnectionInstance client = getConnectionInstance(ovsdbNode.getConnectionInfo());
         if (client != null) {
-            client.disconnect();
-
             // Unregister Cluster Onwership for ConnectionInfo
             unregisterEntityForOwnership(client);
 
+            client.disconnect();
+
             removeInstanceIdentifier(ovsdbNode.getConnectionInfo());
+        } else {
+            LOG.debug("disconnect : connection instance not found for {}",ovsdbNode.getConnectionInfo());
         }
     }
 
@@ -225,8 +235,7 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
 
     public InstanceIdentifier<Node> getInstanceIdentifier(ConnectionInfo key) {
         ConnectionInfo connectionInfo = SouthboundMapper.suppressLocalIpPort(key);
-        InstanceIdentifier<Node> iid = instanceIdentifiers.get(connectionInfo);
-        return iid;
+        return instanceIdentifiers.get(connectionInfo);
     }
 
     public OvsdbConnectionInstance getConnectionInstance(OvsdbBridgeAttributes mn) {
@@ -300,33 +309,27 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
 
     private void handleOwnershipChanged(EntityOwnershipChange ownershipChange) {
         OvsdbConnectionInstance ovsdbConnectionInstance = getConnectionInstanceFromEntity(ownershipChange.getEntity());
-        LOG.info("handleOwnershipChanged: {} event received for device {}",
+        LOG.debug("handleOwnershipChanged: {} event received for device {}",
                 ownershipChange, ovsdbConnectionInstance != null ? ovsdbConnectionInstance.getConnectionInfo()
-                        : "THAT'S NOT REGISTERED BY THIS SOUTHBOUND PLUGIN INSTANCE");
+                        : "that's currently NOT registered by *this* southbound plugin instance");
 
         if (ovsdbConnectionInstance == null) {
             if (ownershipChange.isOwner()) {
-                LOG.warn("handleOwnershipChanged: found no connection instance for {}", ownershipChange.getEntity());
+                LOG.warn("handleOwnershipChanged: *this* instance is elected as an owner of the device {} but it "
+                        + "is NOT registered for ownership", ownershipChange.getEntity());
             } else {
                 // EntityOwnershipService sends notification to all the nodes, irrespective of whether
                 // that instance registered for the device ownership or not. It is to make sure that
                 // If all the controller instance that was connected to the device are down, so the
                 // running instance can clear up the operational data store even though it was not
                 // connected to the device.
-                LOG.debug("handleOwnershipChanged: found no connection instance for {}", ownershipChange.getEntity());
+                LOG.debug("handleOwnershipChanged: No connection instance found for {}", ownershipChange.getEntity());
             }
 
             // If entity has no owner, clean up the operational data store (it's possible because owner controller
             // might went down abruptly and didn't get a chance to clean up the operational data store.
             if (!ownershipChange.hasOwner()) {
-                LOG.debug("{} has no onwer, cleaning up the operational data store", ownershipChange.getEntity());
-                // Below code might look weird but it's required. We want to give first opportunity to the
-                // previous owner of the device to clean up the operational data store if there is no owner now.
-                // That way we will avoid lot of nasty md-sal exceptions because of concurrent delete.
-                if (ownershipChange.wasOwner()) {
-                    cleanEntityOperationalData(ownershipChange.getEntity());
-                }
-                // If first cleanEntityOperationalData() was called, this call will be no-op.
+                LOG.info("{} has no owner, cleaning up the operational data store", ownershipChange.getEntity());
                 cleanEntityOperationalData(ownershipChange.getEntity());
             }
             return;
@@ -335,15 +338,17 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
         putConnectionInstance(ovsdbConnectionInstance.getMDConnectionInfo(),ovsdbConnectionInstance);
 
         if (ownershipChange.isOwner() == ovsdbConnectionInstance.getHasDeviceOwnership()) {
-            LOG.debug("handleOwnershipChanged: no change in ownership for {}. Ownership status is : {}",
-                    ovsdbConnectionInstance.getConnectionInfo(), ovsdbConnectionInstance.getHasDeviceOwnership());
+            LOG.info("handleOwnershipChanged: no change in ownership for {}. Ownership status is : {}",
+                    ovsdbConnectionInstance.getConnectionInfo(), ovsdbConnectionInstance.getHasDeviceOwnership()
+                            ? SouthboundConstants.OWNERSHIPSTATES.OWNER.getState()
+                            : SouthboundConstants.OWNERSHIPSTATES.NONOWNER.getState());
             return;
         }
 
         ovsdbConnectionInstance.setHasDeviceOwnership(ownershipChange.isOwner());
         // You were not an owner, but now you are
         if (ownershipChange.isOwner()) {
-            LOG.info("handleOwnershipChanged: *this* southbound plugin instance is owner of device {}",
+            LOG.info("handleOwnershipChanged: *this* southbound plugin instance is an OWNER of the device {}",
                     ovsdbConnectionInstance.getConnectionInfo());
 
             //*this* instance of southbound plugin is owner of the device,
@@ -358,7 +363,8 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
             //when clustering service implement a ownership grant strategy which can revoke the
             //device ownership for load balancing the devices across the instances.
             //Once this condition occur, we should unregister the callback.
-            LOG.error("handleOwnershipChanged: *this* southbound plugin instance is no longer the owner of device {}",
+            LOG.error("handleOwnershipChanged: *this* southbound plugin instance is no longer the owner of device {}."
+                    + "This should NOT happen.",
                     ovsdbConnectionInstance.getNodeId().getValue());
         }
     }
@@ -387,17 +393,16 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
         if (dbSchema != null) {
             GenericTableSchema openVSwitchSchema = TyperUtils.getTableSchema(dbSchema, OpenVSwitch.class);
 
-            List<String> openVSwitchTableColumn = new ArrayList<String>();
+            List<String> openVSwitchTableColumn = new ArrayList<>();
             openVSwitchTableColumn.addAll(openVSwitchSchema.getColumns());
             Select<GenericTableSchema> selectOperation = op.select(openVSwitchSchema);
-            selectOperation.setColumns(openVSwitchTableColumn);;
+            selectOperation.setColumns(openVSwitchTableColumn);
 
-            ArrayList<Operation> operations = new ArrayList<Operation>();
+            List<Operation> operations = new ArrayList<>();
             operations.add(selectOperation);
             operations.add(op.comment("Fetching Open_VSwitch table rows"));
-            List<OperationResult> results = null;
             try {
-                results = connectionInstance.transact(dbSchema, operations).get();
+                List<OperationResult> results = connectionInstance.transact(dbSchema, operations).get();
                 if (results != null ) {
                     OperationResult selectResult = results.get(0);
                     openVSwitchRow = TyperUtils.getTypedRowWrapper(
@@ -412,8 +417,7 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
         return openVSwitchRow;
     }
     private Entity getEntityFromConnectionInstance(@Nonnull OvsdbConnectionInstance ovsdbConnectionInstance) {
-        YangInstanceIdentifier entityId = null;
-        InstanceIdentifier<Node> iid = ovsdbConnectionInstance.getInstanceIdentifier();;
+        InstanceIdentifier<Node> iid = ovsdbConnectionInstance.getInstanceIdentifier();
         if ( iid == null ) {
             /* Switch initiated connection won't have iid, till it gets OpenVSwitch
              * table update but update callback is always registered after ownership
@@ -423,9 +427,9 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
             iid = SouthboundMapper.getInstanceIdentifier(openvswitchRow);
             LOG.info("InstanceIdentifier {} generated for device "
                     + "connection {}",iid,ovsdbConnectionInstance.getConnectionInfo());
-
+            ovsdbConnectionInstance.setInstanceIdentifier(iid);
         }
-        entityId = SouthboundUtil.getInstanceIdentifierCodec().getYangInstanceIdentifier(iid);
+        YangInstanceIdentifier entityId = SouthboundUtil.getInstanceIdentifierCodec().getYangInstanceIdentifier(iid);
         Entity deviceEntity = new Entity(ENTITY_TYPE, entityId);
         LOG.debug("Entity {} created for device connection {}",
                 deviceEntity, ovsdbConnectionInstance.getConnectionInfo());
@@ -445,7 +449,7 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
             EntityOwnershipCandidateRegistration registration =
                     entityOwnershipService.registerCandidate(candidateEntity);
             ovsdbConnectionInstance.setDeviceOwnershipCandidateRegistration(registration);
-            LOG.info("OVSDB entity {} is registred for ownership.", candidateEntity);
+            LOG.info("OVSDB entity {} is registered for ownership.", candidateEntity);
 
             //If entity already has owner, it won't get notification from EntityOwnershipService
             //so cache the connection instances.
@@ -454,16 +458,14 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos
             if (ownershipStateOpt.isPresent()) {
                 EntityOwnershipState ownershipState = ownershipStateOpt.get();
                 if (ownershipState.hasOwner() && !ownershipState.isOwner()) {
-                    if (getConnectionInstance(ovsdbConnectionInstance.getMDConnectionInfo()) != null) {
-                        LOG.info("OVSDB entity {} is already owned by other southbound plugin "
-                                + "instance, so *this* instance is NOT an OWNER of the device",
-                                ovsdbConnectionInstance.getConnectionInfo());
-                        putConnectionInstance(ovsdbConnectionInstance.getMDConnectionInfo(),ovsdbConnectionInstance);
-                    }
+                    LOG.info("OVSDB entity {} is already owned by other southbound plugin "
+                                    + "instance, so *this* instance is NOT an OWNER of the device",
+                            ovsdbConnectionInstance.getConnectionInfo());
+                    putConnectionInstance(ovsdbConnectionInstance.getMDConnectionInfo(),ovsdbConnectionInstance);
                 }
             }
         } catch (CandidateAlreadyRegisteredException e) {
-            LOG.warn("OVSDB entity {} was already registered for {} ownership", candidateEntity, e);
+            LOG.warn("OVSDB entity {} was already registered for ownership", candidateEntity, e);
         }
 
     }
index 221f9f2eb69e0220eefacd81afccf9746c06286f..8b2859317224fd62ce678a1cc3ce305049f4ea8c 100644 (file)
@@ -176,7 +176,7 @@ public class OvsdbDataChangeListener implements ClusteredDataChangeListener, Aut
     public Map<InstanceIdentifier<Node>,OvsdbConnectionInstance> connectionInstancesFromChanges(
             AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
         Map<InstanceIdentifier<Node>,OvsdbConnectionInstance> result =
-                new HashMap<InstanceIdentifier<Node>,OvsdbConnectionInstance>();
+                new HashMap<>();
         result.putAll(connectionInstancesFromMap(changes.getCreatedData()));
         result.putAll(connectionInstancesFromMap(changes.getUpdatedData()));
         result.putAll(connectionInstancesFromMap(
@@ -188,7 +188,7 @@ public class OvsdbDataChangeListener implements ClusteredDataChangeListener, Aut
             DataObject> map) {
         Preconditions.checkNotNull(map);
         Map<InstanceIdentifier<Node>,OvsdbConnectionInstance> result =
-                new HashMap<InstanceIdentifier<Node>,OvsdbConnectionInstance>();
+                new HashMap<>();
         for ( Entry<InstanceIdentifier<?>, DataObject> created : map.entrySet()) {
             if (created.getValue() instanceof Node) {
                 OvsdbConnectionInstance client = null;
index 36e131fdabd79cbd0d72dc8a2de1617eb4e5288d..1e227c5e73a7d710178d5c2ea428b64b3bd0b1d5 100644 (file)
@@ -34,8 +34,9 @@ public class OvsdbSchemaContants {
         private final String parentTableName;
         private final String columnNameInParentTable;
 
-        private OVSDBSCHEMATABLES(final String tableName, final String parentTableName,
-                                  final String columnNameInParentTable) {
+        OVSDBSCHEMATABLES(
+                final String tableName, final String parentTableName,
+                final String columnNameInParentTable) {
             this.tableName = tableName;
             this.parentTableName = parentTableName;
             this.columnNameInParentTable = columnNameInParentTable;
index 815e17f87d437f78895a3c751c177003a20e53a5..854d5b2febddd1fb03a980c7606d19bf793048e7 100755 (executable)
@@ -94,7 +94,7 @@ public class SouthboundConstants {
             .build();
     public static final String IID_EXTERNAL_ID_KEY = "opendaylight-iid";
 
-    public static enum VLANMODES {
+    public enum VLANMODES {
         ACCESS("access"),
         NATIVE_TAGGED("native-tagged"),
         NATIVE_UNTAGGED("native-untagged"),
@@ -102,7 +102,7 @@ public class SouthboundConstants {
 
         private final String mode;
 
-        private VLANMODES(String mode) {
+        VLANMODES(String mode) {
             this.mode = mode;
         }
         @Override
@@ -114,4 +114,23 @@ public class SouthboundConstants {
             return this.mode;
         }
     }
+
+    public enum OWNERSHIPSTATES {
+        OWNER("OWNER"),
+        NONOWNER("NON-OWNER");
+
+        private final String state;
+
+        OWNERSHIPSTATES(String state) {
+            this.state = state;
+        }
+        @Override
+        public String toString() {
+            return state;
+        }
+
+        public String getState() {
+            return this.state;
+        }
+    }
 }
index 86b76407931d4340f3d5be0b8dd53443028f4244..4f5ae1730bc35538099d788e9f221848cb273f09 100644 (file)
@@ -93,11 +93,10 @@ public class SouthboundMapper {
     }
 
     public static InstanceIdentifier<Node> createInstanceIdentifier(NodeId nodeId) {
-        InstanceIdentifier<Node> nodePath = InstanceIdentifier
+        return InstanceIdentifier
                 .create(NetworkTopology.class)
                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
                 .child(Node.class,new NodeKey(nodeId));
-        return nodePath;
     }
 
     public static InstanceIdentifier<Node> createInstanceIdentifier(OvsdbConnectionInstance client,Bridge bridge) {
@@ -178,14 +177,12 @@ public class SouthboundMapper {
     }
 
     public static String createDatapathType(OvsdbBridgeAugmentation mdsalbridge) {
-        String datapathtype = new String(SouthboundConstants.DATAPATH_TYPE_MAP.get(DatapathTypeSystem.class));
+        String datapathtype = SouthboundConstants.DATAPATH_TYPE_MAP.get(DatapathTypeSystem.class);
 
-        if (mdsalbridge.getDatapathType() != null) {
-            if (SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType()) != null) {
-                datapathtype = SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType());
-            } else {
-                throw new IllegalArgumentException("Unknown datapath type "
-                        + SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType()));
+        if (mdsalbridge.getDatapathType() != null && !mdsalbridge.getDatapathType().equals(DatapathTypeBase.class)) {
+            datapathtype = SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType());
+            if (datapathtype == null) {
+                throw new IllegalArgumentException("Unknown datapath type " + mdsalbridge.getDatapathType().getName());
             }
         }
         return datapathtype;
@@ -246,16 +243,17 @@ public class SouthboundMapper {
         try {
             protocols = bridge.getProtocolsColumn().getData();
         } catch (SchemaVersionMismatchException e) {
-            LOG.warn("protocols not supported by this version of ovsdb", e);
+            // We don't care about the exception stack trace here
+            LOG.warn("protocols not supported by this version of ovsdb: {}", e.getMessage());
         }
-        List<ProtocolEntry> protocolList = new ArrayList<ProtocolEntry>();
+        List<ProtocolEntry> protocolList = new ArrayList<>();
         if (protocols != null && protocols.size() > 0) {
             ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
                     SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
             for (String protocol : protocols) {
                 if (protocol != null && mapper.get(protocol) != null) {
                     protocolList.add(new ProtocolEntryBuilder().
-                            setProtocol((Class<? extends OvsdbBridgeProtocolBase>) mapper.get(protocol)).build());
+                            setProtocol(mapper.get(protocol)).build());
                 }
             }
         }
@@ -276,7 +274,7 @@ public class SouthboundMapper {
         LOG.debug("createControllerEntries Bridge: {}\n, updatedControllerRows: {}",
                 bridge, updatedControllerRows);
         final Set<UUID> controllerUUIDs = bridge.getControllerColumn().getData();
-        final List<ControllerEntry> controllerEntries = new ArrayList<ControllerEntry>();
+        final List<ControllerEntry> controllerEntries = new ArrayList<>();
         for (UUID controllerUUID : controllerUUIDs ) {
             final Controller controller = updatedControllerRows.get(controllerUUID);
             addControllerEntries(controllerEntries, controller);
@@ -298,7 +296,7 @@ public class SouthboundMapper {
 
         LOG.debug("createControllerEntries Bridge 2: {}\n, updatedControllerRows: {}",
                 bridgeNode, updatedControllerRows);
-        final List<ControllerEntry> controllerEntriesCreated = new ArrayList<ControllerEntry>();
+        final List<ControllerEntry> controllerEntriesCreated = new ArrayList<>();
         final OvsdbBridgeAugmentation ovsdbBridgeAugmentation =
                 bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
         if (ovsdbBridgeAugmentation == null) {
@@ -386,7 +384,7 @@ public class SouthboundMapper {
         LOG.debug("createManagerEntries OpenVSwitch: {}\n, updatedManagerRows: {}",
                 ovsdbNode, updatedManagerRows);
         final Set<UUID> managerUUIDs = ovsdbNode.getManagerOptionsColumn().getData();
-        final List<ManagerEntry> managerEntries = new ArrayList<ManagerEntry>();
+        final List<ManagerEntry> managerEntries = new ArrayList<>();
         for (UUID managerUUID : managerUUIDs ) {
             final Manager manager = updatedManagerRows.get(managerUUID);
             addManagerEntries(managerEntries, manager);
@@ -408,7 +406,7 @@ public class SouthboundMapper {
 
         LOG.debug("createManagerEntries based on OVSDB Node: {}\n, updatedManagerRows: {}",
                 ovsdbNode, updatedManagerRows);
-        final List<ManagerEntry> managerEntriesCreated = new ArrayList<ManagerEntry>();
+        final List<ManagerEntry> managerEntriesCreated = new ArrayList<>();
         final OvsdbNodeAugmentation ovsdbNodeAugmentation =
                 ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
         if (ovsdbNodeAugmentation == null) {
@@ -437,7 +435,7 @@ public class SouthboundMapper {
 
         if (manager != null && manager.getTargetColumn() != null) {
             long numberOfConnections = 0;
-            final String targetString = (String)manager.getTargetColumn().getData();
+            final String targetString = manager.getTargetColumn().getData();
 
             final Map<String, String> statusAttributeMap = manager.getStatusColumn().getData();
             if (statusAttributeMap.containsKey(N_CONNECTIONS_STR)) {
index a13e15c422fa0c2bb235b7ea5570166d7b5c8a6e..d88074b9b3f0ee3228de54d6e49d2a6747a512eb 100644 (file)
@@ -16,12 +16,12 @@ import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipC
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipState;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
 import org.opendaylight.ovsdb.lib.OvsdbConnection;
-import org.opendaylight.ovsdb.lib.impl.OvsdbConnectionService;
 import org.opendaylight.ovsdb.southbound.transactions.md.TransactionInvoker;
 import org.opendaylight.ovsdb.southbound.transactions.md.TransactionInvokerImpl;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
@@ -56,9 +56,12 @@ public class SouthboundProvider implements BindingAwareProvider, AutoCloseable {
 
 
     public SouthboundProvider(
-            EntityOwnershipService entityOwnershipServiceDependency) {
+            EntityOwnershipService entityOwnershipServiceDependency,
+            OvsdbConnection ovsdbConnection) {
         this.entityOwnershipService = entityOwnershipServiceDependency;
         registration = null;
+        this.ovsdbConnection = ovsdbConnection;
+        LOG.info("SouthboundProvider ovsdbConnectionService: {}", ovsdbConnection);
     }
 
     @Override
@@ -66,7 +69,7 @@ public class SouthboundProvider implements BindingAwareProvider, AutoCloseable {
         LOG.info("SouthboundProvider Session Initiated");
         db = session.getSALService(DataBroker.class);
         this.txInvoker = new TransactionInvokerImpl(db);
-        cm = new OvsdbConnectionManager(db,txInvoker,entityOwnershipService);
+        cm = new OvsdbConnectionManager(db,txInvoker,entityOwnershipService, ovsdbConnection);
         ovsdbDataChangeListener = new OvsdbDataChangeListener(db,cm);
 
         //Register listener for entityOnwership changes
@@ -77,7 +80,16 @@ public class SouthboundProvider implements BindingAwareProvider, AutoCloseable {
         //register instance entity to get the ownership of the provider
         Entity instanceEntity = new Entity(ENTITY_TYPE, ENTITY_TYPE);
         try {
+            Optional<EntityOwnershipState> ownershipStateOpt = entityOwnershipService.getOwnershipState(instanceEntity);
             registration = entityOwnershipService.registerCandidate(instanceEntity);
+            if (ownershipStateOpt.isPresent()) {
+                EntityOwnershipState ownershipState = ownershipStateOpt.get();
+                if (ownershipState.hasOwner() && !ownershipState.isOwner()) {
+                    ovsdbConnection.registerConnectionListener(cm);
+                    ovsdbConnection.startOvsdbManager(SouthboundConstants.DEFAULT_OVSDB_PORT);
+                    LOG.info("*This* instance of OVSDB southbound provider is set as a SLAVE instance");
+                }
+            }
         } catch (CandidateAlreadyRegisteredException e) {
             LOG.warn("OVSDB Southbound Provider instance entity {} was already "
                     + "registered for {} ownership", instanceEntity, e);
@@ -141,11 +153,8 @@ public class SouthboundProvider implements BindingAwareProvider, AutoCloseable {
         } else {
             LOG.info("*This* instance of OVSDB southbound provider is set as a SLAVE instance");
         }
-        if (ovsdbConnection == null) {
-            ovsdbConnection = new OvsdbConnectionService();
-            ovsdbConnection.registerConnectionListener(cm);
-            ovsdbConnection.startOvsdbManager(SouthboundConstants.DEFAULT_OVSDB_PORT);
-        }
+        ovsdbConnection.registerConnectionListener(cm);
+        ovsdbConnection.startOvsdbManager(SouthboundConstants.DEFAULT_OVSDB_PORT);
     }
 
     private class SouthboundPluginInstanceEntityOwnershipListener implements EntityOwnershipListener {
index 075b53571e21138a01f71e11fb8498992cda26a3..ff6e71cfd1f956967121be95e330b8eb527f63ce 100644 (file)
@@ -15,7 +15,6 @@ import java.util.Set;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 import org.opendaylight.ovsdb.lib.notation.Mutator;
-import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
 import org.opendaylight.ovsdb.lib.notation.UUID;
 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
index d555f8f9f46d40e31ba005da3a40fd6bb7e61830..7622ef47cdf7364886bb93d06b49b0fae48aa31e 100644 (file)
@@ -124,7 +124,7 @@ public class BridgeUpdateCommand extends AbstractTransactCommand {
     private void setOpenDaylightExternalIds(Bridge bridge, InstanceIdentifier<OvsdbBridgeAugmentation> iid,
             OvsdbBridgeAugmentation ovsdbManagedNode) {
         // Set the iid external_id
-        Map<String, String> externalIdMap = new HashMap<String, String>();
+        Map<String, String> externalIdMap = new HashMap<>();
         externalIdMap.put(SouthboundConstants.IID_EXTERNAL_ID_KEY, SouthboundUtil.serializeInstanceIdentifier(iid));
         // Set user provided external ids
         List<BridgeExternalIds> bridgeExternalId = ovsdbManagedNode.getBridgeExternalIds();
@@ -145,7 +145,7 @@ public class BridgeUpdateCommand extends AbstractTransactCommand {
     private void setOpenDaylightOtherConfig(Bridge bridge, OvsdbBridgeAugmentation ovsdbManagedNode) {
         List<BridgeOtherConfigs> bridgeOtherConfig = ovsdbManagedNode.getBridgeOtherConfigs();
         if (bridgeOtherConfig != null) {
-            Map<String, String> otherConfigMap = new HashMap<String, String>();
+            Map<String, String> otherConfigMap = new HashMap<>();
             for (BridgeOtherConfigs otherConf : bridgeOtherConfig) {
                 otherConfigMap.put(otherConf.getBridgeOtherConfigKey(), otherConf.getBridgeOtherConfigValue());
             }
index cc6b7d642ec641a8a45154c606bf7d24872fca1c..5b4acd4c00e5a7884fb23ce1b2cc01e4dfcac074 100644 (file)
@@ -41,7 +41,7 @@ public class DataChangesManagedByOvsdbNodeEvent implements
     private Map<InstanceIdentifier<?>, DataObject> filter(Map<InstanceIdentifier<?>,
             DataObject> data) {
         Map<InstanceIdentifier<?>, DataObject> result
-            = new HashMap<InstanceIdentifier<?>, DataObject>();
+            = new HashMap<>();
         for (Entry<InstanceIdentifier<?>, DataObject> entry: data.entrySet()) {
             if (isManagedBy(entry.getKey())) {
                 result.put(entry.getKey(),entry.getValue());
@@ -76,7 +76,7 @@ public class DataChangesManagedByOvsdbNodeEvent implements
     @Override
     public Set<InstanceIdentifier<?>> getRemovedPaths() {
         if (this.removedPaths == null) {
-            this.removedPaths = new HashSet<InstanceIdentifier<?>>();
+            this.removedPaths = new HashSet<>();
             for (InstanceIdentifier<?> path: event.getRemovedPaths()) {
                 if (isManagedBy(path)) {
                     this.removedPaths.add(path);
index 4d4aa5d0fdf08f097e3c4ab7e320df7816500f92..3db0356abb701be90610b30bdc7b8b81d8e9da32 100644 (file)
@@ -55,7 +55,7 @@ public class OvsdbNodeUpdateCommand implements TransactCommand {
 
             // OpenVSwitchPart
             OpenVSwitch ovs = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), OpenVSwitch.class);
-            Map<String, String> externalIdsMap = new HashMap<String, String>();
+            Map<String, String> externalIdsMap = new HashMap<>();
 
             List<OpenvswitchExternalIds> externalIds = ovsdbNode.getOpenvswitchExternalIds();
 
@@ -82,7 +82,7 @@ public class OvsdbNodeUpdateCommand implements TransactCommand {
 
             List<OpenvswitchOtherConfigs> otherConfigs = ovsdbNode.getOpenvswitchOtherConfigs();
             if (otherConfigs != null) {
-                Map<String, String> otherConfigsMap = new HashMap<String, String>();
+                Map<String, String> otherConfigsMap = new HashMap<>();
                 for (OpenvswitchOtherConfigs otherConfig : otherConfigs) {
                     otherConfigsMap.put(otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
                 }
index f32cfac2df7d29d50959175861cd2306c1cc8acd..e76b96682441f1f7312f8a588d86c5028aa6592f 100644 (file)
@@ -53,7 +53,7 @@ public class ProtocolUpdateCommand extends AbstractTransactCommand {
                         entry.getKey().firstIdentifierOf(OvsdbBridgeAugmentation.class);
                 Optional<OvsdbBridgeAugmentation> bridgeOptional =
                         getOperationalState().getOvsdbBridgeAugmentation(bridgeIid);
-                OvsdbBridgeAugmentation ovsdbBridge = null;
+                OvsdbBridgeAugmentation ovsdbBridge;
                 if (bridgeOptional.isPresent()) {
                     ovsdbBridge = bridgeOptional.get();
                 } else {
@@ -74,7 +74,8 @@ public class ProtocolUpdateCommand extends AbstractTransactCommand {
                                 .where(bridge.getNameColumn().getSchema().opEqual(bridge.getNameColumn().getData()))
                                 .build());
                         } catch (SchemaVersionMismatchException e) {
-                            LOG.warn("protocol not supported by this version of ovsdb", e);
+                            // We don't care about the exception stack trace here
+                            LOG.warn("protocol not supported by this version of ovsdb: {}", e.getMessage());
                         }
                     }
                 }
index 2ffe87bb6af43bf278c64c889d08bb1a32026fe9..4548fd87db88fb53784dfe2d58dd00e7d0f2e9b7 100644 (file)
@@ -77,7 +77,7 @@ public class TerminationPointCreateCommand extends AbstractTransactCommand {
                         getOperationalState().getBridgeTerminationPoint(terminationPointIid);
                 if (!terminationPointOptional.isPresent()) {
                     // Configure interface
-                    String interfaceUuid = "Interface_" + SouthboundMapper.getRandomUUID();;
+                    String interfaceUuid = "Interface_" + SouthboundMapper.getRandomUUID();
                     Interface ovsInterface =
                             TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), Interface.class);
                     createInterface(terminationPoint, ovsInterface);
@@ -171,7 +171,7 @@ public class TerminationPointCreateCommand extends AbstractTransactCommand {
 
         //Configure optional input
         if (terminationPoint.getOptions() != null) {
-            Map<String, String> optionsMap = new HashMap<String, String>();
+            Map<String, String> optionsMap = new HashMap<>();
             for (Options option : terminationPoint.getOptions()) {
                 optionsMap.put(option.getOption(), option.getValue());
             }
@@ -190,7 +190,7 @@ public class TerminationPointCreateCommand extends AbstractTransactCommand {
         List<InterfaceExternalIds> interfaceExternalIds =
                 terminationPoint.getInterfaceExternalIds();
         if (interfaceExternalIds != null && !interfaceExternalIds.isEmpty()) {
-            Map<String, String> externalIdsMap = new HashMap<String, String>();
+            Map<String, String> externalIdsMap = new HashMap<>();
             for (InterfaceExternalIds externalId: interfaceExternalIds) {
                 externalIdsMap.put(externalId.getExternalIdKey(), externalId.getExternalIdValue());
             }
@@ -209,7 +209,7 @@ public class TerminationPointCreateCommand extends AbstractTransactCommand {
         List<InterfaceOtherConfigs> interfaceOtherConfigs =
                 terminationPoint.getInterfaceOtherConfigs();
         if (interfaceOtherConfigs != null && !interfaceOtherConfigs.isEmpty()) {
-            Map<String, String> otherConfigsMap = new HashMap<String, String>();
+            Map<String, String> otherConfigsMap = new HashMap<>();
             for (InterfaceOtherConfigs interfaceOtherConfig : interfaceOtherConfigs) {
                 otherConfigsMap.put(interfaceOtherConfig.getOtherConfigKey(),
                         interfaceOtherConfig.getOtherConfigValue());
@@ -228,7 +228,7 @@ public class TerminationPointCreateCommand extends AbstractTransactCommand {
 
         List<PortExternalIds> portExternalIds = terminationPoint.getPortExternalIds();
         if (portExternalIds != null && !portExternalIds.isEmpty()) {
-            Map<String, String> externalIdsMap = new HashMap<String, String>();
+            Map<String, String> externalIdsMap = new HashMap<>();
             for (PortExternalIds externalId: portExternalIds) {
                 externalIdsMap.put(externalId.getExternalIdKey(), externalId.getExternalIdValue());
             }
@@ -245,7 +245,7 @@ public class TerminationPointCreateCommand extends AbstractTransactCommand {
             final Port port) {
 
         if (terminationPoint.getVlanTag() != null) {
-            Set<Long> vlanTag = new HashSet<Long>();
+            Set<Long> vlanTag = new HashSet<>();
             vlanTag.add(terminationPoint.getVlanTag().getValue().longValue());
             port.setTag(vlanTag);
         }
@@ -256,7 +256,7 @@ public class TerminationPointCreateCommand extends AbstractTransactCommand {
             final Port port) {
 
         if (terminationPoint.getTrunks() != null && terminationPoint.getTrunks().size() > 0) {
-            Set<Long> portTrunks = new HashSet<Long>();
+            Set<Long> portTrunks = new HashSet<>();
             List<Trunks> modelTrunks = terminationPoint.getTrunks();
             for (Trunks trunk: modelTrunks) {
                 if (trunk.getTrunk() != null) {
@@ -271,7 +271,7 @@ public class TerminationPointCreateCommand extends AbstractTransactCommand {
             final OvsdbTerminationPointAugmentation terminationPoint,
             final Port port) {
         if (terminationPoint.getVlanMode() != null) {
-            Set<String> portVlanMode = new HashSet<String>();
+            Set<String> portVlanMode = new HashSet<>();
             VlanMode modelVlanMode = terminationPoint.getVlanMode();
             portVlanMode.add(SouthboundConstants.VLANMODES.values()[modelVlanMode.getIntValue() - 1].getMode());
             port.setVlanMode(portVlanMode);
@@ -284,7 +284,7 @@ public class TerminationPointCreateCommand extends AbstractTransactCommand {
         List<PortOtherConfigs> portOtherConfigs =
                 terminationPoint.getPortOtherConfigs();
         if (portOtherConfigs != null && !portOtherConfigs.isEmpty()) {
-            Map<String, String> otherConfigsMap = new HashMap<String, String>();
+            Map<String, String> otherConfigsMap = new HashMap<>();
             for (PortOtherConfigs portOtherConfig : portOtherConfigs) {
                 otherConfigsMap.put(portOtherConfig.getOtherConfigKey(),
                         portOtherConfig.getOtherConfigValue());
@@ -326,7 +326,7 @@ public class TerminationPointCreateCommand extends AbstractTransactCommand {
     public static void stampInstanceIdentifier(TransactionBuilder transaction,InstanceIdentifier<TerminationPoint> iid,
             String interfaceName) {
         Port port = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), Port.class);
-        port.setName(interfaceName);;
+        port.setName(interfaceName);
         port.setExternalIds(Collections.<String,String>emptyMap());
         Mutate mutate = TransactUtils.stampInstanceIdentifierMutation(transaction,
                 iid,
index fa2f6d52cd9cb5768a9e4dff06368aca78bc26ec..525ab09c08429b3569c538ad4cfa6511eaaaa9da 100644 (file)
@@ -147,7 +147,7 @@ public class TerminationPointUpdateCommand extends AbstractTransactCommand {
 
         //Configure optional input
         if (terminationPoint.getOptions() != null) {
-            Map<String, String> optionsMap = new HashMap<String, String>();
+            Map<String, String> optionsMap = new HashMap<>();
             for (Options option : terminationPoint.getOptions()) {
                 optionsMap.put(option.getOption(), option.getValue());
             }
@@ -166,7 +166,7 @@ public class TerminationPointUpdateCommand extends AbstractTransactCommand {
         List<InterfaceExternalIds> interfaceExternalIds =
                 terminationPoint.getInterfaceExternalIds();
         if (interfaceExternalIds != null && !interfaceExternalIds.isEmpty()) {
-            Map<String, String> externalIdsMap = new HashMap<String, String>();
+            Map<String, String> externalIdsMap = new HashMap<>();
             for (InterfaceExternalIds externalId: interfaceExternalIds) {
                 externalIdsMap.put(externalId.getExternalIdKey(), externalId.getExternalIdValue());
             }
@@ -185,7 +185,7 @@ public class TerminationPointUpdateCommand extends AbstractTransactCommand {
         List<InterfaceOtherConfigs> interfaceOtherConfigs =
                 terminationPoint.getInterfaceOtherConfigs();
         if (interfaceOtherConfigs != null && !interfaceOtherConfigs.isEmpty()) {
-            Map<String, String> otherConfigsMap = new HashMap<String, String>();
+            Map<String, String> otherConfigsMap = new HashMap<>();
             for (InterfaceOtherConfigs interfaceOtherConfig : interfaceOtherConfigs) {
                 otherConfigsMap.put(interfaceOtherConfig.getOtherConfigKey(),
                         interfaceOtherConfig.getOtherConfigValue());
@@ -204,7 +204,7 @@ public class TerminationPointUpdateCommand extends AbstractTransactCommand {
 
         List<PortExternalIds> portExternalIds = terminationPoint.getPortExternalIds();
         if (portExternalIds != null && !portExternalIds.isEmpty()) {
-            Map<String, String> externalIdsMap = new HashMap<String, String>();
+            Map<String, String> externalIdsMap = new HashMap<>();
             for (PortExternalIds externalId: portExternalIds) {
                 externalIdsMap.put(externalId.getExternalIdKey(), externalId.getExternalIdValue());
             }
@@ -221,7 +221,7 @@ public class TerminationPointUpdateCommand extends AbstractTransactCommand {
             final Port port) {
 
         if (terminationPoint.getVlanTag() != null) {
-            Set<Long> vlanTag = new HashSet<Long>();
+            Set<Long> vlanTag = new HashSet<>();
             vlanTag.add(terminationPoint.getVlanTag().getValue().longValue());
             port.setTag(vlanTag);
         }
@@ -232,7 +232,7 @@ public class TerminationPointUpdateCommand extends AbstractTransactCommand {
             final Port port) {
 
         if (terminationPoint.getTrunks() != null && terminationPoint.getTrunks().size() > 0) {
-            Set<Long> portTrunks = new HashSet<Long>();
+            Set<Long> portTrunks = new HashSet<>();
             List<Trunks> modelTrunks = terminationPoint.getTrunks();
             for (Trunks trunk: modelTrunks) {
                 if (trunk.getTrunk() != null) {
@@ -247,7 +247,7 @@ public class TerminationPointUpdateCommand extends AbstractTransactCommand {
             final OvsdbTerminationPointAugmentation terminationPoint,
             final Port port) {
         if (terminationPoint.getVlanMode() != null) {
-            Set<String> portVlanMode = new HashSet<String>();
+            Set<String> portVlanMode = new HashSet<>();
             VlanMode modelVlanMode = terminationPoint.getVlanMode();
             portVlanMode.add(SouthboundConstants.VLANMODES.values()[modelVlanMode.getIntValue() - 1].getMode());
             port.setVlanMode(portVlanMode);
@@ -260,7 +260,7 @@ public class TerminationPointUpdateCommand extends AbstractTransactCommand {
         List<PortOtherConfigs> portOtherConfigs =
                 terminationPoint.getPortOtherConfigs();
         if (portOtherConfigs != null && !portOtherConfigs.isEmpty()) {
-            Map<String, String> otherConfigsMap = new HashMap<String, String>();
+            Map<String, String> otherConfigsMap = new HashMap<>();
             for (PortOtherConfigs portOtherConfig : portOtherConfigs) {
                 otherConfigsMap.put(portOtherConfig.getOtherConfigKey(),
                         portOtherConfig.getOtherConfigValue());
index fccd841692ea945dab493f574213f3b0ebfdc9cb..9bcddbfeaacef5565a79cdca26514e8cab597845 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public class TransactCommandAggregator implements TransactCommand {
 
-    private List<TransactCommand> commands = new ArrayList<TransactCommand>();
+    private List<TransactCommand> commands = new ArrayList<>();
     private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes;
     private BridgeOperationalState operationalState;
 
index ce35156e682c6b0e8b7c433dcb5c59522c5c1b40..0b3088fa72e3f14519dbd5811fa2f10b2836fd95 100644 (file)
@@ -19,7 +19,7 @@ import org.slf4j.LoggerFactory;
 import com.google.common.util.concurrent.ListenableFuture;
 
 public class TransactInvokerImpl implements TransactInvoker {
-    private static final Logger LOG = LoggerFactory.getLogger(BridgeUpdateCommand.class);
+    private static final Logger LOG = LoggerFactory.getLogger(TransactInvokerImpl.class);
     private OvsdbConnectionInstance connectionInstance;
     private DatabaseSchema dbSchema;
 
index 25d875b6631acc39915a37fe08f888843ba9844f..0d37f5ecefa06c66b8ce03b03d35439b1a561934 100644 (file)
@@ -50,8 +50,8 @@ public class TransactUtils {
     public static Map<InstanceIdentifier<Node>,Node> extractNode(
             Map<InstanceIdentifier<?>, DataObject> changes) {
         Map<InstanceIdentifier<Node>,Node> result
-            = new HashMap<InstanceIdentifier<Node>,Node>();
-        if (changes != null && changes.entrySet() != null) {
+            = new HashMap<>();
+        if (changes != null) {
             for (Entry<InstanceIdentifier<?>, DataObject> created : changes.entrySet()) {
                 if (created.getValue() instanceof Node) {
                     Node value = (Node) created.getValue();
@@ -99,7 +99,7 @@ public class TransactUtils {
 
     public static <T extends DataObject> Set<InstanceIdentifier<T>> extractRemoved(
             AsyncDataChangeEvent<InstanceIdentifier<?>,DataObject> changes,Class<T> klazz) {
-        Set<InstanceIdentifier<T>> result = new HashSet<InstanceIdentifier<T>>();
+        Set<InstanceIdentifier<T>> result = new HashSet<>();
         if (changes != null && changes.getRemovedPaths() != null) {
             for (InstanceIdentifier<?> iid : changes.getRemovedPaths()) {
                 if (iid.getTargetType().equals(klazz)) {
@@ -121,8 +121,8 @@ public class TransactUtils {
 
     public static <T extends DataObject> Map<InstanceIdentifier<T>,T> extract(
             Map<InstanceIdentifier<?>, DataObject> changes, Class<T> klazz) {
-        Map<InstanceIdentifier<T>,T> result = new HashMap<InstanceIdentifier<T>,T>();
-        if (changes != null && changes.entrySet() != null) {
+        Map<InstanceIdentifier<T>,T> result = new HashMap<>();
+        if (changes != null) {
             for (Entry<InstanceIdentifier<?>, DataObject> created : changes.entrySet()) {
                 if (klazz.isInstance(created.getValue())) {
                     @SuppressWarnings("unchecked")
@@ -141,12 +141,10 @@ public class TransactUtils {
 
     public static List<Insert> extractInsert(TransactionBuilder transaction, GenericTableSchema schema) {
         List<Operation> operations = transaction.getOperations();
-        List<Insert> inserts = new ArrayList<Insert>();
-        for (int count = 0;count < operations.size();count++) {
-            Operation operation = operations.get(count);
+        List<Insert> inserts = new ArrayList<>();
+        for (Operation operation : operations) {
             if (operation instanceof Insert && operation.getTableSchema().equals(schema)) {
-                Insert insert = (Insert)operation;
-                inserts.add(insert);
+                inserts.add((Insert) operation);
             }
         }
         return inserts;
@@ -164,8 +162,7 @@ public class TransactUtils {
         String uuidString = insert.getUuidName() != null
                 ? insert.getUuidName() : SouthboundMapper.getRandomUUID();
         insert.setUuidName(uuidString);
-        UUID uuid = new UUID(uuidString);
-        return uuid;
+        return new UUID(uuidString);
     }
 
     public static <T  extends TableSchema<T>> void stampInstanceIdentifier(TransactionBuilder transaction,
index dc8bd53c94b9b40627c08cabfcfe6a5a26bed0c6..2ca74ee343b87eef35dc15ad2a7f6a05a30c20ae 100644 (file)
@@ -209,7 +209,8 @@ public class OpenVSwitchUpdateCommand extends AbstractTransactionCommand {
             }
             ovsdbNodeBuilder.setInterfaceTypeEntry(ifEntryList);
         } catch (SchemaVersionMismatchException e) {
-            LOG.debug("Iface types  not supported by this version of ovsdb",e);
+            // We don't care about the exception stack trace here
+            LOG.debug("Iface types  not supported by this version of ovsdb: {}", e.getMessage());
         }
     }
 
@@ -233,7 +234,8 @@ public class OpenVSwitchUpdateCommand extends AbstractTransactionCommand {
             }
             ovsdbNodeBuilder.setDatapathTypeEntry(dpEntryList);
         } catch (SchemaVersionMismatchException e) {
-            LOG.debug("Datapath types not supported by this version of ovsdb",e);
+            // We don't care about the exception stack trace here
+            LOG.debug("Datapath types not supported by this version of ovsdb: {}", e.getMessage());
         }
     }
 
index 55aba8b987f0e101d2d38eaeaa1ba8a57e04ae3a..47767f9da1f5c12613bcbc8ad0c3f854aaccdbb9 100644 (file)
@@ -185,7 +185,8 @@ public class OvsdbBridgeUpdateCommand extends AbstractTransactionCommand {
                 }
             }
         } catch (SchemaVersionMismatchException e) {
-            LOG.warn("protocol not supported by this version of ovsdb", e);
+            // We don't care about the exception stack trace here
+            LOG.warn("protocol not supported by this version of ovsdb: {}", e.getMessage());
         }
         return result;
     }
index a11566aca3fecf8e917c37eab3a4176be289456a..067731b7c457c90f2736d034972bc06996e18960 100644 (file)
@@ -68,7 +68,7 @@ public class OvsdbControllerRemovedCommand extends AbstractTransactionCommand {
         Preconditions.checkNotNull(bridgeIid);
         Preconditions.checkNotNull(bridge);
         List<InstanceIdentifier<ControllerEntry>> result =
-                new ArrayList<InstanceIdentifier<ControllerEntry>>();
+                new ArrayList<>();
         Bridge oldBridgeNode = oldBridgeRows.get(bridge.getUuid());
 
         if (oldBridgeNode != null && oldBridgeNode.getControllerColumn() != null) {
index 94a1bc8b50ca135581017be7e1bcb3da48267221..20d1fdff6126281c80a883a54456abea1e7cc39b 100644 (file)
@@ -184,9 +184,8 @@ public class OvsdbControllerUpdateCommand extends AbstractTransactionCommand {
                 .child(Node.class,nodeKey)
                 .build();
 
-        InstanceIdentifier<ControllerEntry> iid = bridgeIid
+        return bridgeIid
                 .augmentation(OvsdbBridgeAugmentation.class)
                 .child(ControllerEntry.class, controllerEntry.getKey());
-        return iid;
     }
 }
index 42aff407d8ef24b8943911742c9eec526477f7f3..6b9af4b3d72fe20e0eb97d28a6a50791c22f0300 100644 (file)
@@ -69,7 +69,7 @@ public class OvsdbManagersRemovedCommand extends AbstractTransactionCommand {
         Preconditions.checkNotNull(openVSwitch);
 
         List<InstanceIdentifier<ManagerEntry>> result =
-                new ArrayList<InstanceIdentifier<ManagerEntry>>();
+                new ArrayList<>();
         OpenVSwitch oldOvsdbNode = oldOpenVSwitchRows.get(openVSwitch.getUuid());
 
         if (oldOvsdbNode != null && oldOvsdbNode.getManagerOptionsColumn() != null) {
index a33afc30848a6d3186b2752622334fb6c8afdf99..3ad92c2d931347d49deed39a4f9192e2e715cba3 100644 (file)
@@ -146,10 +146,9 @@ public class OvsdbManagersUpdateCommand extends AbstractTransactionCommand {
                 .child(Node.class,nodeKey)
                 .build();
 
-        InstanceIdentifier<ManagerEntry> iid = ovsdbNodeIid
+        return ovsdbNodeIid
                 .augmentation(OvsdbNodeAugmentation.class)
                 .child(ManagerEntry.class, managerEntry.getKey());
-        return iid;
     }
 
     private Map<Uri, Manager> getUriManagerMap(Map<UUID,Manager> uuidManagerMap) {
index 66b8c0745f1cc96e195a868efd093c82e4baf592..735ae97251b141d348946aeb8e188b12140ca85a 100644 (file)
@@ -60,7 +60,7 @@ public class OvsdbNodeRemoveCommand extends AbstractTransactionCommand {
                             getOvsdbConnectionInstance().getInstanceIdentifier());
                 } else {
                     LOG.debug("Other southbound plugin instances in cluster are connected to the device,"
-                            + " not deleting OvsdbNode form data store.");
+                            + " not deleting OvsdbNode from operational data store.");
                 }
             }
         } catch (Exception e) {
@@ -72,25 +72,28 @@ public class OvsdbNodeRemoveCommand extends AbstractTransactionCommand {
         ManagerEntry onlyConnectedManager = null;
         if (ovsdbNodeAugmentation != null) {
             int connectedManager = 0;
-            for (ManagerEntry manager : ovsdbNodeAugmentation.getManagerEntry()) {
-                if (manager.isConnected()) {
-                    connectedManager++;
-                    if (connectedManager > ONE_CONNECTED_MANAGER) {
-                        return false;
+            if (ovsdbNodeAugmentation.getManagerEntry() != null) {
+                for (ManagerEntry manager : ovsdbNodeAugmentation.getManagerEntry()) {
+                    if (manager.isConnected()) {
+                        connectedManager++;
+                        if (connectedManager > ONE_CONNECTED_MANAGER) {
+                            return false;
+                        }
+                        onlyConnectedManager = manager;
                     }
-                    onlyConnectedManager = manager;
                 }
             }
             if (connectedManager == 0) {
                 return true;
             }
-        }
-        /*When switch is listening in passive mode, this number represent number of active connection to the device
-        This is to handle the controller initiated connection scenario, where all the controller will connect, but
-        switch will have only one manager.
-        */
-        if (onlyConnectedManager.getNumberOfConnections().longValue() > ONE_ACTIVE_CONNECTION_IN_PASSIVE_MODE) {
-            return false;
+
+            /*When switch is listening in passive mode, this number represent number of active connection to the device
+            This is to handle the controller initiated connection scenario, where all the controller will connect, but
+            switch will have only one manager.
+            */
+            if (onlyConnectedManager.getNumberOfConnections() > ONE_ACTIVE_CONNECTION_IN_PASSIVE_MODE) {
+                return false;
+            }
         }
         return true;
     }
index 53b35af72733744716417929e5e702881a929342..c1fece74ca029e523a370b4cad3ab391305765f5 100644 (file)
@@ -19,7 +19,7 @@ import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
 public class OvsdbOperationalCommandAggregator implements TransactionCommand {
 
 
-    private List<TransactionCommand> commands = new ArrayList<TransactionCommand>();
+    private List<TransactionCommand> commands = new ArrayList<>();
 
     public OvsdbOperationalCommandAggregator(OvsdbConnectionInstance key,TableUpdates updates,
             DatabaseSchema dbSchema) {
index 1b0bf926bc3769afc695231d414abdf153f51555..0646f6be05007c11ec3a8085cc884b3cb5ef520d 100644 (file)
@@ -271,7 +271,7 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointBuilder) {
 
         Set<Long> portTrunks = port.getTrunksColumn().getData();
-        List<Trunks> modelTrunks = new ArrayList<Trunks>();
+        List<Trunks> modelTrunks = new ArrayList<>();
         if (!portTrunks.isEmpty()) {
             for (Long trunk: portTrunks) {
                 if (trunk != null) {
@@ -355,7 +355,7 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
         if (interfaceExternalIds != null && !interfaceExternalIds.isEmpty()) {
             Set<String> externalIdKeys = interfaceExternalIds.keySet();
             List<InterfaceExternalIds> externalIdsList =
-                    new ArrayList<InterfaceExternalIds>();
+                    new ArrayList<>();
             String externalIdValue;
             for (String externalIdKey : externalIdKeys) {
                 externalIdValue = interfaceExternalIds.get(externalIdKey);
@@ -375,7 +375,7 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
         Map<String, String> portExternalIds = port.getExternalIdsColumn().getData();
         if (portExternalIds != null && !portExternalIds.isEmpty()) {
             Set<String> externalIdKeys = portExternalIds.keySet();
-            List<PortExternalIds> externalIdsList = new ArrayList<PortExternalIds>();
+            List<PortExternalIds> externalIdsList = new ArrayList<>();
             String externalIdValue;
             for (String externalIdKey : externalIdKeys) {
                 externalIdValue = portExternalIds.get(externalIdKey);
@@ -394,7 +394,7 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
 
         Map<String, String> optionsMap = interf.getOptionsColumn().getData();
         if (optionsMap != null && !optionsMap.isEmpty()) {
-            List<Options> options = new ArrayList<Options>();
+            List<Options> options = new ArrayList<>();
             String optionsValueString;
             OptionsKey optionsKey;
             for (String optionsKeyString : optionsMap.keySet()) {
@@ -415,7 +415,7 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
 
         Map<String, String> portOtherConfigMap = port.getOtherConfigColumn().getData();
         if (portOtherConfigMap != null && !portOtherConfigMap.isEmpty()) {
-            List<PortOtherConfigs> portOtherConfigs = new ArrayList<PortOtherConfigs>();
+            List<PortOtherConfigs> portOtherConfigs = new ArrayList<>();
             String portOtherConfigValueString;
             for (String portOtherConfigKeyString : portOtherConfigMap.keySet()) {
                 portOtherConfigValueString = portOtherConfigMap.get(portOtherConfigKeyString);
@@ -434,7 +434,7 @@ public class OvsdbPortUpdateCommand extends AbstractTransactionCommand {
 
         Map<String, String> interfaceOtherConfigMap = interf.getOtherConfigColumn().getData();
         if (interfaceOtherConfigMap != null && !interfaceOtherConfigMap.isEmpty()) {
-            List<InterfaceOtherConfigs> interfaceOtherConfigs = new ArrayList<InterfaceOtherConfigs>();
+            List<InterfaceOtherConfigs> interfaceOtherConfigs = new ArrayList<>();
             String interfaceOtherConfigValueString;
             for (String interfaceOtherConfigKeyString : interfaceOtherConfigMap.keySet()) {
                 interfaceOtherConfigValueString = interfaceOtherConfigMap.get(interfaceOtherConfigKeyString);
index 1b149470582f70eb0f520888722795377a4d373a..cd0541524775e4a3270de75d97e0ca1b00c36459 100644 (file)
@@ -17,6 +17,8 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
@@ -37,15 +39,16 @@ public class TransactionInvokerImpl implements TransactionInvoker,TransactionCha
     private static final int QUEUE_SIZE = 10000;
     private BindingTransactionChain chain;
     private DataBroker db;
-    private BlockingQueue<TransactionCommand> inputQueue = new LinkedBlockingQueue<TransactionCommand>(QUEUE_SIZE);
+    private BlockingQueue<TransactionCommand> inputQueue = new LinkedBlockingQueue<>(QUEUE_SIZE);
     private BlockingQueue<ReadWriteTransaction> successfulTransactionQueue
-        = new LinkedBlockingQueue<ReadWriteTransaction>(QUEUE_SIZE);
+        = new LinkedBlockingQueue<>(QUEUE_SIZE);
     private BlockingQueue<AsyncTransaction<?, ?>> failedTransactionQueue
-        = new LinkedBlockingQueue<AsyncTransaction<?, ?>>(QUEUE_SIZE);
+        = new LinkedBlockingQueue<>(QUEUE_SIZE);
     private ExecutorService executor;
     private Map<ReadWriteTransaction,TransactionCommand> transactionToCommand
-        = new HashMap<ReadWriteTransaction,TransactionCommand>();
-    private List<ReadWriteTransaction> pendingTransactions = new ArrayList<ReadWriteTransaction>();
+        = new HashMap<>();
+    private List<ReadWriteTransaction> pendingTransactions = new ArrayList<>();
+    private final AtomicBoolean runTask = new AtomicBoolean( true );
 
     public TransactionInvokerImpl(DataBroker db) {
         this.db = db;
@@ -75,7 +78,7 @@ public class TransactionInvokerImpl implements TransactionInvoker,TransactionCha
 
     @Override
     public void run() {
-        while (true) {
+        while (runTask.get()) {
             forgetSuccessfulTransactions();
             try {
                 List<TransactionCommand> commands = extractCommands();
@@ -103,7 +106,7 @@ public class TransactionInvokerImpl implements TransactionInvoker,TransactionCha
 
     private List<TransactionCommand> extractResubmitCommands() {
         AsyncTransaction<?, ?> transaction = failedTransactionQueue.poll();
-        List<TransactionCommand> commands = new ArrayList<TransactionCommand>();
+        List<TransactionCommand> commands = new ArrayList<>();
         if (transaction != null) {
             int index = pendingTransactions.lastIndexOf(transaction);
             List<ReadWriteTransaction> transactions =
@@ -119,8 +122,8 @@ public class TransactionInvokerImpl implements TransactionInvoker,TransactionCha
     private void resetTransactionQueue() {
         chain.close();
         chain = db.createTransactionChain(this);
-        pendingTransactions = new ArrayList<ReadWriteTransaction>();
-        transactionToCommand = new HashMap<ReadWriteTransaction,TransactionCommand>();
+        pendingTransactions = new ArrayList<>();
+        transactionToCommand = new HashMap<>();
         failedTransactionQueue.clear();
         successfulTransactionQueue.clear();
     }
@@ -138,7 +141,7 @@ public class TransactionInvokerImpl implements TransactionInvoker,TransactionCha
     }
 
     private List<TransactionCommand> extractCommandsFromQueue() throws InterruptedException {
-        List<TransactionCommand> result = new ArrayList<TransactionCommand>();
+        List<TransactionCommand> result = new ArrayList<>();
         TransactionCommand command = inputQueue.take();
         while (command != null) {
             result.add(command);
@@ -159,5 +162,9 @@ public class TransactionInvokerImpl implements TransactionInvoker,TransactionCha
     @Override
     public void close() throws Exception {
         this.executor.shutdown();
+        if (!this.executor.awaitTermination(1, TimeUnit.SECONDS)) {
+            runTask.set(false);
+            this.executor.shutdownNow();
+        }
     }
 }
index 5014d144549a43120d1f984a965540077020b698..5c543dfc4d0898b624ffecb032996f1058e59417 100644 (file)
@@ -31,7 +31,8 @@ public class SouthboundImplModule extends org.opendaylight.yang.gen.v1.urn.opend
     public java.lang.AutoCloseable createInstance() {
         SouthboundUtil.setInstanceIdentifierCodec(new InstanceIdentifierCodec(getSchemaServiceDependency(),
                 getBindingNormalizedNodeSerializerDependency()));
-        SouthboundProvider provider = new SouthboundProvider(getClusteringEntityOwnershipServiceDependency());
+        SouthboundProvider provider = new SouthboundProvider(getClusteringEntityOwnershipServiceDependency(),
+                getConnectionServiceDependency());
         getBrokerDependency().registerProvider(provider);
         return provider;
     }
index 89a2eac74f8fe0e88981eb50bd0d79e46a257e35..f4c98d40e6c4eff6f4660196185848a2c0f71a3a 100644 (file)
@@ -7,6 +7,7 @@ module southbound-impl {
     import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
     import opendaylight-md-sal-dom {prefix dom; revision-date 2013-10-28;}
     import opendaylight-entity-ownership-service {prefix eos; revision-date 2015-08-10;}
+    import library { prefix library; revision-date 2014-12-10; }
 
     description
         "Service definition for southbound project";
@@ -56,6 +57,14 @@ module southbound-impl {
                     }
                 }
             }
+            container connection-service {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity library:connection-service;
+                    }
+                }
+            }
         }
     }
 }
index cbfe4c2b6543a4f6396ce106e4068e22201c80dc..14b0acb1f98690dabb5671d0186b07dd30daa403 100644 (file)
@@ -116,7 +116,7 @@ public class OvsdbConnectionInstanceTest {
         //callback null case
         MemberModifier.field(OvsdbConnectionInstance.class, "callback").set(ovsdbConnectionInstance , null);
         ListenableFuture<List<String>> listenableFuture = mock(ListenableFuture.class);
-        List<String> databases = new ArrayList<String>();
+        List<String> databases = new ArrayList<>();
         databases.add("Open_vSwitch");
         databases.add("");
         doReturn(listenableFuture).when(ovsdbConnectionInstance).getDatabases();
@@ -144,7 +144,7 @@ public class OvsdbConnectionInstanceTest {
         //transactInvokers null case
         MemberModifier.field(OvsdbConnectionInstance.class, "transactInvokers").set(ovsdbConnectionInstance , null);
         ListenableFuture<List<String>> listenableFuture = mock(ListenableFuture.class);
-        List<String> databases = new ArrayList<String>();
+        List<String> databases = new ArrayList<>();
         databases.add("database1");
         databases.add("database2");
         doReturn(listenableFuture).when(ovsdbConnectionInstance).getDatabases();
@@ -167,7 +167,7 @@ public class OvsdbConnectionInstanceTest {
     @SuppressWarnings("unchecked")
     @Test
     public void testMonitorAllTables() throws Exception {
-        Set<String> tables = new HashSet<String>();
+        Set<String> tables = new HashSet<>();
         tables.add("tableName1");
         tables.add("tableName2");
         DatabaseSchema dbSchema = mock(DatabaseSchema.class);
@@ -175,7 +175,7 @@ public class OvsdbConnectionInstanceTest {
         GenericTableSchema tableSchema = mock(GenericTableSchema.class);
         when(dbSchema.table(anyString(), eq(GenericTableSchema.class))).thenReturn(tableSchema);
 
-        Set<String> columns = new HashSet<String>();
+        Set<String> columns = new HashSet<>();
         columns.add("columnName1");
         columns.add("columnName2");
         when(tableSchema.getColumns()).thenReturn(columns);
@@ -183,7 +183,7 @@ public class OvsdbConnectionInstanceTest {
         PowerMockito.mockStatic(MonitorRequestBuilder.class);
         when(MonitorRequestBuilder.builder(any(GenericTableSchema.class))).thenReturn(monitorBuilder);
         when(monitorBuilder.addColumn(anyString())).thenReturn(monitorBuilder);
-        MonitorRequest<GenericTableSchema> monitorReq = mock(MonitorRequest.class);
+        MonitorRequest monitorReq = mock(MonitorRequest.class);
         when(monitorBuilder.with(any(MonitorSelect.class))).thenReturn(monitorBuilder);
         when(monitorBuilder.build()).thenReturn(monitorReq);
 
index 209301c58d78d97b58540bd31cfdf6042f62c339..5a915d97aea128fe4b7079a9406dfe3f9897e273 100644 (file)
@@ -28,7 +28,6 @@ import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
 import org.opendaylight.ovsdb.lib.OvsdbClient;
 import org.opendaylight.ovsdb.lib.OvsdbConnection;
@@ -59,6 +58,7 @@ public class OvsdbConnectionManagerTest {
     @Mock private DataBroker db;
     @Mock private TransactionInvoker txInvoker;
     @Mock private EntityOwnershipService entityOwnershipService;
+    @Mock private OvsdbConnection ovsdbConnection;
     private Map<ConnectionInfo,OvsdbConnectionInstance> clients;
     private Map<ConnectionInfo,InstanceIdentifier<Node>> instanceIdentifiers;
     private Map<Entity, OvsdbConnectionInstance> entityConnectionMap;
@@ -71,6 +71,8 @@ public class OvsdbConnectionManagerTest {
         MemberModifier.field(OvsdbConnectionManager.class, "db").set(ovsdbConnectionManager, db);
         MemberModifier.field(OvsdbConnectionManager.class, "txInvoker").set(ovsdbConnectionManager, txInvoker);
         MemberModifier.field(OvsdbConnectionManager.class, "entityOwnershipService").set(ovsdbConnectionManager, entityOwnershipService);
+        MemberModifier.field(OvsdbConnectionManager.class, "ovsdbConnection")
+                .set(ovsdbConnectionManager, ovsdbConnection);
         entityConnectionMap = new ConcurrentHashMap<>();
     }
     @Test
@@ -101,7 +103,7 @@ public class OvsdbConnectionManagerTest {
         InetAddress ip = mock(InetAddress.class);
 
         when(externalClient.getConnectionInfo().getRemoteAddress()).thenReturn(ip);
-        when(externalClient.getConnectionInfo().getRemotePort()).thenReturn(new Integer(8080));
+        when(externalClient.getConnectionInfo().getRemotePort()).thenReturn(8080);
 
         ConnectionInfo key = mock(ConnectionInfo.class);
         PowerMockito.mockStatic(SouthboundMapper.class);
@@ -129,13 +131,13 @@ public class OvsdbConnectionManagerTest {
         OvsdbConnectionInstance ovsdbConnectionInstance = mock(OvsdbConnectionInstance.class);
         InetAddress ip = mock(InetAddress.class);
         when(client.getConnectionInfo().getRemoteAddress()).thenReturn(ip);
-        when(client.getConnectionInfo().getRemotePort()).thenReturn(new Integer(8080));
+        when(client.getConnectionInfo().getRemotePort()).thenReturn(8080);
 
         ConnectionInfo key = mock(ConnectionInfo.class);
         PowerMockito.mockStatic(SouthboundMapper.class);
         when(SouthboundMapper.createConnectionInfo(any(OvsdbClient.class))).thenReturn(key);
 
-        clients = new ConcurrentHashMap<ConnectionInfo,OvsdbConnectionInstance>();
+        clients = new ConcurrentHashMap<>();
         clients.put(key, ovsdbConnectionInstance);
         MemberModifier.field(OvsdbConnectionManager.class, "clients").set(ovsdbConnectionManager, clients);
 
@@ -188,7 +190,7 @@ public class OvsdbConnectionManagerTest {
         ConnectionInfo key2 = mock(ConnectionInfo.class);
         OvsdbConnectionInstance ovsdbConnectionInstance1 = mock(OvsdbConnectionInstance.class);
         OvsdbConnectionInstance ovsdbConnectionInstance2 = mock(OvsdbConnectionInstance.class);
-        clients = new ConcurrentHashMap<ConnectionInfo,OvsdbConnectionInstance>();
+        clients = new ConcurrentHashMap<>();
         clients.put(key1, ovsdbConnectionInstance1);
         clients.put(key2, ovsdbConnectionInstance2);
         MemberModifier.field(OvsdbConnectionManager.class, "clients").set(ovsdbConnectionManager, clients);
@@ -205,7 +207,7 @@ public class OvsdbConnectionManagerTest {
         PowerMockito.mockStatic(SouthboundMapper.class);
         when(SouthboundMapper.suppressLocalIpPort(key)).thenReturn(connectionInfo);
 
-        clients = new ConcurrentHashMap<ConnectionInfo,OvsdbConnectionInstance>();
+        clients = new ConcurrentHashMap<>();
         MemberModifier.field(OvsdbConnectionManager.class, "clients").set(ovsdbConnectionManager, clients);
 
         //Test putConnectionInstance()
@@ -226,7 +228,7 @@ public class OvsdbConnectionManagerTest {
         PowerMockito.mockStatic(SouthboundMapper.class);
         when(SouthboundMapper.suppressLocalIpPort(key)).thenReturn(connectionInfo);
 
-        instanceIdentifiers = new ConcurrentHashMap<ConnectionInfo,InstanceIdentifier<Node>>();
+        instanceIdentifiers = new ConcurrentHashMap<>();
         MemberModifier.field(OvsdbConnectionManager.class, "instanceIdentifiers").set(ovsdbConnectionManager, instanceIdentifiers);
 
         //Test putInstanceIdentifier()
@@ -280,12 +282,11 @@ public class OvsdbConnectionManagerTest {
         when(SouthboundMapper.createInetAddress(any(IpAddress.class))).thenReturn(ip);
 
         OvsdbClient client = mock(OvsdbClient.class);
-        OvsdbConnection ovsdbConnection = mock(OvsdbConnection.class);
         PowerMockito.mockStatic(OvsdbConnectionService.class);
         when(OvsdbConnectionService.getService()).thenReturn(ovsdbConnection);
         PortNumber port = mock(PortNumber.class);
         when(connectionInfo.getRemotePort()).thenReturn(port);
-        when(port.getValue()).thenReturn(new Integer(8080));
+        when(port.getValue()).thenReturn(8080);
         when(ovsdbConnection.connect(any(InetAddress.class), anyInt())).thenReturn(client);
 
         //client not null case
index 469bd723400f1db1e6c3bab2e295dfe83e452245..4858eadfc914cc3c5bdf467aeddfc5ed42e0aad2 100644 (file)
@@ -79,7 +79,7 @@ public class OvsdbDataChangeListenerTest {
     @Test
     public void testOnDataChanged() throws Exception {
         AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes = mock(AsyncDataChangeEvent.class);
-        Map<InstanceIdentifier<?>, DataObject> map = new HashMap<InstanceIdentifier<?>, DataObject>();
+        Map<InstanceIdentifier<?>, DataObject> map = new HashMap<>();
         InstanceIdentifier<?> iid1 = mock(InstanceIdentifier.class);
         OvsdbNodeAugmentation ovsdbNode = mock(OvsdbNodeAugmentation.class);
         map.put(iid1, ovsdbNode);
@@ -107,7 +107,7 @@ public class OvsdbDataChangeListenerTest {
     @Test
     public void testUpdateData() throws Exception {
         AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes = mock(AsyncDataChangeEvent.class);
-        Map<InstanceIdentifier<Node>, OvsdbConnectionInstance> map = new HashMap<InstanceIdentifier<Node>, OvsdbConnectionInstance>();
+        Map<InstanceIdentifier<Node>, OvsdbConnectionInstance> map = new HashMap<>();
         InstanceIdentifier<Node> iid = mock(InstanceIdentifier.class);
         OvsdbConnectionInstance connectionInstance = mock(OvsdbConnectionInstance.class);
         map.put(iid, connectionInstance);
@@ -133,8 +133,8 @@ public class OvsdbDataChangeListenerTest {
     @Test
     public void testDisconnectAndConnectAndInit() throws Exception {
         AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes = mock(AsyncDataChangeEvent.class);
-        Map<InstanceIdentifier<?>, DataObject> originalDataObject = new HashMap<InstanceIdentifier<?>, DataObject>();
-        Set<InstanceIdentifier<?>> iiD = new HashSet<InstanceIdentifier<?>>();
+        Map<InstanceIdentifier<?>, DataObject> originalDataObject = new HashMap<>();
+        Set<InstanceIdentifier<?>> iiD = new HashSet<>();
         InstanceIdentifier instanceIdentifier = mock(InstanceIdentifier.class);
         OvsdbNodeAugmentation ovsdbNode = mock(OvsdbNodeAugmentation.class);
         iiD.add(instanceIdentifier);
@@ -165,7 +165,7 @@ public class OvsdbDataChangeListenerTest {
     @Test
     public void testUpdateConnections() throws Exception {
         AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes = mock(AsyncDataChangeEvent.class);
-        Map<InstanceIdentifier<?>, DataObject> map = new HashMap<InstanceIdentifier<?>, DataObject>();
+        Map<InstanceIdentifier<?>, DataObject> map = new HashMap<>();
         InstanceIdentifier instanceIdentifier = mock(InstanceIdentifier.class);
         OvsdbNodeAugmentation value = mock(OvsdbNodeAugmentation.class);
         map.put(instanceIdentifier, value);
@@ -188,8 +188,8 @@ public class OvsdbDataChangeListenerTest {
     @Test
     public void testConnectionInstancesFromChanges() throws Exception {
         AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes = mock(AsyncDataChangeEvent.class);
-        Map<InstanceIdentifier<Node>,OvsdbConnectionInstance> testResultMap = new HashMap<InstanceIdentifier<Node>,OvsdbConnectionInstance>();
-        Map<InstanceIdentifier<Node>,OvsdbConnectionInstance> map1 = new HashMap<InstanceIdentifier<Node>,OvsdbConnectionInstance>();
+        Map<InstanceIdentifier<Node>,OvsdbConnectionInstance> testResultMap = new HashMap<>();
+        Map<InstanceIdentifier<Node>,OvsdbConnectionInstance> map1 = new HashMap<>();
         InstanceIdentifier<Node> key1 = mock(InstanceIdentifier.class);
         OvsdbConnectionInstance value1 = mock(OvsdbConnectionInstance.class);
         map1.put(key1, value1);
@@ -207,13 +207,13 @@ public class OvsdbDataChangeListenerTest {
     @Test
     public void testConnectionInstancesFromMap() {
         reset(cm);
-        Map<InstanceIdentifier<?>,DataObject> map = new HashMap<InstanceIdentifier<?>,DataObject>();
+        Map<InstanceIdentifier<?>,DataObject> map = new HashMap<>();
         Node node = mock(Node.class);
         InstanceIdentifier<Node> iid = mock(InstanceIdentifier.class);
         map.put(iid, node);
         OvsdbConnectionInstance client = mock(OvsdbConnectionInstance.class);
 
-        Map<InstanceIdentifier<Node>,OvsdbConnectionInstance> testResultMap = new HashMap<InstanceIdentifier<Node>,OvsdbConnectionInstance>();
+        Map<InstanceIdentifier<Node>,OvsdbConnectionInstance> testResultMap = new HashMap<>();
         testResultMap.put(iid, client);
 
         //bridge and client not null case
@@ -236,7 +236,7 @@ public class OvsdbDataChangeListenerTest {
 
         //bridge null, ovsnode null, and client not null case
         when(node.getAugmentation(OvsdbNodeAugmentation.class)).thenReturn(null);
-        List<TerminationPoint> terminationPoint = new ArrayList<TerminationPoint>();
+        List<TerminationPoint> terminationPoint = new ArrayList<>();
         terminationPoint.add(0, mock(TerminationPoint.class));
         when(node.getTerminationPoint()).thenReturn(terminationPoint);
         PowerMockito.mockStatic(SouthboundMapper.class);
index 546e004b55cf23ae3ebdd452ae71d6058fd17493..14d4d160918bac9f5f2c865a8dd2aaf1dc53315d 100644 (file)
@@ -131,7 +131,7 @@ public class SouthboundMapperTest {
         //when bridge is not empty
         Column<GenericTableSchema, Map<String, String>> column = mock(Column.class);
         when(bridge.getExternalIdsColumn()).thenReturn(column);
-        Map<String, String> map = new HashMap<String, String>();
+        Map<String, String> map = new HashMap<>();
         map.put(SouthboundConstants.IID_EXTERNAL_ID_KEY, "IID_EXTERNAL_ID_KEY");
         when(column.getData()).thenReturn(map);
         PowerMockito.mockStatic(SouthboundUtil.class);
@@ -166,7 +166,7 @@ public class SouthboundMapperTest {
         //when controller is not empty
         Column<GenericTableSchema, Map<String, String>> column = mock(Column.class);
         when(controller.getExternalIdsColumn()).thenReturn(column);
-        Map<String, String> map = new HashMap<String, String>();
+        Map<String, String> map = new HashMap<>();
         map.put(SouthboundConstants.IID_EXTERNAL_ID_KEY, "IID_EXTERNAL_ID_KEY");
         when(column.getData()).thenReturn(map);
         PowerMockito.mockStatic(SouthboundUtil.class);
@@ -218,7 +218,7 @@ public class SouthboundMapperTest {
 
         Column<GenericTableSchema, Set<String>> column = mock(Column.class);
         when(bridge.getDatapathIdColumn()).thenReturn(column);
-        Set<String> set = new HashSet<String>();
+        Set<String> set = new HashSet<>();
         set.add("dpid");
         when(column.getData()).thenReturn(set);
         assertNotNull(column.getData());
@@ -237,7 +237,7 @@ public class SouthboundMapperTest {
         when(mdsalbridge.getDatapathType()).thenAnswer(new Answer<Class<? extends DatapathTypeBase>>() {
             public Class<? extends DatapathTypeBase> answer(
                     InvocationOnMock invocation) throws Throwable {
-                return (Class<? extends DatapathTypeBase>) DatapathTypeNetdev.class;
+                return DatapathTypeNetdev.class;
             }
         });
         assertEquals("netdev", SouthboundMapper.createDatapathType(mdsalbridge));
@@ -245,7 +245,7 @@ public class SouthboundMapperTest {
         when(mdsalbridge.getDatapathType()).thenAnswer(new Answer<Class<? extends DatapathTypeBase>>() {
             public Class<? extends DatapathTypeBase> answer(
                     InvocationOnMock invocation) throws Throwable {
-                return (Class<? extends DatapathTypeBase>) DatapathTypeSystem.class;
+                return DatapathTypeSystem.class;
             }
         });
         assertEquals("system", SouthboundMapper.createDatapathType(mdsalbridge));
@@ -261,17 +261,17 @@ public class SouthboundMapperTest {
     @Test
     public void testCreateOvsdbBridgeProtocols() {
         OvsdbBridgeAugmentation ovsdbBridgeNode = mock(OvsdbBridgeAugmentation.class);
-        List<ProtocolEntry> protocolList = new ArrayList<ProtocolEntry>();
+        List<ProtocolEntry> protocolList = new ArrayList<>();
         ProtocolEntry protocolEntry = mock(ProtocolEntry.class);
         protocolList.add(protocolEntry);
         when(ovsdbBridgeNode.getProtocolEntry()).thenReturn(protocolList);
         when(protocolEntry.getProtocol()).thenAnswer(new Answer<Class<? extends OvsdbBridgeProtocolBase>>() {
             public Class<? extends OvsdbBridgeProtocolBase> answer(
                     InvocationOnMock invocation) throws Throwable {
-                return (Class<? extends OvsdbBridgeProtocolBase>) OvsdbBridgeProtocolOpenflow10.class;
+                return OvsdbBridgeProtocolOpenflow10.class;
             }
         });
-        Set<String> protocols = new HashSet<String>();
+        Set<String> protocols = new HashSet<>();
         protocols.add("OpenFlow10");
         assertEquals(protocols, SouthboundMapper.createOvsdbBridgeProtocols(ovsdbBridgeNode));
     }
@@ -292,13 +292,13 @@ public class SouthboundMapperTest {
     @Test
     public void testCreateMdsalProtocols() throws Exception {
         Bridge bridge = mock(Bridge.class);
-        Set<String> value = new HashSet<String>();
+        Set<String> value = new HashSet<>();
         value.add("OpenFlow10");
         Column<GenericTableSchema, Set<String>> column = mock(Column.class);
         when(bridge.getProtocolsColumn()).thenReturn(column);
         when(column.getData()).thenReturn(value);
 
-        List<ProtocolEntry> protocolList = new ArrayList<ProtocolEntry>();
+        List<ProtocolEntry> protocolList = new ArrayList<>();
         ProtocolEntry protoEntry = mock(ProtocolEntry.class);
         ProtocolEntryBuilder protocolEntryBuilder = mock(ProtocolEntryBuilder.class);
         PowerMockito.whenNew(ProtocolEntryBuilder.class).withNoArguments().thenReturn(protocolEntryBuilder);
@@ -312,16 +312,16 @@ public class SouthboundMapperTest {
     @Test
     public void testCreateControllerEntries() throws Exception {
         Bridge bridge = mock(Bridge.class);
-        Map<UUID, Controller> updatedControllerRows = new HashMap<UUID, Controller>();
+        Map<UUID, Controller> updatedControllerRows = new HashMap<>();
         Column<GenericTableSchema, Set<UUID>> column = mock(Column.class);
         when(bridge.getControllerColumn()).thenReturn(column);
-        Set<UUID> controllerUUIDs = new HashSet<UUID>();
+        Set<UUID> controllerUUIDs = new HashSet<>();
         UUID uuid = mock(UUID.class);
         controllerUUIDs.add(uuid);
         Controller controller = mock(Controller.class);
         updatedControllerRows.put(uuid, controller);
         when(column.getData()).thenReturn(controllerUUIDs);
-        List<ControllerEntry> controllerEntries = new ArrayList<ControllerEntry>();
+        List<ControllerEntry> controllerEntries = new ArrayList<>();
         ControllerEntry controllerEntry = mock(ControllerEntry.class);
         controllerEntries.add(controllerEntry);
 
@@ -356,11 +356,11 @@ public class SouthboundMapperTest {
     public void testCreateOvsdbController() throws Exception {
         OvsdbBridgeAugmentation omn = mock(OvsdbBridgeAugmentation.class);
         DatabaseSchema dbSchema = mock(DatabaseSchema.class);
-        List<ControllerEntry> controllerEntries = new ArrayList<ControllerEntry>();
+        List<ControllerEntry> controllerEntries = new ArrayList<>();
         ControllerEntry controllerEntry = mock(ControllerEntry.class);
         controllerEntries.add(controllerEntry);
         when(omn.getControllerEntry()).thenReturn(controllerEntries);
-        Map<UUID,Controller> controllerMap = new HashMap<UUID,Controller>();
+        Map<UUID,Controller> controllerMap = new HashMap<>();
         PowerMockito.mockStatic(TyperUtils.class);
         Controller controller = mock(Controller.class);
         PowerMockito.when(TyperUtils.getTypedRowWrapper(any(DatabaseSchema.class), eq(Controller.class))).thenReturn(controller);
@@ -381,9 +381,9 @@ public class SouthboundMapperTest {
         PowerMockito.whenNew(ConnectionInfoBuilder.class).withNoArguments().thenReturn(connectionInfoBuilder);
 
         when(client.getConnectionInfo().getRemoteAddress()).thenReturn(mock(InetAddress.class));
-        when(client.getConnectionInfo().getRemotePort()).thenReturn(new Integer(8080));
+        when(client.getConnectionInfo().getRemotePort()).thenReturn(8080);
         when(client.getConnectionInfo().getLocalAddress()).thenReturn(mock(InetAddress.class));
-        when(client.getConnectionInfo().getLocalPort()).thenReturn(new Integer(8080));
+        when(client.getConnectionInfo().getLocalPort()).thenReturn(8080);
         PortNumber portNum = mock(PortNumber.class);
         PowerMockito.whenNew(PortNumber.class).withAnyArguments().thenReturn(portNum);
         when(connectionInfoBuilder.setRemoteIp(any(IpAddress .class))).thenReturn(connectionInfoBuilder);
@@ -412,8 +412,8 @@ public class SouthboundMapperTest {
     @Test
     public void testCreateManagerEntries() throws Exception {
         OpenVSwitch ovsdbNode = mock(OpenVSwitch.class);
-        Map<UUID, Manager> updatedManagerRows = new HashMap<UUID, Manager>();
-        Set<UUID> managerUUIDs = new HashSet<UUID>();
+        Map<UUID, Manager> updatedManagerRows = new HashMap<>();
+        Set<UUID> managerUUIDs = new HashSet<>();
         UUID managerUUID = mock(UUID.class);
         Manager manager = mock(Manager.class);
         managerUUIDs.add(managerUUID);
@@ -421,7 +421,7 @@ public class SouthboundMapperTest {
         Column<GenericTableSchema, Set<UUID>> column = mock(Column.class);
         when(ovsdbNode.getManagerOptionsColumn()).thenReturn(column);
         when(column.getData()).thenReturn(managerUUIDs);
-        List<ManagerEntry> managerEntries = new ArrayList<ManagerEntry>();
+        List<ManagerEntry> managerEntries = new ArrayList<>();
         ManagerEntry managerEntry = mock(ManagerEntry.class);
         managerEntries.add(managerEntry);
 
@@ -432,7 +432,7 @@ public class SouthboundMapperTest {
 
         Column<GenericTableSchema, Map<String, String>> statusColumn = mock(Column.class);
         when(manager.getStatusColumn()).thenReturn(statusColumn);
-        Map<String, String> statusAttributeMap = new HashMap<String, String>();
+        Map<String, String> statusAttributeMap = new HashMap<>();
         when(statusColumn.getData()).thenReturn(statusAttributeMap);
         String numberOfConnectionValueStr = "999";
 
@@ -462,12 +462,12 @@ public class SouthboundMapperTest {
     @Test
     public void testCreateManagerEntries1() throws Exception {
         Node ovsdbNode = mock(Node.class);
-        Map<Uri, Manager> updatedManagerRows = new HashMap<Uri, Manager>();
+        Map<Uri, Manager> updatedManagerRows = new HashMap<>();
         Uri uri = mock(Uri.class);
         Manager manager = mock(Manager.class);
         updatedManagerRows.put(uri, manager);
 
-        List<ManagerEntry> managerEntriesCreated = new ArrayList<ManagerEntry>();
+        List<ManagerEntry> managerEntriesCreated = new ArrayList<>();
 
         //ovsdbNodeAugmentation is null
         when(ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class)).thenReturn(null);
@@ -477,7 +477,7 @@ public class SouthboundMapperTest {
         OvsdbNodeAugmentation ovsdbNodeAugmentation = mock(OvsdbNodeAugmentation.class);
         when(ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class)).thenReturn(ovsdbNodeAugmentation);
 
-        List<ManagerEntry> managerEntries = new ArrayList<ManagerEntry>();
+        List<ManagerEntry> managerEntries = new ArrayList<>();
         ManagerEntry managerEntry = mock(ManagerEntry.class);
         managerEntries.add(managerEntry);
         when(ovsdbNodeAugmentation.getManagerEntry()).thenReturn(managerEntries);
@@ -490,7 +490,7 @@ public class SouthboundMapperTest {
 
         Column<GenericTableSchema, Map<String, String>> statusColumn = mock(Column.class);
         when(manager.getStatusColumn()).thenReturn(statusColumn);
-        Map<String, String> statusAttributeMap = new HashMap<String, String>();
+        Map<String, String> statusAttributeMap = new HashMap<>();
         when(statusColumn.getData()).thenReturn(statusAttributeMap);
         String numberOfConnectionValueStr = "999";
 
index b62e7e53a9c278f5d93d73aa4a6952acf901da64..d843359ddf98977dcfea38dcdcc601672442057b 100644 (file)
@@ -28,9 +28,11 @@ import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipC
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipState;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.lib.OvsdbConnection;
 import org.opendaylight.ovsdb.southbound.transactions.md.TransactionInvoker;
 import org.opendaylight.ovsdb.southbound.transactions.md.TransactionInvokerImpl;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
@@ -77,11 +79,13 @@ public class SouthboundProviderTest {
         when(session.getSALService(DataBroker.class)).thenReturn(db);
         TransactionInvokerImpl transactionInvokerImpl = mock(TransactionInvokerImpl.class);
         PowerMockito.whenNew(TransactionInvokerImpl.class).withArguments(any(DataBroker.class)).thenReturn(transactionInvokerImpl);
-        PowerMockito.whenNew(OvsdbConnectionManager.class).withArguments(any(DataBroker.class), any(TransactionInvoker.class), any(EntityOwnershipService.class)).thenReturn(cm);
+        PowerMockito.whenNew(OvsdbConnectionManager.class).withArguments(any(DataBroker.class), any(TransactionInvoker.class), any(EntityOwnershipService.class), any(OvsdbConnection.class)).thenReturn(cm);
         PowerMockito.whenNew(OvsdbDataChangeListener.class).withArguments(any(DataBroker.class), any(OvsdbConnectionManager.class)).thenReturn(ovsdbDataChangeListener);
 
         when(entityOwnershipService.registerListener(anyString(), any(EntityOwnershipListener.class))).thenReturn(mock(EntityOwnershipListenerRegistration.class));
         when(entityOwnershipService.registerCandidate(any(Entity.class))).thenReturn(registration);
+        EntityOwnershipState entityOwnershipState = mock(EntityOwnershipState.class);
+        when(entityOwnershipService.getOwnershipState(any(Entity.class))).thenReturn(Optional.of(entityOwnershipState));
 
         southboundProvider.onSessionInitiated(session);
 
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/AbstractTransactCommandTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/AbstractTransactCommandTest.java
new file mode 100644 (file)
index 0000000..df3c1e5
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+public class AbstractTransactCommandTest {
+
+    @Mock private BridgeOperationalState operationalState;
+    @Mock private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes;
+    private AbstractTransactCommandChild abstractTransCmd;
+
+    public class AbstractTransactCommandChild extends AbstractTransactCommand {
+        public AbstractTransactCommandChild(BridgeOperationalState state, AsyncDataChangeEvent<InstanceIdentifier<?>,
+                DataObject> changes) {
+            super(state, changes);
+        }
+
+        @Override
+        public void execute(TransactionBuilder transaction) {
+            // TODO Auto-generated method stub
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        operationalState = mock(BridgeOperationalState.class, Mockito.RETURNS_MOCKS);
+        changes = mock(AsyncDataChangeEvent.class, Mockito.RETURNS_MOCKS);
+        abstractTransCmd = new AbstractTransactCommandChild(operationalState, changes);
+    }
+
+    @Test
+    public void testGetOperationalState() {
+        assertNotNull(abstractTransCmd.getOperationalState());
+        assertEquals(operationalState, abstractTransCmd.getOperationalState());
+    }
+
+    @Test
+    public void testGetChanges() {
+        assertNotNull(abstractTransCmd.getChanges());
+        assertEquals(changes, abstractTransCmd.getChanges());
+    }
+}
\ No newline at end of file
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeOperationalStateTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeOperationalStateTest.java
new file mode 100644 (file)
index 0000000..e12ff53
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
+
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.google.common.base.Optional;
+import org.powermock.api.support.membermodification.MemberMatcher;
+
+@PrepareForTest({BridgeOperationalState.class, Optional.class, InstanceIdentifier.class, Node.class, OvsdbBridgeAugmentation.class})
+@RunWith(PowerMockRunner.class)
+public class BridgeOperationalStateTest {
+
+    @Mock private BridgeOperationalState briOperationState;
+    @Mock private InstanceIdentifier<ProtocolEntry> protocolEntry;
+    @Mock private InstanceIdentifier<?> iid;
+    @Mock private InstanceIdentifier<Node> iidNode;
+    @Mock private Node nd;
+    private Map<InstanceIdentifier<Node>, Node> operationalNodes;
+
+    @Before
+    public void setUp() throws Exception {
+        briOperationState = mock(BridgeOperationalState.class, Mockito.CALLS_REAL_METHODS);
+        iid = mock(InstanceIdentifier.class, Mockito.RETURNS_MOCKS);
+        protocolEntry = mock(InstanceIdentifier.class, Mockito.RETURNS_MOCKS);
+        iidNode = mock(InstanceIdentifier.class, Mockito.RETURNS_MOCKS);
+        nd = mock(Node.class, Mockito.RETURNS_MOCKS);
+
+        operationalNodes = new HashMap<>();
+        operationalNodes.put(iidNode, nd);
+        MemberModifier.field(BridgeOperationalState.class,"operationalNodes").set(briOperationState, operationalNodes);
+        PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(InstanceIdentifier.class));
+    }
+
+    @Test
+    public void testGetBridgeNode() throws Exception {
+        Optional<Node> optNodes = briOperationState.getBridgeNode(iid);
+        verify(iid, times(1)).firstIdentifierOf(Node.class);
+        assertNotNull(optNodes);
+        assertTrue(optNodes.equals(Optional.absent()));
+    }
+
+    @Test
+    public void testGetOvsdbBridgeAugmentation() throws Exception {
+        Optional<OvsdbBridgeAugmentation> optOvsdbBri = briOperationState.getOvsdbBridgeAugmentation(iid);
+        verify(briOperationState, times(1)).getBridgeNode(any(InstanceIdentifier.class));
+        assertNotNull(optOvsdbBri);
+        assertTrue(optOvsdbBri.equals(Optional.absent()));
+
+        Node node = mock(Node.class);
+        Optional<Node> optNode = mock(Optional.class);
+        OvsdbBridgeAugmentation ovsdbBriAug = mock(OvsdbBridgeAugmentation.class);
+        PowerMockito.suppress(MemberMatcher.method(BridgeOperationalState.class, "getBridgeNode", InstanceIdentifier.class));
+        when(briOperationState.getBridgeNode(any(InstanceIdentifier.class))).thenReturn(optNode);
+        when(optNode.isPresent()).thenReturn(true);
+        when(optNode.get()).thenReturn(node);
+        when(node.getAugmentation(OvsdbBridgeAugmentation.class)).thenReturn(ovsdbBriAug);
+        Optional<OvsdbBridgeAugmentation> ovsdbBriAugOptional = briOperationState.getOvsdbBridgeAugmentation(iid);
+        assertNotNull(ovsdbBriAugOptional);
+        assertTrue(ovsdbBriAugOptional.get() instanceof OvsdbBridgeAugmentation);
+    }
+
+    @Test
+    public void testGetBridgeTerminationPoint() throws Exception {
+        Optional<TerminationPoint> optTerm = briOperationState.getBridgeTerminationPoint(iid);
+        verify(briOperationState, times(1)).getBridgeNode(any(InstanceIdentifier.class));
+        assertNotNull(optTerm);
+        assertTrue(optTerm.equals(Optional.absent()));
+
+        Node node = mock(Node.class);
+        Optional<Node> optNode = mock(Optional.class);
+        TerminationPoint termPnt = mock(TerminationPoint.class);
+        List<TerminationPoint> termPntList = new ArrayList<>();
+        termPntList.add(termPnt);
+        TerminationPointKey termPntKey = mock(TerminationPointKey.class);
+
+        PowerMockito.suppress(MemberMatcher.method(BridgeOperationalState.class, "getBridgeNode", InstanceIdentifier.class));
+        when(briOperationState.getBridgeNode(any(InstanceIdentifier.class))).thenReturn(optNode);
+        when(optNode.isPresent()).thenReturn(true);
+        when(optNode.get()).thenReturn(node);
+        when(node.getTerminationPoint()).thenReturn(termPntList);
+        when(termPnt.getKey()).thenReturn(termPntKey);
+
+        final InstanceIdentifier<?> iid2 = PowerMockito.mock(InstanceIdentifier.class);
+        //PowerMockito.suppress(MemberMatcher.method(InstanceIdentifier.class, "firstKeyOf", Class.class, Class.class));
+        //PowerMockito.when(iid2.firstKeyOf(TerminationPoint.class, TerminationPointKey.class)).thenReturn(termPntKey);
+        Optional<TerminationPoint> optTermPnt = briOperationState.getBridgeTerminationPoint(iid2);
+        assertNotNull(optTermPnt);
+        //assertTrue(optTermPnt.get() instanceof TerminationPoint);
+    }
+
+    @Test
+    public void testGetOvsdbTerminationPointAugmentation() {
+        Optional<OvsdbTerminationPointAugmentation> optOvsdbTermPoint = briOperationState.getOvsdbTerminationPointAugmentation(iid);
+        assertNotNull(optOvsdbTermPoint);
+        verify(briOperationState, times(1)).getBridgeTerminationPoint(any(InstanceIdentifier.class));
+        verify(briOperationState, times(1)).getBridgeNode(any(InstanceIdentifier.class));
+        assertTrue(optOvsdbTermPoint.equals(Optional.absent()));
+
+        TerminationPoint termPoint = mock(TerminationPoint.class);
+        Optional<TerminationPoint> termPntOptional = mock(Optional.class);
+        OvsdbTerminationPointAugmentation ovsdbTermPntAug = mock(OvsdbTerminationPointAugmentation.class);
+        PowerMockito.suppress(MemberMatcher.method(BridgeOperationalState.class, "getBridgeTerminationPoint", InstanceIdentifier.class));
+        when(briOperationState.getBridgeTerminationPoint(any(InstanceIdentifier.class))).thenReturn(termPntOptional);
+        when(termPntOptional.isPresent()).thenReturn(true);
+        when(termPntOptional.get()).thenReturn(termPoint);
+        when(termPoint.getAugmentation(OvsdbTerminationPointAugmentation.class)).thenReturn(ovsdbTermPntAug);
+        Optional<OvsdbTerminationPointAugmentation> ovsdbTermPointOpt = briOperationState.getOvsdbTerminationPointAugmentation(iid);
+        assertNotNull(ovsdbTermPointOpt);
+        assertTrue(ovsdbTermPointOpt.get() instanceof OvsdbTerminationPointAugmentation);
+    }
+
+    @Test
+    public void testGetControllerEntry() {
+        Optional<ControllerEntry> optController= briOperationState.getControllerEntry(iid);
+        verify(briOperationState, times(1)).getOvsdbBridgeAugmentation(any(InstanceIdentifier.class));
+        verify(briOperationState, times(1)).getBridgeNode(any(InstanceIdentifier.class));
+        assertNotNull(optController);
+        assertTrue(optController.equals(Optional.absent()));
+    }
+
+    @Test
+    public void testGetProtocolEntry() throws Exception {
+        Optional<ProtocolEntry> optProtocolEntry = briOperationState.getProtocolEntry(protocolEntry);
+        verify(briOperationState, times(1)).getOvsdbBridgeAugmentation(any(InstanceIdentifier.class));
+        verify(briOperationState, times(1)).getBridgeNode(any(InstanceIdentifier.class));
+        assertNotNull(optProtocolEntry);
+        assertTrue(optProtocolEntry.equals(Optional.absent()));
+    }
+}
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeRemovedCommandTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeRemovedCommandTest.java
new file mode 100644 (file)
index 0000000..8ab3705
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberMatcher;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@PrepareForTest(BridgeRemovedCommand.class)
+@RunWith(PowerMockRunner.class)
+public class BridgeRemovedCommandTest {
+
+    @Mock private BridgeRemovedCommand briRemovedCmd;
+    @Mock private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes;
+    @Mock private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> returnChanges;
+    @Mock private Set<InstanceIdentifier<OvsdbBridgeAugmentation>> removed;
+    @Mock private Map<InstanceIdentifier<OvsdbBridgeAugmentation>, OvsdbBridgeAugmentation> originals;
+
+    @Before
+    public void setUp() throws Exception {
+        briRemovedCmd = mock(BridgeRemovedCommand.class, Mockito.CALLS_REAL_METHODS);
+    }
+
+    @Test
+    public void testExecute() throws Exception {
+        TransactionBuilder transaction = mock( TransactionBuilder.class, Mockito.RETURNS_MOCKS);
+
+        PowerMockito.mockStatic(TransactUtils.class);
+        when(TransactUtils.extractRemoved(changes, OvsdbBridgeAugmentation.class)).thenReturn(removed);
+        when(TransactUtils.extractOriginal(changes, OvsdbBridgeAugmentation.class)).thenReturn(originals);
+
+        MemberModifier.suppress(MemberMatcher.method(BridgeRemovedCommand.class, "getChanges"));
+        when(briRemovedCmd.getChanges()).thenReturn(returnChanges);
+
+        briRemovedCmd.execute(transaction);
+        verify(briRemovedCmd, times(2)).getChanges();
+    }
+
+}
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeUpdateCommandTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/BridgeUpdateCommandTest.java
new file mode 100644 (file)
index 0000000..7f55397
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberMatcher;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+
+@PrepareForTest(BridgeUpdateCommand.class)
+@RunWith(PowerMockRunner.class)
+public class BridgeUpdateCommandTest {
+
+    @Mock private BridgeUpdateCommand briUpdatedCmd;
+    @Mock private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes;
+    @Mock private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> returnChanges;
+    @Mock private Map<InstanceIdentifier<OvsdbBridgeAugmentation>, OvsdbBridgeAugmentation> created;
+    @Mock private Map<InstanceIdentifier<OvsdbBridgeAugmentation>, OvsdbBridgeAugmentation> updated;
+
+    @Before
+    public void setUp() throws Exception {
+        briUpdatedCmd = mock(BridgeUpdateCommand.class, Mockito.CALLS_REAL_METHODS);
+    }
+
+    @Test
+    public void testExecute() {
+        TransactionBuilder transaction = mock( TransactionBuilder.class, Mockito.RETURNS_MOCKS);
+
+        PowerMockito.mockStatic(TransactUtils.class);
+        when(TransactUtils.extractCreated(changes, OvsdbBridgeAugmentation.class)).thenReturn(created);
+        when(TransactUtils.extractUpdated(changes, OvsdbBridgeAugmentation.class)).thenReturn(updated);
+
+        MemberModifier.suppress(MemberMatcher.method(BridgeUpdateCommand.class, "getChanges"));
+        when(briUpdatedCmd.getChanges()).thenReturn(returnChanges);
+
+        briUpdatedCmd.execute(transaction);
+        verify(briUpdatedCmd, times(2)).getChanges();
+    }
+
+}
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/ControllerRemovedCommandTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/ControllerRemovedCommandTest.java
new file mode 100644 (file)
index 0000000..6cf1f86
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberMatcher;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@PrepareForTest(ControllerRemovedCommand.class)
+@RunWith(PowerMockRunner.class)
+public class ControllerRemovedCommandTest {
+
+    @Mock private ControllerRemovedCommand contRemoveCmd;
+    @Mock private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes;
+    @Mock private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> returnChanges;
+    @Mock private Set<InstanceIdentifier<ControllerEntry>> removed;
+    @Mock private Map<InstanceIdentifier<ControllerEntry>, ControllerEntry> operationalControllerEntries;
+    @Mock private Map<InstanceIdentifier<OvsdbBridgeAugmentation>, OvsdbBridgeAugmentation> created;
+    @Mock private Map<InstanceIdentifier<OvsdbBridgeAugmentation>, OvsdbBridgeAugmentation> updated;
+    @Before
+    public void setUp() throws Exception {
+        contRemoveCmd = mock(ControllerRemovedCommand.class, Mockito.CALLS_REAL_METHODS);
+    }
+
+    @Test
+    public void testExecute() throws Exception {
+        TransactionBuilder transaction = mock( TransactionBuilder.class, Mockito.RETURNS_MOCKS);
+
+        PowerMockito.mockStatic(TransactUtils.class);
+        when(TransactUtils.extractRemoved(changes, ControllerEntry.class)).thenReturn(removed);
+        when(TransactUtils.extractOriginal(changes, ControllerEntry.class)).thenReturn(operationalControllerEntries);
+        when(TransactUtils.extractCreated(changes, OvsdbBridgeAugmentation.class)).thenReturn(created);
+        when(TransactUtils.extractUpdated(changes, OvsdbBridgeAugmentation.class)).thenReturn(updated);
+
+        MemberModifier.suppress(MemberMatcher.method(ControllerRemovedCommand.class, "getChanges"));
+        when(contRemoveCmd.getChanges()).thenReturn(returnChanges);
+
+        contRemoveCmd.execute(transaction);
+        verify(contRemoveCmd, times(3)).getChanges();
+    }
+
+}
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/ControllerUpdateCommandTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/ControllerUpdateCommandTest.java
new file mode 100644 (file)
index 0000000..9d16d8b
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberMatcher;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@PrepareForTest(ControllerUpdateCommand.class)
+@RunWith(PowerMockRunner.class)
+public class ControllerUpdateCommandTest {
+
+    @Mock private ControllerUpdateCommand contUpdateCmd;
+    @Mock private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes;
+    @Mock private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> returnChanges;
+    @Mock private Map<InstanceIdentifier<ControllerEntry>, ControllerEntry> controllers;
+    @Mock private Map<InstanceIdentifier<OvsdbBridgeAugmentation>, OvsdbBridgeAugmentation> bridges;
+
+    @Before
+    public void setUp() throws Exception {
+        contUpdateCmd = mock(ControllerUpdateCommand.class, Mockito.CALLS_REAL_METHODS);
+    }
+
+    @Test
+    public void testExecute() {
+        TransactionBuilder transaction = mock( TransactionBuilder.class, Mockito.RETURNS_MOCKS);
+
+        PowerMockito.mockStatic(TransactUtils.class);
+        when(TransactUtils.extractCreated(changes, ControllerEntry.class)).thenReturn(controllers);
+        when(TransactUtils.extractUpdated(changes, OvsdbBridgeAugmentation.class)).thenReturn(bridges);
+
+        MemberModifier.suppress(MemberMatcher.method(ControllerUpdateCommand.class, "getChanges"));
+        when(contUpdateCmd.getChanges()).thenReturn(returnChanges);
+
+        contUpdateCmd.execute(transaction);
+        verify(contUpdateCmd, times(2)).getChanges();
+    }
+
+}
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/DataChangesManagedByOvsdbNodeEventTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/DataChangesManagedByOvsdbNodeEventTest.java
new file mode 100644 (file)
index 0000000..1d4b052
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.reflect.Whitebox;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest()
+public class DataChangesManagedByOvsdbNodeEventTest {
+
+    @Mock private InstanceIdentifier<?> iid;
+    @Mock private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> event;
+    private Set<InstanceIdentifier<?>> removedPaths;
+    private DataChangesManagedByOvsdbNodeEvent dataChangesManagedByOvsdbNodeEvent;
+
+    @Before
+    public void setUp() throws Exception {
+        dataChangesManagedByOvsdbNodeEvent = mock(DataChangesManagedByOvsdbNodeEvent.class, Mockito.CALLS_REAL_METHODS);
+        MemberModifier.field(DataChangesManagedByOvsdbNodeEvent.class, "event").set(dataChangesManagedByOvsdbNodeEvent, event);
+    }
+
+    @Test
+    public void testDataChangesManagedByOvsdbNodeEvent() {
+        DataChangesManagedByOvsdbNodeEvent dataChangesManagedByOvsdbNodeEvent1 = new DataChangesManagedByOvsdbNodeEvent(iid, event);
+        assertEquals(iid, Whitebox.getInternalState(dataChangesManagedByOvsdbNodeEvent1, "iid"));
+        assertEquals(event, Whitebox.getInternalState(dataChangesManagedByOvsdbNodeEvent1, "event"));
+    }
+
+    @Test
+    public void testGetMethods() {
+        Map<InstanceIdentifier<?>,DataObject> data = new HashMap<>();
+        DataObject dataObject = mock(DataObject.class);
+
+        //Test getCreatedData()
+        when(event.getCreatedData()).thenReturn(data);
+        assertEquals(data, dataChangesManagedByOvsdbNodeEvent.getCreatedData());
+
+        //Test getUpdatedData()
+        when(event.getUpdatedData()).thenReturn(data);
+        assertEquals(data, dataChangesManagedByOvsdbNodeEvent.getUpdatedData());
+
+        //Test getOriginalData()
+        when(event.getOriginalData()).thenReturn(data);
+        assertEquals(data, dataChangesManagedByOvsdbNodeEvent.getOriginalData());
+
+        //Test getOriginalSubtree()
+        when(event.getOriginalSubtree()).thenReturn(dataObject);
+        assertEquals(dataObject, dataChangesManagedByOvsdbNodeEvent.getOriginalSubtree());
+
+        //Test getUpdatedSubtree()
+        when(event.getUpdatedSubtree()).thenReturn(dataObject);
+        assertEquals(dataObject, dataChangesManagedByOvsdbNodeEvent.getUpdatedSubtree());
+
+        //Test getRemovedPaths()
+        removedPaths = new HashSet<>();
+        when(event.getRemovedPaths()).thenReturn(removedPaths);
+        assertEquals(removedPaths, dataChangesManagedByOvsdbNodeEvent.getRemovedPaths());
+    }
+}
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/OpenVSwitchBridgeAddCommandTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/OpenVSwitchBridgeAddCommandTest.java
new file mode 100644 (file)
index 0000000..6e086b6
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.opendaylight.ovsdb.lib.notation.Column;
+import org.opendaylight.ovsdb.lib.notation.Mutator;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.operations.Insert;
+import org.opendaylight.ovsdb.lib.operations.Mutate;
+import org.opendaylight.ovsdb.lib.operations.Operation;
+import org.opendaylight.ovsdb.lib.operations.Operations;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
+import org.opendaylight.ovsdb.schema.openvswitch.OpenVSwitch;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TyperUtils.class, TransactUtils.class})
+public class OpenVSwitchBridgeAddCommandTest {
+    private OpenVSwitchBridgeAddCommand openVSwitchBridgeAddCommand;
+
+    @Before
+    public void setUp() {
+        openVSwitchBridgeAddCommand = mock(OpenVSwitchBridgeAddCommand.class, Mockito.CALLS_REAL_METHODS);
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Test
+    public void testExecute() throws Exception {
+        TransactionBuilder transaction = mock(TransactionBuilder.class);
+        List<Operation> operations = new ArrayList<>();
+        when(transaction.getOperations()).thenReturn(operations);
+
+        Bridge bridge = mock(Bridge.class);
+        when(transaction.getDatabaseSchema()).thenReturn(mock(DatabaseSchema.class));
+        PowerMockito.mockStatic(TyperUtils.class);
+        PowerMockito.when(TyperUtils.getTypedRowWrapper(any(DatabaseSchema.class), eq(Bridge.class))).thenReturn(bridge);
+
+        List<Insert> inserts = new ArrayList<>();
+        Insert insert = mock(Insert.class);
+        inserts.add(insert);
+        PowerMockito.mockStatic(TransactUtils.class);
+        when(bridge.getSchema()).thenReturn(mock(GenericTableSchema.class));
+        PowerMockito.when(TransactUtils.extractInsert(any(TransactionBuilder.class), any(GenericTableSchema.class))).thenReturn(inserts);
+
+        OpenVSwitch ovs = mock(OpenVSwitch.class);
+        PowerMockito.when(TyperUtils.getTypedRowWrapper(any(DatabaseSchema.class), eq(OpenVSwitch.class))).thenReturn(ovs);
+        PowerMockito.when(TransactUtils.extractNamedUuid(any(Insert.class))).thenReturn(mock(UUID.class));
+        doNothing().when(ovs).setBridges(any(Set.class));
+
+        Mutate<GenericTableSchema> mutate = mock(Mutate.class);
+        Operations op = (Operations) setField("op");
+        when(op.mutate(any(OpenVSwitch.class))).thenReturn(mutate);
+        Column<GenericTableSchema, Set<UUID>> column = mock(Column.class);
+        when(ovs.getBridgesColumn()).thenReturn(column);
+        when(column.getSchema()).thenReturn(mock(ColumnSchema.class));
+        when(column.getData()).thenReturn(new HashSet<UUID>());
+        when(mutate.addMutation(any(ColumnSchema.class), any(Mutator.class), any(Set.class))).thenReturn(mutate);
+        when(transaction.add(any(Operation.class))).thenReturn(transaction);
+
+        openVSwitchBridgeAddCommand.execute(transaction);
+        verify(transaction).add(any(Operation.class));
+    }
+
+    private Object setField(String fieldName) throws Exception {
+        Field field = Operations.class.getDeclaredField(fieldName);
+        field.setAccessible(true);
+        field.set(field.get(Operations.class), mock(Operations.class));
+        return field.get(Operations.class);
+    }
+}
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/OvsdbNodeUpdateCommandTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/OvsdbNodeUpdateCommandTest.java
new file mode 100644 (file)
index 0000000..be1aa59
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.ovsdb.lib.notation.Column;
+import org.opendaylight.ovsdb.lib.operations.Mutate;
+import org.opendaylight.ovsdb.lib.operations.Operation;
+import org.opendaylight.ovsdb.lib.operations.Operations;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.openvswitch.OpenVSwitch;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchExternalIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberMatcher;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.google.common.collect.ImmutableMap;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TransactUtils.class, TyperUtils.class, OvsdbNodeUpdateCommand.class, InstanceIdentifier.class})
+public class OvsdbNodeUpdateCommandTest {
+
+    private static final String EXTERNAL_ID_KEY = "external id key";
+    private static final String EXTERNAL_ID_VALUE = "external id value";
+    private static final String OTHER_CONFIG_KEY = "other config key";
+    private static final String OTHER_CONFIG_VALUE = "other config value";
+
+    @Mock private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes;
+    private OvsdbNodeUpdateCommand ovsdbNodeUpdateCommand;
+
+    @Before
+    public void setUp() {
+        ovsdbNodeUpdateCommand = mock(OvsdbNodeUpdateCommand.class, Mockito.CALLS_REAL_METHODS);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testExecute() throws Exception {
+        TransactionBuilder transaction = mock(TransactionBuilder.class);
+        Map<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> updated = new HashMap<>();
+        InstanceIdentifier<OvsdbNodeAugmentation> iid = mock(InstanceIdentifier.class);
+        OvsdbNodeAugmentation ovsdbNode = mock(OvsdbNodeAugmentation.class);
+        updated.put(iid, ovsdbNode);
+        PowerMockito.mockStatic(TransactUtils.class);
+        PowerMockito.when(TransactUtils.extractCreatedOrUpdated(any(AsyncDataChangeEvent.class), eq(OvsdbNodeAugmentation.class))).thenReturn(updated);
+
+        ConnectionInfo connectionInfo = mock(ConnectionInfo.class);
+        when(ovsdbNode.getConnectionInfo()).thenReturn(connectionInfo);
+        when(connectionInfo.getRemoteIp()).thenReturn(mock(IpAddress.class));
+        when(connectionInfo.getRemotePort()).thenReturn(mock(PortNumber.class));
+
+        OpenVSwitch ovs = mock(OpenVSwitch.class);
+        when(transaction.getDatabaseSchema()).thenReturn(mock(DatabaseSchema.class));
+        PowerMockito.mockStatic(TyperUtils.class);
+        PowerMockito.when(TyperUtils.getTypedRowWrapper(any(DatabaseSchema.class), eq(OpenVSwitch.class))).thenReturn(ovs);
+
+        List<OpenvswitchExternalIds> externalIds = new ArrayList<>();
+        OpenvswitchExternalIds externalId = mock(OpenvswitchExternalIds.class);
+        externalIds.add(externalId);
+        when(externalId.getExternalIdKey()).thenReturn(EXTERNAL_ID_KEY);
+        when(externalId.getExternalIdValue()).thenReturn(EXTERNAL_ID_VALUE);
+        when(ovsdbNode.getOpenvswitchExternalIds()).thenReturn(externalIds);
+        PowerMockito.suppress(MemberMatcher.method(OvsdbNodeUpdateCommand.class, "stampInstanceIdentifier", TransactionBuilder.class, InstanceIdentifier.class));
+        PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(InstanceIdentifier.class));
+        doNothing().when(ovs).setExternalIds(any(ImmutableMap.class));
+
+        Mutate<GenericTableSchema> mutate = mock(Mutate.class);
+        Operations op = (Operations) setField("op");
+        Column<GenericTableSchema, Map<String, String>> column = mock(Column.class);
+        when(ovs.getExternalIdsColumn()).thenReturn(column);
+        when(column.getSchema()).thenReturn(mock(ColumnSchema.class));
+        when(column.getData()).thenReturn(new HashMap<String, String>());
+        when(op.mutate(any(OpenVSwitch.class))).thenReturn(mutate);
+        when(transaction.add(any(Operation.class))).thenReturn(transaction);
+
+        List<OpenvswitchOtherConfigs> otherConfigs = new ArrayList<>();
+        OpenvswitchOtherConfigs otherConfig = mock(OpenvswitchOtherConfigs.class);
+        otherConfigs.add(otherConfig);
+        when(ovsdbNode.getOpenvswitchOtherConfigs()).thenReturn(otherConfigs);
+        when(otherConfig.getOtherConfigKey()).thenReturn(OTHER_CONFIG_KEY);
+        when(otherConfig.getOtherConfigValue()).thenReturn(OTHER_CONFIG_VALUE);
+        doNothing().when(ovs).setOtherConfig(any(ImmutableMap.class));
+        when(ovs.getOtherConfigColumn()).thenReturn(column);
+
+        ovsdbNodeUpdateCommand.execute(transaction);
+        verify(externalId).getExternalIdKey();
+        verify(otherConfig).getOtherConfigKey();
+        verify(ovs, times(2)).getExternalIdsColumn();
+        verify(transaction, times(2)).add(any(Operation.class));
+    }
+
+    private Object setField(String fieldName) throws Exception {
+        Field field = Operations.class.getDeclaredField(fieldName);
+        field.setAccessible(true);
+        field.set(field.get(Operations.class), mock(Operations.class));
+        return field.get(Operations.class);
+    }
+}
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/ProtocolUpdateCommandTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/ProtocolUpdateCommandTest.java
new file mode 100644 (file)
index 0000000..776110f
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.ovsdb.lib.notation.Column;
+import org.opendaylight.ovsdb.lib.notation.Condition;
+import org.opendaylight.ovsdb.lib.notation.Mutator;
+import org.opendaylight.ovsdb.lib.operations.Mutate;
+import org.opendaylight.ovsdb.lib.operations.Operation;
+import org.opendaylight.ovsdb.lib.operations.Operations;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.operations.Where;
+import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow10;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberMatcher;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.reflect.Whitebox;
+
+import com.google.common.base.Optional;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({InstanceIdentifier.class, ProtocolUpdateCommand.class, TyperUtils.class})
+public class ProtocolUpdateCommandTest {
+    private static final String BRIDGE_NAME_COLUMN = null;
+    private Map<InstanceIdentifier<ProtocolEntry>, ProtocolEntry> protocols = new HashMap<>();
+    private ProtocolUpdateCommand protocolUpdateCommand;
+    @Mock private ProtocolEntry protocolEntry;
+
+    @SuppressWarnings("unchecked")
+    @Before
+    public void setUp() throws Exception {
+        protocolUpdateCommand = PowerMockito.mock(ProtocolUpdateCommand.class, Mockito.CALLS_REAL_METHODS);
+        protocols.put(mock(InstanceIdentifier.class), protocolEntry);
+        MemberModifier.field(ProtocolUpdateCommand.class, "protocols").set(protocolUpdateCommand, protocols);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testProtocolUpdateCommand() {
+        BridgeOperationalState state = mock(BridgeOperationalState.class);
+        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes = mock(AsyncDataChangeEvent.class);
+        ProtocolUpdateCommand protocolUpdateCommand1 = new ProtocolUpdateCommand(state, changes);
+        assertEquals(state, Whitebox.getInternalState(protocolUpdateCommand1, "operationalState"));
+        assertEquals(changes, Whitebox.getInternalState(protocolUpdateCommand1, "changes"));
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testExecute() throws Exception {
+        TransactionBuilder transaction = mock(TransactionBuilder.class);
+
+        MemberModifier.suppress(MemberMatcher.method(ProtocolUpdateCommand.class, "getOperationalState"));
+        BridgeOperationalState bridgeOpState = mock(BridgeOperationalState.class);
+        when(protocolUpdateCommand.getOperationalState()).thenReturn(bridgeOpState);
+        Optional<ProtocolEntry> operationalProtocolEntryOptional = mock(Optional.class);
+        when(bridgeOpState.getProtocolEntry(any(InstanceIdentifier.class))).thenReturn(operationalProtocolEntryOptional);
+
+        when(operationalProtocolEntryOptional.isPresent()).thenReturn(false);
+        PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(InstanceIdentifier.class));
+
+        Optional<OvsdbBridgeAugmentation> bridgeOptional = mock(Optional.class);
+        when(bridgeOpState.getOvsdbBridgeAugmentation(any(InstanceIdentifier.class))).thenReturn(bridgeOptional);
+        OvsdbBridgeAugmentation ovsdbBridge= mock(OvsdbBridgeAugmentation.class);
+        when(bridgeOptional.isPresent()).thenReturn(true);
+        when(bridgeOptional.get()).thenReturn(ovsdbBridge);
+
+        OvsdbBridgeName ovsdbBridgeName = mock(OvsdbBridgeName.class);
+        when(ovsdbBridge.getBridgeName()).thenReturn(ovsdbBridgeName);
+        when(protocolEntry.getProtocol()).thenAnswer(new Answer<Class<? extends OvsdbBridgeProtocolBase>>() {
+            public Class<? extends OvsdbBridgeProtocolBase> answer(
+                    InvocationOnMock invocation) throws Throwable {
+                return OvsdbBridgeProtocolOpenflow10.class;
+            }
+        });
+
+        Bridge bridge= mock(Bridge.class);
+        PowerMockito.mockStatic(TyperUtils.class);
+        when(transaction.getDatabaseSchema()).thenReturn(mock(DatabaseSchema.class));
+        when(TyperUtils.getTypedRowWrapper(any(DatabaseSchema.class), eq(Bridge.class))).thenReturn(bridge);
+        doNothing().when(bridge).setName(anyString());
+        doNothing().when(bridge).setProtocols(any(Set.class));
+
+        Operations op = (Operations) setField("op");
+        Mutate<GenericTableSchema> mutate = mock(Mutate.class);
+        when(op.mutate(any(Bridge.class))).thenReturn(mutate);
+        Column<GenericTableSchema, Set<String>> column = mock(Column.class);
+        when(bridge.getProtocolsColumn()).thenReturn(column);
+        when(column.getSchema()).thenReturn(mock(ColumnSchema.class));
+        when(column.getData()).thenReturn(new HashSet<String>());
+        when(mutate.addMutation(any(ColumnSchema.class), any(Mutator.class), any(Set.class))).thenReturn(mutate);
+
+        Column<GenericTableSchema, String> nameColumn = mock(Column.class);
+        when(bridge.getNameColumn()).thenReturn(nameColumn);
+        when(nameColumn.getData()).thenReturn(BRIDGE_NAME_COLUMN);
+        ColumnSchema<GenericTableSchema, String> columnSchema = mock(ColumnSchema.class);
+        when(nameColumn.getSchema()).thenReturn(columnSchema);
+        when(columnSchema.opEqual(anyString())).thenReturn(mock(Condition.class));
+        Where where = mock(Where.class);
+        when(mutate.where(any(Condition.class))).thenReturn(where);
+        when(where.build()).thenReturn(mock(Operation.class));
+        when(transaction.add(any(Operation.class))).thenReturn(transaction);
+
+        protocolUpdateCommand.execute(transaction);
+        verify(transaction).add(any(Operation.class));
+    }
+
+    private Object setField(String fieldName) throws Exception {
+        Field field = Operations.class.getDeclaredField(fieldName);
+        field.setAccessible(true);
+        field.set(field.get(Operations.class), mock(Operations.class));
+        return field.get(Operations.class);
+    }
+}
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TerminationPointCreateCommandTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TerminationPointCreateCommandTest.java
new file mode 100644 (file)
index 0000000..d32f3f4
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+import static org.junit.Assert.*;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.ovsdb.lib.notation.Column;
+import org.opendaylight.ovsdb.lib.notation.Condition;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.operations.Insert;
+import org.opendaylight.ovsdb.lib.operations.Mutate;
+import org.opendaylight.ovsdb.lib.operations.Operation;
+import org.opendaylight.ovsdb.lib.operations.Operations;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.operations.Where;
+import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
+import org.opendaylight.ovsdb.schema.openvswitch.Interface;
+import org.opendaylight.ovsdb.schema.openvswitch.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberMatcher;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.google.common.base.Optional;
+
+@PrepareForTest({TyperUtils.class, TransactUtils.class, TerminationPointCreateCommand.class})
+@RunWith(PowerMockRunner.class)
+public class TerminationPointCreateCommandTest {
+
+    private static final String INTERFACE_NAME = "eth0";
+    private static final String TERMINATION_POINT_NAME = "termination point name";
+    private TerminationPointCreateCommand terminationPointCreateCommand;
+
+    @Before
+    public void setUp() {
+        terminationPointCreateCommand = mock(TerminationPointCreateCommand.class, Mockito.CALLS_REAL_METHODS);
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes"})
+    @Test
+    public void testExecute() throws Exception {
+        TransactionBuilder transaction = mock(TransactionBuilder.class);
+        MemberModifier.suppress(MemberMatcher.method(TerminationPointCreateCommand.class, "getChanges"));
+        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> asynEvent = mock(AsyncDataChangeEvent.class);
+        when(terminationPointCreateCommand.getChanges()).thenReturn(asynEvent);
+        Map<InstanceIdentifier<?>, DataObject> map = new HashMap<>();
+        OvsdbTerminationPointAugmentation terminationPoint= mock(OvsdbTerminationPointAugmentation.class);
+        InstanceIdentifier terminationPointIid = mock(InstanceIdentifier.class);
+        map.put(terminationPointIid, terminationPoint);
+        when(asynEvent.getCreatedData()).thenReturn(map);
+        when(terminationPoint.getName()).thenReturn(TERMINATION_POINT_NAME);
+
+        Optional<TerminationPoint> terminationPointOptional= mock(Optional.class);
+        MemberModifier.suppress(MemberMatcher.method(TerminationPointCreateCommand.class, "getOperationalState"));
+        BridgeOperationalState bridgeOpState = mock(BridgeOperationalState.class);
+        when(terminationPointCreateCommand.getOperationalState()).thenReturn(bridgeOpState);
+        when(bridgeOpState.getBridgeTerminationPoint(any(InstanceIdentifier.class))).thenReturn(terminationPointOptional);
+
+        when(terminationPointOptional.isPresent()).thenReturn(true);
+        Interface ovsInterface = mock(Interface.class);
+        PowerMockito.mockStatic(TyperUtils.class);
+        when(transaction.getDatabaseSchema()).thenReturn(mock(DatabaseSchema.class));
+        when(TyperUtils.getTypedRowWrapper(any(DatabaseSchema.class), eq(Interface.class))).thenReturn(ovsInterface);
+        //createInterface()
+        Operations op = (Operations) setField("op");
+        Insert<GenericTableSchema> insert = mock(Insert.class);
+        when(op.insert(any(Interface.class))).thenReturn(insert);
+        when(insert.withId(anyString())).thenReturn(insert);
+        MemberModifier.suppress(MemberMatcher.method(TerminationPointCreateCommand.class,
+                "stampInstanceIdentifier", TransactionBuilder.class, InstanceIdentifier.class, String.class));
+        when(ovsInterface.getName()).thenReturn(INTERFACE_NAME);
+
+        Port port = mock(Port.class);
+        when(TyperUtils.getTypedRowWrapper(any(DatabaseSchema.class), eq(Port.class))).thenReturn(port);
+        when(op.insert(any(Port.class))).thenReturn(insert);
+
+        Bridge bridge = mock(Bridge.class);
+        when(TyperUtils.getTypedRowWrapper(any(DatabaseSchema.class), eq(Bridge.class))).thenReturn(bridge);
+        doNothing().when(bridge).setName(anyString());
+        PowerMockito.whenNew(UUID.class).withAnyArguments().thenReturn(mock(UUID.class));
+        doNothing().when(bridge).setPorts(any(HashSet.class));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testStampInstanceIdentifier() {
+        TransactionBuilder transaction = mock(TransactionBuilder.class);
+        InstanceIdentifier<TerminationPoint> iid = mock(InstanceIdentifier.class);
+        String interfaceName = INTERFACE_NAME;
+
+        when(transaction.getDatabaseSchema()).thenReturn(mock(DatabaseSchema.class));
+        PowerMockito.mockStatic(TyperUtils.class);
+        Port port = mock(Port.class);
+        PowerMockito.when(TyperUtils.getTypedRowWrapper(any(DatabaseSchema.class), eq(Port.class))).thenReturn(port);
+        doNothing().when(port).setName(anyString());
+        doNothing().when(port).setExternalIds(any(HashMap.class));
+        when(port.getSchema()).thenReturn(mock(GenericTableSchema.class));
+        Column<GenericTableSchema, Map<String, String>> column = mock(Column.class);
+        when(port.getExternalIdsColumn()).thenReturn(column);
+        when(column.getSchema()).thenReturn(mock(ColumnSchema.class));
+
+        Mutate mutate = mock(Mutate.class);
+        PowerMockito.mockStatic(TransactUtils.class);
+        when(TransactUtils.stampInstanceIdentifierMutation(
+                any(TransactionBuilder.class), any(InstanceIdentifier.class), any(GenericTableSchema.class), any(ColumnSchema.class))).thenReturn(mutate);
+
+        Column<GenericTableSchema, String> nameColumn = mock(Column.class);
+        when(port.getNameColumn()).thenReturn(nameColumn);
+        ColumnSchema<GenericTableSchema, String> nameColumnSchema = mock(ColumnSchema.class);
+        when(nameColumn.getSchema()).thenReturn(nameColumnSchema);
+        when(nameColumnSchema.opEqual(anyString())).thenReturn(mock(Condition.class));
+        Where where = mock(Where.class);
+        when(mutate.where(any(Condition.class))).thenReturn(where);
+        when(where.build()).thenReturn(mock(Operation.class));
+        when(transaction.add(any(Operation.class))).thenReturn(transaction);
+
+        TerminationPointCreateCommand.stampInstanceIdentifier(transaction, iid, interfaceName);
+        verify(port).setName(anyString());
+        verify(port).getExternalIdsColumn();
+        verify(transaction).add(any(Operation.class));
+    }
+
+    private Object setField(String fieldName) throws Exception {
+        Field field = Operations.class.getDeclaredField(fieldName);
+        field.setAccessible(true);
+        field.set(field.get(Operations.class), mock(Operations.class));
+        return field.get(Operations.class);
+    }
+}
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TerminationPointDeleteCommandTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TerminationPointDeleteCommandTest.java
new file mode 100644 (file)
index 0000000..d1644bd
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TransactUtils.class, TerminationPointDeleteCommand.class, TyperUtils.class})
+public class TerminationPointDeleteCommandTest {
+
+    private TerminationPointDeleteCommand terminationPointDeleteCommand;
+    @Mock private BridgeOperationalState state;
+    @Mock private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes;
+    private Map<InstanceIdentifier<OvsdbTerminationPointAugmentation>, OvsdbTerminationPointAugmentation> originals = new HashMap<>();
+    private Map<InstanceIdentifier<Node>, Node> originalNodes = new HashMap<>();
+    private Set<InstanceIdentifier<OvsdbTerminationPointAugmentation>> removedTps = new HashSet<>();
+
+    @Before
+    public void setUp() throws Exception {
+        terminationPointDeleteCommand = mock(TerminationPointDeleteCommand.class, Mockito.CALLS_REAL_METHODS);
+        MemberModifier.field(TerminationPointDeleteCommand.class, "operationalState").set(terminationPointDeleteCommand, state);
+        MemberModifier.field(TerminationPointDeleteCommand.class, "changes").set(terminationPointDeleteCommand, changes);
+    }
+
+    @Test
+    public void testExecute() {
+        TransactionBuilder transaction = mock(TransactionBuilder.class);
+        PowerMockito.mockStatic(TransactUtils.class);
+        when(TransactUtils.extractOriginal(changes, OvsdbTerminationPointAugmentation.class)).thenReturn(originals);
+        when(TransactUtils.extractOriginal(changes, Node.class)).thenReturn(originalNodes);
+        when(TransactUtils.extractRemoved(changes, OvsdbTerminationPointAugmentation.class)).thenReturn(removedTps);
+        terminationPointDeleteCommand.execute(transaction);
+        verify(terminationPointDeleteCommand, times(3)).getChanges();
+    }
+}
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TerminationPointUpdateCommandTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TerminationPointUpdateCommandTest.java
new file mode 100644 (file)
index 0000000..58174e2
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.ovsdb.lib.notation.Column;
+import org.opendaylight.ovsdb.lib.notation.Condition;
+import org.opendaylight.ovsdb.lib.operations.Operation;
+import org.opendaylight.ovsdb.lib.operations.Operations;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.operations.Update;
+import org.opendaylight.ovsdb.lib.operations.Where;
+import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.openvswitch.Interface;
+import org.opendaylight.ovsdb.schema.openvswitch.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberMatcher;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.reflect.Whitebox;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TerminationPointUpdateCommand.class, TransactUtils.class, TyperUtils.class, VlanMode.class, TerminationPointCreateCommand.class, InstanceIdentifier.class})
+public class TerminationPointUpdateCommandTest {
+
+    private static final String TERMINATION_POINT_NAME = "termination point name";
+    private TerminationPointUpdateCommand terminationPointUpdateCommand;
+
+    @Before
+    public void setUp() {
+        terminationPointUpdateCommand = mock(TerminationPointUpdateCommand.class, Mockito.CALLS_REAL_METHODS);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testTerminationPointUpdateCommand() {
+        BridgeOperationalState state = mock(BridgeOperationalState.class);
+        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes = mock(AsyncDataChangeEvent.class);
+        TerminationPointUpdateCommand terminationPointUpdateCommand1 = new TerminationPointUpdateCommand(state, changes);
+        assertEquals(state, Whitebox.getInternalState(terminationPointUpdateCommand1, "operationalState"));
+        assertEquals(changes, Whitebox.getInternalState(terminationPointUpdateCommand1, "changes"));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testExecute() {
+        Map<InstanceIdentifier<OvsdbTerminationPointAugmentation>, OvsdbTerminationPointAugmentation> created = new HashMap<>();
+        created.put(mock(InstanceIdentifier.class), mock(OvsdbTerminationPointAugmentation.class));
+        PowerMockito.mockStatic(TransactUtils.class);
+        MemberModifier.suppress(MemberMatcher.method(TerminationPointUpdateCommand.class, "getChanges"));
+        when(terminationPointUpdateCommand.getChanges()).thenReturn(mock(AsyncDataChangeEvent.class));
+        PowerMockito.when(TransactUtils.extractCreated(any(AsyncDataChangeEvent.class), eq(OvsdbTerminationPointAugmentation.class))).thenReturn(created);
+        MemberModifier.suppress(MemberMatcher.method(TerminationPointUpdateCommand.class, "updateTerminationPoint",
+                TransactionBuilder.class, InstanceIdentifier.class, OvsdbTerminationPointAugmentation.class));
+        doNothing().when(terminationPointUpdateCommand)
+                .updateTerminationPoint(any(TransactionBuilder.class), any(InstanceIdentifier.class), any(OvsdbTerminationPointAugmentation.class));
+
+        Map<InstanceIdentifier<OvsdbTerminationPointAugmentation>, OvsdbTerminationPointAugmentation> updated = new HashMap<>();
+        updated.put(mock(InstanceIdentifier.class), mock(OvsdbTerminationPointAugmentation.class));
+        PowerMockito.when(TransactUtils.extractUpdated(any(AsyncDataChangeEvent.class), eq(OvsdbTerminationPointAugmentation.class))).thenReturn(updated);
+
+        TransactionBuilder transactionBuilder = mock(TransactionBuilder.class);
+        terminationPointUpdateCommand.execute(transactionBuilder);
+        verify(terminationPointUpdateCommand, times(2)).
+                updateTerminationPoint(any(TransactionBuilder.class), any(InstanceIdentifier.class), any(OvsdbTerminationPointAugmentation.class));
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Test
+    public void testUpdateTerminationPoint() throws Exception {
+        TransactionBuilder transaction = mock(TransactionBuilder.class);
+        InstanceIdentifier<OvsdbTerminationPointAugmentation> iid = mock(InstanceIdentifier.class);
+        OvsdbTerminationPointAugmentation terminationPoint = mock(OvsdbTerminationPointAugmentation.class);
+        when(terminationPoint.getName()).thenReturn(TERMINATION_POINT_NAME);
+
+        // Test updateInterface()
+        Interface ovsInterface = mock(Interface.class);
+        when(transaction.getDatabaseSchema()).thenReturn(mock(DatabaseSchema.class));
+        PowerMockito.mockStatic(TyperUtils.class);
+        when(TyperUtils.getTypedRowWrapper(any(DatabaseSchema.class), eq(Interface.class))).thenReturn(ovsInterface);
+
+        Interface extraInterface = mock(Interface.class);
+        when(TyperUtils.getTypedRowWrapper(any(DatabaseSchema.class), eq(Interface.class))).thenReturn(extraInterface);
+        doNothing().when(extraInterface).setName(anyString());
+
+        Operations op = (Operations) setField("op");
+        Update update = mock(Update.class);
+        when(op.update(any(Interface.class))).thenReturn(update);
+
+        Column<GenericTableSchema, String> column = mock(Column.class);
+        when(extraInterface.getNameColumn()).thenReturn(column);
+        ColumnSchema<GenericTableSchema, String> columnSchema = mock(ColumnSchema.class);
+        when(column.getSchema()).thenReturn(columnSchema);
+        when(columnSchema.opEqual(anyString())).thenReturn(mock(Condition.class));
+        Where where = mock(Where.class);
+        when(update.where(any(Condition.class))).thenReturn(where);
+        when(where.build()).thenReturn(mock(Operation.class));
+        when(transaction.add(any(Operation.class))).thenReturn(transaction);
+        PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(TerminationPointCreateCommand.class));
+        PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(InstanceIdentifier.class));
+
+        // Test updatePort()
+        Port port = mock(Port.class);
+        when(TyperUtils.getTypedRowWrapper(any(DatabaseSchema.class), eq(Port.class))).thenReturn(port);
+        Port extraPort = mock(Port.class);
+        when(TyperUtils.getTypedRowWrapper(any(DatabaseSchema.class), eq(Port.class))).thenReturn(extraPort);
+        doNothing().when(extraPort).setName(anyString());
+        when(op.update(any(Port.class))).thenReturn(update);
+        when(extraPort.getNameColumn()).thenReturn(column);
+
+        terminationPointUpdateCommand.updateTerminationPoint(transaction, iid, terminationPoint);
+        verify(transaction, times(2)).add(any(Operation.class));
+    }
+
+    private Object setField(String fieldName) throws Exception {
+        Field field = Operations.class.getDeclaredField(fieldName);
+        field.setAccessible(true);
+        field.set(field.get(Operations.class), mock(Operations.class));
+        return field.get(Operations.class);
+    }
+}
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactCommandAggregatorTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactCommandAggregatorTest.java
new file mode 100644 (file)
index 0000000..d1870fd
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.reflect.Whitebox;
+
+@PrepareForTest({})
+@RunWith(PowerMockRunner.class)
+public class TransactCommandAggregatorTest {
+    private static final int NUMBER_OF_COMMANDS = 11;
+    private List<TransactCommand> commands = new ArrayList<>();
+    private TransactCommandAggregator transactCommandAggregator;
+    @Mock private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes;
+    @Mock private BridgeOperationalState operationalState;
+
+    @Before
+    public void setUp() throws Exception {
+        transactCommandAggregator = PowerMockito.mock(TransactCommandAggregator.class, Mockito.CALLS_REAL_METHODS);
+
+        //mock commands field
+        commands.add(mock(BridgeUpdateCommand.class));
+        commands.add(mock(OpenVSwitchBridgeAddCommand.class));
+        commands.add(mock(ControllerUpdateCommand.class));
+        commands.add(mock(ControllerRemovedCommand.class));
+        commands.add(mock(ProtocolUpdateCommand.class));
+        commands.add(mock(ProtocolRemovedCommand.class));
+        commands.add(mock(BridgeRemovedCommand.class));
+        commands.add(mock(TerminationPointCreateCommand.class));
+        commands.add(mock(TerminationPointDeleteCommand.class));
+        commands.add(mock(OvsdbNodeUpdateCommand.class));
+        commands.add(mock(TerminationPointUpdateCommand.class));
+        MemberModifier.field(TransactCommandAggregator.class, "commands").set(transactCommandAggregator, commands);
+    }
+
+    @Test
+    public void testOvsdbOperationalCommandAggregator() throws Exception {
+        TransactCommandAggregator transactCommandAggregator1 = new TransactCommandAggregator(operationalState, changes);
+        List<TransactCommand> testCommands = Whitebox.getInternalState(transactCommandAggregator1, "commands");
+        assertEquals(NUMBER_OF_COMMANDS, testCommands.size());
+    }
+
+    @Test
+    public void testExecute() {
+        TransactionBuilder transaction = mock(TransactionBuilder.class);
+        for (TransactCommand command: commands) {
+            doNothing().when(command).execute(any(TransactionBuilder.class));
+        }
+        transactCommandAggregator.execute(transaction);
+        for (TransactCommand command: commands) {
+            verify(command).execute(any(TransactionBuilder.class));
+        }
+    }
+}
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactInvokerImplTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactInvokerImplTest.java
new file mode 100644 (file)
index 0000000..e867ca1
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.ovsdb.lib.operations.Operation;
+import org.opendaylight.ovsdb.lib.operations.OperationResult;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.reflect.Whitebox;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+@PrepareForTest({TransactInvokerImpl.class})
+@RunWith(PowerMockRunner.class)
+public class TransactInvokerImplTest {
+    @Mock private OvsdbConnectionInstance connectionInstance;
+    @Mock private DatabaseSchema dbSchema;
+    private TransactInvokerImpl transactInvokerImpl;
+
+    @Before
+    public void setUp() throws Exception {
+        transactInvokerImpl = PowerMockito.mock(TransactInvokerImpl.class, Mockito.CALLS_REAL_METHODS);
+        MemberModifier.field(TransactInvokerImpl.class, "connectionInstance").set(transactInvokerImpl, connectionInstance);
+        MemberModifier.field(TransactInvokerImpl.class, "dbSchema").set(transactInvokerImpl, dbSchema);
+    }
+
+    @Test
+    public void testTransactionInvokerImpl() {
+        TransactInvokerImpl transactInvokerImpl1 = new TransactInvokerImpl(connectionInstance, dbSchema);
+        assertEquals(connectionInstance, Whitebox.getInternalState(transactInvokerImpl1, "connectionInstance"));
+        assertEquals(dbSchema, Whitebox.getInternalState(transactInvokerImpl1, "dbSchema"));
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Test
+    public void testInvoke() throws Exception {
+        TransactCommand command = mock(TransactCommand.class);
+        TransactionBuilder tb = mock(TransactionBuilder.class);
+        PowerMockito.whenNew(TransactionBuilder.class).withAnyArguments().thenReturn(tb);
+        doNothing().when(command).execute(any(TransactionBuilder.class));
+
+        ListenableFuture<List<OperationResult>> result = mock(ListenableFuture.class);
+        when(tb.execute()).thenReturn(result);
+        List<Operation> operation = new ArrayList<>();
+        operation.add(mock(Operation.class));
+        when(tb.getOperations()).thenReturn(operation);
+        List<OperationResult> got = new ArrayList<>();
+        when(result.get()).thenReturn(got);
+        transactInvokerImpl.invoke(command);
+        verify(result).get();
+    }
+}
diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactUtilsTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/ovsdb/transact/TransactUtilsTest.java
new file mode 100644 (file)
index 0000000..e361c24
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.southbound.ovsdb.transact;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.ovsdb.lib.notation.Mutation;
+import org.opendaylight.ovsdb.lib.notation.Mutator;
+import org.opendaylight.ovsdb.lib.notation.OvsdbSet;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.operations.Insert;
+import org.opendaylight.ovsdb.lib.operations.Mutate;
+import org.opendaylight.ovsdb.lib.operations.Operation;
+import org.opendaylight.ovsdb.lib.operations.Operations;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+import org.opendaylight.ovsdb.lib.schema.TableSchema;
+import org.opendaylight.ovsdb.southbound.SouthboundMapper;
+import org.opendaylight.ovsdb.southbound.SouthboundUtil;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberMatcher;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.Maps;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TransactUtils.class, SouthboundMapper.class, SouthboundUtil.class, OvsdbSet.class, Operations.class})
+public class TransactUtilsTest {
+
+    private static final String UUID_NAME = "uuid name";
+    private static final String IID_STRING = "iid string";
+    private static final String COLUMN_SCHEMA_NAME = "column schema name";
+
+    @Before
+    public void setUp() {
+        PowerMockito.mockStatic(TransactUtils.class, Mockito.CALLS_REAL_METHODS);
+    }
+
+    @Test
+    public void testExtractNode() {
+        Map<InstanceIdentifier<?>, DataObject> changes = new HashMap<>();
+        assertEquals(HashMap.class, TransactUtils.extractNode(changes).getClass());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testExtractCreatedAndExtractUpdated() {
+        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes = mock(AsyncDataChangeEvent.class);
+        Class<DataObject> klazz = DataObject.class;
+        Map<InstanceIdentifier<?>, DataObject> map = new HashMap<>();
+        when(changes.getCreatedData()).thenReturn(map);
+        when(TransactUtils.extract(any(Map.class),eq(DataObject.class))).thenReturn(map);
+
+        //test extractCreated()
+        assertEquals(map, TransactUtils.extractCreated(changes, klazz));
+
+        //test extractUpdated()
+        assertEquals(map, TransactUtils.extractUpdated(changes, klazz));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testExtractCreatedOrUpdated() {
+        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes = mock(AsyncDataChangeEvent.class);
+        Class<DataObject> klazz = DataObject.class;
+        Map<InstanceIdentifier<DataObject>, DataObject> result = new HashMap<>();
+
+        PowerMockito.suppress(MemberMatcher.method(TransactUtils.class, "extractUpdated", AsyncDataChangeEvent.class, Class.class));
+        PowerMockito.when(TransactUtils.extractUpdated(any(AsyncDataChangeEvent.class),eq(DataObject.class))).thenReturn(result);
+
+        Map<InstanceIdentifier<DataObject>, DataObject> map = new HashMap<>();
+        InstanceIdentifier<DataObject> iid = mock(InstanceIdentifier.class);
+        DataObject db = mock(DataObject.class);
+        map.put(iid, db);
+        PowerMockito.suppress(MemberMatcher.method(TransactUtils.class, "extractCreated", AsyncDataChangeEvent.class, Class.class));
+        PowerMockito.when(TransactUtils.extractCreated(any(AsyncDataChangeEvent.class),eq(DataObject.class))).thenReturn(map);
+
+        Map<InstanceIdentifier<DataObject>, DataObject> testResult = new HashMap<>();
+        testResult.put(iid, db);
+        assertEquals(testResult, TransactUtils.extractCreatedOrUpdated(changes, klazz));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testExtractCreatedOrUpdatedOrRemoved() {
+        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes = mock(AsyncDataChangeEvent.class);
+        Class<DataObject> klazz = DataObject.class;
+        Map<InstanceIdentifier<DataObject>, DataObject> result = new HashMap<>();
+
+        PowerMockito.suppress(MemberMatcher.method(TransactUtils.class, "extractCreatedOrUpdated", AsyncDataChangeEvent.class, Class.class));
+        PowerMockito.when(TransactUtils.extractCreatedOrUpdated(any(AsyncDataChangeEvent.class),eq(DataObject.class))).thenReturn(result);
+
+        Map<InstanceIdentifier<DataObject>, DataObject> map = new HashMap<>();
+        InstanceIdentifier<DataObject> iid = mock(InstanceIdentifier.class);
+        DataObject db = mock(DataObject.class);
+        map.put(iid, db);
+        PowerMockito.suppress(MemberMatcher.method(TransactUtils.class, "extractRemovedObjects", AsyncDataChangeEvent.class, Class.class));
+        PowerMockito.when(TransactUtils.extractRemovedObjects(any(AsyncDataChangeEvent.class),eq(DataObject.class))).thenReturn(map);
+
+        Map<InstanceIdentifier<DataObject>, DataObject> testResult = new HashMap<>();
+        testResult.put(iid, db);
+        assertEquals(testResult, TransactUtils.extractCreatedOrUpdatedOrRemoved(changes, klazz));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testExtractOriginal() {
+        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes = mock(AsyncDataChangeEvent.class);
+        Class<DataObject> klazz = DataObject.class;
+        Map<InstanceIdentifier<?>, DataObject> map = new HashMap<>();
+        when(changes.getOriginalData()).thenReturn(map);
+        when(TransactUtils.extract(any(Map.class),eq(DataObject.class))).thenReturn(map);
+
+        //test extractOriginal()
+        assertEquals(map, TransactUtils.extractCreated(changes, klazz));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testExtractRemoved() {
+        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes = mock(AsyncDataChangeEvent.class);
+        Class<DataObject> klazz = DataObject.class;
+        assertEquals(HashSet.class, TransactUtils.extractRemoved(changes, klazz).getClass());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testExtractRemovedObjects() {
+        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes = mock(AsyncDataChangeEvent.class);
+        Class<DataObject> klazz = DataObject.class;
+        Set<InstanceIdentifier<DataObject>> iids = new HashSet<>();
+        PowerMockito.suppress(MemberMatcher.method(TransactUtils.class, "extractRemoved", AsyncDataChangeEvent.class, Class.class));
+        PowerMockito.when(TransactUtils.extractRemoved(any(AsyncDataChangeEvent.class),eq(DataObject.class))).thenReturn(iids);
+
+        Map<InstanceIdentifier<DataObject>, DataObject> result = new HashMap<>();
+        PowerMockito.suppress(MemberMatcher.method(TransactUtils.class, "extractOriginal", AsyncDataChangeEvent.class, Class.class));
+        PowerMockito.when(TransactUtils.extractOriginal(any(AsyncDataChangeEvent.class),eq(DataObject.class))).thenReturn(result);
+        assertEquals(Maps.filterKeys(result, Predicates.in(iids)), TransactUtils.extractRemovedObjects(changes, klazz));
+    }
+
+    @Test
+    public void testExtract() {
+        Map<InstanceIdentifier<?>, DataObject> changes = new HashMap<>();
+        Class<DataObject> klazz = DataObject.class;
+        assertEquals(HashMap.class, TransactUtils.extract(changes, klazz).getClass());
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Test
+    public void testExtractInsert() {
+        TransactionBuilder transaction = mock(TransactionBuilder.class);
+        GenericTableSchema schema = mock(GenericTableSchema.class);
+
+        List<Operation> operations = new ArrayList<>();
+        Operation operation = mock(Insert.class);
+        operations.add(operation);
+        when(transaction.getOperations()).thenReturn(operations);
+        when(operation.getTableSchema()).thenReturn(schema);
+
+        List<Insert> inserts = TransactUtils.extractInsert(transaction, schema);
+        assertEquals(operation, inserts.get(0));
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Test
+    public void testExtractNamedUuid() throws Exception {
+        Insert insert = mock(Insert.class);
+        when(insert.getUuidName()).thenReturn(UUID_NAME);
+        PowerMockito.mockStatic(SouthboundMapper.class);
+        PowerMockito.when(SouthboundMapper.getRandomUUID()).thenReturn(UUID_NAME);
+        doNothing().when(insert).setUuidName(anyString());
+
+        UUID uuid = mock(UUID.class);
+        PowerMockito.whenNew(UUID.class).withAnyArguments().thenReturn(uuid);
+        assertEquals(uuid, TransactUtils.extractNamedUuid(insert));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testStampInstanceIdentifier() {
+        TransactionBuilder transaction = mock(TransactionBuilder.class);
+        InstanceIdentifier<?> iid = mock(InstanceIdentifier.class);
+        TableSchema<GenericTableSchema> tableSchema = mock(TableSchema.class);
+        ColumnSchema<GenericTableSchema, Map<String,String>> columnSchema = mock(ColumnSchema.class);
+
+        PowerMockito.suppress(MemberMatcher.method(TransactUtils.class, "stampInstanceIdentifierMutation",
+                TransactionBuilder.class,
+                InstanceIdentifier.class,
+                TableSchema.class,
+                ColumnSchema.class));
+        when(TransactUtils.stampInstanceIdentifierMutation(transaction, iid, tableSchema, columnSchema)).thenReturn(mock(Mutate.class));
+        when(transaction.add(any(Operation.class))).thenReturn(transaction);
+        TransactUtils.stampInstanceIdentifier(transaction, iid, tableSchema, columnSchema);
+        verify(transaction).add(any(Operation.class));
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    @Test
+    public void testStampInstanceIdentifierMutation() throws Exception {
+        TransactionBuilder transaction = mock(TransactionBuilder.class);
+        InstanceIdentifier<?> iid = mock(InstanceIdentifier.class);
+        TableSchema<GenericTableSchema> tableSchema = mock(TableSchema.class);
+        ColumnSchema<GenericTableSchema, Map<String,String>> columnSchema = mock(ColumnSchema.class);
+
+        PowerMockito.mockStatic(SouthboundUtil.class);
+        PowerMockito.when(SouthboundUtil.serializeInstanceIdentifier(any(InstanceIdentifier.class))).thenReturn(IID_STRING);
+
+        Mutate<GenericTableSchema> mutate = mock(Mutate.class);
+        Operations op = (Operations) setField("op");
+        when(op.mutate(any(TableSchema.class))).thenReturn(mutate);
+        when(mutate.addMutation(any(ColumnSchema.class), any(Mutator.class), any(Map.class))).thenReturn(mutate);
+
+        Mutation deleteIidMutation = mock(Mutation.class);
+        when(columnSchema.getName()).thenReturn(COLUMN_SCHEMA_NAME);
+        PowerMockito.mockStatic(OvsdbSet.class);
+        PowerMockito.when(OvsdbSet.fromSet(any(Set.class))).thenReturn(mock(OvsdbSet.class));
+        PowerMockito.whenNew(Mutation.class).withAnyArguments().thenReturn(deleteIidMutation);
+
+        List<Mutation> listMutations = new ArrayList<>();
+        when(mutate.getMutations()).thenReturn(listMutations);
+        doNothing().when(mutate).setMutations(any(List.class));
+        assertEquals(mutate, TransactUtils.stampInstanceIdentifierMutation(transaction, iid, tableSchema, columnSchema));
+    }
+
+    private Object setField(String fieldName) throws Exception {
+        Field field = Operations.class.getDeclaredField(fieldName);
+        field.setAccessible(true);
+        field.set(field.get(Operations.class), mock(Operations.class));
+        return field.get(Operations.class);
+    }
+}
index be5f1b20c5b446c7cad5da8c13f4ef206ecaccb2..5d74a23cdbc75854c231ef3980434ab0c22f83db 100644 (file)
@@ -87,12 +87,12 @@ public class OpenVSwitchUpdateCommandTest {
     @Test
     public void testExecute() throws Exception {
         PowerMockito.mockStatic(TyperUtils.class);
-        Map<UUID, OpenVSwitch> updatedOpenVSwitchRows = new HashMap<UUID, OpenVSwitch>();
+        Map<UUID, OpenVSwitch> updatedOpenVSwitchRows = new HashMap<>();
         UUID uuid = mock(UUID.class);
         OpenVSwitch ovs = mock(OpenVSwitch.class);
         updatedOpenVSwitchRows.put(uuid, ovs);
         when(TyperUtils.extractRowsUpdated(eq(OpenVSwitch.class), any(TableUpdates.class), any(DatabaseSchema.class))).thenReturn(updatedOpenVSwitchRows);
-        Map<UUID, OpenVSwitch> deletedOpenVSwitchRows = new HashMap<UUID, OpenVSwitch>();
+        Map<UUID, OpenVSwitch> deletedOpenVSwitchRows = new HashMap<>();
         OpenVSwitch ovs1 = mock(OpenVSwitch.class);
 
         deletedOpenVSwitchRows.put(uuid, ovs1);
@@ -104,7 +104,7 @@ public class OpenVSwitchUpdateCommandTest {
 
         //Test getInstanceIdentifier(): case 1: ovs.getExternalIdsColumn().getData().containsKey(SouthboundConstants.IID_EXTERNAL_ID_KEY)) == true
         Column<GenericTableSchema, Map<String, String>> column = mock(Column.class);
-        Map<String, String> map = new HashMap<String, String>();
+        Map<String, String> map = new HashMap<>();
         map.put(SouthboundConstants.IID_EXTERNAL_ID_KEY, "iidString");
         when(ovs.getExternalIdsColumn()).thenReturn(column);
         when(column.getData()).thenReturn(map);
@@ -164,7 +164,7 @@ public class OpenVSwitchUpdateCommandTest {
 
         Column<GenericTableSchema, Map<String, String>> column = mock(Column.class);
         when(openVSwitch.getOtherConfigColumn()).thenReturn(column);
-        Map<String, String> map = new HashMap<String, String>();
+        Map<String, String> map = new HashMap<>();
         when(column.getData()).thenReturn(map);
         when(oldEntry.getOtherConfigColumn()).thenReturn(column);
         MemberModifier.suppress(MemberMatcher.method(OpenVSwitchUpdateCommand.class, "removeOldConfigs", ReadWriteTransaction.class, Map.class, OpenVSwitch.class));
@@ -179,7 +179,7 @@ public class OpenVSwitchUpdateCommandTest {
     @Test
     public void testRemoveOldConfigs() throws Exception {
         ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
-        Map<String, String> oldOtherConfigs = new HashMap<String, String>();
+        Map<String, String> oldOtherConfigs = new HashMap<>();
         oldOtherConfigs.put("OpenvswitchOtherConfigsKey", "OpenvswitchOtherConfigsValue");
         OpenVSwitch ovs = mock(OpenVSwitch.class);
         doNothing().when(transaction).delete(any(LogicalDatastoreType.class), any(KeyedInstanceIdentifier.class));
@@ -195,7 +195,7 @@ public class OpenVSwitchUpdateCommandTest {
     @Test
     public void testSetNewOtherConfigs() throws Exception {
         OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = mock(OvsdbNodeAugmentationBuilder.class);
-        Map<String, String> otherConfigs = new HashMap<String, String>();
+        Map<String, String> otherConfigs = new HashMap<>();
         otherConfigs.put("otherConfigKey", "otherConfigValue");
 
         OpenvswitchOtherConfigsBuilder openvswitchOtherConfigsBuilder = mock(OpenvswitchOtherConfigsBuilder.class);
@@ -221,7 +221,7 @@ public class OpenVSwitchUpdateCommandTest {
 
         Column<GenericTableSchema, Map<String, String>> column = mock(Column.class);
         when(openVSwitch.getExternalIdsColumn()).thenReturn(column);
-        Map<String, String> map = new HashMap<String, String>();
+        Map<String, String> map = new HashMap<>();
         when(column.getData()).thenReturn(map);
         when(oldEntry.getExternalIdsColumn()).thenReturn(column);
         MemberModifier.suppress(MemberMatcher.method(OpenVSwitchUpdateCommand.class, "removeExternalIds", ReadWriteTransaction.class, Map.class, OpenVSwitch.class));
@@ -236,7 +236,7 @@ public class OpenVSwitchUpdateCommandTest {
     @Test
     public void testRemoveExternalIds() throws Exception {
         ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
-        Map<String, String> oldExternalIds = new HashMap<String, String>();
+        Map<String, String> oldExternalIds = new HashMap<>();
         oldExternalIds.put("OpenvswitchExternalIdKey", "OpenvswitchExternalIdValue");
         OpenVSwitch ovs = mock(OpenVSwitch.class);
         doNothing().when(transaction).delete(any(LogicalDatastoreType.class), any(KeyedInstanceIdentifier.class));
@@ -252,7 +252,7 @@ public class OpenVSwitchUpdateCommandTest {
     @Test
     public void testSetNewExternalIds() throws Exception {
         OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = mock(OvsdbNodeAugmentationBuilder.class);
-        Map<String, String> externalIds = new HashMap<String, String>();
+        Map<String, String> externalIds = new HashMap<>();
         externalIds.put("externalIdsKey", "externalIdsValue");
 
         OpenvswitchExternalIdsBuilder openvswitchExternalIdsBuilder = mock(OpenvswitchExternalIdsBuilder.class);
@@ -276,14 +276,26 @@ public class OpenVSwitchUpdateCommandTest {
 
         Column<GenericTableSchema, Set<String>> column = mock(Column.class);
         when(openVSwitch.getIfaceTypesColumn()).thenReturn(column );
-        Set<String> set = new HashSet<String>();
+        Set<String> set = new HashSet<>();
+        set.add("dpdk");
+        set.add("dpdkr");
+        set.add("dpdkvhostuser");
+        set.add("geneve");
+        set.add("gre");
         set.add("internal");
+        set.add("ipsec_gre");
+        set.add("lisp");
+        set.add("patch");
+        set.add("stt");
+        set.add("system");
+        set.add("tap");
+        set.add("vxlan");
         when(column.getData()).thenReturn(set);
         PowerMockito.mockStatic(SouthboundMapper.class);
         when(SouthboundMapper.createInterfaceType(anyString())).thenAnswer(new Answer<Class<? extends InterfaceTypeBase>>() {
             public Class<? extends InterfaceTypeBase> answer(
                     InvocationOnMock invocation) throws Throwable {
-                return (Class<? extends InterfaceTypeBase>) InterfaceTypeInternal.class;
+                return InterfaceTypeInternal.class;
             }
         });
 
@@ -296,7 +308,7 @@ public class OpenVSwitchUpdateCommandTest {
         when(ovsdbNodeBuilder.setInterfaceTypeEntry(any(List.class))).thenReturn(ovsdbNodeBuilder);
         Whitebox.invokeMethod(openVSwitchUpdateCommand, "setInterfaceTypes", ovsdbNodeBuilder, openVSwitch);
         verify(openVSwitch).getIfaceTypesColumn();
-        verify(interfaceTypeEntryBuilder).setInterfaceType(InterfaceTypeInternal.class);
+        verify(interfaceTypeEntryBuilder,times(13)).setInterfaceType(InterfaceTypeInternal.class);
     }
 
     @SuppressWarnings("unchecked")
@@ -306,17 +318,17 @@ public class OpenVSwitchUpdateCommandTest {
         OpenVSwitch openVSwitch = mock(OpenVSwitch.class);
         Column<GenericTableSchema, Set<String>> column = mock(Column.class);
         when(openVSwitch.getDatapathTypesColumn()).thenReturn(column );
-        Set<String> set = new HashSet<String>();
+        Set<String> set = new HashSet<>();
+        set.add("netdev");
         set.add("system");
         when(column.getData()).thenReturn(set);
         PowerMockito.mockStatic(SouthboundMapper.class);
         when(SouthboundMapper.createDatapathType(anyString())).thenAnswer(new Answer<Class<? extends DatapathTypeBase>>() {
             public Class<? extends DatapathTypeBase> answer(
                     InvocationOnMock invocation) throws Throwable {
-                return (Class<? extends DatapathTypeBase>) DatapathTypeSystem.class;
+                return DatapathTypeSystem.class;
             }
         });
-
         DatapathTypeEntry dpEntry = mock(DatapathTypeEntry.class);
         DatapathTypeEntryBuilder datapathTypeEntryBuilder = mock(DatapathTypeEntryBuilder.class);
         PowerMockito.whenNew(DatapathTypeEntryBuilder.class).withNoArguments().thenReturn(datapathTypeEntryBuilder);
@@ -326,7 +338,7 @@ public class OpenVSwitchUpdateCommandTest {
         when(ovsdbNodeBuilder.setDatapathTypeEntry(any(List.class))).thenReturn(ovsdbNodeBuilder);
         Whitebox.invokeMethod(openVSwitchUpdateCommand, "setDataPathTypes", ovsdbNodeBuilder, openVSwitch);
         verify(openVSwitch).getDatapathTypesColumn();
-        verify(datapathTypeEntryBuilder).setDatapathType(DatapathTypeSystem.class);
+        verify(datapathTypeEntryBuilder,times(2)).setDatapathType(DatapathTypeSystem.class);
     }
 
     @SuppressWarnings("unchecked")
@@ -336,7 +348,7 @@ public class OpenVSwitchUpdateCommandTest {
         OpenVSwitch openVSwitch = mock(OpenVSwitch.class);
         Column<GenericTableSchema, Set<String>> column = mock(Column.class);
         when(openVSwitch.getOvsVersionColumn()).thenReturn(column);
-        Set<String> set = new HashSet<String>();
+        Set<String> set = new HashSet<>();
         set.add("v2.3.0");
         when(column.getData()).thenReturn(set);
         when(ovsdbNodeBuilder.setOvsVersion(anyString())).thenReturn(ovsdbNodeBuilder);
@@ -344,5 +356,7 @@ public class OpenVSwitchUpdateCommandTest {
         Whitebox.invokeMethod(openVSwitchUpdateCommand, "setVersion", ovsdbNodeBuilder, openVSwitch);
         verify(ovsdbNodeBuilder).setOvsVersion(anyString());
         verify(openVSwitch).getOvsVersionColumn();
+
+
     }
 }
\ No newline at end of file
index faa2329269e40c111b6c7112c082bda36453095e..64aee99d98b9aeabaed7d16cbfae2db710738e14 100644 (file)
@@ -64,7 +64,7 @@ public class OvsdbBridgeRemovedCommandTest {
         when(ovsdbBridgeRemovedCommand.getDbSchema()).thenReturn(mock(DatabaseSchema.class));
 
         PowerMockito.mockStatic(TyperUtils.class);
-        Map<UUID, Bridge> map = new HashMap<UUID, Bridge>();
+        Map<UUID, Bridge> map = new HashMap<>();
         when(TyperUtils.extractRowsRemoved(eq(Bridge.class), any(TableUpdates.class), any(DatabaseSchema.class))).thenReturn(map);
 
         ovsdbBridgeRemovedCommand.execute(transaction);
index 9bdd0085686748030090c26c3cc7835bd78b9459..e71d0167002643da51b409c9f49da8ce9bc03475 100644 (file)
@@ -90,8 +90,8 @@ import com.google.common.net.InetAddresses;
 @PrepareForTest({TyperUtils.class, OvsdbBridgeUpdateCommand.class, SouthboundUtil.class, InstanceIdentifier.class, SouthboundMapper.class, InetAddresses.class, NumberUtils.class, NetworkInterface.class})
 @RunWith(PowerMockRunner.class)
 public class OvsdbBridgeUpdateCommandTest {
-    private Map<UUID,Bridge> updatedBridgeRows = new HashMap<UUID,Bridge>();;
-    private Map<UUID, Bridge> oldBridgeRows = new HashMap<UUID,Bridge>();
+    private Map<UUID,Bridge> updatedBridgeRows = new HashMap<>();
+    private Map<UUID, Bridge> oldBridgeRows = new HashMap<>();
     private OvsdbBridgeUpdateCommand ovsdbBridgeUpdateCommand;
 
     @Before
@@ -153,7 +153,7 @@ public class OvsdbBridgeUpdateCommandTest {
     @Test
     public void testDeleteEntries() throws Exception {
         ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
-        List<InstanceIdentifier<DataObject>> entryIids = new ArrayList<InstanceIdentifier<DataObject>>();
+        List<InstanceIdentifier<DataObject>> entryIids = new ArrayList<>();
         InstanceIdentifier<DataObject> iid = mock(InstanceIdentifier.class);
         entryIids.add(iid);
         doNothing().when(transaction).delete(any(LogicalDatastoreType.class), (InstanceIdentifier<?>) any(List.class));
@@ -172,7 +172,7 @@ public class OvsdbBridgeUpdateCommandTest {
         when(bridge.getUuid()).thenReturn(uuid);
         MemberModifier.field(OvsdbBridgeUpdateCommand.class, "oldBridgeRows").set(ovsdbBridgeUpdateCommand, oldBridgeRows);
         Column<GenericTableSchema, Map<String, String>> column = mock(Column.class);
-        Map<String, String> map = new HashMap<String, String>();
+        Map<String, String> map = new HashMap<>();
         map.put("key", "value");
         when(column.getData()).thenReturn(map);
 
@@ -193,7 +193,7 @@ public class OvsdbBridgeUpdateCommandTest {
 
         //test protocolEntriesToRemove()
         Column<GenericTableSchema, Set<String>> column1 = mock(Column.class);
-        Set<String> set = new HashSet<String>();
+        Set<String> set = new HashSet<>();
         set.add("element");
         when(column1.getData()).thenReturn(set);
         when(oldBridge.getProtocolsColumn()).thenReturn(column1);
@@ -302,7 +302,7 @@ public class OvsdbBridgeUpdateCommandTest {
         when(SouthboundMapper.createDatapathType(anyString())).thenAnswer(new Answer<Class<? extends DatapathTypeBase>>() {
             public Class<? extends DatapathTypeBase> answer(
                     InvocationOnMock invocation) throws Throwable {
-                return (Class<? extends DatapathTypeBase>) DatapathTypeSystem.class;
+                return DatapathTypeSystem.class;
             }
         });
         when(ovsdbBridgeAugmentationBuilder.setDatapathType(any(Class.class))).thenReturn(ovsdbBridgeAugmentationBuilder);
@@ -319,7 +319,7 @@ public class OvsdbBridgeUpdateCommandTest {
         Bridge bridge = mock(Bridge.class);
         Column<GenericTableSchema, Set<String>> column = mock(Column.class);
         when(bridge.getFailModeColumn()).thenReturn(column);
-        Set<String> set = new HashSet<String>();
+        Set<String> set = new HashSet<>();
         set.add("standalone");
         when(column.getData()).thenReturn(set);
         when(ovsdbBridgeAugmentationBuilder.setFailMode(OvsdbFailModeStandalone.class)).thenReturn(ovsdbBridgeAugmentationBuilder);
@@ -335,7 +335,7 @@ public class OvsdbBridgeUpdateCommandTest {
         Bridge bridge = mock(Bridge.class);
         Column<GenericTableSchema, Map<String, String>> column = mock(Column.class);
         when(bridge.getOtherConfigColumn()).thenReturn(column);
-        Map<String, String> map = new HashMap<String, String>();
+        Map<String, String> map = new HashMap<>();
         map.put("key", "value");
         when(column.getData()).thenReturn(map);
 
@@ -359,7 +359,7 @@ public class OvsdbBridgeUpdateCommandTest {
         Bridge bridge = mock(Bridge.class);
         Column<GenericTableSchema, Map<String, String>> column = mock(Column.class);
         when(bridge.getExternalIdsColumn()).thenReturn(column);
-        Map<String, String> map = new HashMap<String, String>();
+        Map<String, String> map = new HashMap<>();
         map.put("key", "value");
         when(column.getData()).thenReturn(map);
 
@@ -384,7 +384,7 @@ public class OvsdbBridgeUpdateCommandTest {
         PowerMockito.mockStatic(SouthboundMapper.class);
 
         //Test setProtocol()
-        List<ProtocolEntry> listProtocolEntry = new ArrayList<ProtocolEntry>();
+        List<ProtocolEntry> listProtocolEntry = new ArrayList<>();
         listProtocolEntry.add(mock(ProtocolEntry.class));
         when(SouthboundMapper.createMdsalProtocols(any(Bridge.class))).thenReturn(listProtocolEntry);
         when(ovsdbBridgeAugmentationBuilder.setProtocolEntry(any(List.class))).thenReturn(ovsdbBridgeAugmentationBuilder);
@@ -407,13 +407,13 @@ public class OvsdbBridgeUpdateCommandTest {
         Bridge bridge = mock(Bridge.class);
         PowerMockito.mockStatic(SouthboundMapper.class);
 
-        Map<UUID, Controller> updatedControllerRows = new HashMap<UUID, Controller>();
+        Map<UUID, Controller> updatedControllerRows = new HashMap<>();
         when(ovsdbBridgeUpdateCommand.getUpdates()).thenReturn(mock(TableUpdates.class));
         when(ovsdbBridgeUpdateCommand.getDbSchema()).thenReturn(mock(DatabaseSchema.class));
         PowerMockito.mockStatic(TyperUtils.class);
         when(TyperUtils.extractRowsUpdated(eq(Controller.class), any(TableUpdates.class), any(DatabaseSchema.class))).thenReturn(updatedControllerRows);
 
-        List<ControllerEntry> controllerEntryList = new ArrayList<ControllerEntry>();
+        List<ControllerEntry> controllerEntryList = new ArrayList<>();
         ControllerEntry controllerEntry = mock(ControllerEntry.class);
         controllerEntryList.add(controllerEntry);
         when(SouthboundMapper.createControllerEntries(any(Bridge.class), any(Map.class))).thenReturn(controllerEntryList);
index 22a28bfec92dc548dd8c12e44ae113d80cfd4ef5..762a2d88af141e36ac72a9b6e2ab3bb76d5ecfbc 100644 (file)
@@ -74,7 +74,7 @@ public class OvsdbControllerRemovedCommandTest {
     @Test
     public void testExecute() throws Exception {
         ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
-        updatedBridgeRows = new HashMap<UUID, Bridge>();
+        updatedBridgeRows = new HashMap<>();
         UUID uuid = mock(UUID.class);
         Bridge bridge = mock(Bridge.class);
         updatedBridgeRows.put(uuid, bridge);
@@ -92,7 +92,7 @@ public class OvsdbControllerRemovedCommandTest {
     @Test
     public void testDeleteControllers() throws Exception {
         ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
-        List<InstanceIdentifier<ControllerEntry>> controllerEntryIids = new ArrayList<InstanceIdentifier<ControllerEntry>>();
+        List<InstanceIdentifier<ControllerEntry>> controllerEntryIids = new ArrayList<>();
 
         doNothing().when(transaction).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         Whitebox.invokeMethod(ovsdbControllerRemovedCommand, "deleteControllers", transaction, controllerEntryIids);
@@ -112,12 +112,12 @@ public class OvsdbControllerRemovedCommandTest {
 
         UUID uuid = mock(UUID.class);
         Bridge oldBridgeNode = mock(Bridge.class);
-        oldBridgeRows = new HashMap<UUID, Bridge>();
+        oldBridgeRows = new HashMap<>();
         oldBridgeRows.put(uuid, oldBridgeNode);
         when(bridge.getUuid()).thenReturn(uuid);
         MemberModifier.field(OvsdbControllerRemovedCommand.class, "oldBridgeRows").set(ovsdbControllerRemovedCommand, oldBridgeRows);
         Column<GenericTableSchema, Set<UUID>> column = mock(Column.class);
-        Set<UUID> set = new HashSet<UUID>();
+        Set<UUID> set = new HashSet<>();
         UUID controllerUuid = mock(UUID.class);
         set.add(controllerUuid);
         when(column.getData()).thenReturn(set);
index a0b5b934163aa170b7d58d655d384065191426df..3e66096de5cb677d9b26d1b495581a420e005f3f 100644 (file)
@@ -86,7 +86,7 @@ public class OvsdbControllerUpdateCommandTest {
     @Test
     public void testExecute() throws Exception {
         ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
-        updatedControllerRows = new HashMap<UUID, Controller>();
+        updatedControllerRows = new HashMap<>();
         updatedControllerRows.put(mock(UUID.class), mock(Controller.class));
         MemberModifier.field(OvsdbControllerUpdateCommand.class, "updatedControllerRows").set(ovsdbControllerUpdateCommand, updatedControllerRows);
         MemberModifier.suppress(MemberMatcher.method(OvsdbControllerUpdateCommand.class, "updateController", ReadWriteTransaction.class, Map.class, Map.class));
@@ -97,7 +97,7 @@ public class OvsdbControllerUpdateCommandTest {
         PowerMockito.verifyPrivate(ovsdbControllerUpdateCommand).invoke("updateController", any(ReadWriteTransaction.class), any(Map.class));
 
         //updatedBridgeRows not null case
-        updatedBridgeRows = new HashMap<UUID, Bridge>();
+        updatedBridgeRows = new HashMap<>();
         updatedBridgeRows.put(mock(UUID.class), mock(Bridge.class));
         MemberModifier.field(OvsdbControllerUpdateCommand.class, "updatedBridgeRows").set(ovsdbControllerUpdateCommand, updatedBridgeRows);
     }
@@ -112,7 +112,7 @@ public class OvsdbControllerUpdateCommandTest {
         updatedBridgeRows.put(mock(UUID.class), bridge);
 
         PowerMockito.mockStatic(SouthboundMapper.class);
-        List<ControllerEntry> controllerEntries = new ArrayList<ControllerEntry>();
+        List<ControllerEntry> controllerEntries = new ArrayList<>();
         controllerEntries.add(mock(ControllerEntry.class));
         when(SouthboundMapper.createControllerEntries(any(Bridge.class), any(Map.class))).thenReturn(controllerEntries);
         Column<GenericTableSchema, String> column = mock(Column.class);
index aabf249594baa62ab3681756e08756db5bf92bcb..24153e33e8b97b98c7c93c61eadb84229b687810 100644 (file)
@@ -80,7 +80,7 @@ public class OvsdbManagersRemovedCommandTest {
     @Test
     public void testExecute() throws Exception {
         ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
-        updatedOpenVSwitchRows = new HashMap<UUID, OpenVSwitch>();
+        updatedOpenVSwitchRows = new HashMap<>();
         UUID uuid = mock(UUID.class);
         OpenVSwitch openVSwitch = mock(OpenVSwitch.class);
         updatedOpenVSwitchRows.put(uuid, openVSwitch);
@@ -101,7 +101,7 @@ public class OvsdbManagersRemovedCommandTest {
     @Test
     public void testDeleteManagers() throws Exception {
         ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
-        List<InstanceIdentifier<ManagerEntry>> managerEntryIids = new ArrayList<InstanceIdentifier<ManagerEntry>>();
+        List<InstanceIdentifier<ManagerEntry>> managerEntryIids = new ArrayList<>();
         managerEntryIids.add(mock(InstanceIdentifier.class));
         doNothing().when(transaction).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         Whitebox.invokeMethod(ovsdbManagersRemovedCommand, "deleteManagers", transaction, managerEntryIids);
@@ -116,12 +116,12 @@ public class OvsdbManagersRemovedCommandTest {
 
         UUID uuid = mock(UUID.class);
         OpenVSwitch oldOvsdbNode = mock(OpenVSwitch.class);
-        oldOpenVSwitchRows = new HashMap<UUID, OpenVSwitch>();
+        oldOpenVSwitchRows = new HashMap<>();
         oldOpenVSwitchRows.put(uuid, oldOvsdbNode);
         when(openVSwitch.getUuid()).thenReturn(uuid);
         MemberModifier.field(OvsdbManagersRemovedCommand.class, "oldOpenVSwitchRows").set(ovsdbManagersRemovedCommand, oldOpenVSwitchRows);
         Column<GenericTableSchema, Set<UUID>> column = mock(Column.class);
-        Set<UUID> set = new HashSet<UUID>();
+        Set<UUID> set = new HashSet<>();
         UUID controllerUuid = mock(UUID.class);
         set.add(controllerUuid);
         when(column.getData()).thenReturn(set);
@@ -138,7 +138,7 @@ public class OvsdbManagersRemovedCommandTest {
     public void testCheckIfManagerPresentInUpdatedManagersList() throws Exception {
         Manager removedManager = mock(Manager.class);
         Manager updatedManager = mock(Manager.class);
-        updatedManagerRows = new HashMap<UUID, Manager>();
+        updatedManagerRows = new HashMap<>();
         UUID uuid = mock(UUID.class);
         updatedManagerRows.put(uuid, updatedManager);
         MemberModifier.field(OvsdbManagersRemovedCommand.class, "updatedManagerRows").set(ovsdbManagersRemovedCommand, updatedManagerRows);
index 7ffeb5270a1000344b4fb5a604d3a0dad9abaadf..ee3cedff2b535081b66fe3acaf9697eb23fd7397 100644 (file)
@@ -82,13 +82,13 @@ public class OvsdbManagersUpdateCommandTest {
     @Test
     public void testExecute() throws Exception {
         ReadWriteTransaction transaction= mock(ReadWriteTransaction.class);
-        updatedManagerRows = new HashMap<UUID, Manager>();
+        updatedManagerRows = new HashMap<>();
         updatedManagerRows.put(mock(UUID.class), mock(Manager.class));
         MemberModifier.field(OvsdbManagersUpdateCommand.class, "updatedManagerRows").set(ovsdbManagersUpdateCommand, updatedManagerRows);
         Map<Uri, Manager> updatedManagerRowsWithUri = new HashMap<>();
         PowerMockito.doReturn(updatedManagerRowsWithUri).when(ovsdbManagersUpdateCommand, "getUriManagerMap", any(Map.class));
 
-        updatedOpenVSwitchRows = new HashMap<UUID, OpenVSwitch>();
+        updatedOpenVSwitchRows = new HashMap<>();
         updatedOpenVSwitchRows.put(mock(UUID.class), mock(OpenVSwitch.class));
         MemberModifier.field(OvsdbManagersUpdateCommand.class, "updatedOpenVSwitchRows").set(ovsdbManagersUpdateCommand, updatedOpenVSwitchRows);
 
@@ -110,7 +110,7 @@ public class OvsdbManagersUpdateCommandTest {
         updatedOpenVSwitchRows.put(mock(UUID.class), openVSwitch);
 
         PowerMockito.mockStatic(SouthboundMapper.class);
-        List<ManagerEntry> managerEntries = new ArrayList<ManagerEntry>();
+        List<ManagerEntry> managerEntries = new ArrayList<>();
         managerEntries.add(mock(ManagerEntry.class));
         when(SouthboundMapper.createManagerEntries(any(OpenVSwitch.class), any(Map.class))).thenReturn(managerEntries);
 
@@ -125,7 +125,7 @@ public class OvsdbManagersUpdateCommandTest {
     @Test
     public void testUpdateManagers1() throws Exception {
         ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
-        Map<Uri, Manager> updatedManagerRows = new HashMap<Uri, Manager>();
+        Map<Uri, Manager> updatedManagerRows = new HashMap<>();
         OvsdbConnectionInstance ovsdbConnectionInstance = mock(OvsdbConnectionInstance.class);
         when(ovsdbManagersUpdateCommand.getOvsdbConnectionInstance()).thenReturn(ovsdbConnectionInstance);
         InstanceIdentifier<Node> connectionIId = mock(InstanceIdentifier.class);
index 5fac43c07410742918e23778e27b4165dcbcc845..5fde9bd56b61fa4e6fae7ad92212825f0f56f825 100644 (file)
@@ -86,7 +86,7 @@ public class OvsdbNodeRemoveCommandTest {
 
         PowerMockito.doReturn(true).when(ovsdbNodeRemoveCommand, "checkIfOnlyConnectedManager", any(OvsdbNodeAugmentation.class));
 
-        List<ManagedNodeEntry> listManagedNodeEntry = new ArrayList<ManagedNodeEntry>();
+        List<ManagedNodeEntry> listManagedNodeEntry = new ArrayList<>();
         ManagedNodeEntry managedNode = mock(ManagedNodeEntry.class);
         listManagedNodeEntry.add(managedNode);
         when(ovsdbNodeAugmentation.getManagedNodeEntry()).thenReturn(listManagedNodeEntry);
@@ -106,7 +106,7 @@ public class OvsdbNodeRemoveCommandTest {
         OvsdbNodeAugmentation ovsdbNodeAugmentation = mock(OvsdbNodeAugmentation.class);
         ManagerEntry onlyConnectedManager= mock(ManagerEntry.class);
         ManagerEntry manager = mock(ManagerEntry.class);
-        List<ManagerEntry> listManagerEntry = new ArrayList<ManagerEntry>();
+        List<ManagerEntry> listManagerEntry = new ArrayList<>();
         listManagerEntry.add(manager);
 
         //case 1: connectedManager > ONE_CONNECTED_MANAGER
@@ -121,7 +121,8 @@ public class OvsdbNodeRemoveCommandTest {
         assertEquals(true, Whitebox.invokeMethod(ovsdbNodeRemoveCommand, "checkIfOnlyConnectedManager", ovsdbNodeAugmentation));
 
         //case 3: onlyConnectedManager.getNumberOfConnections().longValue() > ONE_ACTIVE_CONNECTION_IN_PASSIVE_MODE
-        when(onlyConnectedManager.getNumberOfConnections()).thenReturn(new Long(ONE_CONNECTED_MANAGER + 1), new Long(ONE_ACTIVE_CONNECTION_IN_PASSIVE_MODE));
+        when(onlyConnectedManager.getNumberOfConnections()).thenReturn(ONE_CONNECTED_MANAGER + 1,
+                ONE_ACTIVE_CONNECTION_IN_PASSIVE_MODE);
         assertEquals(false, Whitebox.invokeMethod(ovsdbNodeRemoveCommand, "checkIfOnlyConnectedManager", ovsdbNodeAugmentation));
 
         //case 4: when all the above don't apply
index 696c365327c449edcdf719e257c0b7e349be0e17..e2955720a0d2ad5e07ee5e831ec56396b2fd242b 100644 (file)
@@ -9,7 +9,6 @@
 package org.opendaylight.ovsdb.southbound.transactions.md;
 
 import static org.junit.Assert.*;
-import static org.mockito.Matchers.*;
 import static org.mockito.Mockito.*;
 
 import java.util.ArrayList;
@@ -33,7 +32,7 @@ import org.powermock.reflect.Whitebox;
 @RunWith(PowerMockRunner.class)
 public class OvsdbOperationalCommandAggregatorTest {
     private static final int NUMBER_OF_COMMANDS = 9;
-    private List<TransactionCommand> commands = new ArrayList<TransactionCommand>();
+    private List<TransactionCommand> commands = new ArrayList<>();
     private OvsdbOperationalCommandAggregator ovsdbOperationalCommandAggregator;
 
     @Before
index ac7658c57cef59b45633f7389c2e447e1a91620c..52cb756e36b0e27d76431c4389975618eedee1d6 100644 (file)
@@ -290,7 +290,7 @@ import com.google.common.util.concurrent.CheckedFuture;
     @Test
     public void testGetTerminationPointBridge() throws Exception {
         UUID portUUID = mock(UUID.class);
-        bridgeUpdatedRows = new HashMap<UUID, Bridge>();
+        bridgeUpdatedRows = new HashMap<>();
         UUID bridgeUUID = mock(UUID.class);
         Bridge bridge = mock(Bridge.class);
         bridgeUpdatedRows.put(bridgeUUID, bridge);
@@ -376,7 +376,7 @@ import com.google.common.util.concurrent.CheckedFuture;
         PowerMockito.when(SouthboundMapper.createInterfaceType(anyString())).thenAnswer(new Answer<Class<? extends InterfaceTypeBase>>() {
             public Class<? extends InterfaceTypeBase> answer(
                     InvocationOnMock invocation) throws Throwable {
-                return (Class<? extends InterfaceTypeBase>) InterfaceTypeInternal.class;
+                return InterfaceTypeInternal.class;
             }
         });
         when(ovsdbTerminationPointBuilder.setInterfaceType(any(Class.class))).thenReturn(ovsdbTerminationPointBuilder);
index 0060341887294fada2126f65c0eb42632275d78f..1308612fc7d86ef5192293eb7d8bba699115f33f 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Map;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -48,15 +49,16 @@ public class TransactionInvokerImplTest {
     private static final int QUEUE_SIZE = 10000;
     @Mock private BindingTransactionChain chain;
     @Mock private DataBroker db;
-    private BlockingQueue<TransactionCommand> inputQueue = new LinkedBlockingQueue<TransactionCommand>(QUEUE_SIZE);
+    private BlockingQueue<TransactionCommand> inputQueue = new LinkedBlockingQueue<>(QUEUE_SIZE);
     private BlockingQueue<ReadWriteTransaction> successfulTransactionQueue
-        = new LinkedBlockingQueue<ReadWriteTransaction>(QUEUE_SIZE);
+        = new LinkedBlockingQueue<>(QUEUE_SIZE);
     private BlockingQueue<AsyncTransaction<?, ?>> failedTransactionQueue
-        = new LinkedBlockingQueue<AsyncTransaction<?, ?>>(QUEUE_SIZE);
+        = new LinkedBlockingQueue<>(QUEUE_SIZE);
     @Mock private ExecutorService executor;
+    @Mock private AtomicBoolean runTask;
     private Map<ReadWriteTransaction,TransactionCommand> transactionToCommand
-        = new HashMap<ReadWriteTransaction,TransactionCommand>();
-    private List<ReadWriteTransaction> pendingTransactions = new ArrayList<ReadWriteTransaction>();
+        = new HashMap<>();
+    private List<ReadWriteTransaction> pendingTransactions = new ArrayList<>();
     private TransactionInvokerImpl transactionInvokerImpl;
 
     @Before
@@ -109,7 +111,7 @@ public class TransactionInvokerImplTest {
         pendingTransactions.add((ReadWriteTransaction) tx2);
         MemberModifier.field(TransactionInvokerImpl.class, "pendingTransactions").set(transactionInvokerImpl, pendingTransactions);
 
-        List<ReadWriteTransaction> transactions= new ArrayList<ReadWriteTransaction>();
+        List<ReadWriteTransaction> transactions= new ArrayList<>();
         transactions.add((ReadWriteTransaction) tx1);
 
         TransactionCommand txCommand = mock(TransactionCommand.class);
@@ -119,7 +121,7 @@ public class TransactionInvokerImplTest {
         MemberModifier.field(TransactionInvokerImpl.class, "transactionToCommand").set(transactionInvokerImpl, transactionToCommand);
         PowerMockito.suppress(MemberModifier.method(TransactionInvokerImpl.class, "resetTransactionQueue"));
 
-        List<TransactionCommand> testCommands = new ArrayList<TransactionCommand>();
+        List<TransactionCommand> testCommands = new ArrayList<>();
         testCommands.add(txCommand);
 
         assertEquals(testCommands, Whitebox.invokeMethod(transactionInvokerImpl, "extractResubmitCommands"));
@@ -178,7 +180,7 @@ public class TransactionInvokerImplTest {
         TransactionCommand command = mock(TransactionCommand.class);
         inputQueue.add(command);
         MemberModifier.field(TransactionInvokerImpl.class, "inputQueue").set(transactionInvokerImpl, inputQueue);
-        List<TransactionCommand> testResult = new ArrayList<TransactionCommand>();
+        List<TransactionCommand> testResult = new ArrayList<>();
         testResult.add(command);
         assertEquals(testResult, Whitebox.invokeMethod(transactionInvokerImpl, "extractCommandsFromQueue"));
     }
@@ -204,6 +206,7 @@ public class TransactionInvokerImplTest {
     @Test
     public void testClose() throws Exception {
         MemberModifier.field(TransactionInvokerImpl.class, "executor").set(transactionInvokerImpl, executor);
+        MemberModifier.field(TransactionInvokerImpl.class, "runTask").set(transactionInvokerImpl, runTask);
         doNothing().when(executor).shutdown();
         transactionInvokerImpl.close();
         verify(executor).shutdown();
index f70e36eb284427084fb01a315a96b4ecbf2d1832..f46e15fcf9f969f520b81fcbf377342f0eae010a 100644 (file)
@@ -19,24 +19,19 @@ import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRunti
 
 import com.google.common.collect.ImmutableBiMap;
 import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
 import java.io.File;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
 
+import javax.annotation.Nullable;
 import javax.inject.Inject;
 
 import org.junit.Assert;
@@ -44,6 +39,9 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 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;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
@@ -79,6 +77,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.re
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
@@ -103,6 +102,8 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.ops4j.pax.exam.Configuration;
 import org.ops4j.pax.exam.Option;
@@ -124,17 +125,17 @@ import org.slf4j.LoggerFactory;
 @RunWith(PaxExam.class)
 @ExamReactorStrategy(PerClass.class)
 public class SouthboundIT extends AbstractMdsalTestBase {
-    private static final String EXPECTED_VALUES_KEY = "ExpectedValuesKey";
-    private static final String INPUT_VALUES_KEY = "InputValuesKey";
     private static final String NETDEV_DP_TYPE = "netdev";
     private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class);
     private static final int OVSDB_UPDATE_TIMEOUT = 1000;
-    public static final int NUM_THREADS = 4;
+    private static final int OVSDB_ROUNDTRIP_TIMEOUT = 10000;
+    private static final String FORMAT_STR = "%s_%s_%d";
     private static String addressStr;
-    private static String portStr;
+    private static int portNumber;
     private static String connectionType;
-    private static Boolean setup = false;
+    private static boolean setup = false;
     private static MdsalUtils mdsalUtils = null;
+    private static Node ovsdbNode;
 
     // TODO Constants copied from AbstractConfigTestBase, need to be removed (see TODO below)
     private static final String PAX_EXAM_UNPACK_DIRECTORY = "target/exam";
@@ -145,6 +146,56 @@ public class SouthboundIT extends AbstractMdsalTestBase {
     @Inject
     private BundleContext bundleContext;
 
+    private static final NotifyingDataChangeListener CONFIGURATION_LISTENER =
+            new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION);
+    private static final NotifyingDataChangeListener OPERATIONAL_LISTENER =
+            new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL);
+
+    private static class NotifyingDataChangeListener implements DataChangeListener {
+        private final LogicalDatastoreType type;
+        private final Set<InstanceIdentifier<?>> createdIids = new HashSet<>();
+        private final Set<InstanceIdentifier<?>> removedIids = new HashSet<>();
+        private final Set<InstanceIdentifier<?>> updatedIids = new HashSet<>();
+
+        private NotifyingDataChangeListener(LogicalDatastoreType type) {
+            this.type = type;
+        }
+
+        @Override
+        public void onDataChanged(
+                AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> asyncDataChangeEvent) {
+            LOG.info("{} DataChanged: created {}", type, asyncDataChangeEvent.getCreatedData().keySet());
+            LOG.info("{} DataChanged: removed {}", type, asyncDataChangeEvent.getRemovedPaths());
+            LOG.info("{} DataChanged: updated {}", type, asyncDataChangeEvent.getUpdatedData().keySet());
+            createdIids.addAll(asyncDataChangeEvent.getCreatedData().keySet());
+            removedIids.addAll(asyncDataChangeEvent.getRemovedPaths());
+            updatedIids.addAll(asyncDataChangeEvent.getUpdatedData().keySet());
+            // Handled managed iids
+            for (DataObject obj : asyncDataChangeEvent.getCreatedData().values()) {
+                if (obj instanceof ManagedNodeEntry) {
+                    ManagedNodeEntry managedNodeEntry = (ManagedNodeEntry) obj;
+                    LOG.info("{} DataChanged: created managed {}", managedNodeEntry.getBridgeRef().getValue());
+                    createdIids.add(managedNodeEntry.getBridgeRef().getValue());
+                }
+            }
+            synchronized(this) {
+                notifyAll();
+            }
+        }
+
+        public boolean isCreated(InstanceIdentifier<?> iid) {
+            return createdIids.remove(iid);
+        }
+
+        public boolean isRemoved(InstanceIdentifier<?> iid) {
+            return removedIids.remove(iid);
+        }
+
+        public boolean isUpdated(InstanceIdentifier<?> iid) {
+            return updatedIids.remove(iid);
+        }
+    }
+
     @Configuration
     public Option[] config() {
         // TODO Figure out how to use the parent Karaf setup, then just use super.config()
@@ -250,7 +301,7 @@ public class SouthboundIT extends AbstractMdsalTestBase {
     @Override
     public void setup() throws InterruptedException {
         if (setup) {
-            LOG.info("Skipping setUp, already initialized");
+            LOG.info("Skipping setup, already initialized");
             return;
         }
 
@@ -265,11 +316,16 @@ public class SouthboundIT extends AbstractMdsalTestBase {
         Assert.assertNotNull("db should not be null", dataBroker);
 
         addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS);
-        portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT);
+        String portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT);
+        try {
+            portNumber = Integer.parseInt(portStr);
+        } catch (NumberFormatException e) {
+            fail("Invalid port number " + portStr + System.lineSeparator() + usage());
+        }
         connectionType = bundleContext.getProperty(SouthboundITConstants.CONNECTION_TYPE);
 
         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
-                connectionType, addressStr, portStr);
+                connectionType, addressStr, portNumber);
         if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_ACTIVE)) {
             if (addressStr == null) {
                 fail(usage());
@@ -277,6 +333,15 @@ public class SouthboundIT extends AbstractMdsalTestBase {
         }
 
         mdsalUtils = new MdsalUtils(dataBroker);
+        final ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
+        final InstanceIdentifier<Node> iid = createInstanceIdentifier(connectionInfo);
+        dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+                iid, CONFIGURATION_LISTENER, AsyncDataBroker.DataChangeScope.SUBTREE);
+        dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+                iid, OPERATIONAL_LISTENER, AsyncDataBroker.DataChangeScope.SUBTREE);
+
+        ovsdbNode = connectOvsdbNode(connectionInfo);
+
         setup = true;
     }
 
@@ -294,28 +359,26 @@ public class SouthboundIT extends AbstractMdsalTestBase {
         }
     }
 
-    private ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
+    private ConnectionInfo getConnectionInfo(final String addressStr, final int portNumber) {
         InetAddress inetAddress = null;
         try {
             inetAddress = InetAddress.getByName(addressStr);
         } catch (UnknownHostException e) {
-            fail("Could not allocate InetAddress: " + e);
+            fail("Could not resolve " + addressStr + ": " + e);
         }
 
         IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
-        PortNumber port = new PortNumber(Integer.parseInt(portStr));
+        PortNumber port = new PortNumber(portNumber);
 
-        LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
-                .setRemoteIp(address)
-                .setRemotePort(port)
-                .build());
-        return new ConnectionInfoBuilder()
+        final ConnectionInfo connectionInfo = new ConnectionInfoBuilder()
                 .setRemoteIp(address)
                 .setRemotePort(port)
                 .build();
+        LOG.info("connectionInfo: {}", connectionInfo);
+        return connectionInfo;
     }
 
-    private String connectionInfoToString(final ConnectionInfo connectionInfo) {
+    private static String connectionInfoToString(final ConnectionInfo connectionInfo) {
         return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
     }
 
@@ -348,66 +411,80 @@ public class SouthboundIT extends AbstractMdsalTestBase {
                 topology);
     }
 
-    private boolean addOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
-        InstanceIdentifier<Node> iid = createInstanceIdentifier(connectionInfo);
-        // Check that the node doesn't already exist (we don't support connecting twice)
-        Assert.assertNull("The OVSDB node has already been added",
-                mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, iid));
-        boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
-                iid,
-                createNode(connectionInfo));
-        Thread.sleep(OVSDB_UPDATE_TIMEOUT);
-        return result;
-    }
-
-    private InstanceIdentifier<Node> createInstanceIdentifier(
-            ConnectionInfo connectionInfo) {
+    private static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo connectionInfo) {
         return InstanceIdentifier
                 .create(NetworkTopology.class)
                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
                 .child(Node.class,
-                        createNodeKey(connectionInfo.getRemoteIp(),connectionInfo.getRemotePort()));
-    }
-
-    private Node getOvsdbNode(final ConnectionInfo connectionInfo) {
-        return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
-                createInstanceIdentifier(connectionInfo));
-    }
-
-    private boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
-        boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
-                createInstanceIdentifier(connectionInfo));
-        Thread.sleep(OVSDB_UPDATE_TIMEOUT);
-        return result;
+                        createNodeKey(connectionInfo.getRemoteIp(), connectionInfo.getRemotePort()));
     }
 
     private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
-        Assert.assertTrue(addOvsdbNode(connectionInfo));
-        Node node = getOvsdbNode(connectionInfo);
+        final InstanceIdentifier<Node> iid = createInstanceIdentifier(connectionInfo);
+        Assert.assertTrue(mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, iid, createNode(connectionInfo)));
+        waitForOperationalCreation(iid);
+        Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
         Assert.assertNotNull(node);
         LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
         return node;
     }
 
-    private boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
-        Assert.assertTrue(deleteOvsdbNode(connectionInfo));
-        Node node = getOvsdbNode(connectionInfo);
+    private void waitForOperationalCreation(InstanceIdentifier<Node> iid) throws InterruptedException {
+        synchronized (OPERATIONAL_LISTENER) {
+            long _start = System.currentTimeMillis();
+            LOG.info("Waiting for OPERATIONAL DataChanged creation on {}", iid);
+            while (!OPERATIONAL_LISTENER.isCreated(
+                    iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
+                OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
+            }
+            LOG.info("Woke up, waited {} for creation of {}", (System.currentTimeMillis() - _start), iid);
+        }
+    }
+
+    private static void waitForOperationalDeletion(InstanceIdentifier<Node> iid) throws InterruptedException {
+        synchronized (OPERATIONAL_LISTENER) {
+            long _start = System.currentTimeMillis();
+            LOG.info("Waiting for OPERATIONAL DataChanged deletion on {}", iid);
+            while (!OPERATIONAL_LISTENER.isRemoved(
+                    iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
+                OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
+            }
+            LOG.info("Woke up, waited {} for deletion of {}", (System.currentTimeMillis() - _start), iid);
+        }
+    }
+
+    private void waitForOperationalUpdate(InstanceIdentifier<Node> iid) throws InterruptedException {
+        synchronized (OPERATIONAL_LISTENER) {
+            long _start = System.currentTimeMillis();
+            LOG.info("Waiting for OPERATIONAL DataChanged update on {}", iid);
+            while (!OPERATIONAL_LISTENER.isUpdated(
+                    iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
+                OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
+            }
+            LOG.info("Woke up, waited {} for update of {}", (System.currentTimeMillis() - _start), iid);
+        }
+    }
+
+    private static void disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
+        final InstanceIdentifier<Node> iid = createInstanceIdentifier(connectionInfo);
+        Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
+        waitForOperationalDeletion(iid);
+        Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
         Assert.assertNull(node);
         LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
-        return true;
     }
 
     @Test
     public void testAddDeleteOvsdbNode() throws InterruptedException {
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
+        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
+        // At this point we're connected, disconnect and reconnect (the connection will be removed at the very end)
+        disconnectOvsdbNode(connectionInfo);
         connectOvsdbNode(connectionInfo);
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
     }
 
     @Test
     public void testDpdkSwitch() throws InterruptedException {
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        Node ovsdbNode = connectOvsdbNode(connectionInfo);
+        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
         List<DatapathTypeEntry> datapathTypeEntries = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class)
                 .getDatapathTypeEntry();
         if (datapathTypeEntries == null) {
@@ -422,61 +499,71 @@ public class SouthboundIT extends AbstractMdsalTestBase {
                     InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo,
                             new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
                     NodeId bridgeNodeId = createManagedNodeId(bridgeIid);
-                    addBridge(connectionInfo, bridgeIid, SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null,
-                            true, dpType, null, null, null);
-
-                    // Verify that the device is netdev
-                    OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
-                    Assert.assertNotNull(bridge);
-                    Assert.assertEquals(dpType, bridge.getDatapathType());
-
-                    // Add dpdk port
-                    final String TEST_PORT_NAME = "testDPDKPort";
-                    OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
-                            createGenericDpdkOvsdbTerminationPointAugmentationBuilder(TEST_PORT_NAME);
-                    Assert.assertTrue(addTerminationPoint(bridgeNodeId, TEST_PORT_NAME, ovsdbTerminationBuilder));
-
-                    // Verify that DPDK port was created
-                    InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
-                    Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
-                            terminationPointIid);
-                    Assert.assertNotNull(terminationPointNode);
-
-                    // Verify that each termination point has DPDK ifType
-                    Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
-                            .get("dpdk");
-                    List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
-                    for (TerminationPoint terminationPoint : terminationPoints) {
-                        OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint
-                                .getAugmentation(OvsdbTerminationPointAugmentation.class);
-                        if (ovsdbTerminationPointAugmentation.getName().equals(TEST_PORT_NAME)) {
-                            Class<? extends InterfaceTypeBase> opPort = ovsdbTerminationPointAugmentation
-                                    .getInterfaceType();
-                            Assert.assertEquals(dpdkIfType, opPort);
+                    try (TestBridge testBridge = new TestBridge(connectionInfo, bridgeIid,
+                            SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null, true, dpType, null, null,
+                            null)) {
+                        // Verify that the device is netdev
+                        OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
+                        Assert.assertNotNull(bridge);
+                        Assert.assertEquals(dpType, bridge.getDatapathType());
+
+                        // Add port for all dpdk interface types (dpdkvhost not supported in existing dpdk ovs)
+                        List<String> dpdkTypes = new ArrayList<String>();
+                        dpdkTypes.add("dpdk");
+                        dpdkTypes.add("dpdkr");
+                        dpdkTypes.add("dpdkvhostuser");
+                        //dpdkTypes.add("dpdkvhost");
+
+                        for (String dpdkType : dpdkTypes) {
+                            String testPortname = "test"+dpdkType+"port";
+                            LOG.info("DPDK portname and type is {}, {}", testPortname, dpdkType);
+                            Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
+                                    .get(dpdkType);
+                            OvsdbTerminationPointAugmentationBuilder ovsdbTerminationpointBuilder =
+                                    createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(testPortname,
+                                            dpdkIfType);
+                            Assert.assertTrue(
+                                    addTerminationPoint(bridgeNodeId, testPortname, ovsdbTerminationpointBuilder));
+                        }
+
+                        // Verify that all DPDK ports are created
+                        InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
+                        Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
+                                terminationPointIid);
+                        Assert.assertNotNull(terminationPointNode);
+
+                        // Verify that each termination point has the specific DPDK ifType
+                        for (String dpdkType : dpdkTypes) {
+                            String testPortname = "test"+dpdkType+"port";
+                            Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
+                                    .get(dpdkType);
+                            List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
+                            for (TerminationPoint terminationPoint : terminationPoints) {
+                                OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint
+                                        .getAugmentation(OvsdbTerminationPointAugmentation.class);
+                                if (ovsdbTerminationPointAugmentation.getName().equals(testPortname)) {
+                                    Class<? extends InterfaceTypeBase> opPort = ovsdbTerminationPointAugmentation
+                                            .getInterfaceType();
+                                    Assert.assertEquals(dpdkIfType, opPort);
+                                }
+                            }
                         }
                     }
-                    Assert.assertTrue(deleteBridge(connectionInfo));
-                    break;
                 }
+                break;
             }
         }
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
     }
 
     @Test
     public void testOvsdbNodeOvsVersion() throws InterruptedException {
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        Node ovsdbNode = connectOvsdbNode(connectionInfo);
         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
         Assert.assertNotNull(ovsdbNodeAugmentation);
         assertNotNull(ovsdbNodeAugmentation.getOvsVersion());
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
     }
 
     @Test
     public void testOpenVSwitchOtherConfig() throws InterruptedException {
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        Node ovsdbNode = connectOvsdbNode(connectionInfo);
         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
         Assert.assertNotNull(ovsdbNodeAugmentation);
         List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
@@ -492,33 +579,29 @@ public class SouthboundIT extends AbstractMdsalTestBase {
         } else {
             LOG.info("other_config is not present");
         }
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
     }
 
     @Test
     public void testOvsdbBridgeControllerInfo() throws InterruptedException {
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portStr);
-        Node ovsdbNode = connectOvsdbNode(connectionInfo);
+        ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portNumber);
         String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
         assertNotNull("Failed to get controller target", controllerTarget);
         List<ControllerEntry> setControllerEntry = createControllerEntry(controllerTarget);
         Uri setUri = new Uri(controllerTarget);
-        Assert.assertTrue(addBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true,
+        try (TestBridge testBridge = new TestBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true,
                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
-                setControllerEntry, null));
-        OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
-        Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME,  bridge);
-        Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
-                bridge.getControllerEntry());
-        List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
-        for (ControllerEntry entry : getControllerEntries) {
-            if (entry.getTarget() != null) {
-                Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
+                setControllerEntry, null)) {
+            OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
+            Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME,  bridge);
+            Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
+                    bridge.getControllerEntry());
+            List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
+            for (ControllerEntry entry : getControllerEntries) {
+                if (entry.getTarget() != null) {
+                    Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
+                }
             }
         }
-
-        Assert.assertTrue(deleteBridge(connectionInfo));
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
     }
 
     private List<ControllerEntry> createControllerEntry(String controllerTarget) {
@@ -529,13 +612,13 @@ public class SouthboundIT extends AbstractMdsalTestBase {
         return controllerEntriesList;
     }
 
-    private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
+    private static void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
                               final ConnectionInfo connectionInfo) {
         InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
     }
 
-    private List<ProtocolEntry> createMdsalProtocols() {
+    private static List<ProtocolEntry> createMdsalProtocols() {
         List<ProtocolEntry> protocolList = new ArrayList<>();
         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
                 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
@@ -565,6 +648,15 @@ public class SouthboundIT extends AbstractMdsalTestBase {
         return ovsdbTerminationBuilder;
     }
 
+    private OvsdbTerminationPointAugmentationBuilder createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(
+            String testPortname,Class<? extends InterfaceTypeBase> dpdkIfType) {
+        OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
+                createGenericOvsdbTerminationPointAugmentationBuilder();
+        ovsdbTerminationBuilder.setName(testPortname);
+        ovsdbTerminationBuilder.setInterfaceType(dpdkIfType);
+        return ovsdbTerminationBuilder;
+    }
+
     private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
                                         final OvsdbTerminationPointAugmentationBuilder
                                                 ovsdbTerminationPointAugmentationBuilder)
@@ -586,75 +678,81 @@ public class SouthboundIT extends AbstractMdsalTestBase {
         return result;
     }
 
-    /*
-     * base method for adding test bridges.  Other helper methods used to create bridges should utilize this method.
-     *
-     * @param connectionInfo
-     * @param bridgeIid if passed null, one is created
-     * @param bridgeName cannot be null
-     * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
-     * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
-     * @param failMode toggles whether default fail mode is set for the bridge
-     * @param setManagedBy toggles whether to setManagedBy for the bridge
-     * @param dpType if passed null, this parameter is ignored
-     * @param externalIds if passed null, this parameter is ignored
-     * @param otherConfig if passed null, this parameter is ignored
-     * @return success of bridge addition
-     * @throws InterruptedException
-     */
-    private boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
-                              final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
-                              final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
-                              final Class<? extends DatapathTypeBase> dpType,
-                              final List<BridgeExternalIds> externalIds,
-                              final List<ControllerEntry> controllerEntries,
-                              final List<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
-
-        NodeBuilder bridgeNodeBuilder = new NodeBuilder();
-        if (bridgeIid == null) {
-            bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
-        }
-        if (bridgeNodeId == null) {
-            bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
-        }
-        bridgeNodeBuilder.setNodeId(bridgeNodeId);
-        OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
-        ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
-        if (setProtocolEntries) {
-            ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
-        }
-        if (failMode != null) {
+    private static class TestBridge implements AutoCloseable {
+        private final ConnectionInfo connectionInfo;
+        private final String bridgeName;
+
+        /**
+         * Creates a test bridge which can be automatically removed when no longer necessary.
+         *
+         * @param connectionInfo The connection information.
+         * @param bridgeIid The bridge identifier; if {@code null}, one is created based on {@code bridgeName}.
+         * @param bridgeName The bridge name; must be provided.
+         * @param bridgeNodeId The bridge node identifier; if {@code null}, one is created based on {@code bridgeIid}.
+         * @param setProtocolEntries {@code true} to set default protocol entries for the bridge.
+         * @param failMode The fail mode to set for the bridge.
+         * @param setManagedBy {@code true} to specify {@code setManagedBy} for the bridge.
+         * @param dpType The datapath type.
+         * @param externalIds The external identifiers if any.
+         * @param otherConfigs The other configuration items if any.
+         */
+        public TestBridge(final ConnectionInfo connectionInfo, @Nullable InstanceIdentifier<Node> bridgeIid,
+                                  final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
+                                  final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
+                                  @Nullable final Class<? extends DatapathTypeBase> dpType,
+                                  @Nullable final List<BridgeExternalIds> externalIds,
+                                  @Nullable final List<ControllerEntry> controllerEntries,
+                                  @Nullable final List<BridgeOtherConfigs> otherConfigs) {
+            this.connectionInfo = connectionInfo;
+            this.bridgeName = bridgeName;
+            NodeBuilder bridgeNodeBuilder = new NodeBuilder();
+            if (bridgeIid == null) {
+                bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
+            }
+            if (bridgeNodeId == null) {
+                bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
+            }
+            bridgeNodeBuilder.setNodeId(bridgeNodeId);
+            OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
+            ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
+            if (setProtocolEntries) {
+                ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
+            }
             ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
-        }
-        if (setManagedBy) {
-            setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
-        }
-        if (dpType != null) {
+            if (setManagedBy) {
+                setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
+            }
             ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
-        }
-        if (externalIds != null) {
             ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
-        }
-        if (controllerEntries != null) {
             ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
-        }
-        if (otherConfigs != null) {
             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
+            bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
+            LOG.debug("Built with the intent to store bridge data {}", ovsdbBridgeAugmentationBuilder.toString());
+            Assert.assertTrue(
+                    mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeNodeBuilder.build()));
+            try {
+                Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+            } catch (InterruptedException e) {
+                LOG.warn("Sleep interrupted while waiting for bridge creation (bridge {})", bridgeName, e);
+            }
         }
-        bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
-        LOG.debug("Built with the intent to store bridge data {}",
-                ovsdbBridgeAugmentationBuilder.toString());
-        boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
-                bridgeIid, bridgeNodeBuilder.build());
-        Thread.sleep(OVSDB_UPDATE_TIMEOUT);
-        return result;
-    }
 
-    private boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName)
-            throws InterruptedException {
+        public TestBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
+            this(connectionInfo, null, bridgeName, null, true,
+                    SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
+        }
 
-        return addBridge(connectionInfo, null, bridgeName, null, true,
-                SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
+        @Override
+        public void close() {
+            final InstanceIdentifier<Node> iid =
+                    createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
+            Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
+            try {
+                Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+            } catch (InterruptedException e) {
+                LOG.warn("Sleep interrupted while waiting for bridge deletion (bridge {})", bridgeName, e);
+            }
+        }
     }
 
     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
@@ -720,33 +818,15 @@ public class SouthboundIT extends AbstractMdsalTestBase {
         return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
     }
 
-    private boolean deleteBridge(ConnectionInfo connectionInfo) throws InterruptedException {
-        return deleteBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
-    }
-
-    private boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName)
-            throws InterruptedException {
-
-        boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
-                createInstanceIdentifier(connectionInfo,
-                        new OvsdbBridgeName(bridgeName)));
-        Thread.sleep(OVSDB_UPDATE_TIMEOUT);
-        return result;
-    }
-
     @Test
     public void testAddDeleteBridge() throws InterruptedException {
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
-
-        Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
-        OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
-        Assert.assertNotNull(bridge);
-        LOG.info("bridge: {}", bridge);
-
-        Assert.assertTrue(deleteBridge(connectionInfo));
+        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
 
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
+        try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
+            OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
+            Assert.assertNotNull(bridge);
+            LOG.info("bridge: {}", bridge);
+        }
     }
 
     private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
@@ -765,7 +845,7 @@ public class SouthboundIT extends AbstractMdsalTestBase {
      * @return the augmentation (or {@code null} if none)
      */
     private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation(
-            ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index ) {
+            ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index) {
 
         List<TerminationPoint> tpList = getBridgeNode(connectionInfo, bridgeName, store).getTerminationPoint();
         if (tpList == null) {
@@ -778,47 +858,45 @@ public class SouthboundIT extends AbstractMdsalTestBase {
     public void testCRDTerminationPointOfPort() throws InterruptedException {
         final Long OFPORT_EXPECTED = 45002L;
 
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
+        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
 
         // CREATE
-        Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
-        OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
-        Assert.assertNotNull(bridge);
-        LOG.info("bridge: {}", bridge);
-        NodeId nodeId = SouthboundMapper.createManagedNodeId(createInstanceIdentifier(
-                connectionInfo, bridge.getBridgeName()));
-        OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
-                createGenericOvsdbTerminationPointAugmentationBuilder();
-        String portName = "testOfPort";
-        ovsdbTerminationBuilder.setName(portName);
+        try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
+            OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
+            Assert.assertNotNull(bridge);
+            LOG.info("bridge: {}", bridge);
+            NodeId nodeId = SouthboundMapper.createManagedNodeId(createInstanceIdentifier(
+                    connectionInfo, bridge.getBridgeName()));
+            OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
+                    createGenericOvsdbTerminationPointAugmentationBuilder();
+            String portName = "testOfPort";
+            ovsdbTerminationBuilder.setName(portName);
+
+            ovsdbTerminationBuilder.setOfport(OFPORT_EXPECTED);
+            Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
+            InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
+            Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
+            Assert.assertNotNull(terminationPointNode);
 
-        ovsdbTerminationBuilder.setOfport(OFPORT_EXPECTED);
-        Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
-        InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
-        Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
-        Assert.assertNotNull(terminationPointNode);
-
-        // READ
-        List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
-        for (TerminationPoint terminationPoint : terminationPoints) {
-            OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
-                    terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
-            if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
-                Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
-                // if ephemeral port 45002 is in use, ofPort is set to 1
-                Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(new Long(1)));
-                LOG.info("ofPort: {}", ofPort);
+            // READ
+            List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
+            for (TerminationPoint terminationPoint : terminationPoints) {
+                OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
+                        terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
+                if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
+                    Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
+                    // if ephemeral port 45002 is in use, ofPort is set to 1
+                    Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(1L));
+                    LOG.info("ofPort: {}", ofPort);
+                }
             }
-        }
 
-        // UPDATE- Not Applicable.  From the OpenVSwitch Documentation:
-        //   "A client should ideally set this column’s value in the same database transaction that it uses to create
-        //   the interface."
+            // UPDATE- Not Applicable.  From the OpenVSwitch Documentation:
+            //   "A client should ideally set this column’s value in the same database transaction that it uses to create
+            //   the interface."
 
-        // DELETE
-        Assert.assertTrue(deleteBridge(connectionInfo));
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
+            // DELETE handled by TestBridge
+        }
     }
 
     @Test
@@ -826,2680 +904,1025 @@ public class SouthboundIT extends AbstractMdsalTestBase {
         final Long OFPORT_EXPECTED = 45008L;
         final Long OFPORT_INPUT = 45008L;
 
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
+        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
 
         // CREATE
-        Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
-        OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
-        Assert.assertNotNull(bridge);
-        NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
-                connectionInfo, bridge.getBridgeName()));
-        OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
-                createGenericOvsdbTerminationPointAugmentationBuilder();
-        String portName = "testOfPortRequest";
-        ovsdbTerminationBuilder.setName(portName);
-        Integer ofPortRequestExpected = OFPORT_EXPECTED.intValue();
-        ovsdbTerminationBuilder.setOfport(OFPORT_INPUT);
-        ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected);
-        Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
-        InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
-        Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
-        Assert.assertNotNull(terminationPointNode);
-
-        // READ
-        List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
-        for (TerminationPoint terminationPoint : terminationPoints) {
-            OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
-                    terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
-            if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
-                Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
-                // if ephemeral port 45008 is in use, ofPort is set to 1
-                Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(new Long(1)));
-                LOG.info("ofPort: {}", ofPort);
-
-                Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest();
-                Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected));
-                LOG.info("ofPortRequest: {}", ofPortRequest);
+        try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
+            OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
+            Assert.assertNotNull(bridge);
+            NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
+                    connectionInfo, bridge.getBridgeName()));
+            OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
+                    createGenericOvsdbTerminationPointAugmentationBuilder();
+            String portName = "testOfPortRequest";
+            ovsdbTerminationBuilder.setName(portName);
+            Integer ofPortRequestExpected = OFPORT_EXPECTED.intValue();
+            ovsdbTerminationBuilder.setOfport(OFPORT_INPUT);
+            ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected);
+            Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
+            InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
+            Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
+            Assert.assertNotNull(terminationPointNode);
+
+            // READ
+            List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
+            for (TerminationPoint terminationPoint : terminationPoints) {
+                OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
+                        terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
+                if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
+                    Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
+                    // if ephemeral port 45008 is in use, ofPort is set to 1
+                    Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(1L));
+                    LOG.info("ofPort: {}", ofPort);
+
+                    Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest();
+                    Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected));
+                    LOG.info("ofPortRequest: {}", ofPortRequest);
+                }
             }
+
+            // UPDATE- Not Applicable.  From the OpenVSwitch documentation:
+            //   "A client should ideally set this column’s value in the same database transaction that it uses to create
+
+            //   the interface. "
+
+            // DELETE handled by TestBridge
         }
+    }
 
-        // UPDATE- Not Applicable.  From the OpenVSwitch documentation:
-        //   "A client should ideally set this column’s value in the same database transaction that it uses to create
-        //   the interface. "
+    private <T> void assertExpectedExist(List<T> expected, List<T> test) {
+        if (expected != null && test != null) {
+            for (T exp : expected) {
+                Assert.assertTrue("The retrieved values don't contain " + exp, test.contains(exp));
+            }
+        }
+    }
 
-        // DELETE
-        Assert.assertTrue(deleteBridge(connectionInfo));
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
+    private interface SouthboundTerminationPointHelper<T> {
+        void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<T> values);
+        List<T> readValues(OvsdbTerminationPointAugmentation augmentation);
     }
 
     /*
-     * Generates the test cases involved in testing PortExternalIds.  See inline comments for descriptions of
-     * the particular cases considered.
+     * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
      *
-     * The return value is a Map in the form (K,V)=(testCaseName,testCase).
-     * - testCaseName is a String
-     * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
-     *     either corresponding INPUT port external_ids, or EXPECTED port external_ids
-     *     INPUT    is the List we use when calling
-     *              <code>TerminationPointAugmentationBuilder.setPortExternalIds()</code>
-     *     EXPECTED is the List we expect to receive after calling
-     *              <code>TerminationPointAugmentationBuilder.getPortExternalIds()</code>
+     * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
      */
-    private Map<String, Map<String, List<PortExternalIds>>> generatePortExternalIdsTestCases() {
-        Map<String, Map<String, List<PortExternalIds>>> testMap = new HashMap<>();
+    private <T> void testCRUDTerminationPoint(
+            KeyValueBuilder<T> builder, String prefix, SouthboundTerminationPointHelper<T> helper)
+            throws InterruptedException {
+        final int TERMINATION_POINT_TEST_INDEX = 0;
 
-        final String PORT_EXTERNAL_ID_KEY = "PortExternalIdKey";
-        final String PORT_EXTERNAL_ID_VALUE = "PortExternalIdValue";
-        final String FORMAT_STR = "%s_%s_%d";
-        final String GOOD_KEY = "GoodKey";
-        final String GOOD_VALUE = "GoodValue";
-        final String NO_VALUE_FOR_KEY = "NoValueForKey";
-        final String NO_KEY_FOR_VALUE = "NoKeyForValue";
+        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
 
-        // Test Case 1:  TestOneExternalId
-        // Test Type:    Positive
-        // Description:  Create a termination point with one PortExternalIds
-        // Expected:     A port is created with the single external_ids specified below
-        final String testOneExternalIdName = "TestOneExternalId";
-        int externalIdCounter = 0;
-        List<PortExternalIds> oneExternalId = Lists.newArrayList(
-                (new PortExternalIdsBuilder()
-                        .setExternalIdKey(String.format(FORMAT_STR, testOneExternalIdName,
-                                PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setExternalIdValue(String.format(FORMAT_STR, testOneExternalIdName,
-                                PORT_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()));
-        Map<String,List<PortExternalIds>> testCase = Maps.newHashMap();
-        testCase.put(EXPECTED_VALUES_KEY, oneExternalId);
-        testCase.put(INPUT_VALUES_KEY, oneExternalId);
-        testMap.put(testOneExternalIdName, testCase);
-
-        // Test Case 2:  TestFiveExternalId
-        // Test Type:    Positive
-        // Description:  Create a termination point with multiple (five) PortExternalIds
-        // Expected:     A port is created with the five external_ids specified below
-        final String testFiveExternalIdName = "TestFiveExternalId";
-        externalIdCounter = 0;
-        List<PortExternalIds> fiveExternalId = Lists.newArrayList(
-                (new PortExternalIdsBuilder()
-                        .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                PORT_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()),
-                (new PortExternalIdsBuilder()
-                        .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                PORT_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()),
-                (new PortExternalIdsBuilder()
-                        .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                PORT_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()),
-                (new PortExternalIdsBuilder()
-                        .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                PORT_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()),
-                (new PortExternalIdsBuilder()
-                        .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                PORT_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()));
-        testCase = Maps.newHashMap();
-        testCase.put(EXPECTED_VALUES_KEY, fiveExternalId);
-        testCase.put(INPUT_VALUES_KEY, fiveExternalId);
-        testMap.put(testFiveExternalIdName, testCase);
-
-        // Test Case 3:  TestOneGoodExternalIdOneMalformedExternalIdValue
-        // Test Type:    Negative
-        // Description:
-        //     One perfectly fine PortExternalId
-        //        (TestOneGoodExternalIdOneMalformedExternalIdValue_PortExternalIdKey_1,
-        //        TestOneGoodExternalIdOneMalformedExternalId_PortExternalIdValue_1)
-        //     and one malformed PortExternalId which only has key specified
-        //        (TestOneGoodExternalIdOneMalformedExternalIdValue_NoValueForKey_2,
-        //        UNSPECIFIED)
-        // Expected:     A port is created without any external_ids
-        final String testOneGoodExternalIdOneMalformedExternalIdValueName =
-                "TestOneGoodExternalIdOneMalformedExternalIdValue";
-        externalIdCounter = 0;
-        PortExternalIds oneGood = new PortExternalIdsBuilder()
-                .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdValueName,
-                        GOOD_KEY, ++externalIdCounter))
-                .setExternalIdValue(String.format(FORMAT_STR,
-                        testOneGoodExternalIdOneMalformedExternalIdValueName,
-                        GOOD_VALUE, externalIdCounter))
-                .build();
-        PortExternalIds oneBad = new PortExternalIdsBuilder()
-                .setExternalIdKey(String.format(FORMAT_STR,
-                        testOneGoodExternalIdOneMalformedExternalIdValueName, NO_VALUE_FOR_KEY, ++externalIdCounter))
-                .build();
-        List<PortExternalIds> oneGoodOneBadInput = Lists.newArrayList(oneGood, oneBad);
-        List<PortExternalIds> oneGoodOneBadExpected = null;
-        testCase = Maps.newHashMap();
-        testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
-        testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
-        testMap.put(testOneGoodExternalIdOneMalformedExternalIdValueName, testCase);
-
-        // Test Case 4:  TestOneGoodExternalIdOneMalformedExternalIdKey
-        // Test Type:    Negative
-        // Description:
-        //     One perfectly fine PortExternalId
-        //        (TestOneGoodExternalIdOneMalformedExternalIdValue_PortExternalIdKey_1,
-        //        TestOneGoodExternalIdOneMalformedExternalId_PortExternalIdValue_1)
-        //     and one malformed PortExternalId which only has key specified
-        //        (UNSPECIFIED,
-        //        TestOneGoodExternalIdOneMalformedExternalIdKey_NoKeyForValue_2)
-        // Expected:     A port is created without any external_ids
-        final String testOneGoodExternalIdOneMalformedExternalIdKeyName =
-                "TestOneGoodExternalIdOneMalformedExternalIdKey";
-        externalIdCounter = 0;
-        oneGood = new PortExternalIdsBuilder()
-                .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdKeyName,
-                        GOOD_KEY, ++externalIdCounter))
-                .setExternalIdValue(String.format(FORMAT_STR,
-                        testOneGoodExternalIdOneMalformedExternalIdKeyName,
-                        GOOD_VALUE, externalIdCounter))
-                .build();
-        oneBad = new PortExternalIdsBuilder()
-                .setExternalIdKey(String.format(FORMAT_STR,
-                        testOneGoodExternalIdOneMalformedExternalIdKeyName, NO_KEY_FOR_VALUE, ++externalIdCounter))
-                .build();
-        oneGoodOneBadInput = Lists.newArrayList(oneGood, oneBad);
-        oneGoodOneBadExpected = null;
-        testCase = Maps.newHashMap();
-        testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
-        testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
-        testMap.put(testOneGoodExternalIdOneMalformedExternalIdKeyName, testCase);
+        // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
+        // the update has been performed.
+        List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
+        List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
+
+        for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
+            for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
+                String testBridgeAndPortName = String.format("%s_%s", prefix, updateToTestCase.name);
+
+                // CREATE: Create the test bridge
+                try (TestBridge testBridge = new TestBridge(connectionInfo, null, testBridgeAndPortName, null, true,
+                        SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null,
+                        null)) {
+                    NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
+                            connectionInfo, new OvsdbBridgeName(testBridgeAndPortName)));
+                    OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
+                            createGenericOvsdbTerminationPointAugmentationBuilder();
+                    tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
+                    helper.writeValues(tpCreateAugmentationBuilder, updateFromTestCase.inputValues);
+                    Assert.assertTrue(
+                            addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
+
+                    // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
+                    // then repeat for OPERATIONAL data store
+                    OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
+                            getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
+                                    LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
+                    if (updateFromConfigurationTerminationPointAugmentation != null) {
+                        List<T> updateFromConfigurationValues =
+                                helper.readValues(updateFromConfigurationTerminationPointAugmentation);
+                        assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues);
+                    }
+                    OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
+                            getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
+                                    LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
+                    if (updateFromOperationalTerminationPointAugmentation != null) {
+                        List<T> updateFromOperationalValues =
+                                helper.readValues(updateFromOperationalTerminationPointAugmentation);
+                        assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues);
+                    }
+
+                    // UPDATE:  update the values
+                    testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
+                    OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
+                            new OvsdbTerminationPointAugmentationBuilder();
+                    helper.writeValues(tpUpdateAugmentationBuilder, updateToTestCase.inputValues);
+                    InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
+                    NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
+                    NodeId portUpdateNodeId = createManagedNodeId(portIid);
+                    portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
+                    TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
+                    tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
+                    tpUpdateBuilder.addAugmentation(
+                            OvsdbTerminationPointAugmentation.class,
+                            tpUpdateAugmentationBuilder.build());
+                    portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
+                    Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
+                            portIid, portUpdateNodeBuilder.build()));
+                    Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+
+                    // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
+                    // then repeat for OPERATIONAL data store
+                    OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
+                            getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
+                                    LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
+                    if (updateToConfigurationTerminationPointAugmentation != null) {
+                        List<T> updateToConfigurationValues =
+                                helper.readValues(updateToConfigurationTerminationPointAugmentation);
+                        assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues);
+                        assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationValues);
+                    }
+                    OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
+                            getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
+                                    LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
+                    if (updateToOperationalTerminationPointAugmentation != null) {
+                        List<T> updateToOperationalValues =
+                                helper.readValues(updateToOperationalTerminationPointAugmentation);
+                        if (updateFromTestCase.expectedValues != null) {
+                            assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
+                            assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalValues);
+                        }
+                    }
 
-        return testMap;
+                    // DELETE handled by TestBridge
+                }
+            }
+        }
     }
 
     /*
-     * @see <code>SouthboundIT.testCRUDPortExternalIds()</code>
-     * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
+     * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
+     *
+     * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
      */
-    private void assertExpectedPortExternalIdsExist( List<PortExternalIds> expected,
-                                                     List<PortExternalIds> test ) {
-
-        if (expected != null) {
-            for (PortExternalIds expectedExternalId : expected) {
-                Assert.assertTrue(test.contains(expectedExternalId));
-            }
-        }
+    @Test
+    public void testCRUDTerminationPointPortExternalIds() throws InterruptedException {
+        testCRUDTerminationPoint(new SouthboundPortExternalIdsBuilder(), "TPPortExternalIds",
+                new PortExternalIdsSouthboundHelper());
     }
 
     /*
-     * Tests the CRUD operations for <code>Port</code>
-     * <code>external_ids</code>.
+     * Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
      *
-     * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for
-     * specific test case information
+     * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
      */
     @Test
-    public void testCRUDTerminationPointPortExternalIds()
-            throws InterruptedException, ExecutionException {
+    public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException {
+        testCRUDTerminationPoint(new SouthboundInterfaceExternalIdsBuilder(), "TPInterfaceExternalIds",
+                new InterfaceExternalIdsSouthboundHelper());
+    }
 
-        final String TEST_PREFIX = "CRUDTPPortExternalIds";
+    /*
+     * Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
+     *
+     * @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
+     */
+    @Test
+    public void testCRUDTerminationPointOptions() throws InterruptedException {
+        testCRUDTerminationPoint(new SouthboundOptionsBuilder(), "TPOptions", new OptionsSouthboundHelper());
+    }
 
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
+    /*
+     * Tests the CRUD operations for <code>Interface</code> <code>other_configs</code>.
+     *
+     * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
+     */
+    @Test
+    public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
+        testCRUDTerminationPoint(new SouthboundInterfaceOtherConfigsBuilder(), "TPInterfaceOtherConfigs",
+                new InterfaceOtherConfigsSouthboundHelper());
+    }
 
-        // updateFromTestCases represent the original test case value.
-        // updateToTestCases represent the new value after the update has been
-        // performed.
-        Map<String, Map<String, List<PortExternalIds>>> updateFromTestCases =
-                generatePortExternalIdsTestCases();
-        Map<String, Map<String, List<PortExternalIds>>> updateToTestCases =
-                generatePortExternalIdsTestCases();
-        Map<String, List<PortExternalIds>> updateFromTestCase;
-        List<PortExternalIds> updateFromInputExternalIds;
-        List<PortExternalIds> updateFromExpectedExternalIds;
-        Map<String, List<PortExternalIds>> updateToTestCase;
-        List<PortExternalIds> updateToInputExternalIds;
-        List<PortExternalIds> updateToExpectedExternalIds;
-        String testBridgeName;
-        String testPortName;
-
-        int counter = 1;
-        // multihreads the test using NUM_THREADS
-        ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
-        for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
-            updateFromTestCase = updateFromTestCases.get(
-                    updateFromTestCaseKey);
-            updateFromInputExternalIds = updateFromTestCase.get(
-                    INPUT_VALUES_KEY);
-            updateFromExpectedExternalIds = updateFromTestCase.get(
-                    EXPECTED_VALUES_KEY);
-            for (String testCaseKey : updateToTestCases.keySet()) {
-                testPortName = testBridgeName = String.format("%s_%s_%d",
-                        TEST_PREFIX, testCaseKey, counter);
-                counter += 1;
-                updateToTestCase = updateToTestCases.get(testCaseKey);
-                updateToInputExternalIds = updateToTestCase.get(
-                        INPUT_VALUES_KEY);
-                updateToExpectedExternalIds = updateToTestCase.get(
-                        EXPECTED_VALUES_KEY);
-                TestCRUDTerminationPointPortExternalIdsRunnable testRunnable =
-                        new TestCRUDTerminationPointPortExternalIdsRunnable(
-                                connectionInfo, testBridgeName, testPortName,
-                                updateFromInputExternalIds,
-                                updateFromExpectedExternalIds,
-                                updateToInputExternalIds,
-                                updateToExpectedExternalIds);
-                executor.submit(testRunnable);
-            }
-        }
-        executor.shutdown();
-        executor.awaitTermination(5, TimeUnit.MINUTES);
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
+    /*
+     * Tests the CRUD operations for <code>Port</code> <code>other_configs</code>.
+     *
+     * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
+     */
+    @Test
+    public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
+        testCRUDTerminationPoint(new SouthboundPortOtherConfigsBuilder(), "TPPortOtherConfigs",
+                new PortOtherConfigsSouthboundHelper());
     }
 
-    class TestCRUDTerminationPointPortExternalIdsRunnable implements Runnable {
-        ConnectionInfo connectionInfo;
-        String testBridgeName;
-        String testPortName;
-        List<PortExternalIds> updateFromInputExternalIds;
-        List<PortExternalIds> updateFromExpectedExternalIds;
-        List<PortExternalIds> updateToInputExternalIds;
-        List<PortExternalIds> updateToExpectedExternalIds;
+    @Test
+    public void testCRUDTerminationPointVlan() throws InterruptedException {
+        final Integer CREATED_VLAN_ID = 4000;
+        final Integer UPDATED_VLAN_ID = 4001;
 
-        public TestCRUDTerminationPointPortExternalIdsRunnable(
-                ConnectionInfo connectionInfo,
-                String testBridgeName, String testPortName,
-                List<PortExternalIds> updateFromInputExternalIds,
-                List<PortExternalIds> updateFromExpectedExternalIds,
-                List<PortExternalIds> updateToInputExternalIds,
-                List<PortExternalIds> updateToExpectedExternalIds) {
+        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
 
-            this.connectionInfo = connectionInfo;
-            this.testBridgeName = testBridgeName;
-            this.testPortName = testPortName;
-            this.updateFromInputExternalIds = updateFromInputExternalIds;
-            this.updateFromExpectedExternalIds = updateFromExpectedExternalIds;
-            this.updateToInputExternalIds = updateToInputExternalIds;
-            this.updateToExpectedExternalIds = updateToExpectedExternalIds;
-        }
+        // CREATE
+        try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
+            OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
+            Assert.assertNotNull(bridge);
+            NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
+                    connectionInfo, bridge.getBridgeName()));
+            OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
+                    createGenericOvsdbTerminationPointAugmentationBuilder();
+            String portName = "testTerminationPointVlanId";
+            ovsdbTerminationBuilder.setName(portName);
+            ovsdbTerminationBuilder.setVlanTag(new VlanId(CREATED_VLAN_ID));
+            Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
+            InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
+            Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
+            Assert.assertNotNull(terminationPointNode);
 
-        @Override
-        public void run() {
-            try {
-                test();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
+            // READ
+            List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
+            OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation;
+            for (TerminationPoint terminationPoint : terminationPoints) {
+                ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
+                        OvsdbTerminationPointAugmentation.class);
+                if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
+                    VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
+                    Assert.assertNotNull(actualVlanId);
+                    Integer actualVlanIdInt = actualVlanId.getValue();
+                    Assert.assertEquals(CREATED_VLAN_ID, actualVlanIdInt);
+                }
             }
-        }
-
-        private void test() throws InterruptedException {
 
-            final int TERMINATION_POINT_TEST_INDEX = 0;
-            // CREATE: Create the test bridge
-            Assert.assertTrue(addBridge(connectionInfo, null,
-                    testBridgeName, null, true,
-                    SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
-                    true, null, null, null, null));
-            NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
-                    connectionInfo, new OvsdbBridgeName(testBridgeName)));
-            OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
-                    createGenericOvsdbTerminationPointAugmentationBuilder();
-            tpCreateAugmentationBuilder.setName(testPortName);
-            tpCreateAugmentationBuilder.setPortExternalIds(updateFromInputExternalIds);
-            Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
-
-            // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
-            // then repeat for OPERATIONAL data store
-            OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
-            List<PortExternalIds> updateFromConfigurationExternalIds =
-                    updateFromConfigurationTerminationPointAugmentation
-                            .getPortExternalIds();
-            assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateFromConfigurationExternalIds);
-            OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
-            List<PortExternalIds> updateFromOperationalExternalIds = updateFromOperationalTerminationPointAugmenation
-                    .getPortExternalIds();
-            assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds);
-
-            // UPDATE:  update the external_ids
-            testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
+            // UPDATE
+            NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
                     new OvsdbTerminationPointAugmentationBuilder();
-            tpUpdateAugmentationBuilder.setPortExternalIds(updateToInputExternalIds);
+            tpUpdateAugmentationBuilder.setVlanTag(new VlanId(UPDATED_VLAN_ID));
             InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
             NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
             NodeId portUpdateNodeId = createManagedNodeId(portIid);
             portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
-            tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
+            tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
             tpUpdateBuilder.addAugmentation(
                     OvsdbTerminationPointAugmentation.class,
                     tpUpdateAugmentationBuilder.build());
+            tpUpdateBuilder.setTpId(new TpId(portName));
             portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
-            boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
-                    portIid, portUpdateNodeBuilder.build());
+            Assert.assertTrue(
+                    mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
-            Assert.assertTrue(result);
-
-            // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
-            // then repeat for OPERATIONAL data store
-            OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
-            List<PortExternalIds> updateToConfigurationExternalIds = updateToConfigurationTerminationPointAugmentation
-                    .getPortExternalIds();
-            assertExpectedPortExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
-            assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateToConfigurationExternalIds);
-            OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
-            List<PortExternalIds> updateToOperationalExternalIds =
-                    updateToOperationalTerminationPointAugmentation.getPortExternalIds();
-            if (updateFromExpectedExternalIds != null) {
-                assertExpectedPortExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds);
-                assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateToOperationalExternalIds);
-            }
 
-            // DELETE
-            Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
-        }
-    }
-
-
-
-    /*
-     * Generates the test cases involved in testing InterfaceExternalIds.  See inline comments for descriptions of
-     * the particular cases considered.
-     *
-     * The return value is a Map in the form (K,V)=(testCaseName,testCase).
-     * - testCaseName is a String
-     * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
-     *     either corresponding INPUT interface external_ids, or EXPECTED interface external_ids
-     *     INPUT    is the List we use when calling
-     *              <code>TerminationPointAugmentationBuilder.setInterfaceExternalIds()</code>
-     *     EXPECTED is the List we expect to receive after calling
-     *              <code>TerminationPointAugmentationBuilder.getInterfaceExternalIds()</code>
-     */
-    private Map<String, Map<String, List<InterfaceExternalIds>>> generateInterfaceExternalIdsTestCases() {
-        Map<String, Map<String, List<InterfaceExternalIds>>> testMap = new HashMap<>();
-
-        final String INTERFACE_EXTERNAL_ID_KEY = "IntExternalIdKey";
-        final String INTERFACE_EXTERNAL_ID_VALUE = "IntExternalIdValue";
-        final String FORMAT_STR = "%s_%s_%d";
-        final String GOOD_KEY = "GoodKey";
-        final String GOOD_VALUE = "GoodValue";
-        final String NO_VALUE_FOR_KEY = "NoValueForKey";
-        final String NO_KEY_FOR_VALUE = "NoKeyForValue";
-
-        // Test Case 1:  TestOneExternalId
-        // Test Type:    Positive
-        // Description:  Create a termination point with one InterfaceExternalIds
-        // Expected:     A termination point is created with the single external_ids specified below
-        final String testOneExternalIdName = "TestOneExternalId";
-        int externalIdCounter = 0;
-        List<InterfaceExternalIds> oneExternalId = Lists.newArrayList(
-                (new InterfaceExternalIdsBuilder()
-                        .setExternalIdKey(String.format(FORMAT_STR, testOneExternalIdName,
-                                INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setExternalIdValue(String.format(FORMAT_STR, testOneExternalIdName,
-                                INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()));
-        Map<String,List<InterfaceExternalIds>> testCase = Maps.newHashMap();
-        testCase.put(EXPECTED_VALUES_KEY, oneExternalId);
-        testCase.put(INPUT_VALUES_KEY, oneExternalId);
-        testMap.put(testOneExternalIdName, testCase);
-
-        // Test Case 2:  TestFiveExternalId
-        // Test Type:    Positive
-        // Description:  Create a termination point with multiple (five) InterfaceExternalIds
-        // Expected:     A termination point is created with the five external_ids specified below
-        final String testFiveExternalIdName = "TestFiveExternalId";
-        externalIdCounter = 0;
-        List<InterfaceExternalIds> fiveExternalId = Lists.newArrayList(
-                (new InterfaceExternalIdsBuilder()
-                        .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()),
-                (new InterfaceExternalIdsBuilder()
-                        .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()),
-                (new InterfaceExternalIdsBuilder()
-                        .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()),
-                (new InterfaceExternalIdsBuilder()
-                        .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()),
-                (new InterfaceExternalIdsBuilder()
-                        .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()));
-        testCase = Maps.newHashMap();
-        testCase.put(EXPECTED_VALUES_KEY, fiveExternalId);
-        testCase.put(INPUT_VALUES_KEY, fiveExternalId);
-        testMap.put(testFiveExternalIdName, testCase);
-
-        // Test Case 3:  TestOneGoodExternalIdOneMalformedExternalIdValue
-        // Test Type:    Negative
-        // Description:
-        //     One perfectly fine InterfaceExternalId
-        //        (TestOneGoodExternalIdOneMalformedExternalIdValue_IntExternalIdKey_1,
-        //        TestOneGoodExternalIdOneMalformedExternalId_IntExternalIdValue_1)
-        //     and one malformed PortExternalId which only has key specified
-        //        (TestOneGoodExternalIdOneMalformedExternalIdValue_NoValueForKey_2,
-        //        UNSPECIFIED)
-        // Expected:     A termination point is created without any external_ids
-        final String testOneGoodExternalIdOneMalformedExternalIdValueName =
-                "TestOneGoodExternalIdOneMalformedExternalIdValue";
-        externalIdCounter = 0;
-        InterfaceExternalIds oneGood = new InterfaceExternalIdsBuilder()
-                .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdValueName,
-                        GOOD_KEY, ++externalIdCounter))
-                .setExternalIdValue(String.format(FORMAT_STR,
-                        testOneGoodExternalIdOneMalformedExternalIdValueName,
-                        GOOD_VALUE, externalIdCounter))
-                .build();
-        InterfaceExternalIds oneBad = new InterfaceExternalIdsBuilder()
-                .setExternalIdKey(String.format(FORMAT_STR,
-                        testOneGoodExternalIdOneMalformedExternalIdValueName, NO_VALUE_FOR_KEY, ++externalIdCounter))
-                .build();
-        List<InterfaceExternalIds> oneGoodOneBadInput = Lists.newArrayList(
-                oneGood, oneBad);
-        List<InterfaceExternalIds> oneGoodOneBadExpected = null;
-        testCase = Maps.newHashMap();
-        testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
-        testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
-        testMap.put(testOneGoodExternalIdOneMalformedExternalIdValueName, testCase);
-
-        // Test Case 4:  TestOneGoodExternalIdOneMalformedExternalIdKey
-        // Test Type:    Negative
-        // Description:
-        //     One perfectly fine InterfaceExternalId
-        //        (TestOneGoodExternalIdOneMalformedExternalIdValue_IntExternalIdKey_1,
-        //        TestOneGoodExternalIdOneMalformedExternalId_IntExternalIdValue_1)
-        //     and one malformed BridgeExternalId which only has key specified
-        //        (UNSPECIFIED,
-        //        TestOneGoodExternalIdOneMalformedExternalIdKey_NoKeyForValue_2)
-        // Expected:     A termination point is created without any external_ids
-        final String testOneGoodExternalIdOneMalformedExternalIdKeyName =
-                "TestOneGoodExternalIdOneMalformedExternalIdKey";
-        externalIdCounter = 0;
-        oneGood = new InterfaceExternalIdsBuilder()
-                .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdKeyName,
-                        GOOD_KEY, ++externalIdCounter))
-                .setExternalIdValue(String.format(FORMAT_STR,
-                        testOneGoodExternalIdOneMalformedExternalIdKeyName,
-                        GOOD_VALUE, externalIdCounter))
-                .build();
-        oneBad = new InterfaceExternalIdsBuilder()
-                .setExternalIdKey(String.format(FORMAT_STR,
-                        testOneGoodExternalIdOneMalformedExternalIdKeyName, NO_KEY_FOR_VALUE, ++externalIdCounter))
-                .build();
-        oneGoodOneBadInput = Lists.newArrayList(
-                oneGood, oneBad);
-        oneGoodOneBadExpected = null;
-        testCase = Maps.newHashMap();
-        testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
-        testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
-        testMap.put(testOneGoodExternalIdOneMalformedExternalIdKeyName, testCase);
-
-        return testMap;
-    }
-
-    /*
-     * @see <code>SouthboundIT.testCRUDInterfaceExternalIds()</code>
-     * This is helper test method to compare a test "set" of InterfaceExternalIds against an expected "set"
-     */
-    private void assertExpectedInterfaceExternalIdsExist( List<InterfaceExternalIds> expected,
-                                                          List<InterfaceExternalIds> test ) {
-
-        if (expected != null) {
-            for (InterfaceExternalIds expectedExternalId : expected) {
-                Assert.assertTrue(test.contains(expectedExternalId));
+            terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
+            terminationPoints = terminationPointNode.getTerminationPoint();
+            for (TerminationPoint terminationPoint : terminationPoints) {
+                ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
+                        OvsdbTerminationPointAugmentation.class);
+                if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
+                    VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
+                    Assert.assertNotNull(actualVlanId);
+                    Integer actualVlanIdInt = actualVlanId.getValue();
+                    Assert.assertEquals(UPDATED_VLAN_ID, actualVlanIdInt);
+                }
             }
-        }
-    }
 
-    /*
-     * Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
-     *
-     * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
-     */
-    @Test
-    public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException, ExecutionException {
-        final String TEST_PREFIX = "CRUDTPInterfaceExternalIds";
-
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
-
-        // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
-        // the update has been performed.
-        Map<String, Map<String, List<InterfaceExternalIds>>> updateFromTestCases =
-                generateInterfaceExternalIdsTestCases();
-        Map<String, Map<String, List<InterfaceExternalIds>>> updateToTestCases =
-                generateInterfaceExternalIdsTestCases();
-        Map<String, List<InterfaceExternalIds>> updateFromTestCase;
-        List<InterfaceExternalIds> updateFromInputExternalIds;
-        List<InterfaceExternalIds> updateFromExpectedExternalIds;
-        Map<String, List<InterfaceExternalIds>> updateToTestCase;
-        List<InterfaceExternalIds> updateToInputExternalIds;
-        List<InterfaceExternalIds> updateToExpectedExternalIds;
-        String testBridgeName;
-        String testPortName;
-
-        int counter = 1;
-        // multihreads the test using NUM_THREADS
-        ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
-        for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
-            updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
-            updateFromInputExternalIds = updateFromTestCase.get(INPUT_VALUES_KEY);
-            updateFromExpectedExternalIds = updateFromTestCase.get(EXPECTED_VALUES_KEY);
-            for (String testCaseKey : updateToTestCases.keySet()) {
-                testPortName = testBridgeName = String.format("%s_%s_%d", TEST_PREFIX, testCaseKey, counter);
-                counter += 1;
-                updateToTestCase = updateToTestCases.get(testCaseKey);
-                updateToInputExternalIds = updateToTestCase.get(INPUT_VALUES_KEY);
-                updateToExpectedExternalIds = updateToTestCase.get(EXPECTED_VALUES_KEY);
-
-                TestCRUDTerminationPointInterfaceExternalIdsRunnable testRunnable =
-                        new TestCRUDTerminationPointInterfaceExternalIdsRunnable(
-                                connectionInfo, testBridgeName, testPortName,
-                                updateFromInputExternalIds,
-                                updateFromExpectedExternalIds,
-                                updateToInputExternalIds,
-                                updateToExpectedExternalIds);
-                executor.submit(testRunnable);
-            }
+            // DELETE handled by TestBridge
         }
-        executor.shutdown();
-        executor.awaitTermination(5, TimeUnit.MINUTES);
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
     }
 
-    class TestCRUDTerminationPointInterfaceExternalIdsRunnable implements Runnable {
-
-        ConnectionInfo connectionInfo;
-        String testBridgeName;
-        String testPortName;
-        List<InterfaceExternalIds> updateFromInputExternalIds;
-        List<InterfaceExternalIds> updateFromExpectedExternalIds;
-        List<InterfaceExternalIds> updateToInputExternalIds;
-        List<InterfaceExternalIds> updateToExpectedExternalIds;
-
-        TestCRUDTerminationPointInterfaceExternalIdsRunnable(
-                ConnectionInfo connectionInfo, String testBridgeName,
-                String testPortName,
-                List<InterfaceExternalIds> updateFromInputExternalIds,
-                List<InterfaceExternalIds> updateFromExpectedExternalIds,
-                List<InterfaceExternalIds> updateToInputExternalIds,
-                List<InterfaceExternalIds> updateToExpectedExternalIds) {
-
-            this.connectionInfo = connectionInfo;
-            this.testBridgeName = testBridgeName;
-            this.testPortName = testPortName;
-            this.updateFromInputExternalIds = updateFromInputExternalIds;
-            this.updateFromExpectedExternalIds = updateFromExpectedExternalIds;
-            this.updateToInputExternalIds = updateToInputExternalIds;
-            this.updateToExpectedExternalIds = updateToExpectedExternalIds;
-        }
-
-        @Override
-        public void run() {
-            try {
-                test();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
+    @Test
+    public void testCRUDTerminationPointVlanModes() throws InterruptedException {
+        final VlanMode UPDATED_VLAN_MODE = VlanMode.Access;
+        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
+        VlanMode []vlanModes = VlanMode.values();
+        for (VlanMode vlanMode : vlanModes) {
+            // CREATE
+            try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
+                OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
+                Assert.assertNotNull(bridge);
+                NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
+                        connectionInfo, bridge.getBridgeName()));
+                OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
+                        createGenericOvsdbTerminationPointAugmentationBuilder();
+                String portName = "testTerminationPointVlanMode" + vlanMode.toString();
+                ovsdbTerminationBuilder.setName(portName);
+                ovsdbTerminationBuilder.setVlanMode(vlanMode);
+                Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
+                InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
+                Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
+                Assert.assertNotNull(terminationPointNode);
+
+                // READ
+                List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
+                for (TerminationPoint terminationPoint : terminationPoints) {
+                    OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
+                            terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
+                    if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
+                        //test
+                        Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode));
+                    }
+                }
 
-        public void test() throws InterruptedException {
+                // UPDATE
+                NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
+                OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
+                        new OvsdbTerminationPointAugmentationBuilder();
+                tpUpdateAugmentationBuilder.setVlanMode(UPDATED_VLAN_MODE);
+                InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
+                NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
+                NodeId portUpdateNodeId = createManagedNodeId(portIid);
+                portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
+                TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
+                tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
+                tpUpdateBuilder.addAugmentation(
+                        OvsdbTerminationPointAugmentation.class,
+                        tpUpdateAugmentationBuilder.build());
+                tpUpdateBuilder.setTpId(new TpId(portName));
+                portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
+                Assert.assertTrue(
+                        mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
+                Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+
+                terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
+                terminationPoints = terminationPointNode.getTerminationPoint();
+                for (TerminationPoint terminationPoint : terminationPoints) {
+                    OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
+                            terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
+                    if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
+                        //test
+                        Assert.assertEquals(UPDATED_VLAN_MODE, ovsdbTerminationPointAugmentation.getVlanMode());
+                    }
+                }
 
-            final int TERMINATION_POINT_TEST_INDEX = 0;
-            // CREATE: Create the test interface
-            Assert.assertTrue(addBridge(connectionInfo, null,
-                    testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
-                    true, null, null, null, null));
-            NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
-                    connectionInfo, new OvsdbBridgeName(testBridgeName)));
-            OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
-                    createGenericOvsdbTerminationPointAugmentationBuilder();
-            tpCreateAugmentationBuilder.setName(testPortName);
-            tpCreateAugmentationBuilder.setInterfaceExternalIds(updateFromInputExternalIds);
-            Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
-
-            // READ: Read the test interface and ensure changes are propagated to the CONFIGURATION data store,
-            // then repeat for OPERATIONAL data store
-            OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
-            List<InterfaceExternalIds> updateFromConfigurationExternalIds =
-                    updateFromConfigurationTerminationPointAugmentation
-                            .getInterfaceExternalIds();
-            assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
-                    updateFromConfigurationExternalIds);
-            OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
-            List<InterfaceExternalIds> updateFromOperationalExternalIds =
-                    updateFromOperationalTerminationPointAugmenation
-                            .getInterfaceExternalIds();
-            assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
-                    updateFromOperationalExternalIds);
-
-            // UPDATE:  update the external_ids
-            testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
-            OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
-                    new OvsdbTerminationPointAugmentationBuilder();
-            tpUpdateAugmentationBuilder.setInterfaceExternalIds(updateToInputExternalIds);
-            InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
-            NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
-            NodeId portUpdateNodeId = createManagedNodeId(portIid);
-            portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
-            TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
-            tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
-            tpUpdateBuilder.addAugmentation(
-                    OvsdbTerminationPointAugmentation.class,
-                    tpUpdateAugmentationBuilder.build());
-            portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
-            boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
-                    portIid, portUpdateNodeBuilder.build());
-            Thread.sleep(OVSDB_UPDATE_TIMEOUT);
-            Assert.assertTrue(result);
-
-            // READ: the test interface and ensure changes are propagated to the CONFIGURATION data store,
-            // then repeat for OPERATIONAL data store
-            OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
-            List<InterfaceExternalIds> updateToConfigurationExternalIds =
-                    updateToConfigurationTerminationPointAugmentation
-                    .getInterfaceExternalIds();
-            assertExpectedInterfaceExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
-            assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
-                    updateToConfigurationExternalIds);
-            OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
-            List<InterfaceExternalIds> updateToOperationalExternalIds = updateToOperationalTerminationPointAugmentation
-                    .getInterfaceExternalIds();
-            if (updateFromExpectedExternalIds != null) {
-                assertExpectedInterfaceExternalIdsExist(updateToExpectedExternalIds,
-                        updateToOperationalExternalIds);
-                assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
-                        updateToOperationalExternalIds);
-            } else {
-                Assert.assertNull(updateToOperationalExternalIds);
+                // DELETE handled by TestBridge
             }
-
-            // DELETE
-            Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
         }
     }
 
-    /*
-     * Generates the test cases involved in testing TP Options.  See inline comments for descriptions of
-     * the particular cases considered.
-     *
-     * The return value is a Map in the form (K,V)=(testCaseName,testCase).
-     * - testCaseName is a String
-     * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
-     *     either corresponding INPUT TP Options, or EXPECTED TP Options
-     *     INPUT    is the List we use when calling
-     *              <code>TerminationPointAugmentationBuilder.setOptions()</code>
-     *     EXPECTED is the List we expect to receive after calling
-     *              <code>TerminationPointAugmentationBuilder.getOptions()</code>
-     */
-    private Map<String, Map<String, List<Options>>> generateTerminationPointOptionsTestCases() {
-        Map<String, Map<String, List<Options>>> testMap = new HashMap<>();
-
-        final String TP_OPTIONS_KEY = "TPOptionsKey";
-        final String TP_OPTIONS_VALUE = "TPOptionsValue";
-        final String FORMAT_STR = "%s_%s_%d";
-        final String GOOD_KEY = "GoodKey";
-        final String GOOD_VALUE = "GoodValue";
-        final String NO_VALUE_FOR_KEY = "NoValueForKey";
-        final String NO_KEY_FOR_VALUE = "NoKeyForValue";
-
-        // Test Case 1:  TestOneOptions
-        // Test Type:    Positive
-        // Description:  Create a termination point with one Options
-        // Expected:     A termination point is created with the single Options specified below
-        final String testOneOptionsName = "TestOneOptions";
-        int optionsCounter = 0;
-        List<Options> oneOptions = Lists.newArrayList(
-                (new OptionsBuilder()
-                        .setOption(String.format(FORMAT_STR, testOneOptionsName,
-                                TP_OPTIONS_KEY, ++optionsCounter))
-                        .setValue(String.format(FORMAT_STR, testOneOptionsName,
-                                TP_OPTIONS_VALUE, optionsCounter))
-                        .build()));
-        Map<String,List<Options>> testCase = Maps.newHashMap();
-        testCase.put(EXPECTED_VALUES_KEY, oneOptions);
-        testCase.put(INPUT_VALUES_KEY, oneOptions);
-        testMap.put(testOneOptionsName, testCase);
-
-        // Test Case 2:  TestFiveOptions
-        // Test Type:    Positive
-        // Description:  Create a termination point with multiple (five) Options
-        // Expected:     A termination point is created with the five options specified below
-        final String testFiveOptionsName = "TestFiveOptions";
-        optionsCounter = 0;
-        List<Options> fiveOptions = Lists.newArrayList(
-                (new OptionsBuilder()
-                        .setOption(String.format(FORMAT_STR, testFiveOptionsName,
-                                TP_OPTIONS_KEY, ++optionsCounter))
-                        .setValue(String.format(FORMAT_STR, testFiveOptionsName,
-                                TP_OPTIONS_VALUE, optionsCounter))
-                        .build()),
-                (new OptionsBuilder()
-                        .setOption(String.format(FORMAT_STR, testFiveOptionsName,
-                                TP_OPTIONS_KEY, ++optionsCounter))
-                        .setValue(String.format(FORMAT_STR, testFiveOptionsName,
-                                TP_OPTIONS_VALUE, optionsCounter))
-                        .build()),
-                (new OptionsBuilder()
-                        .setOption(String.format(FORMAT_STR, testFiveOptionsName,
-                                TP_OPTIONS_KEY, ++optionsCounter))
-                        .setValue(String.format(FORMAT_STR, testFiveOptionsName,
-                                TP_OPTIONS_VALUE, optionsCounter))
-                        .build()),
-                (new OptionsBuilder()
-                        .setOption(String.format(FORMAT_STR, testFiveOptionsName,
-                                TP_OPTIONS_KEY, ++optionsCounter))
-                        .setValue(String.format(FORMAT_STR, testFiveOptionsName,
-                                TP_OPTIONS_VALUE, optionsCounter))
-                        .build()),
-                (new OptionsBuilder()
-                        .setOption(String.format(FORMAT_STR, testFiveOptionsName,
-                                TP_OPTIONS_KEY, ++optionsCounter))
-                        .setValue(String.format(FORMAT_STR, testFiveOptionsName,
-                                TP_OPTIONS_VALUE, optionsCounter))
-                        .build()));
-        testCase = Maps.newHashMap();
-        testCase.put(EXPECTED_VALUES_KEY, fiveOptions);
-        testCase.put(INPUT_VALUES_KEY, fiveOptions);
-        testMap.put(testFiveOptionsName, testCase);
-
-        // Test Case 3:  TestOneGoodOptionsOneMalformedOptionsValue
-        // Test Type:    Negative
-        // Description:
-        //     One perfectly fine Options
-        //        (TestOneGoodOptionsOneMalformedOptionsValue_OptionsKey_1,
-        //        TestOneGoodOptionsOneMalformedOptions_OptionsValue_1)
-        //     and one malformed Options which only has key specified
-        //        (TestOneGoodOptionsOneMalformedOptionsValue_NoValueForKey_2,
-        //        UNSPECIFIED)
-        // Expected:     A termination point is created without any options
-        final String testOneGoodOptionsOneMalformedOptionsValueName =
-                "TestOneGoodOptionsOneMalformedOptionsValue";
-        optionsCounter = 0;
-        Options oneGood = new OptionsBuilder()
-                .setOption(String.format(FORMAT_STR, testOneGoodOptionsOneMalformedOptionsValueName,
-                        GOOD_KEY, ++optionsCounter))
-                .setValue(String.format(FORMAT_STR,
-                        testOneGoodOptionsOneMalformedOptionsValueName,
-                        GOOD_VALUE, optionsCounter))
-                .build();
-        Options oneBad = new OptionsBuilder()
-                .setOption(String.format(FORMAT_STR,
-                        testOneGoodOptionsOneMalformedOptionsValueName, NO_VALUE_FOR_KEY, ++optionsCounter))
-                .build();
-        List<Options> oneGoodOneBadInput = Lists.newArrayList(oneGood, oneBad);
-        List<Options> oneGoodOneBadExpected = null;
-        testCase = Maps.newHashMap();
-        testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
-        testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
-        testMap.put(testOneGoodOptionsOneMalformedOptionsValueName, testCase);
-
-        // Test Case 4:  TestOneGoodOptionsOneMalformedOptionsKey
-        // Test Type:    Negative
-        // Description:
-        //     One perfectly fine Options
-        //        (TestOneGoodOptionsOneMalformedOptionsValue_OptionsKey_1,
-        //        TestOneGoodOptionsOneMalformedOptions_OptionsValue_1)
-        //     and one malformed Options which only has key specified
-        //        (UNSPECIFIED,
-        //        TestOneGoodOptionsOneMalformedOptionsKey_NoKeyForValue_2)
-        // Expected:     A termination point is created without any options
-        final String testOneGoodOptionsOneMalformedOptionsKeyName =
-                "TestOneGoodOptionsOneMalformedOptionsKey";
-        optionsCounter = 0;
-        oneGood = new OptionsBuilder()
-                .setOption(String.format(FORMAT_STR, testOneGoodOptionsOneMalformedOptionsKeyName,
-                        GOOD_KEY, ++optionsCounter))
-                .setValue(String.format(FORMAT_STR,
-                        testOneGoodOptionsOneMalformedOptionsKeyName,
-                        GOOD_VALUE, optionsCounter))
-                .build();
-        oneBad = new OptionsBuilder()
-                .setOption(String.format(FORMAT_STR,
-                        testOneGoodOptionsOneMalformedOptionsKeyName, NO_KEY_FOR_VALUE, ++optionsCounter))
-                .build();
-        oneGoodOneBadInput = Lists.newArrayList(oneGood, oneBad);
-        oneGoodOneBadExpected = null;
-        testCase = Maps.newHashMap();
-        testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
-        testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
-        testMap.put(testOneGoodOptionsOneMalformedOptionsKeyName, testCase);
-
-        return testMap;
+    @SuppressWarnings("unchecked")
+    private List<Set<Integer>> generateVlanSets() {
+        int min = 0;
+        int max = 4095;
+        return Lists.newArrayList(
+                Collections.<Integer>emptySet(),
+                Sets.newHashSet(2222),
+                Sets.newHashSet(min, max, min + 1, max - 1, (max - min) / 2));
     }
 
-    /*
-     * @see <code>SouthboundIT.testCRUDTerminationPointOptions()</code>
-     * This is helper test method to compare a test "set" of Options against an expected "set"
-     */
-    private void assertExpectedOptionsExist( List<Options> expected,
-                                             List<Options> test ) {
-
-        if (expected != null) {
-            for (Options expectedOption : expected) {
-                Assert.assertTrue(test.contains(expectedOption));
-            }
+    private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
+        List<Trunks> trunkList = Lists.newArrayList();
+        for (Integer trunk : trunkSet) {
+            TrunksBuilder trunkBuilder = new TrunksBuilder();
+            trunkBuilder.setTrunk(new VlanId(trunk));
+            trunkList.add(trunkBuilder.build());
         }
+        return trunkList;
     }
 
-    /*
-     * Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
-     *
-     * @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
-     */
     @Test
-    public void testCRUDTerminationPointOptions() throws InterruptedException {
-        final String TEST_PREFIX = "CRUDTPOptions";
-
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
-
-        // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
-        // the update has been performed.
-        Map<String, Map<String, List<Options>>> updateFromTestCases =
-                generateTerminationPointOptionsTestCases();
-        Map<String, Map<String, List<Options>>> updateToTestCases =
-                generateTerminationPointOptionsTestCases();
-        Map<String, List<Options>> updateFromTestCase;
-        List<Options> updateFromInputOptions;
-        List<Options> updateFromExpectedOptions;
-        Map<String, List<Options>> updateToTestCase;
-        List<Options> updateToInputOptions;
-        List<Options> updateToExpectedOptions;
-        String testBridgeName;
-        String testPortName;
-
-        int counter = 1;
-        ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
-        for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
-            updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
-            updateFromInputOptions = updateFromTestCase.get(INPUT_VALUES_KEY);
-            updateFromExpectedOptions = updateFromTestCase.get(EXPECTED_VALUES_KEY);
-            for (String testCaseKey : updateToTestCases.keySet()) {
-                testPortName = testBridgeName = String.format("%s_%s_%d", TEST_PREFIX, testCaseKey, counter);
-                counter += 1;
-                updateToTestCase = updateToTestCases.get(testCaseKey);
-                updateToInputOptions = updateToTestCase.get(INPUT_VALUES_KEY);
-                updateToExpectedOptions = updateToTestCase.get(EXPECTED_VALUES_KEY);
-
-                TestCRUDTerminationPointOptionsRunnable testRunnable =
-                        new TestCRUDTerminationPointOptionsRunnable(
-                                connectionInfo, testBridgeName, testPortName,
-                                updateFromInputOptions,
-                                updateFromExpectedOptions,
-                                updateToInputOptions,
-                                updateToExpectedOptions);
-                executor.submit(testRunnable);
-            }
-        }
-        executor.shutdown();
-        executor.awaitTermination(5, TimeUnit.MINUTES);
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
-    }
-
-    class TestCRUDTerminationPointOptionsRunnable implements Runnable {
-
-        ConnectionInfo connectionInfo;
-        String testBridgeName;
-        String testPortName;
-        List<Options> updateFromInputOptions;
-        List<Options> updateFromExpectedOptions;
-        List<Options> updateToInputOptions;
-        List<Options> updateToExpectedOptions;
-
-        TestCRUDTerminationPointOptionsRunnable(
-                ConnectionInfo connectionInfo, String testBridgeName,
-                String testPortName,
-                List<Options> updateFromInputOptions,
-                List<Options> updateFromExpectedOptions,
-                List<Options> updateToInputOptions,
-                List<Options> updateToExpectedOptions) {
+    public void testCRUDTerminationPointVlanTrunks() throws InterruptedException {
+        final List<Trunks> UPDATED_TRUNKS = buildTrunkList(Sets.newHashSet(2011));
+        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
+        Iterable<Set<Integer>> vlanSets = generateVlanSets();
+        int testCase = 0;
+        for (Set<Integer> vlanSet : vlanSets) {
+            ++testCase;
+            // CREATE
+            try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
+                OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
+                Assert.assertNotNull(bridge);
+                NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
+                        connectionInfo, bridge.getBridgeName()));
+                OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
+                        createGenericOvsdbTerminationPointAugmentationBuilder();
+                String portName = "testTerminationPointVlanTrunks" + testCase;
+                ovsdbTerminationBuilder.setName(portName);
+                List<Trunks> trunks = buildTrunkList(vlanSet);
+                ovsdbTerminationBuilder.setTrunks(trunks);
+                Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
+                InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
+                Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
+                Assert.assertNotNull(terminationPointNode);
+
+                // READ
+                List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
+                for (TerminationPoint terminationPoint : terminationPoints) {
+                    OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
+                            terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
+                    if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
+                        List<Trunks> actualTrunks = ovsdbTerminationPointAugmentation.getTrunks();
+                        for (Trunks trunk : trunks) {
+                            Assert.assertTrue(actualTrunks.contains(trunk));
+                        }
+                    }
+                }
 
-            this.connectionInfo = connectionInfo;
-            this.testBridgeName = testBridgeName;
-            this.testPortName = testPortName;
-            this.updateFromInputOptions = updateFromInputOptions;
-            this.updateFromExpectedOptions = updateFromExpectedOptions;
-            this.updateToInputOptions = updateToInputOptions;
-            this.updateToExpectedOptions = updateToExpectedOptions;
-        }
 
-        @Override
-        public void run() {
-            try {
-                test();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
+                // UPDATE
+                NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
+                OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
+                        new OvsdbTerminationPointAugmentationBuilder();
+                tpUpdateAugmentationBuilder.setTrunks(UPDATED_TRUNKS);
+                InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
+                NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
+                NodeId portUpdateNodeId = createManagedNodeId(portIid);
+                portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
+                TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
+                tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
+                tpUpdateBuilder.addAugmentation(
+                        OvsdbTerminationPointAugmentation.class,
+                        tpUpdateAugmentationBuilder.build());
+                tpUpdateBuilder.setTpId(new TpId(portName));
+                portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
+                Assert.assertTrue(
+                        mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
+                Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+
+                terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
+                terminationPoints = terminationPointNode.getTerminationPoint();
+                for (TerminationPoint terminationPoint : terminationPoints) {
+                    OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
+                            terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
+                    if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
+                        //test
+                        Assert.assertEquals(UPDATED_TRUNKS, ovsdbTerminationPointAugmentation.getTrunks());
+                    }
+                }
 
-        public void test() throws InterruptedException {
-            final int TERMINATION_POINT_TEST_INDEX = 0;
-            // CREATE: Create the test interface
-            Assert.assertTrue(addBridge(connectionInfo, null,
-                    testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
-                    true, null, null, null, null));
-            NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
-                    connectionInfo, new OvsdbBridgeName(testBridgeName)));
-            OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
-                    createGenericOvsdbTerminationPointAugmentationBuilder();
-            tpCreateAugmentationBuilder.setName(testPortName);
-            tpCreateAugmentationBuilder.setOptions(updateFromInputOptions);
-            Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
-
-            // READ: Read the test interface and ensure changes are propagated to the CONFIGURATION data store,
-            // then repeat for OPERATIONAL data store
-            OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
-            List<Options> updateFromConfigurationOptions = updateFromConfigurationTerminationPointAugmentation
-                    .getOptions();
-            assertExpectedOptionsExist(updateFromExpectedOptions,
-                    updateFromConfigurationOptions);
-            OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
-            List<Options> updateFromOperationalOptions = updateFromOperationalTerminationPointAugmentation
-                    .getOptions();
-            assertExpectedOptionsExist(updateFromExpectedOptions,
-                    updateFromOperationalOptions);
-
-            // UPDATE:  update the external_ids
-            testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
-            OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
-                    new OvsdbTerminationPointAugmentationBuilder();
-            tpUpdateAugmentationBuilder.setOptions(updateToInputOptions);
-            InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
-            NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
-            NodeId portUpdateNodeId = createManagedNodeId(portIid);
-            portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
-            TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
-            tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
-            tpUpdateBuilder.addAugmentation(
-                    OvsdbTerminationPointAugmentation.class,
-                    tpUpdateAugmentationBuilder.build());
-            portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
-            boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
-                    portIid, portUpdateNodeBuilder.build());
-            Thread.sleep(OVSDB_UPDATE_TIMEOUT);
-            Assert.assertTrue(result);
-
-            // READ: the test interface and ensure changes are propagated to the CONFIGURATION data store,
-            // then repeat for OPERATIONAL data store
-            OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
-            List<Options> updateToConfigurationOptions = updateToConfigurationTerminationPointAugmentation
-                    .getOptions();
-            assertExpectedOptionsExist(updateToExpectedOptions, updateToConfigurationOptions);
-            assertExpectedOptionsExist(updateFromExpectedOptions, updateToConfigurationOptions);
-            OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
-            List<Options> updateToOperationalOptions = updateToOperationalTerminationPointAugmentation
-                    .getOptions();
-            if (updateFromExpectedOptions != null) {
-                assertExpectedOptionsExist(updateToExpectedOptions, updateToOperationalOptions);
-                assertExpectedOptionsExist(updateFromExpectedOptions, updateToOperationalOptions);
+                // DELETE handled by TestBridge
             }
-
-            // DELETE
-            Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
         }
     }
 
-    /*
-     * Generates the test cases involved in testing Interface other_configs.  See inline comments for descriptions of
-     * the particular cases considered.
-     *
-     * The return value is a Map in the form (K,V)=(testCaseName,testCase).
-     * - testCaseName is a String
-     * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
-     *     either corresponding INPUT interface other_configs, or EXPECTED interface other_configs
-     *     INPUT    is the List we use when calling
-     *              <code>TerminationPointAugmentationBuilder.setInterfaceOtherConfigs()</code>
-     *     EXPECTED is the List we expect to receive after calling
-     *              <code>TerminationPointAugmentationBuilder.getInterfaceOtherConfigs()</code>
-     */
-    private Map<String, Map<String, List<InterfaceOtherConfigs>>> generateInterfaceOtherConfigsTestCases() {
-        Map<String, Map<String, List<InterfaceOtherConfigs>>> testMap = new HashMap<>();
-
-        final String INT_OTHER_CONFIGS_KEY = "IntOtherConfigsKey";
-        final String INT_OTHER_CONFIGS_VALUE = "IntOtherConfigsValue";
-        final String FORMAT_STR = "%s_%s_%d";
-        final String GOOD_KEY = "GoodKey";
-        final String GOOD_VALUE = "GoodValue";
-        final String NO_VALUE_FOR_KEY = "NoValueForKey";
-        final String NO_KEY_FOR_VALUE = "NoKeyForValue";
-
-        // Test Case 1:  TestOneOtherConfigs
-        // Test Type:    Positive
-        // Description:  Create an interface with one other_Configs
-        // Expected:     An interface is created with the single other_configs specified below
-        final String testOneOtherConfigsName = "TestOneInterfaceOtherConfigs";
-        int otherConfigsCounter = 0;
-        List<InterfaceOtherConfigs> oneOtherConfigs = Lists.newArrayList(
-                (new InterfaceOtherConfigsBuilder()
-                        .setOtherConfigKey(String.format(FORMAT_STR, testOneOtherConfigsName,
-                                INT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
-                        .setOtherConfigValue(String.format(FORMAT_STR, testOneOtherConfigsName,
-                                INT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
-                        .build()));
-        Map<String,List<InterfaceOtherConfigs>> testCase = Maps.newHashMap();
-        testCase.put(EXPECTED_VALUES_KEY, oneOtherConfigs);
-        testCase.put(INPUT_VALUES_KEY, oneOtherConfigs);
-        testMap.put(testOneOtherConfigsName, testCase);
-
-        // Test Case 2:  TestFiveInterfaceOtherConfigs
-        // Test Type:    Positive
-        // Description:  Create a termination point with multiple (five) InterfaceOtherConfigs
-        // Expected:     A termination point is created with the five InterfaceOtherConfigs specified below
-        final String testFiveInterfaceOtherConfigsName = "TestFiveInterfaceOtherConfigs";
-        otherConfigsCounter = 0;
-        List<InterfaceOtherConfigs> fiveInterfaceOtherConfigs = Lists.newArrayList(
-                (new InterfaceOtherConfigsBuilder()
-                        .setOtherConfigKey(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
-                                INT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
-                        .setOtherConfigValue(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
-                                INT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
-                        .build()),
-                (new InterfaceOtherConfigsBuilder()
-                        .setOtherConfigKey(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
-                                INT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
-                        .setOtherConfigValue(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
-                                INT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
-                        .build()),
-                (new InterfaceOtherConfigsBuilder()
-                        .setOtherConfigKey(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
-                                INT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
-                        .setOtherConfigValue(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
-                                INT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
-                        .build()),
-                (new InterfaceOtherConfigsBuilder()
-                        .setOtherConfigKey(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
-                                INT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
-                        .setOtherConfigValue(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
-                                INT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
-                        .build()),
-                (new InterfaceOtherConfigsBuilder()
-                        .setOtherConfigKey(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
-                                INT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
-                        .setOtherConfigValue(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
-                                INT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
-                        .build()));
-        testCase = Maps.newHashMap();
-        testCase.put(EXPECTED_VALUES_KEY, fiveInterfaceOtherConfigs);
-        testCase.put(INPUT_VALUES_KEY, fiveInterfaceOtherConfigs);
-        testMap.put(testFiveInterfaceOtherConfigsName, testCase);
-
-        // Test Case 3:  TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValue
-        // Test Type:    Negative
-        // Description:
-        //     One perfectly fine InterfaceOtherConfigs
-        //        (TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValue_InterfaceOtherConfigsKey_1,
-        //        TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigs_InterfaceOtherConfigsValue_1)
-        //     and one malformed InterfaceOtherConfigs which only has key specified
-        //        (TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValue_NoValueForKey_2,
-        //        UNSPECIFIED)
-        // Expected:     A termination point is created without any InterfaceOtherConfigs
-        final String testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValueName =
-                "TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValue";
-        otherConfigsCounter = 0;
-        InterfaceOtherConfigs oneGood = new InterfaceOtherConfigsBuilder()
-                .setOtherConfigKey(String.format(FORMAT_STR,
-                        testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValueName,
-                        GOOD_KEY, ++otherConfigsCounter))
-                .setOtherConfigValue(String.format(FORMAT_STR,
-                        testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValueName,
-                        GOOD_VALUE, otherConfigsCounter))
-                .build();
-        InterfaceOtherConfigs oneBad = new InterfaceOtherConfigsBuilder()
-                .setOtherConfigKey(String.format(FORMAT_STR,
-                        testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValueName, NO_VALUE_FOR_KEY,
-                        ++otherConfigsCounter))
-                .build();
-        List<InterfaceOtherConfigs> oneGoodOneBadInput = Lists.newArrayList(oneGood, oneBad);
-        List<InterfaceOtherConfigs> oneGoodOneBadExpected = null;
-        testCase = Maps.newHashMap();
-        testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
-        testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
-        testMap.put(testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValueName, testCase);
-
-        // Test Case 4:  TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKey
-        // Test Type:    Negative
-        // Description:
-        //     One perfectly fine InterfaceOtherConfigs
-        //        (TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValue_InterfaceOtherConfigsKey_1,
-        //        TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigs_InterfaceOtherConfigsValue_1)
-        //     and one malformed InterfaceOtherConfigs which only has key specified
-        //        (UNSPECIFIED,
-        //        TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKey_NoKeyForValue_2)
-        // Expected:     A termination point is created without any InterfaceOtherConfigs
-        final String testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKeyName =
-                "TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKey";
-        otherConfigsCounter = 0;
-        oneGood = new InterfaceOtherConfigsBuilder()
-                .setOtherConfigKey(String.format(FORMAT_STR,
-                        testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKeyName,
-                        GOOD_KEY, ++otherConfigsCounter))
-                .setOtherConfigValue(String.format(FORMAT_STR,
-                        testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKeyName,
-                        GOOD_VALUE, otherConfigsCounter))
-                .build();
-        oneBad = new InterfaceOtherConfigsBuilder()
-                .setOtherConfigKey(String.format(FORMAT_STR,
-                        testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKeyName, NO_KEY_FOR_VALUE,
-                        ++otherConfigsCounter))
-                .build();
-        oneGoodOneBadInput = Lists.newArrayList(oneGood, oneBad);
-        oneGoodOneBadExpected = null;
-        testCase = Maps.newHashMap();
-        testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
-        testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
-        testMap.put(testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKeyName, testCase);
-
-        return testMap;
-    }
-
-    /*
-     * @see <code>SouthboundIT.testCRUDInterfaceOtherConfigs()</code>
-     * This is helper test method to compare a test "set" of Options against an expected "set"
-     */
-    private void assertExpectedInterfaceOtherConfigsExist( List<InterfaceOtherConfigs> expected,
-                                                           List<InterfaceOtherConfigs> test ) {
+    @Test
+    public void testGetOvsdbNodes() throws InterruptedException {
+        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
+        InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
+                .create(NetworkTopology.class)
+                .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
 
-        if (expected != null && test != null) {
-            for (InterfaceOtherConfigs expectedOtherConfigs : expected) {
-                Assert.assertTrue(test.contains(expectedOtherConfigs));
+        Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
+        InstanceIdentifier<Node> expectedNodeIid = createInstanceIdentifier(connectionInfo);
+        NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class, NodeKey.class).getNodeId();
+        Node foundNode = null;
+        Assert.assertNotNull("Expected to find topology: " + topologyPath, topology);
+        Assert.assertNotNull("Expected to find some nodes" + topology.getNode());
+        LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode());
+        for (Node node : topology.getNode()) {
+            if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) {
+                foundNode = node;
+                break;
             }
         }
+        Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode);
     }
 
     /*
-     * Tests the CRUD operations for <code>Interface</code> <code>other_configs</code>.
-     *
-     * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
+     * @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
      */
     @Test
-    public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
-        final String TEST_PREFIX = "CRUDTPInterfaceOtherConfigs";
+    public void testCRUDBridgeOtherConfigs() throws InterruptedException {
+        testCRUDBridge("BridgeOtherConfigs", new SouthboundBridgeOtherConfigsBuilder(),
+                new BridgeOtherConfigsSouthboundHelper());
+    }
 
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
+    private interface SouthboundBridgeHelper<T> {
+        void writeValues(OvsdbBridgeAugmentationBuilder builder, List<T> values);
+        List<T> readValues(OvsdbBridgeAugmentation augmentation);
+    }
 
+    private <T> void testCRUDBridge(String prefix, KeyValueBuilder<T> builder, SouthboundBridgeHelper<T> helper)
+            throws InterruptedException {
+        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
         // the update has been performed.
-        Map<String, Map<String, List<InterfaceOtherConfigs>>> updateFromTestCases =
-                generateInterfaceOtherConfigsTestCases();
-        Map<String, Map<String, List<InterfaceOtherConfigs>>> updateToTestCases =
-                generateInterfaceOtherConfigsTestCases();
-        Map<String, List<InterfaceOtherConfigs>> updateFromTestCase;
-        List<InterfaceOtherConfigs> updateFromInputOtherConfigs;
-        List<InterfaceOtherConfigs> updateFromExpectedOtherConfigs;
-        Map<String, List<InterfaceOtherConfigs>> updateToTestCase;
-        List<InterfaceOtherConfigs> updateToInputOtherConfigs;
-        List<InterfaceOtherConfigs> updateToExpectedOtherConfigs;
-        String testBridgeName;
-        String testPortName;
-
-        int counter = 1;
-        ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
-        for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
-            updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
-            updateFromInputOtherConfigs = updateFromTestCase.get(INPUT_VALUES_KEY);
-            updateFromExpectedOtherConfigs = updateFromTestCase.get(EXPECTED_VALUES_KEY);
-            for (String testCaseKey : updateToTestCases.keySet()) {
-                testPortName = testBridgeName = String.format("%s_%s_%d", TEST_PREFIX, testCaseKey, counter);
-                counter += 1;
-                updateToTestCase = updateToTestCases.get(testCaseKey);
-                updateToInputOtherConfigs = updateToTestCase.get(INPUT_VALUES_KEY);
-                updateToExpectedOtherConfigs = updateToTestCase.get(EXPECTED_VALUES_KEY);
-
-                TestCRUDTerminationPointInterfaceOtherConfigsRunnable testRunnable =
-                        new TestCRUDTerminationPointInterfaceOtherConfigsRunnable(
-                                connectionInfo, testBridgeName, testPortName,
-                                updateFromInputOtherConfigs,
-                                updateFromExpectedOtherConfigs,
-                                updateToInputOtherConfigs,
-                                updateToExpectedOtherConfigs);
-                executor.submit(testRunnable);
-            }
-        }
-        executor.shutdown();
-        executor.awaitTermination(5, TimeUnit.MINUTES);
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
-    }
-
-    class TestCRUDTerminationPointInterfaceOtherConfigsRunnable implements Runnable {
-
-        ConnectionInfo connectionInfo;
-        String testBridgeName;
-        String testPortName;
-        List<InterfaceOtherConfigs> updateFromInputOtherConfigs;
-        List<InterfaceOtherConfigs> updateFromExpectedOtherConfigs;
-        List<InterfaceOtherConfigs> updateToInputOtherConfigs;
-        List<InterfaceOtherConfigs> updateToExpectedOtherConfigs;
-
-        TestCRUDTerminationPointInterfaceOtherConfigsRunnable(
-                ConnectionInfo connectionInfo, String testBridgeName,
-                String testPortName,
-                List<InterfaceOtherConfigs> updateFromInputOtherConfigs,
-                List<InterfaceOtherConfigs> updateFromExpectedOtherConfigs,
-                List<InterfaceOtherConfigs> updateToInputOtherConfigs,
-                List<InterfaceOtherConfigs> updateToExpectedOtherConfigs) {
-
-            this.connectionInfo = connectionInfo;
-            this.testBridgeName = testBridgeName;
-            this.testPortName = testPortName;
-            this.updateFromInputOtherConfigs = updateFromInputOtherConfigs;
-            this.updateFromExpectedOtherConfigs = updateFromExpectedOtherConfigs;
-            this.updateToInputOtherConfigs = updateToInputOtherConfigs;
-            this.updateToExpectedOtherConfigs = updateToExpectedOtherConfigs;
-        }
-
-        @Override
-        public void run() {
-            try {
-                test();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
-
-        public void test() throws InterruptedException {
-            final int TERMINATION_POINT_TEST_INDEX = 0;
-
-            // CREATE: Create the test interface
-            Assert.assertTrue(addBridge(connectionInfo, null,
-                    testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
-                    true, null, null, null, null));
-            NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
-                    connectionInfo, new OvsdbBridgeName(testBridgeName)));
-            OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
-                    createGenericOvsdbTerminationPointAugmentationBuilder();
-            tpCreateAugmentationBuilder.setName(testPortName);
-            tpCreateAugmentationBuilder.setInterfaceOtherConfigs(updateFromInputOtherConfigs);
-            Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
-
-            // READ: Read the test interface and ensure changes are propagated to the CONFIGURATION data store,
-            // then repeat for OPERATIONAL data store
-            OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                    LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
-            List<InterfaceOtherConfigs> updateFromConfigurationOtherConfigs;
-            if (updateFromConfigurationTerminationPointAugmentation != null) {
-                updateFromConfigurationOtherConfigs = updateFromConfigurationTerminationPointAugmentation
-                        .getInterfaceOtherConfigs();
-            } else {
-                updateFromConfigurationOtherConfigs = null;
-            }
-            assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
-                    updateFromConfigurationOtherConfigs);
-            OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
-            List<InterfaceOtherConfigs> updateFromOperationalOtherConfigs =
-                    updateFromOperationalTerminationPointAugmenation.getInterfaceOtherConfigs();
-            if (updateFromOperationalOtherConfigs != null) {
-                updateFromOperationalOtherConfigs = updateFromOperationalTerminationPointAugmenation
-                        .getInterfaceOtherConfigs();
-            } else {
-                updateFromOperationalOtherConfigs = null;
-            }
-            assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
-                    updateFromOperationalOtherConfigs);
+        List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
+        List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
+        for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
+            for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
+                String testBridgeName = String.format("%s_%s", prefix, updateToTestCase.name);
+
+                // CREATE: Create the test bridge
+                final OvsdbBridgeName ovsdbBridgeName = new OvsdbBridgeName(testBridgeName);
+                final InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo, ovsdbBridgeName);
+                final NodeId bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
+                final NodeBuilder bridgeCreateNodeBuilder = new NodeBuilder();
+                bridgeCreateNodeBuilder.setNodeId(bridgeNodeId);
+                OvsdbBridgeAugmentationBuilder bridgeCreateAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
+                bridgeCreateAugmentationBuilder.setBridgeName(ovsdbBridgeName);
+                bridgeCreateAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
+                bridgeCreateAugmentationBuilder.setFailMode(
+                        SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
+                setManagedBy(bridgeCreateAugmentationBuilder, connectionInfo);
+                helper.writeValues(bridgeCreateAugmentationBuilder, updateFromTestCase.inputValues);
+                bridgeCreateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
+                        bridgeCreateAugmentationBuilder.build());
+                LOG.debug("Built with the intent to store bridge data {}", bridgeCreateAugmentationBuilder.toString());
+                Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
+                        bridgeCreateNodeBuilder.build()));
+                Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+
+                // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
+                // then repeat for OPERATIONAL data store
+                List<T> updateFromConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
+                        LogicalDatastoreType.CONFIGURATION));
+                assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationExternalIds);
+                List<T> updateFromOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
+                assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalExternalIds);
+
+                // UPDATE:  update the values
+                final OvsdbBridgeAugmentationBuilder bridgeUpdateAugmentationBuilder =
+                        new OvsdbBridgeAugmentationBuilder();
+                helper.writeValues(bridgeUpdateAugmentationBuilder, updateToTestCase.inputValues);
+                final NodeBuilder bridgeUpdateNodeBuilder = new NodeBuilder();
+                final Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
+                bridgeUpdateNodeBuilder.setNodeId(bridgeNode.getNodeId());
+                bridgeUpdateNodeBuilder.setKey(bridgeNode.getKey());
+                bridgeUpdateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
+                        bridgeUpdateAugmentationBuilder.build());
+                Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
+                        bridgeUpdateNodeBuilder.build()));
+                Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+
+                // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
+                // then repeat for OPERATIONAL data store
+                List<T> updateToConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
+                        LogicalDatastoreType.CONFIGURATION));
+                assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationExternalIds);
+                assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationExternalIds);
+                List<T> updateToOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
+                if (updateFromTestCase.expectedValues != null) {
+                    assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalExternalIds);
+                    assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalExternalIds);
+                }
 
-            // UPDATE:  update the other_configs
-            testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
-            OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
-                    new OvsdbTerminationPointAugmentationBuilder();
-            tpUpdateAugmentationBuilder.setInterfaceOtherConfigs(updateToInputOtherConfigs);
-            InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
-            NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
-            NodeId portUpdateNodeId = createManagedNodeId(portIid);
-            portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
-            TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
-            tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
-            tpUpdateBuilder.addAugmentation(
-                    OvsdbTerminationPointAugmentation.class,
-                    tpUpdateAugmentationBuilder.build());
-            portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
-            boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
-                    portIid, portUpdateNodeBuilder.build());
-            Thread.sleep(OVSDB_UPDATE_TIMEOUT);
-            Assert.assertTrue(result);
-
-            // READ: the test interface and ensure changes are propagated to the CONFIGURATION data store,
-            // then repeat for OPERATIONAL data store
-            OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
-            List<InterfaceOtherConfigs> updateToConfigurationOtherConfigs =
-                    updateToConfigurationTerminationPointAugmentation
-                            .getInterfaceOtherConfigs();
-            assertExpectedInterfaceOtherConfigsExist(updateToExpectedOtherConfigs,
-                    updateToConfigurationOtherConfigs);
-            assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
-                    updateToConfigurationOtherConfigs);
-            OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
-            List<InterfaceOtherConfigs> updateToOperationalOtherConfigs =
-                    updateToOperationalTerminationPointAugmentation
-                            .getInterfaceOtherConfigs();
-            if (updateFromExpectedOtherConfigs != null) {
-                assertExpectedInterfaceOtherConfigsExist(updateToExpectedOtherConfigs,
-                        updateToOperationalOtherConfigs);
-                assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
-                        updateToOperationalOtherConfigs);
+                // DELETE
+                Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, bridgeIid));
+                Thread.sleep(OVSDB_UPDATE_TIMEOUT);
             }
-
-            // DELETE
-            Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
         }
     }
 
     /*
-     * Generates the test cases involved in testing Port other_configs.  See inline comments for descriptions of
-     * the particular cases considered.
-     *
-     * The return value is a Map in the form (K,V)=(testCaseName,testCase).
-     * - testCaseName is a String
-     * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
-     *     either corresponding INPUT port other_configs, or EXPECTED port other_configs
-     *     INPUT    is the List we use when calling
-     *              <code>TerminationPointAugmentationBuilder.setPortOtherConfigs()</code>
-     *     EXPECTED is the List we expect to receive after calling
-     *              <code>TerminationPointAugmentationBuilder.getPortOtherConfigs()</code>
+     * @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
      */
-    private Map<String, Map<String, List<PortOtherConfigs>>> generatePortOtherConfigsTestCases() {
-        Map<String, Map<String, List<PortOtherConfigs>>> testMap = new HashMap<>();
-
-        final String PORT_OTHER_CONFIGS_KEY = "PortOtherConfigsKey";
-        final String PORT_OTHER_CONFIGS_VALUE = "PortOtherConfigsValue";
-        final String FORMAT_STR = "%s_%s_%d";
-        final String GOOD_KEY = "GoodKey";
-        final String GOOD_VALUE = "GoodValue";
-        final String NO_VALUE_FOR_KEY = "NoValueForKey";
-        final String NO_KEY_FOR_VALUE = "NoKeyForValue";
-
-        // Test Case 1:  TestOneOtherConfigs
-        // Test Type:    Positive
-        // Description:  Create an port with one other_Configs
-        // Expected:     A port is created with the single other_configs specified below
-        final String testOneOtherConfigsName = "TestOnePortOtherConfigs";
-        int otherConfigsCounter = 0;
-        List<PortOtherConfigs> oneOtherConfigs = Lists.newArrayList(
-                (new PortOtherConfigsBuilder()
-                        .setOtherConfigKey(String.format(FORMAT_STR, testOneOtherConfigsName,
-                                PORT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
-                        .setOtherConfigValue(String.format(FORMAT_STR, testOneOtherConfigsName,
-                                PORT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
-                        .build()));
-        Map<String,List<PortOtherConfigs>> testCase = Maps.newHashMap();
-        testCase.put(EXPECTED_VALUES_KEY, oneOtherConfigs);
-        testCase.put(INPUT_VALUES_KEY, oneOtherConfigs);
-        testMap.put(testOneOtherConfigsName, testCase);
-
-        // Test Case 2:  TestFivePortOtherConfigs
-        // Test Type:    Positive
-        // Description:  Create a termination point with multiple (five) PortOtherConfigs
-        // Expected:     A termination point is created with the five PortOtherConfigs specified below
-        final String testFivePortOtherConfigsName = "TestFivePortOtherConfigs";
-        otherConfigsCounter = 0;
-        List<PortOtherConfigs> fivePortOtherConfigs = Lists.newArrayList(
-                (new PortOtherConfigsBuilder()
-                        .setOtherConfigKey(String.format(FORMAT_STR, testFivePortOtherConfigsName,
-                                PORT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
-                        .setOtherConfigValue(String.format(FORMAT_STR, testFivePortOtherConfigsName,
-                                PORT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
-                        .build()),
-                (new PortOtherConfigsBuilder()
-                        .setOtherConfigKey(String.format(FORMAT_STR, testFivePortOtherConfigsName,
-                                PORT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
-                        .setOtherConfigValue(String.format(FORMAT_STR, testFivePortOtherConfigsName,
-                                PORT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
-                        .build()),
-                (new PortOtherConfigsBuilder()
-                        .setOtherConfigKey(String.format(FORMAT_STR, testFivePortOtherConfigsName,
-                                PORT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
-                        .setOtherConfigValue(String.format(FORMAT_STR, testFivePortOtherConfigsName,
-                                PORT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
-                        .build()),
-                (new PortOtherConfigsBuilder()
-                        .setOtherConfigKey(String.format(FORMAT_STR, testFivePortOtherConfigsName,
-                                PORT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
-                        .setOtherConfigValue(String.format(FORMAT_STR, testFivePortOtherConfigsName,
-                                PORT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
-                        .build()),
-                (new PortOtherConfigsBuilder()
-                        .setOtherConfigKey(String.format(FORMAT_STR, testFivePortOtherConfigsName,
-                                PORT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
-                        .setOtherConfigValue(String.format(FORMAT_STR, testFivePortOtherConfigsName,
-                                PORT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
-                        .build()));
-        testCase = Maps.newHashMap();
-        testCase.put(EXPECTED_VALUES_KEY, fivePortOtherConfigs);
-        testCase.put(INPUT_VALUES_KEY, fivePortOtherConfigs);
-        testMap.put(testFivePortOtherConfigsName, testCase);
-
-        // Test Case 3:  TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValue
-        // Test Type:    Negative
-        // Description:
-        //     One perfectly fine PortOtherConfigs
-        //        (TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValue_PortOtherConfigsKey_1,
-        //        TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigs_PortOtherConfigsValue_1)
-        //     and one malformed PortOtherConfigs which only has key specified
-        //        (TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValue_NoValueForKey_2,
-        //        UNSPECIFIED)
-        // Expected:     A termination point is created without any PortOtherConfigs
-        final String testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValueName =
-                "TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValue";
-        otherConfigsCounter = 0;
-        PortOtherConfigs oneGood = new PortOtherConfigsBuilder()
-                .setOtherConfigKey(String.format(FORMAT_STR,
-                        testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValueName,
-                        GOOD_KEY, ++otherConfigsCounter))
-                .setOtherConfigValue(String.format(FORMAT_STR,
-                        testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValueName,
-                        GOOD_VALUE, otherConfigsCounter))
-                .build();
-        PortOtherConfigs oneBad = new PortOtherConfigsBuilder()
-                .setOtherConfigKey(String.format(FORMAT_STR,
-                        testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValueName, NO_VALUE_FOR_KEY,
-                        ++otherConfigsCounter))
-                .build();
-        List<PortOtherConfigs> oneGoodOneBadInput = Lists.newArrayList(oneGood, oneBad);
-        List<PortOtherConfigs> oneGoodOneBadExpected = null;
-        testCase = Maps.newHashMap();
-        testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
-        testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
-        testMap.put(testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValueName, testCase);
-
-        // Test Case 4:  TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKey
-        // Test Type:    Negative
-        // Description:
-        //     One perfectly fine PortOtherConfigs
-        //        (TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValue_PortOtherConfigsKey_1,
-        //        TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigs_PortOtherConfigsValue_1)
-        //     and one malformed PortOtherConfigs which only has key specified
-        //        (UNSPECIFIED,
-        //        TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKey_NoKeyForValue_2)
-        // Expected:     A termination point is created without any PortOtherConfigs
-        final String testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKeyName =
-                "TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKey";
-        otherConfigsCounter = 0;
-        oneGood = new PortOtherConfigsBuilder()
-                .setOtherConfigKey(String.format(FORMAT_STR,
-                        testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKeyName,
-                        GOOD_KEY, ++otherConfigsCounter))
-                .setOtherConfigValue(String.format(FORMAT_STR,
-                        testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKeyName,
-                        GOOD_VALUE, otherConfigsCounter))
-                .build();
-        oneBad = new PortOtherConfigsBuilder()
-                .setOtherConfigKey(String.format(FORMAT_STR,
-                        testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKeyName, NO_KEY_FOR_VALUE,
-                        ++otherConfigsCounter))
-                .build();
-        oneGoodOneBadInput = Lists.newArrayList(oneGood, oneBad);
-        oneGoodOneBadExpected = null;
-        testCase = Maps.newHashMap();
-        testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
-        testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
-        testMap.put(testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKeyName, testCase);
-
-        return testMap;
+    @Test
+    public void testCRUDBridgeExternalIds() throws InterruptedException {
+        testCRUDBridge("BridgeExternalIds", new SouthboundBridgeExternalIdsBuilder(),
+                new BridgeExternalIdsSouthboundHelper());
     }
 
-    /*
-     * @see <code>SouthboundIT.testCRUDPortOtherConfigs()</code>
-     * This is helper test method to compare a test "set" of Options against an expected "set"
-     */
-    private void assertExpectedPortOtherConfigsExist( List<PortOtherConfigs> expected,
-                                                      List<PortOtherConfigs> test ) {
-
-        if (expected != null && test != null) {
-            for (PortOtherConfigs expectedOtherConfigs : expected) {
-                Assert.assertTrue(test.contains(expectedOtherConfigs));
-            }
-        }
+    public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
+        return SouthboundMapper.createInstanceIdentifier(createManagedNodeId(key, bridgeName));
     }
 
-    /*
-     * Tests the CRUD operations for <code>Port</code> <code>other_configs</code>.
-     *
-     * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
-     */
-    @Test
-    public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
-        final String TEST_PREFIX = "CRUDTPPortOtherConfigs";
-
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
-
-        // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
-        // the update has been performed.
-        Map<String, Map<String, List<PortOtherConfigs>>> updateFromTestCases =
-                generatePortOtherConfigsTestCases();
-        Map<String, Map<String, List<PortOtherConfigs>>> updateToTestCases =
-                generatePortOtherConfigsTestCases();
-        Map<String, List<PortOtherConfigs>> updateFromTestCase;
-        List<PortOtherConfigs> updateFromInputOtherConfigs;
-        List<PortOtherConfigs> updateFromExpectedOtherConfigs;
-        Map<String, List<PortOtherConfigs>> updateToTestCase;
-        List<PortOtherConfigs> updateToInputOtherConfigs;
-        List<PortOtherConfigs> updateToExpectedOtherConfigs;
-        String testBridgeName;
-        String testPortName;
-
-        int counter = 1;
-        ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
-        for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
-            updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
-            updateFromInputOtherConfigs = updateFromTestCase.get(INPUT_VALUES_KEY);
-            updateFromExpectedOtherConfigs = updateFromTestCase.get(EXPECTED_VALUES_KEY);
-            for (String testCaseKey : updateToTestCases.keySet()) {
-                testPortName = testBridgeName = String.format("%s_%s_%d", TEST_PREFIX, testCaseKey, counter);
-                counter += 1;
-                updateToTestCase = updateToTestCases.get(testCaseKey);
-                updateToInputOtherConfigs = updateToTestCase.get(INPUT_VALUES_KEY);
-                updateToExpectedOtherConfigs = updateToTestCase.get(EXPECTED_VALUES_KEY);
-
-                TestCRUDTerminationPointPortOtherConfigsRunnable testRunnable =
-                        new TestCRUDTerminationPointPortOtherConfigsRunnable(
-                                connectionInfo, testBridgeName, testPortName,
-                                updateFromInputOtherConfigs,
-                                updateFromExpectedOtherConfigs,
-                                updateToInputOtherConfigs,
-                                updateToExpectedOtherConfigs);
-                executor.submit(testRunnable);
-            }
-        }
-        executor.shutdown();
-        executor.awaitTermination(5, TimeUnit.MINUTES);
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
+    public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
+        return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
     }
 
-    class TestCRUDTerminationPointPortOtherConfigsRunnable implements Runnable {
-        ConnectionInfo connectionInfo;
-        String testBridgeName;
-        String testPortName;
-        List<PortOtherConfigs> updateFromInputOtherConfigs;
-        List<PortOtherConfigs> updateFromExpectedOtherConfigs;
-        List<PortOtherConfigs> updateToInputOtherConfigs;
-        List<PortOtherConfigs> updateToExpectedOtherConfigs;
-
-        TestCRUDTerminationPointPortOtherConfigsRunnable(
-                ConnectionInfo connectionInfo, String testBridgeName,
-                String testPortName,
-                List<PortOtherConfigs> updateFromInputOtherConfigs,
-                List<PortOtherConfigs> updateFromExpectedOtherConfigs,
-                List<PortOtherConfigs> updateToInputOtherConfigs,
-                List<PortOtherConfigs> updateToExpectedOtherConfigs) {
-
-            this.connectionInfo = connectionInfo;
-            this.testBridgeName = testBridgeName;
-            this.testPortName = testPortName;
-            this.updateFromInputOtherConfigs = updateFromInputOtherConfigs;
-            this.updateFromExpectedOtherConfigs = updateFromExpectedOtherConfigs;
-            this.updateToInputOtherConfigs = updateToInputOtherConfigs;
-            this.updateToExpectedOtherConfigs = updateToExpectedOtherConfigs;
-        }
-
-        @Override
-        public void run() {
-            try {
-                test();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
-
-        public void test() throws InterruptedException {
-            final int TERMINATION_POINT_TEST_INDEX = 0;
-            // CREATE: Create the test port
-            Assert.assertTrue(addBridge(connectionInfo, null,
-                    testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
-                    true, null, null, null, null));
-            NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
-                    connectionInfo, new OvsdbBridgeName(testBridgeName)));
-            OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
-                    createGenericOvsdbTerminationPointAugmentationBuilder();
-            tpCreateAugmentationBuilder.setName(testPortName);
-            tpCreateAugmentationBuilder.setPortOtherConfigs(updateFromInputOtherConfigs);
-            Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
-
-            // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
-            // then repeat for OPERATIONAL data store
-            OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
-            List<PortOtherConfigs> updateFromConfigurationOtherConfigs;
-            if (updateFromConfigurationTerminationPointAugmentation != null) {
-                updateFromConfigurationOtherConfigs = updateFromConfigurationTerminationPointAugmentation
-                        .getPortOtherConfigs();
-            } else {
-                updateFromConfigurationOtherConfigs = null;
-            }
-            assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
-                    updateFromConfigurationOtherConfigs);
-            OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
-            List<PortOtherConfigs> updateFromOperationalOtherConfigs =
-                    updateFromOperationalTerminationPointAugmenation.getPortOtherConfigs();
-            if (updateFromOperationalOtherConfigs != null) {
-                updateFromOperationalOtherConfigs = updateFromOperationalTerminationPointAugmenation
-                        .getPortOtherConfigs();
-            } else {
-                updateFromOperationalOtherConfigs = null;
-            }
-            assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
-                    updateFromOperationalOtherConfigs);
-
-            // UPDATE:  update the other_configs
-            testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
-            OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
-                    new OvsdbTerminationPointAugmentationBuilder();
-            tpUpdateAugmentationBuilder.setPortOtherConfigs(updateToInputOtherConfigs);
-            InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
-            NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
-            NodeId portUpdateNodeId = createManagedNodeId(portIid);
-            portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
-            TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
-            tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
-            tpUpdateBuilder.addAugmentation(
-                    OvsdbTerminationPointAugmentation.class,
-                    tpUpdateAugmentationBuilder.build());
-            portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
-            boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
-                    portIid, portUpdateNodeBuilder.build());
-            Thread.sleep(OVSDB_UPDATE_TIMEOUT);
-            Assert.assertTrue(result);
-
-            // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
-            // then repeat for OPERATIONAL data store
-            OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
-            List<PortOtherConfigs> updateToConfigurationOtherConfigs = updateToConfigurationTerminationPointAugmentation
-                    .getPortOtherConfigs();
-            assertExpectedPortOtherConfigsExist(updateToExpectedOtherConfigs,
-                    updateToConfigurationOtherConfigs);
-            assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
-                    updateToConfigurationOtherConfigs);
-            OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
-                    getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
-                            LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
-            List<PortOtherConfigs> updateToOperationalOtherConfigs = updateToOperationalTerminationPointAugmentation
-                    .getPortOtherConfigs();
-            if (updateFromExpectedOtherConfigs != null) {
-                assertExpectedPortOtherConfigsExist(updateToExpectedOtherConfigs,
-                        updateToOperationalOtherConfigs);
-                assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
-                        updateToOperationalOtherConfigs);
-            }
-
-            // DELETE
-            Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
-        }
+    public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
+        return new NodeId(createNodeId(ip,port).getValue()
+                + "/" + SouthboundConstants.BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
     }
 
-    @Test
-    public void testCRUDTerminationPointVlan() throws InterruptedException {
-        final Integer CREATED_VLAN_ID = 4000;
-        final Integer UPDATED_VLAN_ID = 4001;
-
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
-
-        // CREATE
-        Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
-        OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
-        Assert.assertNotNull(bridge);
-        NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
-                connectionInfo, bridge.getBridgeName()));
-        OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
-                createGenericOvsdbTerminationPointAugmentationBuilder();
-        String portName = "testTerminationPointVlanId";
-        ovsdbTerminationBuilder.setName(portName);
-        ovsdbTerminationBuilder.setVlanTag(new VlanId(CREATED_VLAN_ID));
-        Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
-        InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
-        Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
-        Assert.assertNotNull(terminationPointNode);
-
-        // READ
-        List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
-        OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation;
-        for (TerminationPoint terminationPoint : terminationPoints) {
-            ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
-                    OvsdbTerminationPointAugmentation.class);
-            if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
-                VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
-                Assert.assertNotNull(actualVlanId);
-                Integer actualVlanIdInt = actualVlanId.getValue();
-                Assert.assertEquals(CREATED_VLAN_ID, actualVlanIdInt);
-            }
-        }
-
-        // UPDATE
-        NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
-        OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
-                new OvsdbTerminationPointAugmentationBuilder();
-        tpUpdateAugmentationBuilder.setVlanTag(new VlanId(UPDATED_VLAN_ID));
-        InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
-        NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
-        NodeId portUpdateNodeId = createManagedNodeId(portIid);
-        portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
-        TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
-        tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
-        tpUpdateBuilder.addAugmentation(
-                OvsdbTerminationPointAugmentation.class,
-                tpUpdateAugmentationBuilder.build());
-        tpUpdateBuilder.setTpId(new TpId(portName));
-        portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
-        boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
-                portIid, portUpdateNodeBuilder.build());
-        Assert.assertTrue(result);
-        Thread.sleep(OVSDB_UPDATE_TIMEOUT);
-
-        terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
-        terminationPoints = terminationPointNode.getTerminationPoint();
-        for (TerminationPoint terminationPoint : terminationPoints) {
-            ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
-                    OvsdbTerminationPointAugmentation.class);
-            if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
-                VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
-                Assert.assertNotNull(actualVlanId);
-                Integer actualVlanIdInt = actualVlanId.getValue();
-                Assert.assertEquals(UPDATED_VLAN_ID, actualVlanIdInt);
-            }
-        }
-
-        // DELETE
-        Assert.assertTrue(deleteBridge(connectionInfo));
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
+    public static NodeId createNodeId(IpAddress ip, PortNumber port) {
+        String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
+                + new String(ip.getValue()) + ":" + port.getValue();
+        Uri uri = new Uri(uriString);
+        return new NodeId(uri);
     }
 
-    @Test
-    public void testCRUDTerminationPointVlanModes() throws InterruptedException {
-        final VlanMode UPDATED_VLAN_MODE = VlanMode.Access;
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
-        VlanMode []vlanModes = VlanMode.values();
-        for (VlanMode vlanMode : vlanModes) {
-            // CREATE
-            Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
-            OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
-            Assert.assertNotNull(bridge);
-            NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
-                    connectionInfo, bridge.getBridgeName()));
-            OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
-                    createGenericOvsdbTerminationPointAugmentationBuilder();
-            String portName = "testTerminationPointVlanMode" + vlanMode.toString();
-            ovsdbTerminationBuilder.setName(portName);
-            ovsdbTerminationBuilder.setVlanMode(vlanMode);
-            Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
-            InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
-            Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
-            Assert.assertNotNull(terminationPointNode);
+    public static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
+        return new NodeKey(createNodeId(ip,port));
+    }
 
-            // READ
-            List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
-            for (TerminationPoint terminationPoint : terminationPoints) {
-                OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
-                        terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
-                if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
-                    //test
-                    Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode));
-                }
-            }
+    public static Node createNode(ConnectionInfo key) {
+        NodeBuilder nodeBuilder = new NodeBuilder();
+        nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(),key.getRemotePort()));
+        nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
+        return nodeBuilder.build();
+    }
 
-            // UPDATE
-            NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
-            OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
-                    new OvsdbTerminationPointAugmentationBuilder();
-            tpUpdateAugmentationBuilder.setVlanMode(UPDATED_VLAN_MODE);
-            InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
-            NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
-            NodeId portUpdateNodeId = createManagedNodeId(portIid);
-            portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
-            TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
-            tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
-            tpUpdateBuilder.addAugmentation(
-                    OvsdbTerminationPointAugmentation.class,
-                    tpUpdateAugmentationBuilder.build());
-            tpUpdateBuilder.setTpId(new TpId(portName));
-            portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
-            boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
-                    portIid, portUpdateNodeBuilder.build());
-            Assert.assertTrue(result);
-            Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+    public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
+        OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
+        ovsdbNodeBuilder.setConnectionInfo(key);
+        return ovsdbNodeBuilder.build();
+    }
 
-            terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
-            terminationPoints = terminationPointNode.getTerminationPoint();
-            for (TerminationPoint terminationPoint : terminationPoints) {
-                OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
-                        terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
-                if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
-                    //test
-                    Assert.assertEquals(UPDATED_VLAN_MODE, ovsdbTerminationPointAugmentation.getVlanMode());
-                }
-            }
+    public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
+        NodeKey nodeKey = iid.firstKeyOf(Node.class, NodeKey.class);
+        return nodeKey.getNodeId();
+    }
 
-            // DELETE
-            Assert.assertTrue(deleteBridge(connectionInfo));
+    /**
+     * <p>
+     * Representation of a southbound test case. Each test case has a name, a list of input values and a list of
+     * expected values. The input values are provided to the augmentation builder, and the expected values are checked
+     * against the output of the resulting augmentation.
+     * </p>
+     * <p>
+     * Instances of this class are immutable.
+     * </p>
+     *
+     * @param <T> The type of data used for the test case.
+     */
+    private static final class SouthboundTestCase<T> {
+        private final String name;
+        private final List<T> inputValues;
+        private final List<T> expectedValues;
+
+        /**
+         * Creates an instance of a southbound test case.
+         *
+         * @param name The test case's name.
+         * @param inputValues The input values (provided as input to the underlying augmentation builder).
+         * @param expectedValues The expected values (checked against the output of the underlying augmentation).
+         */
+        public SouthboundTestCase(
+                final String name, final List<T> inputValues, final List<T> expectedValues) {
+            this.name = name;
+            this.inputValues = inputValues;
+            this.expectedValues = expectedValues;
         }
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
     }
 
-    private ArrayList<Set<Integer>> generateVlanSets() {
-        ArrayList<Set<Integer>> vlanSets = new ArrayList<>();
+    /**
+     * Southbound test case builder.
+     *
+     * @param <T> The type of data used for the test case.
+     */
+    private static final class SouthboundTestCaseBuilder<T> {
+        private String name;
+        private List<T> inputValues;
+        private List<T> expectedValues;
+
+        /**
+         * Creates a builder. Builders may be reused, the generated immutable instances are independent of the
+         * builders. There are no default values.
+         */
+        public SouthboundTestCaseBuilder() {
+            // Nothing to do
+        }
 
-        Set<Integer> emptySet = new HashSet<>();
-        vlanSets.add(emptySet);
+        /**
+         * Sets the test case's name.
+         *
+         * @param name The test case's name.
+         * @return The builder.
+         */
+        public SouthboundTestCaseBuilder<T> name(final String name) {
+            this.name = name;
+            return this;
+        }
 
-        Set<Integer> singleSet = new HashSet<>();
-        Integer single = 2222;
-        singleSet.add(single);
-        vlanSets.add(singleSet);
+        /**
+         * Sets the input values.
+         *
+         * @param inputValues The input values.
+         * @return The builder.
+         */
+        @SafeVarargs
+        public final SouthboundTestCaseBuilder<T> input(final T... inputValues) {
+            this.inputValues = Lists.newArrayList(inputValues);
+            return this;
+        }
 
-        Set<Integer> minMaxMiddleSet = new HashSet<>();
-        Integer min = 0;
-        minMaxMiddleSet.add(min);
-        Integer max = 4095;
-        minMaxMiddleSet.add(max);
-        Integer minPlusOne = min + 1;
-        minMaxMiddleSet.add(minPlusOne);
-        Integer maxMinusOne = max - 1;
-        minMaxMiddleSet.add(maxMinusOne);
-        Integer middle = (max - min) / 2;
-        minMaxMiddleSet.add(middle);
-        vlanSets.add(minMaxMiddleSet);
+        /**
+         * Indicates that the provided input values should be expected as output values.
+         *
+         * @return The builder.
+         */
+        public SouthboundTestCaseBuilder<T> expectInputAsOutput() {
+            this.expectedValues = this.inputValues;
+            return this;
+        }
 
-        return vlanSets;
-    }
+        /**
+         * Indicates that no output should be expected.
+         *
+         * @return The builder.
+         */
+        public SouthboundTestCaseBuilder<T> expectNoOutput() {
+            this.expectedValues = null;
+            return this;
+        }
 
-    private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
-        List<Trunks> trunkList = Lists.newArrayList();
-        for (Integer trunk : trunkSet) {
-            TrunksBuilder trunkBuilder = new TrunksBuilder();
-            trunkBuilder.setTrunk(new VlanId(trunk));
-            trunkList.add(trunkBuilder.build());
+        /**
+         * Builds an immutable instance representing the test case.
+         *
+         * @return The test case.
+         */
+        @SuppressWarnings("unchecked")
+        public SouthboundTestCase<T> build() {
+            return new SouthboundTestCase<>(name, inputValues, expectedValues);
         }
-        return trunkList;
     }
 
-    @Test
-    public void testCRUDTerminationPointVlanTrunks() throws InterruptedException {
-        final List<Trunks> UPDATED_TRUNKS = buildTrunkList(Sets.newHashSet(2011));
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
-        Iterable<Set<Integer>> vlanSets = generateVlanSets();
-        int testCase = 0;
-        for (Set<Integer> vlanSet : vlanSets) {
-            ++testCase;
-            // CREATE
-            Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
-            OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
-            Assert.assertNotNull(bridge);
-            NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
-                    connectionInfo, bridge.getBridgeName()));
-            OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
-                    createGenericOvsdbTerminationPointAugmentationBuilder();
-            String portName = "testTerminationPointVlanTrunks" + testCase;
-            ovsdbTerminationBuilder.setName(portName);
-            List<Trunks> trunks = buildTrunkList(vlanSet);
-            ovsdbTerminationBuilder.setTrunks(trunks);
-            Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
-            InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
-            Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
-            Assert.assertNotNull(terminationPointNode);
+    private abstract static class KeyValueBuilder<T> {
+        private static final int COUNTER_START = 0;
+        private int counter = COUNTER_START;
 
-            // READ
-            List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
-            for (TerminationPoint terminationPoint : terminationPoints) {
-                OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
-                        terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
-                if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
-                    List<Trunks> actualTrunks = ovsdbTerminationPointAugmentation.getTrunks();
-                    for (Trunks trunk : trunks) {
-                        Assert.assertTrue(actualTrunks.contains(trunk));
-                    }
-                }
-            }
+        protected abstract Builder<T> builder();
 
+        protected abstract void setKey(Builder<T> builder, String key);
 
-            // UPDATE
-            NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
-            OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
-                    new OvsdbTerminationPointAugmentationBuilder();
-            tpUpdateAugmentationBuilder.setTrunks(UPDATED_TRUNKS);
-            InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
-            NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
-            NodeId portUpdateNodeId = createManagedNodeId(portIid);
-            portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
-            TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
-            tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
-            tpUpdateBuilder.addAugmentation(
-                    OvsdbTerminationPointAugmentation.class,
-                    tpUpdateAugmentationBuilder.build());
-            tpUpdateBuilder.setTpId(new TpId(portName));
-            portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
-            boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
-                    portIid, portUpdateNodeBuilder.build());
-            Assert.assertTrue(result);
-            Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+        protected abstract void setValue(Builder<T> builder, String value);
 
-            terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
-            terminationPoints = terminationPointNode.getTerminationPoint();
-            for (TerminationPoint terminationPoint : terminationPoints) {
-                OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
-                        terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
-                if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
-                    //test
-                    Assert.assertEquals(UPDATED_TRUNKS, ovsdbTerminationPointAugmentation.getTrunks());
-                }
+        public final T build(final String testName, final String key, final String value) {
+            final Builder<T> builder = builder();
+            this.counter++;
+            if (key != null) {
+                setKey(builder, String.format(FORMAT_STR, testName, key, this.counter));
+            }
+            if (value != null) {
+                setValue(builder, String.format(FORMAT_STR, testName, value, this.counter));
             }
+            return builder.build();
+        }
 
-            // DELETE
-            Assert.assertTrue(deleteBridge(connectionInfo));
+        public final void reset() {
+            this.counter = COUNTER_START;
         }
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
     }
 
-    @Test
-    public void testGetOvsdbNodes() throws InterruptedException {
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
-        InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
-                .create(NetworkTopology.class)
-                .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
+    private static final class SouthboundPortExternalIdsBuilder extends KeyValueBuilder<PortExternalIds> {
+        @Override
+        protected Builder<PortExternalIds> builder() {
+            return new PortExternalIdsBuilder();
+        }
 
-        Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
-        InstanceIdentifier<Node> expectedNodeIid = createInstanceIdentifier(connectionInfo);
-        NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class, NodeKey.class).getNodeId();
-        Node foundNode = null;
-        Assert.assertNotNull("Expected to find topology: " + topologyPath, topology);
-        Assert.assertNotNull("Expected to find some nodes" + topology.getNode());
-        LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode());
-        for (Node node : topology.getNode()) {
-            if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) {
-                foundNode = node;
-                break;
-            }
+        @Override
+        protected void setKey(Builder<PortExternalIds> builder, String key) {
+            ((PortExternalIdsBuilder) builder).setExternalIdKey(key);
         }
-        Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode);
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
-    }
 
-    /*
-     * Generates the test cases involved in testing BridgeOtherConfigs.  See inline comments for descriptions of
-     * the particular cases considered.
-     *
-     * The return value is a Map in the form (K,V)=(testCaseName,testCase).
-     * - testCaseName is a String
-     * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
-     *     either corresponding INPUT bridge other_configs, or EXPECTED bridge other_configs
-     *     INPUT is the List we use when calling BridgeAugmentationBuilder.setBridgeOtherConfigs()
-     *     EXPECTED is the List we expect to receive after calling BridgeAugmentationBuilder.getBridgeOtherConfigs()
-     */
-    private Map<String, Map<String, List<BridgeOtherConfigs>>> generateBridgeOtherConfigsTestCases() {
-        Map<String, Map<String, List<BridgeOtherConfigs>>> testMap = new HashMap<>();
+        @Override
+        protected void setValue(Builder<PortExternalIds> builder, String value) {
+            ((PortExternalIdsBuilder) builder).setExternalIdValue(value);
+        }
+    }
 
-        final String BRIDGE_OTHER_CONFIGS_KEY = "BridgeOtherConfigKey";
-        final String BRIDGE_OTHER_CONFIGS_VALUE = "BridgeOtherConfigValue";
-        final String FORMAT_STR = "%s_%s_%d";
-        final String GOOD_KEY = "GoodKey";
-        final String GOOD_VALUE = "GoodValue";
-        final String NO_VALUE_FOR_KEY = "NoValueForKey";
-        final String NO_KEY_FOR_VALUE = "NoKeyForValue";
+    private static final class SouthboundInterfaceExternalIdsBuilder extends KeyValueBuilder<InterfaceExternalIds> {
+        @Override
+        protected Builder<InterfaceExternalIds> builder() {
+            return new InterfaceExternalIdsBuilder();
+        }
 
-        // Test Case 1:  TestOneOtherConfig
-        // Test Type:    Positive
-        // Description:  Create a bridge with one other_config
-        // Expected:     A bridge is created with the single other_config specified below
-        final String testOneOtherConfigName = "TestOneOtherConfig";
-        int otherConfigCounter = 0;
-        List<BridgeOtherConfigs> oneOtherConfig = Lists.newArrayList(
-                (new BridgeOtherConfigsBuilder()
-                        .setBridgeOtherConfigKey(String.format(FORMAT_STR, testOneOtherConfigName,
-                                BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
-                        .setBridgeOtherConfigValue(String.format(FORMAT_STR, testOneOtherConfigName,
-                                BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
-                        .build()));
-        Map<String,List<BridgeOtherConfigs>> testCase = Maps.newHashMap();
-        testCase.put(EXPECTED_VALUES_KEY, oneOtherConfig);
-        testCase.put(INPUT_VALUES_KEY, oneOtherConfig);
-        testMap.put(testOneOtherConfigName, testCase);
-
-        // Test Case 2:  TestFiveOtherConfig
-        // Test Type:    Positive
-        // Description:  Create a bridge with multiple (five) other_configs
-        // Expected:     A bridge is created with the five other_configs specified below
-        final String testFiveOtherConfigName = "TestFiveOtherConfig";
-        otherConfigCounter = 0;
-        List<BridgeOtherConfigs> fiveOtherConfig = Lists.newArrayList(
-                (new BridgeOtherConfigsBuilder()
-                        .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
-                                BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
-                        .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
-                                BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
-                        .build()),
-                (new BridgeOtherConfigsBuilder()
-                        .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
-                                BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
-                        .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
-                                BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
-                        .build()),
-                (new BridgeOtherConfigsBuilder()
-                        .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
-                                BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
-                        .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
-                                BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
-                        .build()),
-                (new BridgeOtherConfigsBuilder()
-                        .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
-                                BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
-                        .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
-                                BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
-                        .build()),
-                (new BridgeOtherConfigsBuilder()
-                        .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
-                                BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
-                        .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
-                                BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
-                        .build()));
-        testCase = Maps.newHashMap();
-        testCase.put(EXPECTED_VALUES_KEY, fiveOtherConfig);
-        testCase.put(INPUT_VALUES_KEY, fiveOtherConfig);
-        testMap.put(testFiveOtherConfigName, testCase);
-
-        // Test Case 3:  TestOneGoodOtherConfigOneMalformedOtherConfigValue
-        // Test Type:    Negative
-        // Description:
-        //     One perfectly fine BridgeOtherConfig
-        //        (TestOneGoodOtherConfigOneMalformedOtherConfigValue_BridgeOtherConfigKey_1,
-        //        TestOneGoodOtherConfigOneMalformedOtherConfig_BridgeOtherConfigValue_1)
-        //     and one malformed BridgeOtherConfig which only has key specified
-        //        (TestOneGoodOtherConfigOneMalformedOtherConfigValue_NoValueForKey_2,
-        //        UNSPECIFIED)
-        // Expected:     A bridge is created without any other_config
-        final String testOneGoodOtherConfigOneMalformedOtherConfigValueName =
-                "TestOneGoodOtherConfigOneMalformedOtherConfigValue";
-        otherConfigCounter = 0;
-        BridgeOtherConfigs oneGood = new BridgeOtherConfigsBuilder()
-                .setBridgeOtherConfigKey(String.format(FORMAT_STR,
-                        testOneGoodOtherConfigOneMalformedOtherConfigValueName, GOOD_KEY, ++otherConfigCounter))
-                .setBridgeOtherConfigValue(String.format(FORMAT_STR,
-                        testOneGoodOtherConfigOneMalformedOtherConfigValueName,
-                        GOOD_VALUE, otherConfigCounter))
-                .build();
-        BridgeOtherConfigs oneBad = new BridgeOtherConfigsBuilder()
-                .setBridgeOtherConfigKey(String.format(FORMAT_STR,
-                        testOneGoodOtherConfigOneMalformedOtherConfigValueName, NO_VALUE_FOR_KEY, ++otherConfigCounter))
-                .build();
-        List<BridgeOtherConfigs> oneGoodOneBadInput = Lists.newArrayList(oneGood, oneBad);
-        List<BridgeOtherConfigs> oneGoodOneBadExpected = null;
-        testCase = Maps.newHashMap();
-        testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
-        testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
-        testMap.put(testOneGoodOtherConfigOneMalformedOtherConfigValueName, testCase);
-
-        // Test Case 4:  TestOneGoodOtherConfigOneMalformedOtherConfigKey
-        // Test Type:    Negative
-        // Description:
-        //     One perfectly fine BridgeOtherConfig
-        //        (TestOneGoodOtherConfigOneMalformedOtherConfigValue_BridgeOtherConfigKey_1,
-        //        TestOneGoodOtherConfigOneMalformedOtherConfig_BridgeOtherConfigValue_1)
-        //     and one malformed BridgeOtherConfig which only has key specified
-        //        (UNSPECIFIED,
-        //        TestOneGoodOtherConfigOneMalformedOtherConfigKey_NoKeyForValue_2)
-        // Expected:     A bridge is created without any other_config
-        final String testOneGoodOtherConfigOneMalformedOtherConfigKeyName =
-                "TestOneGoodOtherConfigOneMalformedOtherConfigIdKey";
-        otherConfigCounter = 0;
-        oneGood = new BridgeOtherConfigsBuilder()
-                .setBridgeOtherConfigKey(String.format(FORMAT_STR, testOneGoodOtherConfigOneMalformedOtherConfigKeyName,
-                        GOOD_KEY, ++otherConfigCounter))
-                .setBridgeOtherConfigValue(String.format(FORMAT_STR,
-                        testOneGoodOtherConfigOneMalformedOtherConfigKeyName,
-                        GOOD_VALUE, otherConfigCounter))
-                .build();
-        oneBad = new BridgeOtherConfigsBuilder()
-                .setBridgeOtherConfigKey(String.format(FORMAT_STR,
-                        testOneGoodOtherConfigOneMalformedOtherConfigKeyName, NO_KEY_FOR_VALUE, ++otherConfigCounter))
-                .build();
-        oneGoodOneBadInput = Lists.newArrayList(oneGood, oneBad);
-        oneGoodOneBadExpected = null;
-        testCase = Maps.newHashMap();
-        testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
-        testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
-        testMap.put(testOneGoodOtherConfigOneMalformedOtherConfigKeyName, testCase);
+        @Override
+        protected void setKey(Builder<InterfaceExternalIds> builder, String key) {
+            ((InterfaceExternalIdsBuilder) builder).setExternalIdKey(key);
+        }
 
-        return testMap;
+        @Override
+        protected void setValue(Builder<InterfaceExternalIds> builder, String value) {
+            ((InterfaceExternalIdsBuilder) builder).setExternalIdValue(value);
+        }
     }
 
-    /*
-     * @see <code>SouthboundIT.testCRUDBridgeOtherConfigs()</code>
-     * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
-     */
-    private void assertExpectedBridgeOtherConfigsExist( List<BridgeOtherConfigs> expected,
-                                                        List<BridgeOtherConfigs> test ) {
+    private static final class SouthboundOptionsBuilder extends KeyValueBuilder<Options> {
+        @Override
+        protected Builder<Options> builder() {
+            return new OptionsBuilder();
+        }
 
-        if (expected != null) {
-            for (BridgeOtherConfigs expectedOtherConfig : expected) {
-                Assert.assertTrue(test.contains(expectedOtherConfig));
-            }
+        @Override
+        protected void setKey(Builder<Options> builder, String key) {
+            ((OptionsBuilder) builder).setOption(key);
+        }
+
+        @Override
+        protected void setValue(Builder<Options> builder, String value) {
+            ((OptionsBuilder) builder).setValue(value);
         }
     }
 
-    /*
-     * @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
-     */
-    @Test
-    public void testCRUDBridgeOtherConfigs() throws InterruptedException {
-        final String TEST_BRIDGE_PREFIX = "CRUDBridgeOtherConfigs";
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
-        // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
-        // the update has been performed.
-        Map<String, Map<String, List<BridgeOtherConfigs>>> updateFromTestCases = generateBridgeOtherConfigsTestCases();
-        Map<String, Map<String, List<BridgeOtherConfigs>>> updateToTestCases = generateBridgeOtherConfigsTestCases();
-        Map<String, List<BridgeOtherConfigs>> updateFromTestCase;
-        Map<String, List<BridgeOtherConfigs>> updateToTestCase;
-        List<BridgeOtherConfigs> updateFromInputOtherConfigs;
-        List<BridgeOtherConfigs> updateFromExpectedOtherConfigs;
-        List<BridgeOtherConfigs> updateToInputOtherConfigs;
-        List<BridgeOtherConfigs> updateToExpectedOtherConfigs;
-        String testBridgeName;
-
-        int counter = 1;
-        ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
-        for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
-            updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
-            updateFromInputOtherConfigs = updateFromTestCase.get(INPUT_VALUES_KEY);
-            updateFromExpectedOtherConfigs = updateFromTestCase.get(EXPECTED_VALUES_KEY);
-            for (String testCaseKey : updateToTestCases.keySet()) {
-                testBridgeName = String.format("%s_%s_%d", TEST_BRIDGE_PREFIX, testCaseKey, counter);
-                counter += 1;
-                updateToTestCase = updateToTestCases.get(testCaseKey);
-                updateToInputOtherConfigs = updateToTestCase.get(INPUT_VALUES_KEY);
-                updateToExpectedOtherConfigs = updateToTestCase.get(EXPECTED_VALUES_KEY);
-
-                TestCRUDBridgeOtherConfigsRunnable testRunnable =
-                        new TestCRUDBridgeOtherConfigsRunnable(
-                                connectionInfo, testBridgeName,
-                                updateFromInputOtherConfigs,
-                                updateFromExpectedOtherConfigs,
-                                updateToInputOtherConfigs,
-                                updateToExpectedOtherConfigs);
-                executor.submit(testRunnable);
-            }
+    private static final class SouthboundInterfaceOtherConfigsBuilder extends KeyValueBuilder<InterfaceOtherConfigs> {
+        @Override
+        protected Builder<InterfaceOtherConfigs> builder() {
+            return new InterfaceOtherConfigsBuilder();
         }
-        executor.shutdown();
-        executor.awaitTermination(5, TimeUnit.MINUTES);
 
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
+        @Override
+        protected void setKey(Builder<InterfaceOtherConfigs> builder, String key) {
+            ((InterfaceOtherConfigsBuilder) builder).setOtherConfigKey(key);
+        }
+
+        @Override
+        protected void setValue(Builder<InterfaceOtherConfigs> builder, String value) {
+            ((InterfaceOtherConfigsBuilder) builder).setOtherConfigValue(value);
+        }
     }
 
-    class TestCRUDBridgeOtherConfigsRunnable implements Runnable {
+    private static final class SouthboundPortOtherConfigsBuilder extends KeyValueBuilder<PortOtherConfigs> {
+        @Override
+        protected Builder<PortOtherConfigs> builder() {
+            return new PortOtherConfigsBuilder();
+        }
+
+        @Override
+        protected void setKey(Builder<PortOtherConfigs> builder, String key) {
+            ((PortOtherConfigsBuilder) builder).setOtherConfigKey(key);
+        }
 
-        ConnectionInfo connectionInfo;
-        String testBridgeName;
-        List<BridgeOtherConfigs> updateFromInputOtherConfigs;
-        List<BridgeOtherConfigs> updateFromExpectedOtherConfigs;
-        List<BridgeOtherConfigs> updateToInputOtherConfigs;
-        List<BridgeOtherConfigs> updateToExpectedOtherConfigs;
+        @Override
+        protected void setValue(Builder<PortOtherConfigs> builder, String value) {
+            ((PortOtherConfigsBuilder) builder).setOtherConfigValue(value);
+        }
+    }
 
-        TestCRUDBridgeOtherConfigsRunnable(
-                ConnectionInfo connectionInfo, String testBridgeName,
-                List<BridgeOtherConfigs> updateFromInputOtherConfigs,
-                List<BridgeOtherConfigs> updateFromExpectedOtherConfigs,
-                List<BridgeOtherConfigs> updateToInputOtherConfigs,
-                List<BridgeOtherConfigs> updateToExpectedOtherConfigs) {
+    private static final class SouthboundBridgeOtherConfigsBuilder extends KeyValueBuilder<BridgeOtherConfigs> {
+        @Override
+        protected Builder<BridgeOtherConfigs> builder() {
+            return new BridgeOtherConfigsBuilder();
+        }
 
-            this.connectionInfo = connectionInfo;
-            this.testBridgeName = testBridgeName;
-            this.updateFromInputOtherConfigs = updateFromInputOtherConfigs;
-            this.updateFromExpectedOtherConfigs = updateFromExpectedOtherConfigs;
-            this.updateToInputOtherConfigs = updateToInputOtherConfigs;
-            this.updateToExpectedOtherConfigs = updateToExpectedOtherConfigs;
+        @Override
+        protected void setKey(Builder<BridgeOtherConfigs> builder, String key) {
+            ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigKey(key);
         }
 
         @Override
-        public void run() {
-            try {
-                test();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
+        protected void setValue(Builder<BridgeOtherConfigs> builder, String value) {
+            ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigValue(value);
         }
+    }
 
-        public void test() throws InterruptedException {
-            // CREATE: Create the test bridge
-            boolean bridgeAdded = addBridge(connectionInfo, null,
-                    testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
-                    true, null, null, null, updateFromInputOtherConfigs);
-            Assert.assertTrue(bridgeAdded);
-
-            // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
-            // then repeat for OPERATIONAL data store
-            List<BridgeOtherConfigs> updateFromConfigurationOtherConfigs = getBridge(connectionInfo, testBridgeName,
-                    LogicalDatastoreType.CONFIGURATION).getBridgeOtherConfigs();
-            assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
-                    updateFromConfigurationOtherConfigs);
-            List<BridgeOtherConfigs> updateFromOperationalOtherConfigs = getBridge(connectionInfo, testBridgeName)
-                    .getBridgeOtherConfigs();
-            assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
-                    updateFromOperationalOtherConfigs);
-
-            // UPDATE:  update the external_ids
-            OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
-            bridgeAugmentationBuilder.setBridgeOtherConfigs(updateToInputOtherConfigs);
-            InstanceIdentifier<Node> bridgeIid =
-                    createInstanceIdentifier(connectionInfo,
-                            new OvsdbBridgeName(testBridgeName));
-            NodeBuilder bridgeNodeBuilder = new NodeBuilder();
-            Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
-            bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
-            bridgeNodeBuilder.setKey(bridgeNode.getKey());
-            bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
-            boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
-                    bridgeNodeBuilder.build());
-            Thread.sleep(OVSDB_UPDATE_TIMEOUT);
-            Assert.assertTrue(result);
-
-            // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
-            // then repeat for OPERATIONAL data store
-            List<BridgeOtherConfigs> updateToConfigurationOtherConfigs = getBridge(connectionInfo, testBridgeName,
-                    LogicalDatastoreType.CONFIGURATION).getBridgeOtherConfigs();
-            assertExpectedBridgeOtherConfigsExist(updateToExpectedOtherConfigs, updateToConfigurationOtherConfigs);
-            assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
-                    updateToConfigurationOtherConfigs);
-            List<BridgeOtherConfigs> updateToOperationalOtherConfigs = getBridge(connectionInfo, testBridgeName)
-                    .getBridgeOtherConfigs();
-            if (updateFromExpectedOtherConfigs != null) {
-                assertExpectedBridgeOtherConfigsExist(updateToExpectedOtherConfigs,
-                        updateToOperationalOtherConfigs);
-                assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
-                        updateToOperationalOtherConfigs);
-            }
+    private static final class SouthboundBridgeExternalIdsBuilder extends KeyValueBuilder<BridgeExternalIds> {
+        @Override
+        protected Builder<BridgeExternalIds> builder() {
+            return new BridgeExternalIdsBuilder();
+        }
+
+        @Override
+        protected void setKey(Builder<BridgeExternalIds> builder, String key) {
+            ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdKey(key);
+        }
 
-            // DELETE
-            Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
+        @Override
+        protected void setValue(Builder<BridgeExternalIds> builder, String value) {
+            ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdValue(value);
         }
     }
 
     /*
-     * Generates the test cases involved in testing BridgeExternalIds.  See inline comments for descriptions of
+     * Generates the test cases involved in testing key-value-based data.  See inline comments for descriptions of
      * the particular cases considered.
-     *
-     * The return value is a Map in the form (K,V)=(testCaseName,testCase).
-     * - testCaseName is a String
-     * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
-     *     either corresponding INPUT bridge external ids, or EXPECTED bridge external ids
-     *     INPUT is the List we use when calling BridgeAugmentationBuilder.setBridgeExternalIds()
-     *     EXPECTED is the List we expect to receive after calling BridgeAugmentationBuilder.getBridgeExternalIds()
      */
-    private Map<String, Map<String, List<BridgeExternalIds>>> generateBridgeExternalIdsTestCases() {
-        Map<String, Map<String, List<BridgeExternalIds>>> testMap = new HashMap<>();
+    private static <T> List<SouthboundTestCase<T>> generateKeyValueTestCases(
+            KeyValueBuilder<T> builder, String testName) {
+        List<SouthboundTestCase<T>> testCases = new ArrayList<>();
 
-        final String BRIDGE_EXTERNAL_ID_KEY = "BridgeExternalIdKey";
-        final String BRIDGE_EXTERNAL_ID_VALUE = "BridgeExternalIdValue";
-        final String FORMAT_STR = "%s_%s_%d";
         final String GOOD_KEY = "GoodKey";
         final String GOOD_VALUE = "GoodValue";
         final String NO_VALUE_FOR_KEY = "NoValueForKey";
-        final String NO_KEY_FOR_VALUE = "NoKeyForValue";
 
-        // Test Case 1:  TestOneExternalId
+        final String idKey = testName + "Key";
+        final String idValue = testName + "Value";
+
+        // Test Case 1:  TestOne
         // Test Type:    Positive
-        // Description:  Create a bridge with one BridgeExternalIds
-        // Expected:     A bridge is created with the single external_ids specified below
-        final String testOneExternalIdName = "TestOneExternalId";
-        int externalIdCounter = 0;
-        List<BridgeExternalIds> oneExternalId = Lists.newArrayList(
-                (new BridgeExternalIdsBuilder()
-                        .setBridgeExternalIdKey(String.format(FORMAT_STR, testOneExternalIdName,
-                                BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setBridgeExternalIdValue(String.format(FORMAT_STR, testOneExternalIdName,
-                                BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()));
-        Map<String,List<BridgeExternalIds>> testCase = Maps.newHashMap();
-        testCase.put(EXPECTED_VALUES_KEY, oneExternalId);
-        testCase.put(INPUT_VALUES_KEY, oneExternalId);
-        testMap.put(testOneExternalIdName, testCase);
-
-        // Test Case 2:  TestFiveExternalId
+        // Description:  Create a termination point with one value
+        // Expected:     A port is created with the single value specified below
+        final String testOneName = "TestOne" + testName;
+        testCases.add(new SouthboundTestCaseBuilder<T>()
+                .name(testOneName)
+                .input(builder.build(testOneName, idKey, idValue))
+                .expectInputAsOutput()
+                .build());
+
+        // Test Case 2:  TestFive
         // Test Type:    Positive
-        // Description:  Create a bridge with multiple (five) BridgeExternalIds
-        // Expected:     A bridge is created with the five external_ids specified below
-        final String testFiveExternalIdName = "TestFiveExternalId";
-        externalIdCounter = 0;
-        List<BridgeExternalIds> fiveExternalId = Lists.newArrayList(
-                (new BridgeExternalIdsBuilder()
-                        .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()),
-                (new BridgeExternalIdsBuilder()
-                        .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()),
-                (new BridgeExternalIdsBuilder()
-                        .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()),
-                (new BridgeExternalIdsBuilder()
-                        .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()),
-                (new BridgeExternalIdsBuilder()
-                        .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
-                                BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
-                        .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
-                                BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
-                        .build()));
-        testCase = Maps.newHashMap();
-        testCase.put(EXPECTED_VALUES_KEY, fiveExternalId);
-        testCase.put(INPUT_VALUES_KEY, fiveExternalId);
-        testMap.put(testFiveExternalIdName, testCase);
-
-        // Test Case 3:  TestOneGoodExternalIdOneMalformedExternalIdValue
+        // Description:  Create a termination point with multiple (five) values
+        // Expected:     A port is created with the five values specified below
+        final String testFiveName = "TestFive" + testName;
+        builder.reset();
+        testCases.add(new SouthboundTestCaseBuilder<T>()
+                .name(testFiveName)
+                .input(
+                        builder.build(testFiveName, idKey, idValue),
+                        builder.build(testFiveName, idKey, idValue),
+                        builder.build(testFiveName, idKey, idValue),
+                        builder.build(testFiveName, idKey, idValue),
+                        builder.build(testFiveName, idKey, idValue))
+                .expectInputAsOutput()
+                .build());
+
+        // Test Case 3:  TestOneGoodOneMalformedValue
         // Test Type:    Negative
         // Description:
-        //     One perfectly fine BridgeExternalId
-        //        (TestOneGoodExternalIdOneMalformedExternalIdValue_BridgeExternalIdKey_1,
-        //        TestOneGoodExternalIdOneMalformedExternalId_BridgeExternalIdValue_1)
-        //     and one malformed BridgeExternalId which only has key specified
-        //        (TestOneGoodExternalIdOneMalformedExternalIdValue_NoValueForKey_2,
+        //     One perfectly fine input
+        //        (TestOneGoodOneMalformedValue_GoodKey_1,
+        //        TestOneGoodOneMalformedValue_GoodValue_1)
+        //     and one malformed input which only has key specified
+        //        (TestOneGoodOneMalformedValue_NoValueForKey_2,
         //        UNSPECIFIED)
-        // Expected:     A bridge is created without any external_ids
-        final String testOneGoodExternalIdOneMalformedExternalIdValueName =
-                "TestOneGoodExternalIdOneMalformedExternalIdValue";
-        externalIdCounter = 0;
-        BridgeExternalIds oneGood = new BridgeExternalIdsBuilder()
-                .setBridgeExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdValueName,
-                        GOOD_KEY, ++externalIdCounter))
-                .setBridgeExternalIdValue(String.format(FORMAT_STR,
-                        testOneGoodExternalIdOneMalformedExternalIdValueName,
-                        GOOD_VALUE, externalIdCounter))
-                .build();
-        BridgeExternalIds oneBad = new BridgeExternalIdsBuilder()
-                .setBridgeExternalIdKey(String.format(FORMAT_STR,
-                        testOneGoodExternalIdOneMalformedExternalIdValueName, NO_VALUE_FOR_KEY, ++externalIdCounter))
-                .build();
-        List<BridgeExternalIds> oneGoodOneBadInput = Lists.newArrayList(oneGood, oneBad);
-        List<BridgeExternalIds> oneGoodOneBadExpected = null;
-        testCase = Maps.newHashMap();
-        testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
-        testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
-        testMap.put(testOneGoodExternalIdOneMalformedExternalIdValueName, testCase);
-
-        // Test Case 4:  TestOneGoodExternalIdOneMalformedExternalIdKey
-        // Test Type:    Negative
-        // Description:
-        //     One perfectly fine BridgeExternalId
-        //        (TestOneGoodExternalIdOneMalformedExternalIdValue_BridgeExternalIdKey_1,
-        //        TestOneGoodExternalIdOneMalformedExternalId_BridgeExternalIdValue_1)
-        //     and one malformed BridgeExternalId which only has key specified
-        //        (UNSPECIFIED,
-        //        TestOneGoodExternalIdOneMalformedExternalIdKey_NoKeyForValue_2)
-        // Expected:     A bridge is created without any external_ids
-        final String testOneGoodExternalIdOneMalformedExternalIdKeyName =
-                "TestOneGoodExternalIdOneMalformedExternalIdKey";
-        externalIdCounter = 0;
-        oneGood = new BridgeExternalIdsBuilder()
-                .setBridgeExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdKeyName,
-                        GOOD_KEY, ++externalIdCounter))
-                .setBridgeExternalIdValue(String.format(FORMAT_STR,
-                        testOneGoodExternalIdOneMalformedExternalIdKeyName,
-                        GOOD_VALUE, externalIdCounter))
-                .build();
-        oneBad = new BridgeExternalIdsBuilder()
-                .setBridgeExternalIdKey(String.format(FORMAT_STR,
-                        testOneGoodExternalIdOneMalformedExternalIdKeyName, NO_KEY_FOR_VALUE, ++externalIdCounter))
-                .build();
-        oneGoodOneBadInput = Lists.newArrayList(oneGood, oneBad);
-        oneGoodOneBadExpected = null;
-        testCase = Maps.newHashMap();
-        testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
-        testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
-        testMap.put(testOneGoodExternalIdOneMalformedExternalIdKeyName, testCase);
-        return testMap;
-    }
-
-    /*
-     * @see <code>SouthboundIT.testCRUDBridgeExternalIds()</code>
-     * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
-     */
-    private void assertExpectedBridgeExternalIdsExist( List<BridgeExternalIds> expected,
-                                                       List<BridgeExternalIds> test ) {
+        // Expected:     A port is created without any values
+        final String testOneGoodOneMalformedValueName = "TestOneGoodOneMalformedValue" + testName;
+        builder.reset();
+        testCases.add(new SouthboundTestCaseBuilder<T>()
+                .name(testOneGoodOneMalformedValueName)
+                .input(
+                        builder.build(testOneGoodOneMalformedValueName, GOOD_KEY, GOOD_VALUE),
+                        builder.build(testOneGoodOneMalformedValueName, NO_VALUE_FOR_KEY, null))
+                .expectNoOutput()
+                .build());
+        builder.reset();
 
-        if (expected != null) {
-            for (BridgeExternalIds expectedExternalId : expected) {
-                Assert.assertTrue(test.contains(expectedExternalId));
-            }
-        }
+        return testCases;
     }
 
-    /*
-     * @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
-     */
-    @Test
-    public void testCRUDBridgeExternalIds() throws InterruptedException {
-        final String TEST_BRIDGE_PREFIX = "CRUDBridgeExternalIds";
-        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
-        // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
-        // the update has been performed.
-        Map<String, Map<String, List<BridgeExternalIds>>> updateFromTestCases = generateBridgeExternalIdsTestCases();
-        Map<String, Map<String, List<BridgeExternalIds>>> updateToTestCases = generateBridgeExternalIdsTestCases();
-        Map<String, List<BridgeExternalIds>> updateFromTestCase;
-        List<BridgeExternalIds> updateFromInputExternalIds;
-        List<BridgeExternalIds> updateFromExpectedExternalIds;
-        Map<String, List<BridgeExternalIds>> updateToTestCase;
-        List<BridgeExternalIds> updateToInputExternalIds;
-        List<BridgeExternalIds> updateToExpectedExternalIds;
-        String testBridgeName;
-
-        int counter = 1;
-        ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
-        for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
-            updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
-            updateFromInputExternalIds = updateFromTestCase.get(INPUT_VALUES_KEY);
-            updateFromExpectedExternalIds = updateFromTestCase.get(EXPECTED_VALUES_KEY);
-            for (String testCaseKey : updateToTestCases.keySet()) {
-                testBridgeName = String.format("%s_%s_%d", TEST_BRIDGE_PREFIX, testCaseKey, counter);
-                counter += 1;
-                updateToTestCase = updateToTestCases.get(testCaseKey);
-                updateToInputExternalIds = updateToTestCase.get(INPUT_VALUES_KEY);
-                updateToExpectedExternalIds = updateToTestCase.get(EXPECTED_VALUES_KEY);
-
-                TestCRUDBridgeExternalIdsRunnable testRunnable =
-                        new TestCRUDBridgeExternalIdsRunnable(
-                                connectionInfo, testBridgeName,
-                                updateFromInputExternalIds,
-                                updateFromExpectedExternalIds,
-                                updateToInputExternalIds,
-                                updateToExpectedExternalIds);
-                executor.submit(testRunnable);
-            }
+    private static class PortExternalIdsSouthboundHelper implements SouthboundTerminationPointHelper<PortExternalIds> {
+        @Override
+        public void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<PortExternalIds> values) {
+            builder.setPortExternalIds(values);
         }
-        executor.shutdown();
-        executor.awaitTermination(5, TimeUnit.MINUTES);
 
-        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
+        @Override
+        public List<PortExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
+            return augmentation.getPortExternalIds();
+        }
     }
 
-    class TestCRUDBridgeExternalIdsRunnable implements Runnable {
-        ConnectionInfo connectionInfo;
-        String testBridgeName;
-        List<BridgeExternalIds> updateFromInputExternalIds;
-        List<BridgeExternalIds> updateFromExpectedExternalIds;
-        List<BridgeExternalIds> updateToInputExternalIds;
-        List<BridgeExternalIds> updateToExpectedExternalIds;
-
-        TestCRUDBridgeExternalIdsRunnable(
-                ConnectionInfo connectionInfo, String testBridgeName,
-                List<BridgeExternalIds> updateFromInputExternalIds,
-                List<BridgeExternalIds> updateFromExpectedExternalIds,
-                List<BridgeExternalIds> updateToInputExternalIds,
-                List<BridgeExternalIds> updateToExpectedExternalIds) {
-
-            this.connectionInfo = connectionInfo;
-            this.testBridgeName = testBridgeName;
-            this.updateFromInputExternalIds = updateFromInputExternalIds;
-            this.updateFromExpectedExternalIds = updateFromExpectedExternalIds;
-            this.updateToInputExternalIds = updateToInputExternalIds;
-            this.updateToExpectedExternalIds = updateToExpectedExternalIds;
+    private static class InterfaceExternalIdsSouthboundHelper implements
+            SouthboundTerminationPointHelper<InterfaceExternalIds> {
+        @Override
+        public void writeValues(
+                OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceExternalIds> values) {
+            builder.setInterfaceExternalIds(values);
         }
 
         @Override
-        public void run() {
-            try {
-                test();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
+        public List<InterfaceExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
+            return augmentation.getInterfaceExternalIds();
         }
+    }
 
-        public void test() throws InterruptedException {
-            // CREATE: Create the test bridge
-            boolean bridgeAdded = addBridge(connectionInfo, null,
-                    testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
-                    true, null, updateFromInputExternalIds, null, null);
-            Assert.assertTrue(bridgeAdded);
-
-            // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
-            // then repeat for OPERATIONAL data store
-            List<BridgeExternalIds> updateFromConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
-                    LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
-            assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromConfigurationExternalIds);
-            List<BridgeExternalIds> updateFromOperationalExternalIds = getBridge(connectionInfo, testBridgeName)
-                    .getBridgeExternalIds();
-            assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds);
-
-            // UPDATE:  update the external_ids
-            OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
-            bridgeAugmentationBuilder.setBridgeExternalIds(updateToInputExternalIds);
-            InstanceIdentifier<Node> bridgeIid =
-                    createInstanceIdentifier(connectionInfo,
-                            new OvsdbBridgeName(testBridgeName));
-            NodeBuilder bridgeNodeBuilder = new NodeBuilder();
-            Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
-            bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
-            bridgeNodeBuilder.setKey(bridgeNode.getKey());
-            bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
-            boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
-                    bridgeNodeBuilder.build());
-            Thread.sleep(OVSDB_UPDATE_TIMEOUT);
-            Assert.assertTrue(result);
-
-            // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
-            // then repeat for OPERATIONAL data store
-            List<BridgeExternalIds> updateToConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
-                    LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
-            assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
-            assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateToConfigurationExternalIds);
-            List<BridgeExternalIds> updateToOperationalExternalIds = getBridge(connectionInfo, testBridgeName)
-                    .getBridgeExternalIds();
-            if (updateFromExpectedExternalIds != null) {
-                assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds);
-                assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateToOperationalExternalIds);
-            }
+    private static class OptionsSouthboundHelper implements SouthboundTerminationPointHelper<Options> {
+        @Override
+        public void writeValues(
+                OvsdbTerminationPointAugmentationBuilder builder, List<Options> values) {
+            builder.setOptions(values);
+        }
 
-            // DELETE
-            Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
+        @Override
+        public List<Options> readValues(OvsdbTerminationPointAugmentation augmentation) {
+            return augmentation.getOptions();
         }
     }
 
-    public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
-        return SouthboundMapper.createInstanceIdentifier(createManagedNodeId(key, bridgeName));
-    }
+    private static class InterfaceOtherConfigsSouthboundHelper implements
+            SouthboundTerminationPointHelper<InterfaceOtherConfigs> {
+        @Override
+        public void writeValues(
+                OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceOtherConfigs> values) {
+            builder.setInterfaceOtherConfigs(values);
+        }
 
-    public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
-        return createManagedNodeId(key.getRemoteIp(),key.getRemotePort(),bridgeName);
+        @Override
+        public List<InterfaceOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
+            return augmentation.getInterfaceOtherConfigs();
+        }
     }
 
-    public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
-        return new NodeId(createNodeId(ip,port).getValue()
-                + "/" + SouthboundConstants.BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
-    }
+    private static class PortOtherConfigsSouthboundHelper implements
+            SouthboundTerminationPointHelper<PortOtherConfigs> {
+        @Override
+        public void writeValues(
+                OvsdbTerminationPointAugmentationBuilder builder, List<PortOtherConfigs> values) {
+            builder.setPortOtherConfigs(values);
+        }
 
-    public static NodeId createNodeId(IpAddress ip, PortNumber port) {
-        String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
-                + new String(ip.getValue()) + ":" + port.getValue();
-        Uri uri = new Uri(uriString);
-        return new NodeId(uri);
+        @Override
+        public List<PortOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
+            return augmentation.getPortOtherConfigs();
+        }
     }
 
-    public static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
-        return new NodeKey(createNodeId(ip,port));
-    }
+    private static class BridgeExternalIdsSouthboundHelper implements SouthboundBridgeHelper<BridgeExternalIds> {
+        @Override
+        public void writeValues(
+                OvsdbBridgeAugmentationBuilder builder, List<BridgeExternalIds> values) {
+            builder.setBridgeExternalIds(values);
+        }
 
-    public static Node createNode(ConnectionInfo key) {
-        NodeBuilder nodeBuilder = new NodeBuilder();
-        nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(),key.getRemotePort()));
-        nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
-        return nodeBuilder.build();
+        @Override
+        public List<BridgeExternalIds> readValues(OvsdbBridgeAugmentation augmentation) {
+            return augmentation.getBridgeExternalIds();
+        }
     }
 
-    public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
-        OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
-        ovsdbNodeBuilder.setConnectionInfo(key);
-        return ovsdbNodeBuilder.build();
-    }
+    private static class BridgeOtherConfigsSouthboundHelper implements SouthboundBridgeHelper<BridgeOtherConfigs> {
+        @Override
+        public void writeValues(
+                OvsdbBridgeAugmentationBuilder builder, List<BridgeOtherConfigs> values) {
+            builder.setBridgeOtherConfigs(values);
+        }
 
-    public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
-        NodeKey nodeKey = iid.firstKeyOf(Node.class, NodeKey.class);
-        return nodeKey.getNodeId();
+        @Override
+        public List<BridgeOtherConfigs> readValues(OvsdbBridgeAugmentation augmentation) {
+            return augmentation.getBridgeOtherConfigs();
+        }
     }
 }
index f593f18ca99a0d6444cbfe872b42835badf68fca..307ca23e1594d0443e4114f55bdbd97d76d2938a 100644 (file)
@@ -13,8 +13,7 @@ import java.math.BigInteger;
 public class StringConvertor{
 
     public static long dpidStringToLong(String values) {
-        long value = new BigInteger(values.replaceAll(":", ""), 16).longValue();
-        return value;
+        return new BigInteger(values.replaceAll(":", ""), 16).longValue();
     }
 
 }
index c819d7729f9031c4ca7647f776db5b636c30317a..474a582ebb221b7792a221bcc3688947e0768e0c 100644 (file)
@@ -66,7 +66,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <groupId>org.opendaylight.mdsal.model</groupId>
       <artifactId>opendaylight-l2-types</artifactId>
     </dependency>
-    <!-- Controller Dependencies -->
     <dependency>
       <groupId>org.opendaylight.openflowplugin</groupId>
       <artifactId>openflowjava-extension-nicira</artifactId>
@@ -95,6 +94,18 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   </dependencies>
   <build>
     <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Export-Package>
+              org.opendaylight.ovsdb.utils.mdsal.openflow
+            </Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-checkstyle-plugin</artifactId>
index 7469dff49118f9db6076a74f1e30aee94fe83669..c3b878c593b0a00402facf842654f15d68438114 100644 (file)
@@ -31,25 +31,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.DstChoice;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxArpShaCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxArpThaCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIdCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIpv4DstCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpOpCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpSpaCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpTpaCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfEthDstCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegLoadNodesNodeGroupBucketsBucketActionsCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegMoveNodesNodeGroupBucketsBucketActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionOutputRegNodesNodeTableFlowApplyActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.NxOutputReg;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.NxOutputRegBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
@@ -58,17 +49,25 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ni
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMove;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMoveBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.nx.reg.move.SrcBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._1.grouping.NxSetNshc1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._1.grouping.NxSetNshc1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._2.grouping.NxSetNshc2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._2.grouping.NxSetNshc2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._3.grouping.NxSetNshc3;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._3.grouping.NxSetNshc3Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._4.grouping.NxSetNshc4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._4.grouping.NxSetNshc4Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.SrcChoice;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxArpShaCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc1CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc2CaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxRegCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxTunIdCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxTunIpv4DstCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfArpSpaCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfEthSrcCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.OfjNxHashFields;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.OfjNxMpAlgorithm;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionMultipathNodesNodeTableFlowApplyActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionResubmitNodesNodeTableFlowApplyActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionSetNsiNodesNodeTableFlowApplyActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionSetNspNodesNodeTableFlowApplyActionsCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.multipath.grouping.NxMultipath;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.multipath.grouping.NxMultipathBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmit;
@@ -173,8 +172,8 @@ public final class ActionUtils {
         NxRegLoad r = new NxRegLoadBuilder()
             .setDst(new DstBuilder()
                 .setDstChoice(dstChoice)
-                .setStart(Integer.valueOf(0))
-                .setEnd(Integer.valueOf(endOffset))
+                .setStart(0)
+                .setEnd(endOffset)
                 .build())
             .setValue(value)
             .build();
@@ -240,13 +239,13 @@ public final class ActionUtils {
         NxRegMove r = new NxRegMoveBuilder()
             .setSrc(new SrcBuilder()
                 .setSrcChoice(srcChoice)
-                .setStart(Integer.valueOf(0))
-                .setEnd(Integer.valueOf(endOffset))
+                .setStart(0)
+                .setEnd(endOffset)
                 .build())
             .setDst(new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.nx.reg.move.DstBuilder()
                 .setDstChoice(dstChoice)
-                .setStart(Integer.valueOf(0))
-                .setEnd(Integer.valueOf(endOffset))
+                .setStart(0)
+                .setEnd(endOffset)
                 .build())
             .build();
         if (groupBucket) {
@@ -265,44 +264,36 @@ public final class ActionUtils {
 
     public static Action nxMoveRegTunIdAction(Class<? extends NxmNxReg> src,
                                               boolean groupBucket) {
-        return nxMoveRegAction(new SrcNxRegCaseBuilder()
-                                    .setNxReg(src).build(),
-                               new DstNxTunIdCaseBuilder()
-                                   .setNxTunId(Boolean.TRUE).build(),
+        return nxMoveRegAction(new SrcNxRegCaseBuilder().setNxReg(src).build(),
+                               new DstNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(),
                                31,
                                groupBucket);
     }
 
     public static Action nxMoveArpShaToArpThaAction() {
-        return nxMoveRegAction(new SrcNxArpShaCaseBuilder()
-                                   .setNxArpSha(Boolean.TRUE).build(),
-                               new DstNxArpThaCaseBuilder()
-                                   .setNxArpTha(Boolean.TRUE).build(),
+        return nxMoveRegAction(new SrcNxArpShaCaseBuilder().setNxArpSha(Boolean.TRUE).build(),
+                               new DstNxArpThaCaseBuilder().setNxArpTha(Boolean.TRUE).build(),
                                47, false);
     }
 
     public static Action nxMoveEthSrcToEthDstAction() {
-        return nxMoveRegAction(new SrcOfEthSrcCaseBuilder()
-                                   .setOfEthSrc(Boolean.TRUE).build(),
-                               new DstOfEthDstCaseBuilder()
-                                   .setOfEthDst(Boolean.TRUE).build(),
+        return nxMoveRegAction(new SrcOfEthSrcCaseBuilder().setOfEthSrc(Boolean.TRUE).build(),
+                               new DstOfEthDstCaseBuilder().setOfEthDst(Boolean.TRUE).build(),
                                47, false);
     }
 
     public static Action nxMoveArpSpaToArpTpaAction() {
-        return nxMoveRegAction(new SrcOfArpSpaCaseBuilder()
-                                   .setOfArpSpa(Boolean.TRUE).build(),
-                               new DstOfArpTpaCaseBuilder()
-                                   .setOfArpTpa(Boolean.TRUE).build());
+        return nxMoveRegAction(new SrcOfArpSpaCaseBuilder().setOfArpSpa(Boolean.TRUE).build(),
+                               new DstOfArpTpaCaseBuilder().setOfArpTpa(Boolean.TRUE).build());
     }
 
     public static Action nxOutputRegAction(SrcChoice srcChoice) {
         NxOutputReg r = new NxOutputRegBuilder()
             .setSrc(new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.nx.output.reg.SrcBuilder()
                 .setSrcChoice(srcChoice)
-                .setOfsNbits(Integer.valueOf(31))
+                .setOfsNbits(31)
                 .build())
-            .setMaxLen(Integer.valueOf(0xffff))
+            .setMaxLen(0xffff)
             .build();
         return new NxActionOutputRegNodesNodeTableFlowApplyActionsCaseBuilder()
             .setNxOutputReg(r).build();
@@ -333,15 +324,67 @@ public final class ActionUtils {
         return new NxActionSetNspNodesNodeTableFlowApplyActionsCaseBuilder().setNxSetNsp(r).build();
     }
 
-    public static Action nxSetNsiAction(Short nsp) {
+    public static Action nxSetNsiAction(Short nsi) {
         NxSetNsiBuilder builder = new NxSetNsiBuilder();
-        if (nsp != null) {
-            builder.setNsi(nsp);
+        if (nsi != null) {
+            builder.setNsi(nsi);
         }
         NxSetNsi r = builder.build();
         return new NxActionSetNsiNodesNodeTableFlowApplyActionsCaseBuilder().setNxSetNsi(r).build();
     }
 
+    public static Action nxLoadNshc1RegAction(Long value) {
+        NxSetNshc1 newNshc1 = new NxSetNshc1Builder().setNshc(value).build();
+        return new NxActionSetNshc1NodesNodeTableFlowApplyActionsCaseBuilder().setNxSetNshc1(newNshc1).build();
+    }
+
+    public static Action nxLoadNshc2RegAction(Long value) {
+        NxSetNshc2 newNshc2 = new NxSetNshc2Builder().setNshc(value).build();
+        return new NxActionSetNshc2NodesNodeTableFlowApplyActionsCaseBuilder().setNxSetNshc2(newNshc2).build();
+    }
+
+    public static Action nxLoadNshc3RegAction(Long value) {
+        NxSetNshc3 newNshc3 = new NxSetNshc3Builder().setNshc(value).build();
+        return new NxActionSetNshc3NodesNodeTableFlowApplyActionsCaseBuilder().setNxSetNshc3(newNshc3).build();
+    }
+
+    public static Action nxLoadNshc4RegAction(Long value) {
+        NxSetNshc4 newNshc4 = new NxSetNshc4Builder().setNshc(value).build();
+        return new NxActionSetNshc4NodesNodeTableFlowApplyActionsCaseBuilder().setNxSetNshc4(newNshc4).build();
+    }
+
+    public static Action nxMoveRegTunDstToNshc1() {
+        return nxMoveRegAction(
+                new SrcNxTunIpv4DstCaseBuilder().setNxTunIpv4Dst(Boolean.TRUE).build(),
+                new DstNxNshc1CaseBuilder().setNxNshc1Dst(Boolean.TRUE).build(),
+                31, false);
+    }
+
+    public static Action nxMoveTunIdtoNshc2() {
+        return nxMoveRegAction(
+                new SrcNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(),
+                new DstNxNshc2CaseBuilder().setNxNshc2Dst(Boolean.TRUE).build(),
+                31, false);
+    }
+
+    public static Action nxMoveNshc1ToTunIpv4Dst() {
+        return nxMoveRegAction(
+                new SrcNxNshc1CaseBuilder().setNxNshc1Dst(Boolean.TRUE).build(),
+                new DstNxTunIpv4DstCaseBuilder().setNxTunIpv4Dst(Boolean.TRUE).build(),
+                31, false);
+    }
+
+    public static Action nxMoveNshc2ToTunId() {
+        return nxMoveRegAction(
+                new SrcNxNshc2CaseBuilder().setNxNshc2Dst(Boolean.TRUE).build(),
+                new DstNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(),
+                31, false);
+    }
+
+    public static Action nxLoadTunIdAction(BigInteger tunnelId, boolean groupBucket) {
+        return nxLoadRegAction(new DstNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(), tunnelId, 31, groupBucket);
+    }
+
     public static Action nxMultipathAction(OfjNxHashFields fields, Integer basis,
             OfjNxMpAlgorithm algorithm, Integer maxLink, Long arg, DstChoice dstChoice,
             Integer start, Integer end) {
diff --git a/utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/FlowUtils.java b/utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/FlowUtils.java
new file mode 100644 (file)
index 0000000..f916026
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2015 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.utils.mdsal.openflow;
+
+import com.google.common.base.Optional;
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+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.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FlowUtils {
+    private static final Logger LOG = LoggerFactory.getLogger(FlowUtils.class);
+    private static final String OPENFLOW = "openflow";
+    public final static long REG_VALUE_FROM_LOCAL = 0x1L;
+    public final static long REG_VALUE_FROM_REMOTE = 0x2L;
+    public static final Class<? extends NxmNxReg> REG_FIELD = NxmNxReg0.class;
+    public static final int ARP_OP_REQUEST = 0x1;
+    public static final int ARP_OP_REPLY = 0x2;
+
+
+    public static String getNodeName(long dpidLong) {
+        return OPENFLOW + ":" + dpidLong;
+    }
+
+    public static NodeConnectorId getNodeConnectorId(long ofPort, String nodeName) {
+        return new NodeConnectorId(nodeName + ":" + ofPort);
+    }
+
+    public static NodeConnectorId getSpecialNodeConnectorId(long dpidLong, String portName) {
+        return new NodeConnectorId(getNodeName(dpidLong) + ":" + portName);
+    }
+
+    public static NodeConnectorId getNodeConnectorId(long dpidLong, long ofPort) {
+        return getNodeConnectorId(ofPort, getNodeName(dpidLong));
+    }
+
+    public static NodeBuilder createNodeBuilder(String nodeId) {
+        NodeBuilder builder = new NodeBuilder();
+        builder.setId(new NodeId(nodeId));
+        builder.setKey(new NodeKey(builder.getId()));
+        return builder;
+    }
+
+    public static NodeBuilder createNodeBuilder(long dpidLong) {
+        return createNodeBuilder(getNodeName(dpidLong));
+    }
+
+    public static InstanceIdentifier<Flow> createFlowPath(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
+        return InstanceIdentifier.builder(Nodes.class)
+                .child(Node.class, nodeBuilder.getKey())
+                .augmentation(FlowCapableNode.class)
+                .child(Table.class, new TableKey(flowBuilder.getTableId()))
+                .child(Flow.class, flowBuilder.getKey()).build();
+    }
+
+    public static InstanceIdentifier<Node> createNodePath(NodeBuilder nodeBuilder) {
+        return InstanceIdentifier.builder(Nodes.class).child(Node.class, nodeBuilder.getKey()).build();
+    }
+
+    public static Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder,
+                               ReadOnlyTransaction readTx, final LogicalDatastoreType store) {
+        try {
+            Optional<Flow> data = readTx.read(store, createFlowPath(flowBuilder, nodeBuilder)).get();
+            if (data.isPresent()) {
+                return data.get();
+            }
+        } catch (InterruptedException|ExecutionException e) {
+            LOG.error(e.getMessage(), e);
+        }
+
+        LOG.info("Cannot find data for Flow {} in {}", flowBuilder.getFlowName(), store);
+        return null;
+    }
+
+    public static FlowBuilder getPipelineFlow(short table, short gotoTable) {
+        FlowBuilder flowBuilder = new FlowBuilder();
+        flowBuilder.setMatch(new MatchBuilder().build());
+
+        String flowId = "DEFAULT_PIPELINE_FLOW_" + table;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(true);
+        flowBuilder.setBarrier(false);
+        flowBuilder.setTableId(table);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        flowBuilder.setPriority(0);
+        return flowBuilder;
+    }
+}
index 627849b2e88f8e4eabd1e4551c2a5c37ce68fae5..4534e8efc6eeb0d8bec24a36f511b7a7f6e97d11 100644 (file)
@@ -68,8 +68,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
 
-import com.google.common.collect.Lists;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -91,7 +89,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createSendToControllerInstructions(String nodeName, InstructionBuilder ib) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
 
         OutputActionBuilder output = new OutputActionBuilder();
@@ -124,7 +122,7 @@ public class InstructionUtils {
 
     public static InstructionBuilder createNormalInstructions(String nodeName, InstructionBuilder ib) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
 
         OutputActionBuilder output = new OutputActionBuilder();
@@ -146,6 +144,35 @@ public class InstructionUtils {
         return ib;
     }
 
+    /**
+     * Create LOCAL Reserved Port Instruction
+     *
+     * @param ib Map InstructionBuilder without any instructions
+     * @param dpidLong Long the datapath ID of a switch/node
+     * @return ib Map InstructionBuilder with instructions
+     */
+    public static InstructionBuilder createLocalInstructions(InstructionBuilder ib, long dpidLong) {
+        List<Action> actionList = new ArrayList<>();
+        ActionBuilder ab = new ActionBuilder();
+
+        OutputActionBuilder output = new OutputActionBuilder();
+        output.setOutputNodeConnector(new NodeConnectorId("openflow:" + dpidLong + ":"
+                + OutputPortValues.LOCAL.toString()));
+        ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
+        ab.setOrder(0);
+        ab.setKey(new ActionKey(0));
+        actionList.add(ab.build());
+
+        // Create an Apply Action
+        ApplyActionsBuilder aab = new ApplyActionsBuilder();
+        aab.setAction(actionList);
+
+        // Wrap our Apply Action in an Instruction
+        ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+
+        return ib;
+    }
+
     /**
      * Create Output Port Instruction
      *
@@ -160,7 +187,7 @@ public class InstructionUtils {
         LOG.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ",
                 dpidLong, port);
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
         OutputActionBuilder oab = new OutputActionBuilder();
         oab.setOutputNodeConnector(ncid);
@@ -196,7 +223,7 @@ public class InstructionUtils {
                 "addOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}",
                 dpidLong, port, instructions);
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
 
         List<Action> existingActions;
@@ -242,7 +269,7 @@ public class InstructionUtils {
                 "removeOutputPortFromInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}",
                 dpidLong, port, instructions);
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab;
 
         // Start of by locating actions that will have port removed, from the existing instructionList
@@ -345,7 +372,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createSetVlanInstructions(InstructionBuilder ib, VlanId vlanId) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
 
         /* First we push vlan header */
@@ -380,7 +407,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createPopVlanInstructions(InstructionBuilder ib) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
 
         PopVlanActionBuilder popVlanActionBuilder = new PopVlanActionBuilder();
@@ -407,7 +434,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createNwSrcInstructions(InstructionBuilder ib, Ipv4Prefix prefixsrc) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
 
         SetNwSrcActionBuilder setNwsrcActionBuilder = new SetNwSrcActionBuilder();
@@ -440,7 +467,7 @@ public class InstructionUtils {
     public static InstructionBuilder createNwDstInstructions(InstructionBuilder ib, Ipv4Prefix prefixdst,
                                                              ActionBuilder extraAction) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
 
         SetNwDstActionBuilder setNwDstActionBuilder = new SetNwDstActionBuilder();
@@ -484,7 +511,7 @@ public class InstructionUtils {
         ab.setKey(new ActionKey(0));
 
         // Add our drop action to a list
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         actionList.add(ab.build());
 
         // Create an Apply Action
@@ -524,7 +551,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createSetTunnelIdInstructions(InstructionBuilder ib, BigInteger tunnelId) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
 
@@ -555,7 +582,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createSetSrcTCPPort(InstructionBuilder ib, PortNumber tcpport) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
 
@@ -586,7 +613,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createSetDstTCPPort(InstructionBuilder ib, PortNumber tcpport) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
 
@@ -617,7 +644,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createSetSrcUDPPort(InstructionBuilder ib, PortNumber udpport) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
 
@@ -648,7 +675,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createSetDstUDPPort(InstructionBuilder ib, PortNumber udpport) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
 
@@ -680,7 +707,7 @@ public class InstructionUtils {
 
     public static InstructionBuilder createSetIcmpCodeInstruction(InstructionBuilder ib, short code) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
@@ -710,7 +737,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createSetIcmpTypeInstruction(InstructionBuilder ib, short type) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
@@ -747,7 +774,7 @@ public class InstructionUtils {
         ab.setKey(new ActionKey(0));
 
         // Add our drop action to a list
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         actionList.add(ab.build());
 
         // Create an Apply Action
@@ -768,7 +795,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createSrcArpMacInstructions(InstructionBuilder ib, MacAddress macsrc) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
 
         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
@@ -798,7 +825,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createDstArpMacInstructions(InstructionBuilder ib, MacAddress macdst) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
 
@@ -827,7 +854,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createDstArpIpInstructions(InstructionBuilder ib, Ipv4Prefix dstiparp) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
 
@@ -855,7 +882,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createSrcArpIpInstructions(InstructionBuilder ib, Ipv4Prefix srciparp) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
 
@@ -883,7 +910,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createTunnelIpv4SrcInstructions(InstructionBuilder ib, Ipv4Prefix srcIp) {
 
-        List<Action> actionList = new ArrayList<Action>();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
 
         // Build the tunnel endpoint source IPv4 address
@@ -917,7 +944,7 @@ public class InstructionUtils {
      */
     public static InstructionBuilder createTunnelIpv4DstInstructions(InstructionBuilder ib, Ipv4Prefix dstIp) {
 
-        List<Action> actionList = new ArrayList<Action>();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
 
         // Build the tunnel endpoint dst IPv4 address
@@ -974,7 +1001,7 @@ public class InstructionUtils {
 
     public static InstructionBuilder createDlSrcInstructions(InstructionBuilder ib, MacAddress macAddress) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
 
         SetDlSrcActionBuilder dlSrcActionBuilder= new SetDlSrcActionBuilder();
@@ -999,7 +1026,7 @@ public class InstructionUtils {
 
     public static InstructionBuilder createDlDstInstructions(InstructionBuilder ib, MacAddress macAddress) {
 
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         ActionBuilder ab = new ActionBuilder();
 
         SetDlDstActionBuilder dlDstActionBuilder= new SetDlDstActionBuilder();
@@ -1024,7 +1051,7 @@ public class InstructionUtils {
     public static List<Action>
                   actionList(org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action... actions) {
 
-        ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> alist
+        List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> alist
             = new ArrayList<>();
         int count = 0;
         for (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action : actions) {
index dd7222080a038e32243008a9970afb0902104088..930a1d507b8f25a70e7aee8f517819346630e24f 100644 (file)
@@ -81,6 +81,7 @@ public class MatchUtils {
     public static final String UDP = "udp";
     private static final int TCP_SYN = 0x0002;
     public static final String ICMP = "icmp";
+    public static final short ALL_ICMP = -1;
 
     /**
      * Create Ingress Port Match dpidLong, inPort
@@ -100,6 +101,17 @@ public class MatchUtils {
         return matchBuilder;
     }
 
+    public static MatchBuilder createInPortReservedMatch(MatchBuilder matchBuilder, Long dpidLong, String inPort) {
+
+        NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + inPort);
+        LOG.debug("createInPortResrevedMatch() Node Connector ID is - Type=openflow: DPID={} inPort={} ",
+                dpidLong, inPort);
+        matchBuilder.setInPort(NodeConnectorId.getDefaultInstance(ncid.getValue()));
+        matchBuilder.setInPort(ncid);
+
+        return matchBuilder;
+    }
+
     /**
      * Create EtherType Match
      *
@@ -208,8 +220,10 @@ public class MatchUtils {
 
         // Build the ICMPv4 Match
         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
-        icmpv4match.setIcmpv4Type(type);
-        icmpv4match.setIcmpv4Code(code);
+        if (type != ALL_ICMP || code != ALL_ICMP) {
+            icmpv4match.setIcmpv4Type(type);
+            icmpv4match.setIcmpv4Code(code);
+        }
         matchBuilder.setIcmpv4Match(icmpv4match.build());
 
         return matchBuilder;
@@ -244,7 +258,8 @@ public class MatchUtils {
      */
     public static MatchBuilder createArpDstIpv4Match(MatchBuilder matchBuilder, Ipv4Prefix dstip) {
         ArpMatchBuilder arpDstMatch = new ArpMatchBuilder();
-        arpDstMatch.setArpTargetTransportAddress(dstip);
+        arpDstMatch.setArpTargetTransportAddress(dstip)
+                .setArpOp(FlowUtils.ARP_OP_REQUEST);
         matchBuilder.setLayer3Match(arpDstMatch.build());
 
         return matchBuilder;
@@ -1075,8 +1090,7 @@ public class MatchUtils {
         }
     }
 
-    public static void addNxRegMatch(MatchBuilder match,
-                                     RegMatch... matches) {
+    public static MatchBuilder addNxRegMatch(MatchBuilder matchBuilder, RegMatch... matches) {
         List<ExtensionList> extensions = new ArrayList<>();
         for (RegMatch rm : matches) {
             Class<? extends ExtensionKey> key;
@@ -1099,67 +1113,68 @@ public class MatchUtils {
             }
             NxAugMatchNodesNodeTableFlow am =
                     new NxAugMatchNodesNodeTableFlowBuilder()
-                .setNxmNxReg(new NxmNxRegBuilder()
-                    .setReg(rm.reg)
-                    .setValue(rm.value)
-                    .build())
-                .build();
+                            .setNxmNxReg(new NxmNxRegBuilder()
+                                    .setReg(rm.reg)
+                                    .setValue(rm.value)
+                                    .build())
+                            .build();
             extensions.add(new ExtensionListBuilder()
-                .setExtensionKey(key)
-                .setExtension(new ExtensionBuilder()
-                     .addAugmentation(NxAugMatchNodesNodeTableFlow.class, am)
-                     .build())
-                .build());
+                    .setExtensionKey(key)
+                    .setExtension(new ExtensionBuilder()
+                            .addAugmentation(NxAugMatchNodesNodeTableFlow.class, am)
+                            .build())
+                    .build());
         }
-        GeneralAugMatchNodesNodeTableFlow m =
-                new GeneralAugMatchNodesNodeTableFlowBuilder()
-            .setExtensionList(extensions)
-            .build();
-        match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
+        GeneralAugMatchNodesNodeTableFlow m = new GeneralAugMatchNodesNodeTableFlowBuilder()
+                .setExtensionList(extensions)
+                .build();
+        matchBuilder.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
+        return matchBuilder;
     }
 
-    public static void addNxTunIdMatch(MatchBuilder match,
-                                       int tunId) {
-        NxAugMatchNodesNodeTableFlow am =
-               new NxAugMatchNodesNodeTableFlowBuilder()
-                   .setNxmNxTunId(new NxmNxTunIdBuilder()
-                       .setValue(BigInteger.valueOf(tunId))
-                       .build())
-                   .build();
+    public static MatchBuilder addNxTunIdMatch(MatchBuilder matchBuilder, int tunId) {
+        NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder()
+                .setNxmNxTunId(new NxmNxTunIdBuilder()
+                        .setValue(BigInteger.valueOf(tunId))
+                        .build())
+                .build();
         GeneralAugMatchNodesNodeTableFlow m =
                 new GeneralAugMatchNodesNodeTableFlowBuilder()
-            .setExtensionList(ImmutableList.of(new ExtensionListBuilder()
-                .setExtensionKey(NxmNxTunIdKey.class)
-                .setExtension(new ExtensionBuilder()
-                    .addAugmentation(NxAugMatchNodesNodeTableFlow.class, am)
-                    .build())
-                .build()))
-            .build();
-        match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
+                        .setExtensionList(ImmutableList.of(new ExtensionListBuilder()
+                                .setExtensionKey(NxmNxTunIdKey.class)
+                                .setExtension(new ExtensionBuilder()
+                                        .addAugmentation(NxAugMatchNodesNodeTableFlow.class, am)
+                                        .build())
+                                .build()))
+                        .build();
+        matchBuilder.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
+        return matchBuilder;
     }
 
-    public static void addNxNsp(MatchBuilder match, long nsp) {
-        org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow am =
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlowBuilder()
+    public static MatchBuilder addNxNspMatch(MatchBuilder matchBuilder, long nsp) {
+        NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder()
                 .setNxmNxNsp(new NxmNxNspBuilder()
-                .setValue(nsp)
-                .build())
+                        .setValue(nsp)
+                        .build())
                 .build();
-        addExtension(match, NxmNxNspKey.class, am);
+        addExtension(matchBuilder, NxmNxNspKey.class, am);
+        return matchBuilder;
     }
 
-    public static void addNxNsi(MatchBuilder match, short nsi) {
-        org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow am =
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlowBuilder()
+    public static MatchBuilder addNxNsiMatch(MatchBuilder matchBuilder, short nsi) {
+        NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder()
                 .setNxmNxNsi(new NxmNxNsiBuilder()
-                .setNsi(nsi)
-                .build())
+                        .setNsi(nsi)
+                        .build())
                 .build();
-        addExtension(match, NxmNxNsiKey.class, am);
+        addExtension(matchBuilder, NxmNxNsiKey.class, am);
+        return matchBuilder;
     }
 
-    private static void addExtension (MatchBuilder match, Class<? extends ExtensionKey> extensionKey, org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow am) {
-        GeneralAugMatchNodesNodeTableFlow existingAugmentations = match.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
+    private static void addExtension(MatchBuilder matchBuilder, Class<? extends ExtensionKey> extensionKey,
+                                     NxAugMatchNodesNodeTableFlow am) {
+        GeneralAugMatchNodesNodeTableFlow existingAugmentations =
+                matchBuilder.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
         List<ExtensionList> extensions = null;
         if (existingAugmentations != null ) {
             extensions = existingAugmentations.getExtensionList();
@@ -1169,16 +1184,16 @@ public class MatchUtils {
         }
 
         extensions.add(new ExtensionListBuilder()
-                           .setExtensionKey(extensionKey)
-                           .setExtension(new ExtensionBuilder()
-                           .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow.class, am)
-                           .build())
-                           .build());
+                .setExtensionKey(extensionKey)
+                .setExtension(new ExtensionBuilder()
+                        .addAugmentation(NxAugMatchNodesNodeTableFlow.class, am)
+                        .build())
+                .build());
 
         GeneralAugMatchNodesNodeTableFlow m = new GeneralAugMatchNodesNodeTableFlowBuilder()
-        .setExtensionList(extensions)
-        .build();
-        match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
+                .setExtensionList(extensions)
+                .build();
+        matchBuilder.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
     }
 
     public static EthernetMatch ethernetMatch(MacAddress srcMac,
index ffdb77d2bea3b71906a7743f02d1e8dcad8512d7..11ddb71dd893cf3145bbb52d631b1a3d5b43d3b0 100644 (file)
   <version>1.2.1-SNAPSHOT</version>
   <packaging>bundle</packaging>
 
+  <developers>
+    <developer>
+      <name>Anil Vishnoi</name>
+      <email>vishnoianil@gmail.com</email>
+      <url>https://github.com/vishnoianil</url>
+    </developer>
+  </developers>
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/ovsdb.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/ovsdb.git</developerConnection>
+    <tag>HEAD</tag>
+    <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
+  </scm>
+
+  <properties>
+    <neutron.model.version>0.6.0-SNAPSHOT</neutron.model.version>
+  </properties>
+
   <dependencies>
     <dependency>
       <groupId>com.google.guava</groupId>
       <artifactId>mockito-all</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.neutron</groupId>
+      <artifactId>model</artifactId>
+      <version>${neutron.model.version}</version>
+    </dependency>
   </dependencies>
 
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Export-Package>
+              org.opendaylight.ovsdb.utils.mdsal.utils
+            </Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
\ No newline at end of file
diff --git a/utils/mdsal-utils/src/main/java/org/opendaylight/ovsdb/utils/mdsal/utils/NeutronModelsDataStoreHelper.java b/utils/mdsal-utils/src/main/java/org/opendaylight/ovsdb/utils/mdsal/utils/NeutronModelsDataStoreHelper.java
new file mode 100644 (file)
index 0000000..e22b724
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.utils.mdsal.utils;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronModelsDataStoreHelper {
+
+    private static final Logger LOG = LoggerFactory.getLogger(MdsalUtils.class);
+    private DataBroker databroker = null;
+    private MdsalUtils mdsalClient = null;
+
+    /**
+     * Class constructor setting the data broker.
+     *
+     * @param dataBroker the {@link org.opendaylight.controller.md.sal.binding.api.DataBroker}
+     */
+    public NeutronModelsDataStoreHelper(DataBroker dataBroker) {
+        this.databroker = dataBroker;
+        this.mdsalClient = new MdsalUtils(this.databroker);
+    }
+
+    public Routers readAllNeutronRouters() {
+        Routers routers = this.mdsalClient.read(LogicalDatastoreType.CONFIGURATION, getNeutrounRoutersPath());
+        if(routers != null ) {
+            LOG.debug("{} routers present in data store", routers.getRouter()!=null? routers.getRouter().size():0);
+        }
+        return routers;
+    }
+
+    public Ports readAllNeutronPorts() {
+        Ports ports = this.mdsalClient.read(LogicalDatastoreType.CONFIGURATION, getNeutrounPortsPath());
+        if(ports != null ) {
+            LOG.debug("{} ports present in data store", ports.getPort()!=null? ports.getPort().size():0);
+        }
+        return ports;
+    }
+    public Port readNeutronPort(Uuid portId) {
+        Port mdsalPort = this.mdsalClient.read(LogicalDatastoreType.CONFIGURATION, getNeutronPortPath(portId));
+        if (mdsalPort != null) {
+            LOG.debug("Port {} fetched from config data store for router interface {}",mdsalPort, portId);
+        }
+        return mdsalPort;
+    }
+
+    private InstanceIdentifier<Routers> getNeutrounRoutersPath() {
+        return InstanceIdentifier
+                .create(Neutron.class)
+                .child(Routers.class);
+    }
+
+    private InstanceIdentifier<Ports> getNeutrounPortsPath() {
+        return InstanceIdentifier
+                .create(Neutron.class)
+                .child(Ports.class);
+    }
+
+    private InstanceIdentifier<Port> getNeutronPortPath(Uuid portId) {
+        return InstanceIdentifier
+                .create(Neutron.class)
+                .child(Ports.class)
+                .child(Port.class,new PortKey(portId));
+    }
+}
index 73da69da6b0cc0a8ee2460ec83ef91d84f6ad04f..f34a96dc1227db6a2ea95541e44ab393d29dddae 100644 (file)
@@ -95,6 +95,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
         <groupId>org.apache.felix</groupId>
         <artifactId>maven-bundle-plugin</artifactId>
         <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Export-Package>
+              org.opendaylight.ovsdb.utils.servicehelper
+            </Export-Package>
+          </instructions>
+        </configuration>
       </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
index 7ac9a396bb8c244232eb5788dd3aab3b48ffda90..9111acc92e35f5b81e5b8e7873461039f6d52bfa 100644 (file)
@@ -10,12 +10,11 @@ package org.opendaylight.ovsdb.utils.southbound.utils;
 
 import com.google.common.collect.ImmutableBiMap;
 import java.net.InetAddress;
-import java.net.NetworkInterface;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
-import java.util.Enumeration;
 
 import java.util.List;
+import java.util.Map;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
@@ -23,15 +22,7 @@ import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
@@ -40,13 +31,24 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.re
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -57,11 +59,31 @@ public class SouthboundUtils {
     private static final String DEFAULT_OPENFLOW_PORT = "6653";
     private static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
     private MdsalUtils mdsalUtils;
+    public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
 
     public SouthboundUtils(MdsalUtils mdsalUtils) {
         this.mdsalUtils = mdsalUtils;
     }
 
+    public static final ImmutableBiMap<String, Class<? extends InterfaceTypeBase>> OVSDB_INTERFACE_TYPE_MAP
+            = new ImmutableBiMap.Builder<String, Class<? extends InterfaceTypeBase>>()
+            .put("internal", InterfaceTypeInternal.class)
+            .put("vxlan", InterfaceTypeVxlan.class)
+            .put("patch", InterfaceTypePatch.class)
+            .put("system", InterfaceTypeSystem.class)
+            .put("tap", InterfaceTypeTap.class)
+            .put("geneve", InterfaceTypeGeneve.class)
+            .put("gre", InterfaceTypeGre.class)
+            .put("ipsec_gre", InterfaceTypeIpsecGre.class)
+            .put("gre64", InterfaceTypeGre64.class)
+            .put("ipsec_gre64", InterfaceTypeIpsecGre64.class)
+            .put("lisp", InterfaceTypeLisp.class)
+            .put("dpdk", InterfaceTypeDpdk.class)
+            .put("dpdkr", InterfaceTypeDpdkr.class)
+            .put("dpdkvhost", InterfaceTypeDpdkvhost.class)
+            .put("dpdkvhostuser", InterfaceTypeDpdkvhostuser.class)
+            .build();
+
     public NodeId createNodeId(IpAddress ip, PortNumber port) {
         String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
                 + new String(ip.getValue()) + ":" + port.getValue();
@@ -99,6 +121,18 @@ public class SouthboundUtils {
         return SouthboundMapper.createInstanceIdentifier(createManagedNodeId(key, bridgeName));
     }
 
+    public InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(Node node, String portName){
+
+        InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
+                .create(NetworkTopology.class)
+                .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
+                .child(Node.class,node.getKey())
+                .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
+
+        LOG.debug("Termination point InstanceIdentifier generated : {}",terminationPointPath);
+        return terminationPointPath;
+    }
+
     public NodeKey createNodeKey(IpAddress ip, PortNumber port) {
         return new NodeKey(createNodeId(ip, port));
     }
@@ -144,15 +178,14 @@ public class SouthboundUtils {
         try {
             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
         } catch (InterruptedException e) {
-            e.printStackTrace();
+            LOG.warn("Interrupted while waiting after adding OVSDB node {}", connectionInfoToString(connectionInfo), e);
         }
         return result;
     }
 
     public Node getOvsdbNode(final ConnectionInfo connectionInfo) {
-        Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
+        return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
                 createInstanceIdentifier(connectionInfo));
-        return node;
     }
 
     public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) {
@@ -161,7 +194,8 @@ public class SouthboundUtils {
         try {
             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
         } catch (InterruptedException e) {
-            e.printStackTrace();
+            LOG.warn("Interrupted while waiting after deleting OVSDB node {}", connectionInfoToString(connectionInfo),
+                    e);
         }
         return result;
     }
@@ -240,7 +274,7 @@ public class SouthboundUtils {
         try {
             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
         } catch (InterruptedException e) {
-            e.printStackTrace();
+            LOG.warn("Interrupted while waiting after deleting bridge {}", bridgeName, e);
         }
         return result;
     }
@@ -270,12 +304,13 @@ public class SouthboundUtils {
      * @throws InterruptedException
      */
     public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
-                              final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
-                              final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
-                              final Class<? extends DatapathTypeBase> dpType,
-                              final List<BridgeExternalIds> externalIds,
-                              final List<ControllerEntry> controllerEntries,
-                              final List<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
+                             final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
+                             final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
+                             final Class<? extends DatapathTypeBase> dpType,
+                             final List<BridgeExternalIds> externalIds,
+                             final List<ControllerEntry> controllerEntries,
+                             final List<BridgeOtherConfigs> otherConfigs,
+                             final String dpid) throws InterruptedException {
 
         NodeBuilder bridgeNodeBuilder = new NodeBuilder();
         if (bridgeIid == null) {
@@ -308,6 +343,10 @@ public class SouthboundUtils {
         if (otherConfigs != null) {
             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
         }
+        if (dpid != null && !dpid.isEmpty()) {
+            DatapathId datapathId = new DatapathId(dpid);
+            ovsdbBridgeAugmentationBuilder.setDatapathId(datapathId);
+        }
         bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
         LOG.debug("Built with the intent to store bridge data {}",
                 ovsdbBridgeAugmentationBuilder.toString());
@@ -317,9 +356,85 @@ public class SouthboundUtils {
         return result;
     }
 
+    public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
+                             final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
+                             final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
+                             final Class<? extends DatapathTypeBase> dpType,
+                             final List<BridgeExternalIds> externalIds,
+                             final List<ControllerEntry> controllerEntries,
+                             final List<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
+        return addBridge(connectionInfo, bridgeIid, bridgeName, bridgeNodeId, setProtocolEntries,
+                failMode, setManagedBy, dpType, externalIds, controllerEntries,
+                otherConfigs, null);
+    }
+
+    public boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName)
+            throws InterruptedException {
+
+        return addBridge(connectionInfo, null, bridgeName, null, true,
+                SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
+    }
+
     private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
                               final ConnectionInfo connectionInfo) {
         InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
     }
+
+    public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName,
+                                       String type, Map<String, String> options,
+                                       Map<String, String> externalIds) {
+        InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
+        OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
+
+        tpAugmentationBuilder.setName(portName);
+        if (type != null) {
+            tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
+        }
+
+        if (options != null && options.size() > 0) {
+            List<Options> optionsList = new ArrayList<>();
+            for (Map.Entry<String, String> entry : options.entrySet()) {
+                OptionsBuilder optionsBuilder = new OptionsBuilder();
+                optionsBuilder.setKey(new OptionsKey(entry.getKey()));
+                optionsBuilder.setOption(entry.getKey());
+                optionsBuilder.setValue(entry.getValue());
+                optionsList.add(optionsBuilder.build());
+            }
+            tpAugmentationBuilder.setOptions(optionsList);
+        }
+
+        if (externalIds != null && externalIds.size() > 0) {
+            List<InterfaceExternalIds> externalIdsList = new ArrayList<>();
+            for (Map.Entry<String, String> entry : externalIds.entrySet()) {
+                InterfaceExternalIdsBuilder interfaceExternalIdsBuilder = new InterfaceExternalIdsBuilder();
+                interfaceExternalIdsBuilder.setKey(new InterfaceExternalIdsKey(entry.getKey()));
+                interfaceExternalIdsBuilder.setExternalIdKey(entry.getKey());
+                interfaceExternalIdsBuilder.setExternalIdValue(entry.getValue());
+                externalIdsList.add(interfaceExternalIdsBuilder.build());
+            }
+            tpAugmentationBuilder.setInterfaceExternalIds(externalIdsList);
+        }
+
+        TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+        tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
+        tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
+        /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
+        return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
+    }
+
+    public TerminationPoint readTerminationPoint(Node bridgeNode, String bridgeName, String portName) {
+        InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
+                bridgeNode, portName);
+        return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpIid);
+    }
+
+    public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName, String type) {
+        return addTerminationPoint(bridgeNode, bridgeName, portName, type, null, null);
+    }
+
+    public Boolean addTunnelTerminationPoint(Node bridgeNode, String bridgeName, String portName, String type,
+                                             Map<String, String> options) {
+        return addTerminationPoint(bridgeNode, bridgeName, portName, type, options, null);
+    }
 }